@hology/core 0.0.275 → 0.0.276

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.
Files changed (80) hide show
  1. package/dist/effects/sequence/sequence-player.d.ts +1 -0
  2. package/dist/effects/sequence/sequence-player.js +1 -1
  3. package/dist/gameplay/actors/builtin/components/index.d.ts +6 -0
  4. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  5. package/dist/gameplay/actors/builtin/components/primitive-mesh-component.d.ts +66 -0
  6. package/dist/gameplay/actors/builtin/components/primitive-mesh-component.js +4 -0
  7. package/dist/gameplay/actors/builtin/index.d.ts +6 -0
  8. package/dist/gameplay/actors/builtin/index.js +1 -1
  9. package/dist/gameplay/actors/builtin/light-actor.d.ts +54 -0
  10. package/dist/gameplay/actors/builtin/light-actor.js +4 -0
  11. package/dist/gameplay/actors/builtin/mesh-actor.d.ts +9 -0
  12. package/dist/gameplay/actors/builtin/mesh-actor.js +4 -0
  13. package/dist/gameplay/actors/factory.js +1 -1
  14. package/dist/gameplay/actors/index.d.ts +5 -0
  15. package/dist/gameplay/actors/index.js +1 -1
  16. package/dist/gameplay/index.d.ts +1 -0
  17. package/dist/gameplay/index.js +1 -1
  18. package/dist/gameplay/initiate.js +1 -1
  19. package/dist/gameplay/rendering-host.d.ts +1 -0
  20. package/dist/gameplay/rendering-host.js +1 -1
  21. package/dist/gameplay/services/asset-loader.d.ts +3 -0
  22. package/dist/gameplay/services/asset-loader.js +1 -1
  23. package/dist/gameplay/services/physics/physics-system.js +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +1 -1
  26. package/dist/rendering/node-material-webgpu-resolver.d.ts +1 -0
  27. package/dist/rendering/node-material-webgpu-resolver.js +1 -1
  28. package/dist/rendering/post-process-color.d.ts +9 -0
  29. package/dist/rendering/post-process-color.js +4 -0
  30. package/dist/rendering/webgl-backend.d.ts +243 -9
  31. package/dist/rendering/webgl-backend.js +1 -1
  32. package/dist/rendering/webgpu-experimental-backend.d.ts +4 -1
  33. package/dist/rendering/webgpu-experimental-backend.js +1 -1
  34. package/dist/rendering.d.ts +45 -209
  35. package/dist/rendering.js +1 -1
  36. package/dist/scene/actor-material-parameters.d.ts +19 -0
  37. package/dist/scene/actor-material-parameters.js +4 -0
  38. package/dist/scene/actor-mesh-provider.d.ts +2 -0
  39. package/dist/scene/actor-mesh-provider.js +4 -0
  40. package/dist/scene/actor-mesh-renderer.d.ts +40 -0
  41. package/dist/scene/actor-mesh-renderer.js +4 -0
  42. package/dist/scene/asset-resource-loader.d.ts +2 -0
  43. package/dist/scene/asset-resource-loader.js +1 -1
  44. package/dist/scene/batched-mesh-2.js +1 -1
  45. package/dist/scene/custom-param-deserialize.js +1 -1
  46. package/dist/scene/custom-param-runtime-types.js +1 -1
  47. package/dist/scene/material-ref.d.ts +7 -0
  48. package/dist/scene/material-ref.js +4 -0
  49. package/dist/scene/materializer.d.ts +16 -0
  50. package/dist/scene/materializer.js +1 -1
  51. package/dist/scene/model.d.ts +2 -1
  52. package/dist/scene/model.js +1 -1
  53. package/dist/scene/runtime-bundled-backend-service.d.ts +1 -0
  54. package/dist/scene/runtime-bundled-backend-service.js +1 -1
  55. package/dist/scene/scene-object-actor-conversion.d.ts +10 -0
  56. package/dist/scene/scene-object-actor-conversion.js +4 -0
  57. package/dist/shader/parameter.d.ts +5 -2
  58. package/dist/shader-nodes/particle.d.ts +2 -2
  59. package/dist/test/actor-mesh-renderer.test.d.ts +2 -0
  60. package/dist/test/actor-mesh-renderer.test.js +4 -0
  61. package/dist/test/actor-persistence-runtime.test.js +1 -1
  62. package/dist/test/asset-resource-loader-converted-fbx.test.js +1 -1
  63. package/dist/test/asset-resource-loader-skinned-merge.test.js +1 -1
  64. package/dist/test/landscape-static-draw-sets.test.js +1 -1
  65. package/dist/test/node-material-webgpu-resolver.test.js +1 -1
  66. package/dist/test/physics-ray-object.test.js +1 -1
  67. package/dist/test/primitive-actors.test.d.ts +2 -0
  68. package/dist/test/primitive-actors.test.js +4 -0
  69. package/dist/test/rendering-host.test.js +1 -1
  70. package/dist/test/runtime-bundled-backend-service.test.d.ts +2 -0
  71. package/dist/test/runtime-bundled-backend-service.test.js +4 -0
  72. package/dist/test/scene-object-actor-conversion.test.d.ts +2 -0
  73. package/dist/test/scene-object-actor-conversion.test.js +4 -0
  74. package/dist/test/webgl-backend.test.d.ts +2 -0
  75. package/dist/test/webgl-backend.test.js +4 -0
  76. package/dist/utils/async.d.ts +2 -0
  77. package/dist/utils/async.js +1 -1
  78. package/dist/utils/mesh.js +1 -1
  79. package/package.json +2 -2
  80. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import{createAuthoredCollisionShapes as e}from"./collision/authored-colliders.js";import{parseAnimationClips as t}from"./animation-binary.js";import{AudioLoader as r,BufferGeometry as i,Group as a,LoadingManager as s,Mesh as n,Object3D as o,Texture as l,TextureLoader as c,Vector3 as h}from"three";import{MTLLoader as u,OBJLoader as m,LUTCubeLoader as d}from"three-stdlib";import{cloneMesh as p,mergeCompatibleSkinnedMeshes as f}from"../utils/mesh.js";import{pathJoin as g}from"../utils/files.js";import{Subject as y,firstValueFrom as x}from"rxjs";import{importCollisionShapes as w,isCollisionMesh as M}from"./collision/collision-shape-import.js";import*as b from"three";import{iterateMaterials as A}from"../utils/materials.js";import{applyMaterial as T,getConvertedFbxToGlbAssignedMaterialTextureFlipY as L}from"./materializer.js";import{BufferGeometryUtils as v,DRACOLoader as S,EXRLoader as _,FBXLoader as R,GLTFLoader as K,KTX2Loader as B,TGALoader as C,UltraHDRLoader as F}from"three/examples/jsm/Addons.js";import{disposeScene as I}from"../utils/three/cleanup.js";import{resolveAnimationRigBasisRotation as P,setAnimationClipRigId as k}from"../gameplay/animation/retarget.js";import{parseNativeTexture as D,selectNativeTexture as j}from"./native-texture.js";(()=>{const e=new Uint8Array([255,0,0,255]),t=new b.DataTexture(e,1,1,b.RGBAFormat);t.needsUpdate=!0})();const W=new S;W.setDecoderConfig({type:"js"}),W.setDecoderPath("/assets/draco/");const U=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new K(this.loadingManager).setDRACOLoader(W),this.fbxLoader=new R(this.loadingManager),this.objLoader=new m(this.loadingManager),this.textureLoader=new c(this.loadingManager),this.tgaLoader=new C(this.loadingManager),this.exrLoader=new _(this.loadingManager),this.cubeLoader=new d(this.loadingManager),this.hdrLoader=new F(this.loadingManager),this.ktx2Loader=new B(this.loadingManager),this.ktx2Ready=Promise.resolve(),this.nativeTextureLoader=new b.FileLoader(this.loadingManager).setResponseType("arraybuffer"),this.nativeBcSupported=!1,this.nativeAstcSupported=!1,this._textureLoader=new b.ImageBitmapLoader(this.loadingManager),this.audioLoader=new r(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new y,this.ready=x(this.makeReady),this.directFileLoading=!1,this.imageTextureOrientations=new WeakMap,this._texturePromises=new Map,this._arrayTexturesByFileKey=new Map,this._arrayTexturePromisesByFileKey=new Map,this._arrayTextureSettingsByFileKey=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.clipsRequests=new Set,this.timeToLoadClips=0,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}setDirectFileLoading(e){this.directFileLoading=e}setImageBitmapDecoder(e){this.imageBitmapDecoder=e}setImageTextureDecoder(e){this.imageTextureDecoder=e}decodeImageBitmap(e){return this.imageBitmapDecoder?.(e)}configureKtx2(){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.setWorkerLimit(6)}initKtx2(e){this.configureKtx2(),this.ktx2Loader.detectSupport(e),this.nativeBcSupported=e.extensions.has("EXT_texture_compression_bptc"),this.nativeAstcSupported=e.extensions.has("WEBGL_compressed_texture_astc")}initKtx2ForWebGpu(e){this.configureKtx2(),this.ktx2Ready=Promise.resolve(e??navigator.gpu?.requestAdapter({powerPreference:"high-performance"})??null).then(e=>{this.nativeBcSupported=!0===e?.features.has("texture-compression-bc"),this.nativeAstcSupported=!0===e?.features.has("texture-compression-astc"),this.ktx2Loader.detectSupport({isWebGPURenderer:!0,hasFeature:t=>"texture-compression-bptc"===t?this.nativeBcSupported:!0===e?.features.has(t)})})}setDataDir(e){this.basePath=g(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){if(e.startsWith("asset://"))return e;const t=function(e){return G.get(e)}(e),r=getElectronArg("windowId");return null!=r||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?g(this.basePath,e)+(null!=r?`?windowId=${r}${null!=t?`&v=${t}`:""}`:""):new URL(g("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if("png"===e.fileFormat||e.fileFormat,this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;await this.ready,e.fileKey.toLowerCase().endsWith(".ktx2")&&await this.ktx2Ready;const t=e.texture?.flipY??!0,r=this.textureCache.get(e.id);if(r&&this.imageTextureOrientations.has(r)&&this.imageTextureOrientations.get(r)!==t&&this.textureCache.delete(e.id),this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);if(null!=e.texture){const r=!this.imageTextureOrientations.has(t)&&N(t,e);t.flipY!==r?(t.needsUpdate=!0,t.flipY=r):t.wrapS!==O(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=O(e.texture?.wrapS)):t.wrapT!==O(e.texture?.wrapT)&&(t.wrapT=O(e.texture?.wrapT),t.needsUpdate=!0)}const r=Y(q(e));t.colorSpace!==r&&(t.colorSpace=r,t.needsUpdate=!0)}else try{const r=this._getTextureLoader(e.fileKey),i=(null!=this.imageTextureDecoder||null!=this.imageBitmapDecoder)&&/\.(png|jpe?g)$/i.test(e.fileKey),a=i||this.directFileLoading&&r===this.textureLoader,s=this.getUri(e.fileKey),n=i?(this.imageTextureDecoder?.(s,t)??this.imageBitmapDecoder(s)).catch(t=>(console.warn(`Worker image decode failed for ${e.name}; falling back to ImageBitmapLoader`,t),this._textureLoader.loadAsync(s))):e.texture?.nativeFileKeys&&r===this.ktx2Loader?this.loadKtx2Texture(e.fileKey,e.texture.nativeFileKeys):(a?this._textureLoader:r).loadAsync(s);await n.then(r=>(i&&this.imageTextureDecoder&&r.isTexture&&this.imageTextureOrientations.set(r,t),a&&!r.isTexture&&((r=new l(r)).needsUpdate=!0),r.texture3D?r=r.texture3D:(r.wrapS=O(e.texture?.wrapS),r.wrapT=O(e.texture?.wrapT),r.flipY=!this.imageTextureOrientations.has(r)&&N(r,e),r.colorSpace=Y(q(e))),this.textureCache.set(e.id,r),this._retrievedTextures.push(r),r))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}const i=this.textureCache.get(e.id);return null!=i&&(i.userData.assetId=e.id),i}async getTextureArray(e){const t=e.texture?.textureArrayFileKey,r=e.texture?.textureArrayLayer;if(!t||null==r)return{texture:null,layerIndex:null};let i=this._arrayTexturesByFileKey.get(t);if(null==i){let r=this._arrayTexturePromisesByFileKey.get(t);null==r&&(r=this.loadTextureArray(t,e.texture?.nativeArrayFileKeys).finally(()=>{this._arrayTexturePromisesByFileKey.delete(t)}),this._arrayTexturePromisesByFileKey.set(t,r)),i=await r}return this.applyTextureArraySettings(t,i,e),{texture:i,layerIndex:r}}async loadKtx2Texture(e,t){await this.ktx2Ready;const r=j(t,this.nativeBcSupported,this.nativeAstcSupported);if(r)try{const e=await this.nativeTextureLoader.loadAsync(this.getUri(r.fileKey));return D(e,r.format)}catch(e){console.warn(`Failed to load native texture ${r.fileKey}; using portable KTX2`,e)}return this._getTextureLoader(e).loadAsync(this.getUri(e))}async loadTextureArray(e,t){let r=await this.loadKtx2Texture(e,t);return r instanceof l||(r=r.texture3D),this._arrayTexturesByFileKey.set(e,r),this._retrievedTextures.push(r),r}applyTextureArraySettings(e,t,r){const i=function(e){return{wrapS:O(e.texture?.wrapS),wrapT:O(e.texture?.wrapT)}}(r),a=this._arrayTextureSettingsByFileKey.get(e);if(null!=a&&(n=i,(s=a).wrapS!==n.wrapS||s.wrapT!==n.wrapT))return void console.warn(`Texture array ${e} is used with incompatible texture settings. Texture arrays share wrapping; rebuild arrays so incompatible textures are grouped separately.`);var s,n;null==a&&this._arrayTextureSettingsByFileKey.set(e,i);let o=!1;t.wrapS!==i.wrapS&&(t.wrapS=i.wrapS,o=!0),t.wrapT!==i.wrapT&&(t.wrapT=i.wrapT,o=!0),!1!==t.flipY&&(t.flipY=!1,o=!0),o&&(t.needsUpdate=!0)}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){this.clearCacheByAsset(e)}clearCacheByAsset(e){null!=e&&(this.clearCacheById(e.id),null!=e.fileKey&&(Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)}),Array.from(this.asyncMeshResults.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.asyncMeshResults.delete(t)}),Array.from(this._animationCache.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationCache.delete(t)}),Array.from(this._animationPromises.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationPromises.delete(t)}),z(e.fileKey)),null!=e.materialLib&&z(e.materialLib))}clearCacheById(e){const t=Array.from(this.cache.values()).find(t=>t.scene.userData.assetId===e);t&&Array.from(this.cache.keys()).forEach(e=>{this.cache.get(e)===t&&this.cache.delete(e)}),this.textureCache.delete(e),this._texturePromises.delete(e),Array.from(this.collisionShapeCache.keys()).forEach(t=>{t.startsWith(e+"|")&&this.collisionShapeCache.delete(t)})}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new a,animations:[]};if(!U.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new a,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new a,animations:[]}}const i=this.cache.get(r),s=i.scene,o=i.animations;if(!1===t?.clone)return{scene:s,animations:o};const l=this.computeCollisionShapes(e,s),c=(e.mesh?.secondaryMotion?.regions.length??0)>0;!0!==t?.mergeGeomtries||c||this.optimizeDrawGroups(s);const h=p(s);h.traverse(e=>{e instanceof n&&e.material instanceof Array&&(e.material=e.material.slice())});const u=new AssetMeshInstance;u.add(h),u.collisionShapes=l,u.animations=o,u.userData.assetId=e.id,u.userData.secondaryMotion=e.mesh?.secondaryMotion,function(e){const t=e.children.length>0?e.children:[e];for(let e=0;e<t.length;e++)r(t[e],"",e);function r(e,t,i){const a=e instanceof n?"Mesh":"Group",s=`${t}/${e.name?.trim()?.length>0?e.name:a}[${i}]`;e.userData.secondaryMotionMeshPath=s;for(let t=0;t<e.children.length;t++)r(e.children[t],s,t)}}(u);const m=e.mesh?.animationRigId??e.anim?.rigId;if(u.userData.animationRigId=m,h.userData.animationRigId=m,null!=m&&null!=this.animationRigProvider){const e=await this.animationRigProvider(m);u.userData.animationRig=e,h.userData.animationRig=e,null!=e&&!1!==t?.applyRigBasis&&u.quaternion.copy(P(e))}const d=e.receiveShadow??!1,f=e.castShadow??!1;if(h.traverse(e=>{e.castShadow=f,e.receiveShadow=d}),!0===t?.rescale&&"number"==typeof e.mesh?.rescale&&u.scale.setScalar(e.mesh?.rescale),!0===t?.applyMaterials){const r=t?.materialResolver??this.materialProvider;if(null!=r)for(const t of e.materialAssignments??[])await T(u,t,r,void 0,{textureFlipY:L(e)});else console.warn(`applyMaterials was set to true for ${e.name} but no material resolver was provided.`)}return{scene:u,animations:o}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const r=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,r),r}async getAnimationClip(e){if(null==e||null==e.fileKey||null==e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const r=e.anim.clip,i=e.fileKey,a=i+"|"+r;if(this._animationCache.has(a))return this._animationCache.get(a);if(this._animationPromises.has(a))return this._animationPromises.get(a);this.clipsRequests.add(e.id);const s=(async()=>{try{const s=("anim"===e.fileFormat?t(await new b.FileLoader(this.loadingManager).setResponseType("arraybuffer").loadAsync(this.getUri(i))):(await this.getMesh(e,{mergeGeomtries:!1,clone:!1})).animations).find(e=>e.name===r);return null!=s&&(k(s,e.anim?.rigId),this._animationCache.set(a,s)),s}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(a),1e3)}})();return this._animationPromises.set(a,s),s}computeCollisionShapes(t,r){if(!0!==t.collisionDetection)return[];const i=t.id+"|"+(t.mesh?.collisions?.shapeType??"")+"|"+(t.mesh?.rescale??1)+"|"+JSON.stringify(t.mesh?.colliders??[]);if(!this.collisionShapeCache.has(i)){const a=t.mesh?.colliders??[],s=a.length>0?e(a,t.mesh?.rescale):w(r,t);this.collisionShapeCache.set(i,s)}return this.collisionShapeCache.get(i)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(t=>(t.scene.traverse(t=>{if(t instanceof n&&t.geometry instanceof i){const r=removeInvalidFaces(t.geometry);r>0&&console.warn(`Removed ${r} invalid face${1===r?"":"s"} from ${e.name}/${t.name||"unnamed mesh"}`)}t instanceof n&&t.material&&function(e){let t=e.material;if(null==t)return;Array.isArray(t)?e.material=t.map(H):e.material=H(t)}(t),M(t)?t.visible=!1:t instanceof n&&t.geometry instanceof i&&(t.geometry.hasAttribute("normal")||t.geometry.computeVertexNormals())}),this._retrievedMeshes.push(t.scene),t.scene=function(e,t){let r=!1;if(t.traverseVisible(e=>{J.test(e.name)&&(r=!0)}),!r)return t;const i=[],a=[t];for(;a.length>0;){const e=a.shift(),t=e.name.match(J);if(null!=t){const r=parseInt(t[1]);if(0!==r){console.warn(`Skipping LOD level ${r} for now as LOD is not fully supported`),i.push(e);continue}}a.push(...e.children)}for(const e of i)e.removeFromParent();return t}(0,t.scene),function(e){const t=V;V.length=0,e.traverse(e=>{(e instanceof b.Camera||e instanceof b.Light)&&t.push(e)}),t.forEach(e=>e.removeFromParent())}(t.scene),t.scene.userData.assetId=e.id,t))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid),e.updateWorldMatrix(!0,!0);const t=[];e.traverse(e=>{e instanceof n&&!(e instanceof b.SkinnedMesh)&&e.geometry instanceof i&&Array.isArray(e.material)&&!M(e)&&t.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:r,geometry:i,materialArray:a,parent:s}of t){r.removeFromParent();for(let t=0;t<a.length;t++){const o=a[t],l=i.groups.filter(e=>e.materialIndex===t);if(0===l.length)continue;const c=this.extractGeometryGroups(i,l);c.groups.length>1&&v.mergeGroups(c);const h=new n(c,o);h.copy(r,!1),h.geometry=c,h.material=o,s?s.add(h):e.add(h)}i.dispose()}f(e,M);let r=!0,a=0,s=0;if(e.traverse(e=>{if(e instanceof n&&e.geometry instanceof i&&!M(e)){a++;const t=Object.keys(e.geometry.attributes).length;t!==s&&0!==s&&(r=!1),s=t}else(e instanceof b.SkinnedMesh||e instanceof b.Bone)&&(r=!1)}),a>1&&r){const t=new Map;e.traverse(r=>{if(r instanceof n&&r.geometry instanceof i&&!M(r)){if(Array.isArray(r.material))return;r.updateWorldMatrix(!0,!0);const i=r.material?.uuid||"default";t.has(i)||t.set(i,{material:r.material,geometries:[],objects:[]});const a=t.get(i),s=e.matrixWorld.clone().invert().multiply(r.matrixWorld);a.geometries.push(r.geometry.clone().applyMatrix4(s)),a.objects.push(r)}});for(const e of t.values())for(const t of e.objects)t.removeFromParent();for(const r of t.values()){let t,i=r.geometries;if(i.some(e=>null!=e.index)&&(i=i.map(e=>{if(null!=e.index)return e;const t=e.getAttribute("position");if(null==t)return e;const r=t.count>65535?new Uint32Array(t.count):new Uint16Array(t.count);for(let e=0;e<r.length;e++)r[e]=e;return e.setIndex(new b.BufferAttribute(r,1)),e})),t=1===r.geometries.length?i[0]:E(i)?v.mergeGeometries(i,!0):null,null!=t)t.groups.length>1&&v.mergeGroups(t),e.add(new n(t,r.material));else for(const t of i)e.add(new n(t,r.material))}}e.traverse(e=>{if(e instanceof n&&e.geometry instanceof i&&!M(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&v.mergeGroups(t)}})}extractGeometryGroups(e,t){const r=e.index;if(!r){const r=new i;let a=0;for(const e of t)a+=e.count;if(0===a)return r;for(const i in e.attributes){const s=e.attributes[i],n=s.itemSize,o=s.array,l=new(0,o.constructor)(a*n);let c=0;for(const e of t){const t=e.start*n,r=e.count*n;for(let e=0;e<r;e++)l[c+e]=o[t+e];c+=r}const h=new b.BufferAttribute(l,n,s.normalized);r.setAttribute(i,h)}return r.groups=[{start:0,count:a,materialIndex:0}],r}const a=[];for(const e of t)for(let t=0;t<e.count;t++){const i=r.getX(e.start+t);a.push(i)}if(0===a.length)return new i;const s=new Map,n=[];let o=0;for(const e of a)s.has(e)||(s.set(e,o),o++),n.push(s.get(e));if(0===n.length||0===s.size)return new i;const l=new i;for(const t in e.attributes){const r=e.attributes[t],i=r.itemSize,a=r.array,n=new(0,a.constructor)(s.size*i);for(const[e,t]of s)for(let r=0;r<i;r++)n[t*i+r]=a[e*i+r];const o=new b.BufferAttribute(n,i,r.normalized);l.setAttribute(t,o)}const c=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)c[e]=n[e];return l.setIndex(new b.BufferAttribute(c,1)),l.groups=[{start:0,count:n.length,materialIndex:0}],l}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(t=>{const r=!0===e.originalFileKey?.toLowerCase().endsWith(".fbx")&&1===t.scene.children.length?t.scene.children[0]:t.scene;return r!==t.scene&&t.scene.remove(r),{scene:r,animations:t.animations}});case"fbx":if(this.directFileLoading){const e=await fetch(t);if(!e.ok)throw new Error(`Failed to load FBX ${t}: ${e.status}`);const r=await e.arrayBuffer(),i=this.fbxLoader.parse(r,b.LoaderUtils.extractUrlBase(t));return{scene:i,animations:i.animations}}return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new u;t.materialOptions={normalizeRGB:!1};const r=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(r)}return this.objLoader.loadAsync(t).then(e=>($(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>I(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}const G=new Map;function z(e){G.set(e,(G.get(e)??0)+1)}function E(e){if(e.length<2)return!0;const t=e[0],r=Object.keys(t.attributes).sort(),i=Object.keys(t.morphAttributes).sort();return e.slice(1).every(e=>{if(null==e.index!=(null==t.index))return!1;if(e.morphTargetsRelative!==t.morphTargetsRelative)return!1;const a=Object.keys(e.attributes).sort(),s=Object.keys(e.morphAttributes).sort();if(a.join("|")!==r.join("|"))return!1;if(s.join("|")!==i.join("|"))return!1;for(const i of r){const r=t.getAttribute(i),a=e.getAttribute(i);if(r.itemSize!==a.itemSize||r.normalized!==a.normalized||r.array.constructor!==a.array.constructor)return!1}for(const r of i){const i=t.morphAttributes[r],a=e.morphAttributes[r];if(i.length!==a.length)return!1;for(let e=0;e<i.length;e++)if(i[e].itemSize!==a[e].itemSize||i[e].normalized!==a[e].normalized||i[e].array.constructor!==a[e].array.constructor)return!1}return!0})}function $(e){if(e instanceof n)for(const t of A(e.material))t instanceof b.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach($)}export class AssetMeshInstance extends o{}export{createAuthoredCollisionShapes}from"./collision/authored-colliders.js";export function getElectronArg(e){const t=`--${e}=`,r=window.process?.argv.find(e=>e.startsWith(t));return r?.substring(t.length)}function O(e){switch(e){case"clamp":return b.ClampToEdgeWrapping;case"repeat":return b.RepeatWrapping;case"mirror":return b.MirroredRepeatWrapping}return b.RepeatWrapping}function N(e,t){const r=e;return!0!==r.isCompressedTexture&&!0!==r.isCompressedArrayTexture&&(t.texture?.flipY??!0)}function q(e){return e.texture?.colorSpace??function(e){if("exr"===e.fileFormat||e.fileKey?.toLowerCase().endsWith(".exr"))return"linear";const t=`${e.name} ${e.fileKey??""}`.toLowerCase();if(X.some(e=>t.includes(e)))return"linear";return"srgb"}(e)}function Y(e){return"linear"===e?b.LinearSRGBColorSpace:b.SRGBColorSpace}const X=["_normal","_nrm","_nor","_norm","_roughness","_rough","_metalness","_metallic","_metal","_ao","_ambient","_occlusion","_mask","_height","_disp","_displacement","_bump","_opacity"];new b.Matrix4;const V=[];const J=/_LOD(\d+)/;export function removeInvalidFaces(e){const t=e.getAttribute("position");if(null==t||t.itemSize<3)return 0;const r=e.index,i=r?.count??t.count,a=Math.floor(i/3),s=[],n=new Uint32Array(a+1),o=new h,l=new h,c=new h;let u=0;for(let e=0;e<a;e++){const i=3*e,a=r?.getX(i)??i,h=r?.getX(i+1)??i+1,m=r?.getX(i+2)??i+2;let d=Number.isInteger(a)&&Number.isInteger(h)&&Number.isInteger(m)&&a>=0&&h>=0&&m>=0&&a<t.count&&h<t.count&&m<t.count;if(d){o.fromBufferAttribute(t,a),l.fromBufferAttribute(t,h).sub(o),c.fromBufferAttribute(t,m).sub(o);const e=Math.max(l.lengthSq(),c.lengthSq(),l.distanceToSquared(c)),r=l.cross(c).lengthSq();d=Number.isFinite(e)&&Number.isFinite(r)&&e>0&&r>Number.EPSILON*e*e}d?s.push(a,h,m):u++,n[e+1]=s.length}if(0===u)return 0;if(e.setIndex(s),e.groups.length>0){const t=e.groups.slice();e.clearGroups();for(const r of t){const t=Math.max(0,Math.ceil(r.start/3)),i=Math.min(a,Math.floor((r.start+r.count)/3));if(i<=t)continue;const s=n[t],o=n[i]-s;o>0&&e.addGroup(s,o,r.materialIndex)}}const m=Math.max(0,Math.ceil(e.drawRange.start/3)),d=Number.isFinite(e.drawRange.count)?Math.min(a,Math.floor((e.drawRange.start+e.drawRange.count)/3)):a,p=Math.min(m,a),f=Math.min(a,Math.max(p,d)),g=n[p];return e.setDrawRange(g,n[f]-g),u}function H(e){let t=e instanceof b.MeshPhysicalMaterial&&0===e.sheen&&0===e.anisotropy;if("MeshLambertMaterial"===e.type||"MeshPhongMaterial"===e.type||t){let t={};(e instanceof b.MeshLambertMaterial||e instanceof b.MeshPhongMaterial||e instanceof b.MeshPhysicalMaterial)&&(t.color=e.color,t.map=e.map,t.bumpMap=e.bumpMap,t.bumpScale=e.bumpScale,t.lightMap=e.lightMap,t.lightMapIntensity=e.lightMapIntensity,t.aoMap=e.aoMap,t.aoMapIntensity=e.aoMapIntensity,t.emissiveMap=e.emissiveMap,t.alphaMap=e.alphaMap,t.envMap=e.envMap,t.envMapRotation=e.envMapRotation,t.wireframe=e.wireframe,t.wireframeLinewidth=e.wireframeLinewidth,t.fog=e.fog,t.opacity=e.opacity,t.transparent=e.transparent,t.side=e.side,t.depthTest=e.depthTest,t.depthWrite=e.depthWrite,t.alphaTest=e.alphaTest,t.displacementMap=e.displacementMap,t.displacementScale=e.displacementScale,t.displacementBias=e.displacementBias);const r=new b.MeshStandardMaterial(t);return r.userData={...e.userData??{}},r.name=e.name,r}return e}/*
1
+ import{createAuthoredCollisionShapes as e}from"./collision/authored-colliders.js";import{parseAnimationClips as t}from"./animation-binary.js";import{AudioLoader as r,BufferGeometry as i,Group as a,LoadingManager as s,Mesh as n,Object3D as o,Texture as l,TextureLoader as c,Vector3 as h}from"three";import{MTLLoader as u,OBJLoader as m,LUTCubeLoader as d}from"three-stdlib";import{cloneMesh as p,mergeCompatibleSkinnedMeshes as f}from"../utils/mesh.js";import{pathJoin as g}from"../utils/files.js";import{Subject as y,firstValueFrom as x}from"rxjs";import{importCollisionShapes as w,isCollisionMesh as M}from"./collision/collision-shape-import.js";import*as b from"three";import{iterateMaterials as A}from"../utils/materials.js";import{applyMaterial as T,getConvertedFbxToGlbAssignedMaterialTextureFlipY as L}from"./materializer.js";import{BufferGeometryUtils as v,DRACOLoader as S,EXRLoader as _,FBXLoader as R,GLTFLoader as K,KTX2Loader as B,TGALoader as C,UltraHDRLoader as F}from"three/examples/jsm/Addons.js";import{disposeScene as I}from"../utils/three/cleanup.js";import{resolveAnimationRigBasisRotation as P,setAnimationClipRigId as D}from"../gameplay/animation/retarget.js";import{parseNativeTexture as k,selectNativeTexture as j}from"./native-texture.js";(()=>{const e=new Uint8Array([255,0,0,255]),t=new b.DataTexture(e,1,1,b.RGBAFormat);t.needsUpdate=!0})();const W=new S;W.setDecoderConfig({type:"js"}),W.setDecoderPath("/assets/draco/");const U=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new K(this.loadingManager).setDRACOLoader(W),this.fbxLoader=new R(this.loadingManager),this.objLoader=new m(this.loadingManager),this.textureLoader=new c(this.loadingManager),this.tgaLoader=new C(this.loadingManager),this.exrLoader=new _(this.loadingManager),this.cubeLoader=new d(this.loadingManager),this.hdrLoader=new F(this.loadingManager),this.ktx2Loader=new B(this.loadingManager),this.ktx2Ready=Promise.resolve(),this.nativeTextureLoader=new b.FileLoader(this.loadingManager).setResponseType("arraybuffer"),this.nativeBcSupported=!1,this.nativeAstcSupported=!1,this._textureLoader=new b.ImageBitmapLoader(this.loadingManager),this.audioLoader=new r(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new y,this.ready=x(this.makeReady),this.directFileLoading=!1,this.imageTextureOrientations=new WeakMap,this._texturePromises=new Map,this._arrayTexturesByFileKey=new Map,this._arrayTexturePromisesByFileKey=new Map,this._arrayTextureSettingsByFileKey=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.clipsRequests=new Set,this.timeToLoadClips=0,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}setDirectFileLoading(e){this.directFileLoading=e}setImageBitmapDecoder(e){this.imageBitmapDecoder=e}setImageTextureDecoder(e){this.imageTextureDecoder=e}decodeImageBitmap(e){return this.imageBitmapDecoder?.(e)}configureKtx2(){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.setWorkerLimit(6)}initKtx2(e){this.configureKtx2(),this.ktx2Loader.detectSupport(e),this.nativeBcSupported=e.extensions.has("EXT_texture_compression_bptc"),this.nativeAstcSupported=e.extensions.has("WEBGL_compressed_texture_astc")}initKtx2ForWebGpu(e){this.configureKtx2(),this.ktx2Ready=Promise.resolve(e??navigator.gpu?.requestAdapter({powerPreference:"high-performance"})??null).then(e=>{this.nativeBcSupported=!0===e?.features.has("texture-compression-bc"),this.nativeAstcSupported=!0===e?.features.has("texture-compression-astc"),this.ktx2Loader.detectSupport({isWebGPURenderer:!0,hasFeature:t=>"texture-compression-bptc"===t?this.nativeBcSupported:!0===e?.features.has(t)})})}setDataDir(e){this.basePath=g(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){if(e.startsWith("asset://"))return e;const t=function(e){return G.get(e)}(e),r=getElectronArg("windowId");return null!=r||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?g(this.basePath,e)+(null!=r?`?windowId=${r}${null!=t?`&v=${t}`:""}`:""):new URL(g("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if("png"===e.fileFormat||e.fileFormat,this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;await this.ready,e.fileKey.toLowerCase().endsWith(".ktx2")&&await this.ktx2Ready;const t=e.texture?.flipY??!0,r=this.textureCache.get(e.id);if(r&&this.imageTextureOrientations.has(r)&&this.imageTextureOrientations.get(r)!==t&&this.textureCache.delete(e.id),this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);if(null!=e.texture){const r=!this.imageTextureOrientations.has(t)&&N(t,e);t.flipY!==r?(t.needsUpdate=!0,t.flipY=r):t.wrapS!==O(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=O(e.texture?.wrapS)):t.wrapT!==O(e.texture?.wrapT)&&(t.wrapT=O(e.texture?.wrapT),t.needsUpdate=!0)}const r=Y(q(e));t.colorSpace!==r&&(t.colorSpace=r,t.needsUpdate=!0)}else try{const r=this._getTextureLoader(e.fileKey),i=(null!=this.imageTextureDecoder||null!=this.imageBitmapDecoder)&&/\.(png|jpe?g)$/i.test(e.fileKey),a=i||this.directFileLoading&&r===this.textureLoader,s=this.getUri(e.fileKey),n=i?(this.imageTextureDecoder?.(s,t)??this.imageBitmapDecoder(s)).catch(t=>(console.warn(`Worker image decode failed for ${e.name}; falling back to ImageBitmapLoader`,t),this._textureLoader.loadAsync(s))):e.texture?.nativeFileKeys&&r===this.ktx2Loader?this.loadKtx2Texture(e.fileKey,e.texture.nativeFileKeys):(a?this._textureLoader:r).loadAsync(s);await n.then(r=>(i&&this.imageTextureDecoder&&r.isTexture&&this.imageTextureOrientations.set(r,t),a&&!r.isTexture&&((r=new l(r)).needsUpdate=!0),r.texture3D?r=r.texture3D:(r.wrapS=O(e.texture?.wrapS),r.wrapT=O(e.texture?.wrapT),r.flipY=!this.imageTextureOrientations.has(r)&&N(r,e),r.colorSpace=Y(q(e))),this.textureCache.set(e.id,r),this._retrievedTextures.push(r),r))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}const i=this.textureCache.get(e.id);return null!=i&&(i.userData.assetId=e.id),i}async getTextureArray(e){const t=e.texture?.textureArrayFileKey,r=e.texture?.textureArrayLayer;if(!t||null==r)return{texture:null,layerIndex:null};let i=this._arrayTexturesByFileKey.get(t);if(null==i){let r=this._arrayTexturePromisesByFileKey.get(t);null==r&&(r=this.loadTextureArray(t,e.texture?.nativeArrayFileKeys).finally(()=>{this._arrayTexturePromisesByFileKey.delete(t)}),this._arrayTexturePromisesByFileKey.set(t,r)),i=await r}return this.applyTextureArraySettings(t,i,e),{texture:i,layerIndex:r}}async loadKtx2Texture(e,t){await this.ktx2Ready;const r=j(t,this.nativeBcSupported,this.nativeAstcSupported);if(r)try{const e=await this.nativeTextureLoader.loadAsync(this.getUri(r.fileKey));return k(e,r.format)}catch(e){console.warn(`Failed to load native texture ${r.fileKey}; using portable KTX2`,e)}return this._getTextureLoader(e).loadAsync(this.getUri(e))}async loadTextureArray(e,t){let r=await this.loadKtx2Texture(e,t);return r instanceof l||(r=r.texture3D),this._arrayTexturesByFileKey.set(e,r),this._retrievedTextures.push(r),r}applyTextureArraySettings(e,t,r){const i=function(e){return{wrapS:O(e.texture?.wrapS),wrapT:O(e.texture?.wrapT)}}(r),a=this._arrayTextureSettingsByFileKey.get(e);if(null!=a&&(n=i,(s=a).wrapS!==n.wrapS||s.wrapT!==n.wrapT))return void console.warn(`Texture array ${e} is used with incompatible texture settings. Texture arrays share wrapping; rebuild arrays so incompatible textures are grouped separately.`);var s,n;null==a&&this._arrayTextureSettingsByFileKey.set(e,i);let o=!1;t.wrapS!==i.wrapS&&(t.wrapS=i.wrapS,o=!0),t.wrapT!==i.wrapT&&(t.wrapT=i.wrapT,o=!0),!1!==t.flipY&&(t.flipY=!1,o=!0),o&&(t.needsUpdate=!0)}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){this.clearCacheByAsset(e)}clearCacheByAsset(e){null!=e&&(this.clearCacheById(e.id),null!=e.fileKey&&(Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)}),Array.from(this.asyncMeshResults.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.asyncMeshResults.delete(t)}),Array.from(this._animationCache.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationCache.delete(t)}),Array.from(this._animationPromises.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationPromises.delete(t)}),z(e.fileKey)),null!=e.materialLib&&z(e.materialLib))}clearCacheById(e){const t=Array.from(this.cache.values()).find(t=>t.scene.userData.assetId===e);t&&Array.from(this.cache.keys()).forEach(e=>{this.cache.get(e)===t&&this.cache.delete(e)}),this.textureCache.delete(e),this._texturePromises.delete(e),Array.from(this.collisionShapeCache.keys()).forEach(t=>{t.startsWith(e+"|")&&this.collisionShapeCache.delete(t)})}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new a,animations:[]};if(!U.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new a,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new a,animations:[]}}const i=this.cache.get(r),s=i.scene,o=i.animations;if(!1===t?.clone)return{scene:s,animations:o};const l=this.computeCollisionShapes(e,s,t?.collisionDetection),c=(e.mesh?.secondaryMotion?.regions.length??0)>0;!0!==t?.mergeGeomtries||c||this.optimizeDrawGroups(s);const h=p(s);h.traverse(e=>{e instanceof n&&e.material instanceof Array&&(e.material=e.material.slice())});const u=new AssetMeshInstance;u.add(h),u.collisionShapes=l,u.animations=o,u.userData.assetId=e.id,u.userData.secondaryMotion=e.mesh?.secondaryMotion,function(e){const t=e.children.length>0?e.children:[e];for(let e=0;e<t.length;e++)r(t[e],"",e);function r(e,t,i){const a=e instanceof n?"Mesh":"Group",s=`${t}/${e.name?.trim()?.length>0?e.name:a}[${i}]`;e.userData.secondaryMotionMeshPath=s;for(let t=0;t<e.children.length;t++)r(e.children[t],s,t)}}(u);const m=e.mesh?.animationRigId??e.anim?.rigId;if(u.userData.animationRigId=m,h.userData.animationRigId=m,null!=m&&null!=this.animationRigProvider){const e=await this.animationRigProvider(m);u.userData.animationRig=e,h.userData.animationRig=e,null!=e&&!1!==t?.applyRigBasis&&u.quaternion.copy(P(e))}const d=e.receiveShadow??!1,f=e.castShadow??!1;if(h.traverse(e=>{e.castShadow=f,e.receiveShadow=d}),!0===t?.rescale&&"number"==typeof e.mesh?.rescale&&u.scale.setScalar(e.mesh?.rescale),!0===t?.applyMaterials){const r=t?.materialResolver??this.materialProvider;if(null!=r)for(const t of e.materialAssignments??[])await T(u,t,r,void 0,{textureFlipY:L(e)});else console.warn(`applyMaterials was set to true for ${e.name} but no material resolver was provided.`)}return{scene:u,animations:o}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const r=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,r),r}async getAnimationClip(e){if(null==e||null==e.fileKey||null==e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const r=e.anim.clip,i=e.fileKey,a=i+"|"+r;if(this._animationCache.has(a))return this._animationCache.get(a);if(this._animationPromises.has(a))return this._animationPromises.get(a);this.clipsRequests.add(e.id);const s=(async()=>{try{const s=("anim"===e.fileFormat?t(await new b.FileLoader(this.loadingManager).setResponseType("arraybuffer").loadAsync(this.getUri(i))):(await this.getMesh(e,{mergeGeomtries:!1,clone:!1})).animations).find(e=>e.name===r);return null!=s&&(D(s,e.anim?.rigId),this._animationCache.set(a,s)),s}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(a),1e3)}})();return this._animationPromises.set(a,s),s}computeCollisionShapes(t,r,i=!0===t.collisionDetection){if(!i)return[];const a=t.id+"|"+(t.mesh?.collisions?.shapeType??"")+"|"+(t.mesh?.rescale??1)+"|"+JSON.stringify(t.mesh?.colliders??[]);if(!this.collisionShapeCache.has(a)){const i=t.mesh?.colliders??[],s=i.length>0?e(i,t.mesh?.rescale):w(r,t);this.collisionShapeCache.set(a,s)}return this.collisionShapeCache.get(a)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(t=>(t.scene.traverse(t=>{if(t instanceof n&&t.geometry instanceof i){const r=removeInvalidFaces(t.geometry);r>0&&console.warn(`Removed ${r} invalid face${1===r?"":"s"} from ${e.name}/${t.name||"unnamed mesh"}`)}t instanceof n&&t.material&&function(e){let t=e.material;if(null==t)return;Array.isArray(t)?e.material=t.map(H):e.material=H(t)}(t),M(t)?t.visible=!1:t instanceof n&&t.geometry instanceof i&&(t.geometry.hasAttribute("normal")||t.geometry.computeVertexNormals())}),this._retrievedMeshes.push(t.scene),t.scene=function(e,t){let r=!1;if(t.traverseVisible(e=>{J.test(e.name)&&(r=!0)}),!r)return t;const i=[],a=[t];for(;a.length>0;){const e=a.shift(),t=e.name.match(J);if(null!=t){const r=parseInt(t[1]);if(0!==r){console.warn(`Skipping LOD level ${r} for now as LOD is not fully supported`),i.push(e);continue}}a.push(...e.children)}for(const e of i)e.removeFromParent();return t}(0,t.scene),function(e){const t=V;V.length=0,e.traverse(e=>{(e instanceof b.Camera||e instanceof b.Light)&&t.push(e)}),t.forEach(e=>e.removeFromParent())}(t.scene),t.scene.userData.assetId=e.id,t))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid),e.updateWorldMatrix(!0,!0);const t=[];e.traverse(e=>{e instanceof n&&!(e instanceof b.SkinnedMesh)&&e.geometry instanceof i&&Array.isArray(e.material)&&!M(e)&&t.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:r,geometry:i,materialArray:a,parent:s}of t){r.removeFromParent();for(let t=0;t<a.length;t++){const o=a[t],l=i.groups.filter(e=>e.materialIndex===t);if(0===l.length)continue;const c=this.extractGeometryGroups(i,l);c.groups.length>1&&v.mergeGroups(c);const h=new n(c,o);h.copy(r,!1),h.geometry=c,h.material=o,s?s.add(h):e.add(h)}i.dispose()}f(e,M);let r=!0,a=0,s=0;if(e.traverse(e=>{if(e instanceof n&&e.geometry instanceof i&&!M(e)){a++;const t=Object.keys(e.geometry.attributes).length;t!==s&&0!==s&&(r=!1),s=t}else(e instanceof b.SkinnedMesh||e instanceof b.Bone)&&(r=!1)}),a>1&&r){const t=new Map;e.traverse(r=>{if(r instanceof n&&r.geometry instanceof i&&!M(r)){if(Array.isArray(r.material))return;r.updateWorldMatrix(!0,!0);const i=r.material?.uuid||"default";t.has(i)||t.set(i,{material:r.material,geometries:[],objects:[]});const a=t.get(i),s=e.matrixWorld.clone().invert().multiply(r.matrixWorld);a.geometries.push(r.geometry.clone().applyMatrix4(s)),a.objects.push(r)}});for(const e of t.values())for(const t of e.objects)t.removeFromParent();for(const r of t.values()){let t,i=r.geometries;if(i.some(e=>null!=e.index)&&(i=i.map(e=>{if(null!=e.index)return e;const t=e.getAttribute("position");if(null==t)return e;const r=t.count>65535?new Uint32Array(t.count):new Uint16Array(t.count);for(let e=0;e<r.length;e++)r[e]=e;return e.setIndex(new b.BufferAttribute(r,1)),e})),t=1===r.geometries.length?i[0]:E(i)?v.mergeGeometries(i,!0):null,null!=t)t.groups.length>1&&v.mergeGroups(t),e.add(new n(t,r.material));else for(const t of i)e.add(new n(t,r.material))}}e.traverse(e=>{if(e instanceof n&&e.geometry instanceof i&&!M(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&v.mergeGroups(t)}})}extractGeometryGroups(e,t){const r=e.index;if(!r){const r=new i;let a=0;for(const e of t)a+=e.count;if(0===a)return r;for(const i in e.attributes){const s=e.attributes[i],n=s.itemSize,o=s.array,l=new(0,o.constructor)(a*n);let c=0;for(const e of t){const t=e.start*n,r=e.count*n;for(let e=0;e<r;e++)l[c+e]=o[t+e];c+=r}const h=new b.BufferAttribute(l,n,s.normalized);r.setAttribute(i,h)}return r.groups=[{start:0,count:a,materialIndex:0}],r}const a=[];for(const e of t)for(let t=0;t<e.count;t++){const i=r.getX(e.start+t);a.push(i)}if(0===a.length)return new i;const s=new Map,n=[];let o=0;for(const e of a)s.has(e)||(s.set(e,o),o++),n.push(s.get(e));if(0===n.length||0===s.size)return new i;const l=new i;for(const t in e.attributes){const r=e.attributes[t],i=r.itemSize,a=r.array,n=new(0,a.constructor)(s.size*i);for(const[e,t]of s)for(let r=0;r<i;r++)n[t*i+r]=a[e*i+r];const o=new b.BufferAttribute(n,i,r.normalized);l.setAttribute(t,o)}const c=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)c[e]=n[e];return l.setIndex(new b.BufferAttribute(c,1)),l.groups=[{start:0,count:n.length,materialIndex:0}],l}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(t=>{const r=!0===e.originalFileKey?.toLowerCase().endsWith(".fbx")&&1===t.scene.children.length?t.scene.children[0]:t.scene;return r!==t.scene&&t.scene.remove(r),{scene:r,animations:t.animations}});case"fbx":if(this.directFileLoading){const e=await fetch(t);if(!e.ok)throw new Error(`Failed to load FBX ${t}: ${e.status}`);const r=await e.arrayBuffer(),i=this.fbxLoader.parse(r,b.LoaderUtils.extractUrlBase(t));return{scene:i,animations:i.animations}}return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new u;t.materialOptions={normalizeRGB:!1};const r=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(r)}return this.objLoader.loadAsync(t).then(e=>($(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>I(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}const G=new Map;function z(e){G.set(e,(G.get(e)??0)+1)}function E(e){if(e.length<2)return!0;const t=e[0],r=Object.keys(t.attributes).sort(),i=Object.keys(t.morphAttributes).sort();return e.slice(1).every(e=>{if(null==e.index!=(null==t.index))return!1;if(e.morphTargetsRelative!==t.morphTargetsRelative)return!1;const a=Object.keys(e.attributes).sort(),s=Object.keys(e.morphAttributes).sort();if(a.join("|")!==r.join("|"))return!1;if(s.join("|")!==i.join("|"))return!1;for(const i of r){const r=t.getAttribute(i),a=e.getAttribute(i);if(r.itemSize!==a.itemSize||r.normalized!==a.normalized||r.array.constructor!==a.array.constructor)return!1}for(const r of i){const i=t.morphAttributes[r],a=e.morphAttributes[r];if(i.length!==a.length)return!1;for(let e=0;e<i.length;e++)if(i[e].itemSize!==a[e].itemSize||i[e].normalized!==a[e].normalized||i[e].array.constructor!==a[e].array.constructor)return!1}return!0})}function $(e){if(e instanceof n)for(const t of A(e.material))t instanceof b.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach($)}export class AssetMeshInstance extends o{}export{createAuthoredCollisionShapes}from"./collision/authored-colliders.js";export function getElectronArg(e){const t=`--${e}=`,r=window.process?.argv.find(e=>e.startsWith(t));return r?.substring(t.length)}function O(e){switch(e){case"clamp":return b.ClampToEdgeWrapping;case"repeat":return b.RepeatWrapping;case"mirror":return b.MirroredRepeatWrapping}return b.RepeatWrapping}function N(e,t){const r=e;return!0!==r.isCompressedTexture&&!0!==r.isCompressedArrayTexture&&(t.texture?.flipY??!0)}function q(e){return e.texture?.colorSpace??function(e){if("exr"===e.fileFormat||e.fileKey?.toLowerCase().endsWith(".exr"))return"linear";const t=`${e.name} ${e.fileKey??""}`.toLowerCase();if(X.some(e=>t.includes(e)))return"linear";return"srgb"}(e)}function Y(e){return"linear"===e?b.LinearSRGBColorSpace:b.SRGBColorSpace}const X=["_normal","_nrm","_nor","_norm","_roughness","_rough","_metalness","_metallic","_metal","_ao","_ambient","_occlusion","_mask","_height","_disp","_displacement","_bump","_opacity"];new b.Matrix4;const V=[];const J=/_LOD(\d+)/;export function removeInvalidFaces(e){const t=e.getAttribute("position");if(null==t||t.itemSize<3)return 0;const r=e.index,i=r?.count??t.count,a=Math.floor(i/3),s=[],n=new Uint32Array(a+1),o=new h,l=new h,c=new h;let u=0;for(let e=0;e<a;e++){const i=3*e,a=r?.getX(i)??i,h=r?.getX(i+1)??i+1,m=r?.getX(i+2)??i+2;let d=Number.isInteger(a)&&Number.isInteger(h)&&Number.isInteger(m)&&a>=0&&h>=0&&m>=0&&a<t.count&&h<t.count&&m<t.count;if(d){o.fromBufferAttribute(t,a),l.fromBufferAttribute(t,h).sub(o),c.fromBufferAttribute(t,m).sub(o);const e=Math.max(l.lengthSq(),c.lengthSq(),l.distanceToSquared(c)),r=l.cross(c).lengthSq();d=Number.isFinite(e)&&Number.isFinite(r)&&e>0&&r>Number.EPSILON*e*e}d?s.push(a,h,m):u++,n[e+1]=s.length}if(0===u)return 0;if(e.setIndex(s),e.groups.length>0){const t=e.groups.slice();e.clearGroups();for(const r of t){const t=Math.max(0,Math.ceil(r.start/3)),i=Math.min(a,Math.floor((r.start+r.count)/3));if(i<=t)continue;const s=n[t],o=n[i]-s;o>0&&e.addGroup(s,o,r.materialIndex)}}const m=Math.max(0,Math.ceil(e.drawRange.start/3)),d=Number.isFinite(e.drawRange.count)?Math.min(a,Math.floor((e.drawRange.start+e.drawRange.count)/3)):a,p=Math.min(m,a),f=Math.min(a,Math.max(p,d)),g=n[p];return e.setDrawRange(g,n[f]-g),u}function H(e){let t=e instanceof b.MeshPhysicalMaterial&&0===e.sheen&&0===e.anisotropy;if("MeshLambertMaterial"===e.type||"MeshPhongMaterial"===e.type||t){let t={};(e instanceof b.MeshLambertMaterial||e instanceof b.MeshPhongMaterial||e instanceof b.MeshPhysicalMaterial)&&(t.color=e.color,t.map=e.map,t.bumpMap=e.bumpMap,t.bumpScale=e.bumpScale,t.lightMap=e.lightMap,t.lightMapIntensity=e.lightMapIntensity,t.aoMap=e.aoMap,t.aoMapIntensity=e.aoMapIntensity,t.emissiveMap=e.emissiveMap,t.alphaMap=e.alphaMap,t.envMap=e.envMap,t.envMapRotation=e.envMapRotation,t.wireframe=e.wireframe,t.wireframeLinewidth=e.wireframeLinewidth,t.fog=e.fog,t.opacity=e.opacity,t.transparent=e.transparent,t.side=e.side,t.depthTest=e.depthTest,t.depthWrite=e.depthWrite,t.alphaTest=e.alphaTest,t.displacementMap=e.displacementMap,t.displacementScale=e.displacementScale,t.displacementBias=e.displacementBias);const r=new b.MeshStandardMaterial(t);return r.userData={...e.userData??{}},r.name=e.name,r}return e}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import*as t from"three";function s(t,s){return t.z-s.z}function e(t,s){return s.z-t.z}export class BatchedMesh2 extends t.BatchedMesh{constructor(){super(...arguments),this.uniformTextures={},this.uniformSize={},this.instanceCastShadowCount=0,this.surfaceByInstance=[],this.perInstanceCastShadow=!1,this.customSort=(t,n)=>{this.material.transparent?t.sort(e):t.sort(s)}}initUniform(s,e,n=0){if(e<1||e>4||3===e)throw"Element size must be between 1,2, or 4";let i=Math.sqrt(this.maxInstanceCount);i=Math.ceil(i);let a=t.RedFormat;2===e?a=t.RGFormat:4===e&&(a=t.RGBAFormat);const o=new Float32Array(i*i*e).fill(n),r=new t.DataTexture(o,i,i,a,t.FloatType);this.uniformTextures[s]=r,this.uniformSize[s]=e;const h=this.material;if(!(h instanceof t.ShaderMaterial))throw"Can not use custom uniforms with other materials than ShaderMaterial";for(const[t,s]of Object.entries(this.uniformTextures))h.uniforms[t]={value:s};h.uniformsNeedUpdate=!0}setUniformAt(s,e,n){const i=this.uniformTextures[s],a=i.image.data,o=this.getInstanceInfo(),r=o[e];if(e>=o.length||null==r||!1===r.active)return this;"number"==typeof n?a[e*this.uniformSize[s]]=n:n.toArray(a,e*this.uniformSize[s]),i.needsUpdate=!0;const h=this.material;h instanceof t.ShaderMaterial&&(h.uniformsNeedUpdate=!0)}getUniformAt(s,e,n){const i=this.uniformTextures[s].image.data,a=this.getInstanceInfo(),o=a[e];return e>=a.length||null==o||!1===o.active?null:1===this.uniformSize[s]?i[e]:void((n instanceof t.Vector2||n instanceof t.Vector2||n instanceof t.Vector3||n instanceof t.Vector4||n instanceof t.Color)&&n.fromArray(i,e*this.uniformSize[s]))}setCastShadowAt(t,s){const e=this.getInstanceInfo(),n=e[t];if(t>=e.length||null==n||!1===n.active)return this;this.setupInstanceCastShadow();const i=this.perInstanceCastShadow;this.perInstanceCastShadow=!0;const a=!0===this.instanceCastShadow[t];return a!==s&&(this.instanceCastShadow[t]=s,this.instanceCastShadowCount+=s?1:-1),this.castShadow=this.instanceCastShadowCount>0,a===s&&i||(this._visibilityChanged=!0),this}getCastShadowAt(t){return this.instanceCastShadow?.[t]??!1}setupInstanceCastShadow(){null==this.instanceCastShadow&&(this.instanceCastShadow=new Array(this.maxInstanceCount).fill(!1),this.instanceCastShadowCount=0)}getInstanceInfo(){return this._drawInfo??this._instanceInfo??[]}deleteInstance(t){const s=this.getInstanceInfo(),e=s[t]?.active&&!0===this.instanceCastShadow?.[t];return super.deleteInstance(t),e&&(this.instanceCastShadow[t]=!1,this.instanceCastShadowCount--,this.castShadow=this.instanceCastShadowCount>0,this._visibilityChanged=!0),this}onBeforeShadow(t,s,e,i,a,o,r){if(!this.perInstanceCastShadow)return void super.onBeforeShadow(t,s,e,i,a,o,r);const h=this.getInstanceInfo();n.length=0;for(let t=0,s=h.length;t<s;t++){const s=h[t];null!=s&&s.visible&&s.active&&!this.getCastShadowAt(t)&&(s.visible=!1,n.push(t))}n.length>0&&(this._visibilityChanged=!0);try{super.onBeforeShadow(t,s,e,i,a,o,r)}finally{for(const t of n){const s=h[t];null!=s&&(s.visible=!0)}n.length>0&&(this._visibilityChanged=!0)}}dispose(){super.dispose();for(const t of Object.values(this.uniformTextures))t.dispose();return this.uniformTextures=null,this}}const n=[];/*
1
+ import*as t from"three";function s(t,s){return t.z-s.z}function e(t,s){return s.z-t.z}export class BatchedMesh2 extends t.BatchedMesh{constructor(){super(...arguments),this.uniformTextures={},this.uniformSize={},this.instanceCastShadowCount=0,this.surfaceByInstance=[],this.perInstanceCastShadow=!1,this.customSort=(t,n)=>{this.material.transparent?t.sort(e):t.sort(s)}}initUniform(s,e,n=0){if(e<1||e>4||3===e)throw"Element size must be between 1,2, or 4";let i=Math.sqrt(this.maxInstanceCount);i=Math.ceil(i);let a=t.RedFormat;2===e?a=t.RGFormat:4===e&&(a=t.RGBAFormat);const o=new Float32Array(i*i*e).fill(n),r=new t.DataTexture(o,i,i,a,t.FloatType);this.uniformTextures[s]=r,this.uniformSize[s]=e;const h=this.material;if(!h.isShaderMaterial)throw"Can not use custom uniforms with other materials than ShaderMaterial";for(const[t,s]of Object.entries(this.uniformTextures))h.uniforms[t]={value:s};h.uniformsNeedUpdate=!0}setUniformAt(t,s,e){const n=this.uniformTextures[t],i=n.image.data,a=this.getInstanceInfo(),o=a[s];if(s>=a.length||null==o||!1===o.active)return this;"number"==typeof e?i[s*this.uniformSize[t]]=e:e.toArray(i,s*this.uniformSize[t]),n.needsUpdate=!0;const r=this.material;r.isShaderMaterial&&(r.uniformsNeedUpdate=!0)}getUniformAt(s,e,n){const i=this.uniformTextures[s].image.data,a=this.getInstanceInfo(),o=a[e];return e>=a.length||null==o||!1===o.active?null:1===this.uniformSize[s]?i[e]:n instanceof t.Vector2||n instanceof t.Vector2||n instanceof t.Vector3||n instanceof t.Vector4||n instanceof t.Color?(n.fromArray(i,e*this.uniformSize[s]),n):void 0}setCastShadowAt(t,s){const e=this.getInstanceInfo(),n=e[t];if(t>=e.length||null==n||!1===n.active)return this;this.setupInstanceCastShadow();const i=this.perInstanceCastShadow;this.perInstanceCastShadow=!0;const a=!0===this.instanceCastShadow[t];return a!==s&&(this.instanceCastShadow[t]=s,this.instanceCastShadowCount+=s?1:-1),this.castShadow=this.instanceCastShadowCount>0,a===s&&i||(this._visibilityChanged=!0),this}getCastShadowAt(t){return this.instanceCastShadow?.[t]??!1}setupInstanceCastShadow(){null==this.instanceCastShadow&&(this.instanceCastShadow=new Array(this.maxInstanceCount).fill(!1),this.instanceCastShadowCount=0)}getInstanceInfo(){return this._drawInfo??this._instanceInfo??[]}deleteInstance(t){const s=this.getInstanceInfo(),e=s[t]?.active&&!0===this.instanceCastShadow?.[t];return super.deleteInstance(t),e&&(this.instanceCastShadow[t]=!1,this.instanceCastShadowCount--,this.castShadow=this.instanceCastShadowCount>0,this._visibilityChanged=!0),this}onBeforeShadow(t,s,e,i,a,o,r){if(!this.perInstanceCastShadow)return void super.onBeforeShadow(t,s,e,i,a,o,r);const h=this.getInstanceInfo();n.length=0;for(let t=0,s=h.length;t<s;t++){const s=h[t];null!=s&&s.visible&&s.active&&!this.getCastShadowAt(t)&&(s.visible=!1,n.push(t))}n.length>0&&(this._visibilityChanged=!0);try{super.onBeforeShadow(t,s,e,i,a,o,r)}finally{for(const t of n){const s=h[t];null!=s&&(s.visible=!0)}n.length>0&&(this._visibilityChanged=!0)}}dispose(){super.dispose();for(const t of Object.values(this.uniformTextures))t.dispose();return this.uniformTextures=null,this}}const n=[];/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{Color as e,Euler as a,Vector2 as r,Vector3 as u,Vector4 as t}from"three";import{getParameterDefinitionType as l,isParameterDefinitionAbstract as n}from"../shader/parameter.js";import{Curve2 as s}from"../utils/curve.js";import{isSequenceData as c,Sequence as o}from"../effects/sequence/sequence-data.js";import{SerializedParamType as v}from"./model.js";import{ModelRef as i}from"./model-ref.js";export function customParamValueNeedsAsyncResolution(e){if(null==e||null==e.value||""===e.value)return!1;if(f(e))return e.value.some(a=>customParamValueNeedsAsyncResolution(m(e,a)));switch(e.type){case v.Texture:case v.Sampler2DNode:case v.Object3D:case v.Material:case v.AudioBuffer:case v.VisualEffect:case v.Prefab:case v.PrefabActor:case v.DataAsset:case v.AnimationClip:return!0;case v.Sequence:return!c(e.value);case v.SequenceData:return!1;case v.Struct:return Object.values(p(e.value)).some(e=>customParamValueNeedsAsyncResolution(e));default:return!1}}export function deserializeCustomParamValueSync(l,n={}){if(null==l||null==l.value||""===l.value)return l?.value??null;switch(l.type){case v.Array:return f(l)&&Array.isArray(l.value)?l.value.map(e=>deserializeCustomParamValueSync(m(l,e),n)):[];case v.Number:case v.FloatNode:return"string"==typeof l.value?parseFloat(l.value):l.value;case v.Boolean:case v.BooleanNode:case v.String:return l.value;case v.Vector2:case v.Vec2Node:return"object"==typeof l.value?Array.isArray(l.value)?(new r).fromArray(l.value):new r(l.value.x,l.value.y):null;case v.Vector3:case v.Vec3Node:return"object"==typeof l.value?Array.isArray(l.value)?(new u).fromArray(l.value):new u(l.value.x,l.value.y,l.value.z):null;case v.Vector4:case v.Vec4Node:return"object"==typeof l.value?Array.isArray(l.value)?(new t).fromArray(l.value):new t(l.value.x,l.value.y,l.value.z,l.value.w):null;case v.Color:case v.RgbNode:return new e(l.value);case v.Euler:return Array.isArray(l.value)?(new a).fromArray(l.value):l.value;case v.BaseActor:return n.actor?.(l.value)??l.value;case v.ModelRef:return"string"==typeof l.value?new i(l.value):null;case v.Sequence:return c(l.value)?new o(l.value):l.value;case v.SequenceData:return c(l.value)?l.value:null;case v.Curve:return s.decode(l.value);case v.Struct:return function(e,a){const r=A(e.value),u=y(r?.struct??e.struct);for(const[t,l]of Object.entries(r?.value??p(e.value)))u[t]=deserializeCustomParamValueSync(l,a);return u}(l,n);default:return l.value}}export async function deserializeCustomParamValue(e,a={}){if(null==e||null==e.value||""===e.value)return e?.value??null;if(!customParamValueNeedsAsyncResolution(e))return deserializeCustomParamValueSync(e,a);switch(e.type){case v.Array:return f(e)&&Array.isArray(e.value)?Promise.all(e.value.map(r=>deserializeCustomParamValue(m(e,r),a))):[];case v.Texture:return a.texture?.(e.value)??null;case v.Sampler2DNode:return a.sampler2DNode?.(e.value)??null;case v.Object3D:return a.object3D?.(e.value)??null;case v.Material:return a.material?.(e.value)??null;case v.AudioBuffer:return a.audioBuffer?.(e.value)??null;case v.VisualEffect:return a.visualEffect?.(e.value)??null;case v.Prefab:return a.prefab?.(e.value)??null;case v.PrefabActor:return a.prefabActor?.(e.value)??null;case v.DataAsset:return a.dataAsset?.(e.value)??null;case v.Sequence:return c(e.value)?new o(e.value):a.sequence?.(e.value)??null;case v.SequenceData:return c(e.value)?e.value:null;case v.AnimationClip:return a.animationClip?.(e.value)??null;case v.Struct:return async function(e,a){const r=A(e.value),u=y(r?.struct??e.struct);for(const[t,l]of Object.entries(r?.value??p(e.value)))u[t]=await deserializeCustomParamValue(l,a);return u}(e,a);default:return deserializeCustomParamValueSync(e,a)}}function f(e){return e.type===v.Array}function m(e,a){const r=A(a);return{type:e.element,...null!=r?.struct||null!=e.elementStruct?{struct:r?.struct??e.elementStruct}:{},value:r?.value??a}}function y(e){const a=null!=e?l(e):void 0;if(null==a||n(e))return{};try{return new a}catch{return{}}}function p(e){const a=A(e);return null!=a?a.value:d(e)?e:null!=e&&"object"==typeof e&&d(e.params)?e.params:{}}function A(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"string"==typeof e.struct&&d(e.value)?e:null}function d(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&Object.values(e).every(e=>null!=e&&"object"==typeof e&&"type"in e)}/*
1
+ import{Color as e,Euler as a,Vector2 as r,Vector3 as u,Vector4 as t}from"three";import{getParameterDefinitionType as l,isParameterDefinitionAbstract as n}from"../shader/parameter.js";import{Curve2 as s}from"../utils/curve.js";import{isSequenceData as c,Sequence as o}from"../effects/sequence/sequence-data.js";import{SerializedParamType as i}from"./model.js";import{ModelRef as v}from"./model-ref.js";import{MaterialRef as f}from"./material-ref.js";export function customParamValueNeedsAsyncResolution(e){if(null==e||null==e.value||""===e.value)return!1;if(m(e))return e.value.some(a=>customParamValueNeedsAsyncResolution(y(e,a)));switch(e.type){case i.Texture:case i.Sampler2DNode:case i.Object3D:case i.Material:case i.AudioBuffer:case i.VisualEffect:case i.Prefab:case i.PrefabActor:case i.DataAsset:case i.AnimationClip:return!0;case i.Sequence:return!c(e.value);case i.SequenceData:return!1;case i.Struct:return Object.values(A(e.value)).some(e=>customParamValueNeedsAsyncResolution(e));default:return!1}}export function deserializeCustomParamValueSync(l,n={}){if(null==l||null==l.value||""===l.value)return l?.value??null;switch(l.type){case i.Array:return m(l)&&Array.isArray(l.value)?l.value.map(e=>deserializeCustomParamValueSync(y(l,e),n)):[];case i.Number:case i.FloatNode:return"string"==typeof l.value?parseFloat(l.value):l.value;case i.Boolean:case i.BooleanNode:case i.String:return l.value;case i.Vector2:case i.Vec2Node:return"object"==typeof l.value?Array.isArray(l.value)?(new r).fromArray(l.value):new r(l.value.x,l.value.y):null;case i.Vector3:case i.Vec3Node:return"object"==typeof l.value?Array.isArray(l.value)?(new u).fromArray(l.value):new u(l.value.x,l.value.y,l.value.z):null;case i.Vector4:case i.Vec4Node:return"object"==typeof l.value?Array.isArray(l.value)?(new t).fromArray(l.value):new t(l.value.x,l.value.y,l.value.z,l.value.w):null;case i.Color:case i.RgbNode:return new e(l.value);case i.Euler:return Array.isArray(l.value)?(new a).fromArray(l.value):l.value;case i.BaseActor:return n.actor?.(l.value)??l.value;case i.ModelRef:return"string"==typeof l.value?new v(l.value):null;case i.MaterialRef:return"string"==typeof l.value?new f(l.value):null;case i.Sequence:return c(l.value)?new o(l.value):l.value;case i.SequenceData:return c(l.value)?l.value:null;case i.Curve:return s.decode(l.value);case i.Struct:return function(e,a){const r=d(e.value),u=p(r?.struct??e.struct);for(const[t,l]of Object.entries(r?.value??A(e.value)))u[t]=deserializeCustomParamValueSync(l,a);return u}(l,n);default:return l.value}}export async function deserializeCustomParamValue(e,a={}){if(null==e||null==e.value||""===e.value)return e?.value??null;if(!customParamValueNeedsAsyncResolution(e))return deserializeCustomParamValueSync(e,a);switch(e.type){case i.Array:return m(e)&&Array.isArray(e.value)?Promise.all(e.value.map(r=>deserializeCustomParamValue(y(e,r),a))):[];case i.Texture:return a.texture?.(e.value)??null;case i.Sampler2DNode:return a.sampler2DNode?.(e.value)??null;case i.Object3D:return a.object3D?.(e.value)??null;case i.Material:return a.material?.(e.value)??null;case i.AudioBuffer:return a.audioBuffer?.(e.value)??null;case i.VisualEffect:return a.visualEffect?.(e.value)??null;case i.Prefab:return a.prefab?.(e.value)??null;case i.PrefabActor:return a.prefabActor?.(e.value)??null;case i.DataAsset:return a.dataAsset?.(e.value)??null;case i.Sequence:return c(e.value)?new o(e.value):a.sequence?.(e.value)??null;case i.SequenceData:return c(e.value)?e.value:null;case i.AnimationClip:return a.animationClip?.(e.value)??null;case i.Struct:return async function(e,a){const r=d(e.value),u=p(r?.struct??e.struct);for(const[t,l]of Object.entries(r?.value??A(e.value)))u[t]=await deserializeCustomParamValue(l,a);return u}(e,a);default:return deserializeCustomParamValueSync(e,a)}}function m(e){return e.type===i.Array}function y(e,a){const r=d(a);return{type:e.element,...null!=r?.struct||null!=e.elementStruct?{struct:r?.struct??e.elementStruct}:{},value:r?.value??a}}function p(e){const a=null!=e?l(e):void 0;if(null==a||n(e))return{};try{return new a}catch{return{}}}function A(e){const a=d(e);return null!=a?a.value:b(e)?e:null!=e&&"object"==typeof e&&b(e.params)?e.params:{}}function d(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"string"==typeof e.struct&&b(e.value)?e:null}function b(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&Object.values(e).every(e=>null!=e&&"object"==typeof e&&"type"in e)}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{Color as e,Euler as r,Material as t,Object3D as n,Texture as u,Vector2 as o,Vector3 as a,Vector4 as c,AnimationClip as i}from"three";import{BooleanNode as l,FloatNode as s,RgbNode as f,Sampler2DNode as y,Texture2dLookupNode as p,Vec2Node as m,Vec3Node as d,Vec4Node as b}from"three-shader-graph";import{getParameterDefinitionId as A,getParameterDefinitionType as g,isParameterDefinitionStructAssignableTo as S}from"../shader/parameter.js";import{Curve2 as N}from"../utils/curve.js";import{isSequenceData as V}from"../effects/sequence/sequence-data.js";import{SerializedParamType as v}from"./model.js";import{ModelRef as P}from"./model-ref.js";export const applyRuntimeParamTypeInference=!0;export function convertConfiguredParamsToRuntimeTypes(e,r={}){const t={},n=[],u=Object.entries(e),o=r.applyRuntimeParamTypeInference??true;if(0===u.length||!o)return o?{params:t,skipped:n}:{params:e,skipped:n};const a=getRuntimeParameterTypeHints(e,r);for(const[e,r]of u){const u=a.get(e),o=T(r,u);if(null==o)continue;if(!1===o.override){t[e]=o;continue}const c=null!=u?convertConfiguredParamValueToRuntimeType(o,u):o;null!=c?t[e]=c:n.push({key:e,sourceType:o.type,targetType:u.type})}return{params:t,skipped:n}}function T(e,r){return function(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"number"==typeof e.type&&"value"in e}(e)?e:r?.type===v.SequenceData&&V(e)?{type:v.SequenceData,value:e}:null}export function getRuntimeParameterTypeHints(e,r={}){const t=new Map,n=Object.keys(e).filter(r=>!1!==e[r]?.override);if(0===n.length)return t;const u=new Set(n),o=r.parameterTarget??function(e){if(null==e)return null;try{return new e}catch{return null}}(r.parameterType),a=function(e,r){if(null!=r.propertyParams)return r.propertyParams;if(null==r.extractPropertyParameters)return[];if(null!=r.parameterType)return C(r.parameterType,r.extractPropertyParameters);if(null!=e)return C(e.constructor,r.extractPropertyParameters);return[]}(o,r);for(const e of a){if(!u.has(e.name))continue;const n=D(e,r.toSerializedParamType);null!=n&&t.set(e.name,n);const a=inferRuntimeSerializedParamTypeHint(w(o,e.name))??inferRuntimeSerializedParamTypeHint(e.options.defaultValue);null!=a&&t.set(e.name,B(a,n))}if(null!=o)for(const e of n){const r=inferRuntimeSerializedParamTypeHint(w(o,e));if(null!=r){const n=t.get(e);t.set(e,B(r,n))}}return t}const R=new WeakMap,h=new WeakMap,j=Symbol("noCachedSerializedParamType");function C(e,r){let t=R.get(r);null==t&&(t=new WeakMap,R.set(r,t));const n=t.get(e);if(null!=n)return n;const u=function(e,r){try{return r(e)}catch{return[]}}(e,r);return t.set(e,u),u}function w(e,r){return null!=e?e[r]:void 0}function D(e,r){const t=function(e,r){if(null==e||null==r)return;const t=function(e,r){const t=h.get(r);if(null==t||!t.has(e))return j;const n=t.get(e);return null===n?void 0:n}(e,r);if(t!==j)return t;try{const t=r(e);return x(e,r,t),t}catch{return void x(e,r,void 0)}}(e.type,r),n=t===v.Struct?A(e.type):void 0;return!0===e.options.array?{type:v.Array,...null!=t?{element:t}:{},...null!=n?{elementStruct:n}:{}}:null!=t?{type:t,...null!=n?{struct:n}:{}}:void 0}function x(e,r,t){let n=h.get(r);null==n&&(n=new WeakMap,h.set(r,n)),n.set(e,t??null)}function B(e,r){return e.type!==v.Array?e:{type:v.Array,element:e.element??r?.element,elementStruct:e.elementStruct??r?.elementStruct}}export function inferRuntimeSerializedParamTypeHint(g){if(null==g)return;if(Array.isArray(g)){const e=g.map(e=>inferRuntimeSerializedParamTypeHint(e)).find(e=>null!=e);return{type:v.Array,...null!=e&&e.type!==v.Array?{element:e.type}:{},...null!=e?.struct?{elementStruct:e.struct}:{}}}switch(typeof g){case"number":return{type:v.Number};case"boolean":return{type:v.Boolean};case"string":return{type:v.String}}const S=function(e){const r=e;if(e instanceof s||"function"==typeof r?.isFloat||!0===r?.isFloat)return v.FloatNode;if(e instanceof l||"function"==typeof r?.isBool||!0===r?.isBool)return v.BooleanNode;if(e instanceof f||"function"==typeof r?.isRgb||!0===r?.isRgb)return v.RgbNode;if(e instanceof m||"function"==typeof r?.isVec2||!0===r?.isVec2)return v.Vec2Node;if(e instanceof d||"function"==typeof r?.isVec3||!0===r?.isVec3)return v.Vec3Node;if(e instanceof b||"function"==typeof r?.isVec4||!0===r?.isVec4)return v.Vec4Node;if(e instanceof y||e instanceof p||"function"==typeof r?.isSampler2D||!0===r?.isSampler2D)return v.Sampler2DNode;return}(g);if(null!=S)return{type:S};if(g instanceof o)return{type:v.Vector2};if(g instanceof a)return{type:v.Vector3};if(g instanceof c)return{type:v.Vector4};if(g instanceof e)return{type:v.Color};if(g instanceof r)return{type:v.Euler};if(g instanceof u)return{type:v.Texture};if(g instanceof t)return{type:v.Material};if(g instanceof n)return{type:v.Object3D};if(g instanceof P)return{type:v.ModelRef};if("undefined"!=typeof AudioBuffer&&g instanceof AudioBuffer)return{type:v.AudioBuffer};if(Y(g,"VisualEffect"))return{type:v.VisualEffect};if(Y(g,"PrefabOf"))return{type:v.PrefabActor};if(Y(g,"Prefab"))return{type:v.Prefab};if(Y(g,"DataAssetRef"))return{type:v.DataAsset};if(g instanceof N)return{type:v.Curve};if(Y(g,"ColorLayer"))return{type:v.ColorLayer};if(Y(g,"MaskLayer"))return{type:v.MaskLayer};if(g instanceof i)return{type:v.AnimationClip};if(Y(g,"Sequence"))return{type:v.Sequence};if(V(g))return{type:v.SequenceData};const T=A(g.constructor);return null!=T?{type:v.Struct,struct:T}:void 0}export function convertConfiguredParamValueToRuntimeType(e,r){if(null==e||null==r)return e;if(e.type===v.Array||r.type===v.Array)return function(e,r){if(r.type===v.Array){const t=M(e),n=r.element??(t?e.element:e.type);if(null==n)return t?e:null;const u=t?e.element:e.type,o=(t?Array.isArray(e.value)?e.value:[]:[e.value]).map(e=>z(e,u,n));return o.some(e=>e===q)?null:{...e,type:v.Array,element:n,...F(e,r),value:o}}if(!M(e))return null;const t=Array.isArray(e.value)?e.value[0]:void 0;if(null==t)return null;const n=z(t,e.element,r.type);if(n===q)return null;return{...e,type:r.type,...k(e,r),value:n}}(e,r);const t=z(e.value,e.type,r.type);return t===q?null:{...e,type:r.type,...k(e,r),value:t}}function M(e){return e.type===v.Array}function k(e,r){if(r.type!==v.Struct&&e.type!==v.Struct)return{};const t=function(e,r){if(null==r)return e;if(null==e)return r;if(e===r||S(e,r))return e;const t=g(e),n=g(r);if(null==t||null==n)return e;return r}(e.type===v.Struct?e.struct:void 0,r.struct);return null!=t?{struct:t}:{}}function F(e,r){if(r.type!==v.Array)return{};const t=M(e)?e.elementStruct:void 0,n=r.elementStruct??t;return null!=n?{elementStruct:n}:{}}const q=Symbol("skippedParamValue");function z(e,r,t){if(function(e,r){if(e===r)return!0;const t=H(e);return null!=t&&t===H(r)}(r,t)&&function(e,r){switch(r){case v.Number:return"number"==typeof e||"string"==typeof e&&Number.isFinite(parseFloat(e));case v.FloatNode:return"number"==typeof e||"string"==typeof e&&Number.isFinite(parseFloat(e))||function(e){if(null==e||"object"!=typeof e||Array.isArray(e))return!1;const r=e;return"particle"===r.time&&"string"==typeof r.easing&&null!=E(r.a)&&null!=E(r.b)}(e);case v.Boolean:case v.BooleanNode:return"boolean"==typeof e;case v.Vector2:case v.Vec2Node:return L(e,2);case v.Vector3:case v.Vec3Node:return L(e,3);case v.Vector4:case v.Vec4Node:return L(e,4);case v.Euler:return Array.isArray(e)&&e.length>=3&&null!=W(e,3);case v.Color:case v.RgbNode:return null!=X(e);case v.String:return"string"==typeof e;case v.Scene:return null!=e&&"object"==typeof e&&"string"==typeof e.id;case v.ModelRef:return"string"==typeof e;case v.Array:return Array.isArray(e);case v.Texture:case v.Sampler2DNode:case v.BaseActor:case v.Object3D:case v.Material:case v.AudioBuffer:case v.VisualEffect:case v.Prefab:case v.PrefabActor:case v.DataAsset:case v.AnimationClip:case v.Sequence:return null==e||"string"==typeof e||"object"==typeof e;case v.SequenceData:return null==e||V(e);case v.Struct:return null!=e&&"object"==typeof e&&!Array.isArray(e);case v.Curve:case v.ColorLayer:case v.MaskLayer:return null!=e}return!0}(e,t))return e;switch(t){case v.Number:case v.FloatNode:{const r=E(e);return null!=r?r:q}case v.Boolean:case v.BooleanNode:{const r=function(e){if("boolean"==typeof e)return e;if("number"==typeof e)return 0!==e;if("string"==typeof e){const r=e.trim().toLowerCase();if(["true","1","yes","on"].includes(r))return!0;if(["false","0","no","off"].includes(r))return!1}return null}(e);return null!=r?r:q}case v.Vector2:case v.Vec2Node:return O(e,2,r)??q;case v.Vector3:case v.Vec3Node:return O(e,3,r)??q;case v.Vector4:case v.Vec4Node:return O(e,4,r)??q;case v.Color:case v.RgbNode:return function(e,r){if(r===v.Color||r===v.RgbNode)return"string"==typeof e||"number"==typeof e?e:I(e);return I(e)}(e,r)??q;case v.Euler:return function(e,r){if(Array.isArray(e)){const r=W(e,3);if(null==r)return null;const t="string"==typeof e[3]?e[3]:"XYZ";return[r[0],r[1],r[2],t]}const t=O(e,3,r);return null!=t?[t[0],t[1],t[2],"XYZ"]:null}(e,r)??q;case v.String:return"string"==typeof e?e:String(e);case v.Scene:return"string"==typeof e?{id:e,name:e}:null!=e&&"object"==typeof e&&"string"==typeof e.id?e:q;case v.ModelRef:return"string"==typeof e?e:q;case v.Texture:case v.Sampler2DNode:case v.BaseActor:case v.Object3D:case v.Material:case v.AudioBuffer:case v.VisualEffect:case v.Curve:case v.ColorLayer:case v.MaskLayer:case v.Prefab:case v.PrefabActor:case v.DataAsset:case v.AnimationClip:case v.Sequence:case v.SequenceData:case v.Struct:return t===v.SequenceData&&V(e)?e:q}return q}function L(e,r){if(Array.isArray(e))return e.length>=r&&null!=W(e,r);if(null!=e&&"object"==typeof e){const t=e;return["x","y","z","w"].slice(0,r).every(e=>null!=E(t[e]))}return!1}function H(e){switch(e){case v.Number:case v.FloatNode:return"number";case v.Boolean:case v.BooleanNode:return"boolean";case v.Vector2:case v.Vec2Node:return"vector2";case v.Vector3:case v.Vec3Node:return"vector3";case v.Vector4:case v.Vec4Node:return"vector4";case v.Color:case v.RgbNode:return"color";case v.Texture:case v.Sampler2DNode:return"texture";case v.Prefab:case v.PrefabActor:return"prefab";case v.DataAsset:return"dataAsset";case v.Struct:return"struct"}}function E(e){if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"==typeof e){const r=parseFloat(e);return Number.isFinite(r)?r:null}if("boolean"==typeof e)return e?1:0;if(Array.isArray(e))return E(e[0]);if(null!=e&&"object"==typeof e){const r=e;return E(r.x??r.r??r.value)}return null}function O(e,r,t){if(t===v.Color||t===v.RgbNode){const t=X(e);if(null!=t)return W(t.toArray(),r,4===r?1:0)}if(Array.isArray(e))return W(e,r);if("number"==typeof e||"string"==typeof e||"boolean"==typeof e){const t=E(e);return null!=t?new Array(r).fill(t):null}if(null!=e&&"object"==typeof e){const t=e,n=["x","y","z","w"].slice(0,r).map(e=>t[e]);if(n.some(e=>null!=e))return W(n,r);const u=["r","g","b","a"].slice(0,r).map(e=>t[e]);if(u.some(e=>null!=e))return W(u,r,4===r?1:0)}return null}function W(e,r,t=0){const n=[];for(let u=0;u<r;u++){const r=E(e[u]??t);if(null==r)return null;n.push(r)}return n}function I(e){const r=X(e);return null!=r?"#"+r.getHexString():null}function X(r){try{if(r instanceof e)return r.clone();if("string"==typeof r)return function(e){return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(e.trim())||/^(rgb|hsl)a?\(/i.test(e.trim())}(r)?new e(r):null;if("number"==typeof r)return Number.isInteger(r)&&r>=0?new e(r):null;if(Array.isArray(r)){const t=W(r,3);return null!=t?(new e).fromArray(t):null}if(null!=r&&"object"==typeof r){const t=r;if(null!=t.r||null!=t.g||null!=t.b){const r=W([t.r,t.g,t.b],3);return null!=r?(new e).fromArray(r):null}if(null!=t.x||null!=t.y||null!=t.z){const r=W([t.x,t.y,t.z],3);return null!=r?(new e).fromArray(r):null}}}catch{return null}return null}function Y(e,r){return null!=e&&"object"==typeof e&&e.constructor?.name===r}/*
1
+ import{Color as e,Euler as t,Material as r,Object3D as n,Texture as u,Vector2 as o,Vector3 as a,Vector4 as c,AnimationClip as l}from"three";import{BooleanNode as i,FloatNode as s,RgbNode as f,Sampler2DNode as y,Texture2dLookupNode as p,Vec2Node as m,Vec3Node as d,Vec4Node as b}from"three-shader-graph";import{getParameterDefinitionId as A,getParameterDefinitionType as g,isParameterDefinitionStructAssignableTo as S}from"../shader/parameter.js";import{Curve2 as N}from"../utils/curve.js";import{isSequenceData as V}from"../effects/sequence/sequence-data.js";import{SerializedParamType as v}from"./model.js";import{ModelRef as P}from"./model-ref.js";import{MaterialRef as R}from"./material-ref.js";export const applyRuntimeParamTypeInference=!0;export function convertConfiguredParamsToRuntimeTypes(e,t={}){const r={},n=[],u=Object.entries(e),o=t.applyRuntimeParamTypeInference??true;if(0===u.length||!o)return o?{params:r,skipped:n}:{params:e,skipped:n};const a=getRuntimeParameterTypeHints(e,t);for(const[e,t]of u){const u=a.get(e),o=T(t,u);if(null==o)continue;if(!1===o.override){r[e]=o;continue}const c=null!=u?convertConfiguredParamValueToRuntimeType(o,u):o;null!=c?r[e]=c:n.push({key:e,sourceType:o.type,targetType:u.type})}return{params:r,skipped:n}}function T(e,t){return function(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"number"==typeof e.type&&"value"in e}(e)?e:t?.type===v.SequenceData&&V(e)?{type:v.SequenceData,value:e}:null}export function getRuntimeParameterTypeHints(e,t={}){const r=new Map,n=Object.keys(e).filter(t=>!1!==e[t]?.override);if(0===n.length)return r;const u=new Set(n),o=t.parameterTarget??function(e){if(null==e)return null;try{return new e}catch{return null}}(t.parameterType),a=function(e,t){if(null!=t.propertyParams)return t.propertyParams;if(null==t.extractPropertyParameters)return[];if(null!=t.parameterType)return w(t.parameterType,t.extractPropertyParameters);if(null!=e)return w(e.constructor,t.extractPropertyParameters);return[]}(o,t);for(const e of a){if(!u.has(e.name))continue;const n=x(e,t.toSerializedParamType);null!=n&&r.set(e.name,n);const a=inferRuntimeSerializedParamTypeHint(D(o,e.name))??inferRuntimeSerializedParamTypeHint(e.options.defaultValue);null!=a&&r.set(e.name,B(a,n))}if(null!=o)for(const e of n){const t=inferRuntimeSerializedParamTypeHint(D(o,e));if(null!=t){const n=r.get(e);r.set(e,B(t,n))}}return r}const h=new WeakMap,j=new WeakMap,C=Symbol("noCachedSerializedParamType");function w(e,t){let r=h.get(t);null==r&&(r=new WeakMap,h.set(t,r));const n=r.get(e);if(null!=n)return n;const u=function(e,t){try{return t(e)}catch{return[]}}(e,t);return r.set(e,u),u}function D(e,t){return null!=e?e[t]:void 0}function x(e,t){const r=function(e,t){if(null==e||null==t)return;const r=function(e,t){const r=j.get(t);if(null==r||!r.has(e))return C;const n=r.get(e);return null===n?void 0:n}(e,t);if(r!==C)return r;try{const r=t(e);return M(e,t,r),r}catch{return void M(e,t,void 0)}}(e.type,t),n=r===v.Struct?A(e.type):void 0;return!0===e.options.array?{type:v.Array,...null!=r?{element:r}:{},...null!=n?{elementStruct:n}:{}}:null!=r?{type:r,...null!=n?{struct:n}:{}}:void 0}function M(e,t,r){let n=j.get(t);null==n&&(n=new WeakMap,j.set(t,n)),n.set(e,r??null)}function B(e,t){return e.type===v.Struct&&t?.type===v.Struct&&null!=t.struct&&null!=e.struct&&S(e.struct,t.struct)?t:e.type!==v.Array?e:{type:v.Array,element:e.element??t?.element,elementStruct:e.elementStruct??t?.elementStruct}}export function inferRuntimeSerializedParamTypeHint(g){if(null==g)return;if(Array.isArray(g)){const e=g.map(e=>inferRuntimeSerializedParamTypeHint(e)).find(e=>null!=e);return{type:v.Array,...null!=e&&e.type!==v.Array?{element:e.type}:{},...null!=e?.struct?{elementStruct:e.struct}:{}}}switch(typeof g){case"number":return{type:v.Number};case"boolean":return{type:v.Boolean};case"string":return{type:v.String}}const S=function(e){const t=e;if(e instanceof s||"function"==typeof t?.isFloat||!0===t?.isFloat)return v.FloatNode;if(e instanceof i||"function"==typeof t?.isBool||!0===t?.isBool)return v.BooleanNode;if(e instanceof f||"function"==typeof t?.isRgb||!0===t?.isRgb)return v.RgbNode;if(e instanceof m||"function"==typeof t?.isVec2||!0===t?.isVec2)return v.Vec2Node;if(e instanceof d||"function"==typeof t?.isVec3||!0===t?.isVec3)return v.Vec3Node;if(e instanceof b||"function"==typeof t?.isVec4||!0===t?.isVec4)return v.Vec4Node;if(e instanceof y||e instanceof p||"function"==typeof t?.isSampler2D||!0===t?.isSampler2D)return v.Sampler2DNode;return}(g);if(null!=S)return{type:S};if(g instanceof o)return{type:v.Vector2};if(g instanceof a)return{type:v.Vector3};if(g instanceof c)return{type:v.Vector4};if(g instanceof e)return{type:v.Color};if(g instanceof t)return{type:v.Euler};if(g instanceof u)return{type:v.Texture};if(g instanceof r)return{type:v.Material};if(g instanceof n)return{type:v.Object3D};if(g instanceof P)return{type:v.ModelRef};if(g instanceof R)return{type:v.MaterialRef};if("undefined"!=typeof AudioBuffer&&g instanceof AudioBuffer)return{type:v.AudioBuffer};if(Z(g,"VisualEffect"))return{type:v.VisualEffect};if(Z(g,"PrefabOf"))return{type:v.PrefabActor};if(Z(g,"Prefab"))return{type:v.Prefab};if(Z(g,"DataAssetRef"))return{type:v.DataAsset};if(g instanceof N)return{type:v.Curve};if(Z(g,"ColorLayer"))return{type:v.ColorLayer};if(Z(g,"MaskLayer"))return{type:v.MaskLayer};if(g instanceof l)return{type:v.AnimationClip};if(Z(g,"Sequence"))return{type:v.Sequence};if(V(g))return{type:v.SequenceData};const T=A(g.constructor);return null!=T?{type:v.Struct,struct:T}:void 0}export function convertConfiguredParamValueToRuntimeType(e,t){if(null==e||null==t)return e;if(e.type===v.Array||t.type===v.Array)return function(e,t){if(t.type===v.Array){const r=k(e),n=t.element??(r?e.element:e.type);if(null==n)return r?e:null;const u=r?e.element:e.type,o=(r?Array.isArray(e.value)?e.value:[]:[e.value]).map(e=>L(e,u,n));return o.some(e=>e===z)?null:{...e,type:v.Array,element:n,...q(e,t),value:o}}if(!k(e))return null;const r=Array.isArray(e.value)?e.value[0]:void 0;if(null==r)return null;const n=L(r,e.element,t.type);if(n===z)return null;return{...e,type:t.type,...F(e,t),value:n}}(e,t);const r=L(e.value,e.type,t.type);return r===z?null:{...e,type:t.type,...F(e,t),value:r}}function k(e){return e.type===v.Array}function F(e,t){if(t.type!==v.Struct&&e.type!==v.Struct)return{};const r=function(e,t){if(null==t)return e;if(null==e)return t;if(e===t||S(e,t))return e;const r=g(e),n=g(t);if(null==r||null==n)return e;return t}(e.type===v.Struct?e.struct:void 0,t.struct);return null!=r?{struct:r}:{}}function q(e,t){if(t.type!==v.Array)return{};const r=k(e)?e.elementStruct:void 0,n=t.elementStruct??r;return null!=n?{elementStruct:n}:{}}const z=Symbol("skippedParamValue");function L(e,t,r){if(function(e,t){if(e===t)return!0;const r=E(e);return null!=r&&r===E(t)}(t,r)&&function(e,t){switch(t){case v.Number:return"number"==typeof e||"string"==typeof e&&Number.isFinite(parseFloat(e));case v.FloatNode:return"number"==typeof e||"string"==typeof e&&Number.isFinite(parseFloat(e))||function(e){if(null==e||"object"!=typeof e||Array.isArray(e))return!1;const t=e;return"particle"===t.time&&"string"==typeof t.easing&&null!=O(t.a)&&null!=O(t.b)}(e);case v.Boolean:case v.BooleanNode:return"boolean"==typeof e;case v.Vector2:case v.Vec2Node:return H(e,2);case v.Vector3:case v.Vec3Node:return H(e,3);case v.Vector4:case v.Vec4Node:return H(e,4);case v.Euler:return Array.isArray(e)&&e.length>=3&&null!=I(e,3);case v.Color:case v.RgbNode:return null!=Y(e);case v.String:return"string"==typeof e;case v.Scene:return null!=e&&"object"==typeof e&&"string"==typeof e.id;case v.ModelRef:return"string"==typeof e;case v.MaterialRef:return null==e||"string"==typeof e;case v.Array:return Array.isArray(e);case v.Texture:case v.Sampler2DNode:case v.BaseActor:case v.Object3D:case v.Material:case v.AudioBuffer:case v.VisualEffect:case v.Prefab:case v.PrefabActor:case v.DataAsset:case v.AnimationClip:case v.Sequence:return null==e||"string"==typeof e||"object"==typeof e;case v.SequenceData:return null==e||V(e);case v.Struct:return null!=e&&"object"==typeof e&&!Array.isArray(e);case v.Curve:case v.ColorLayer:case v.MaskLayer:return null!=e}return!0}(e,r))return e;switch(r){case v.Number:case v.FloatNode:{const t=O(e);return null!=t?t:z}case v.Boolean:case v.BooleanNode:{const t=function(e){if("boolean"==typeof e)return e;if("number"==typeof e)return 0!==e;if("string"==typeof e){const t=e.trim().toLowerCase();if(["true","1","yes","on"].includes(t))return!0;if(["false","0","no","off"].includes(t))return!1}return null}(e);return null!=t?t:z}case v.Vector2:case v.Vec2Node:return W(e,2,t)??z;case v.Vector3:case v.Vec3Node:return W(e,3,t)??z;case v.Vector4:case v.Vec4Node:return W(e,4,t)??z;case v.Color:case v.RgbNode:return function(e,t){if(t===v.Color||t===v.RgbNode)return"string"==typeof e||"number"==typeof e?e:X(e);return X(e)}(e,t)??z;case v.Euler:return function(e,t){if(Array.isArray(e)){const t=I(e,3);if(null==t)return null;const r="string"==typeof e[3]?e[3]:"XYZ";return[t[0],t[1],t[2],r]}const r=W(e,3,t);return null!=r?[r[0],r[1],r[2],"XYZ"]:null}(e,t)??z;case v.String:return"string"==typeof e?e:String(e);case v.Scene:return"string"==typeof e?{id:e,name:e}:null!=e&&"object"==typeof e&&"string"==typeof e.id?e:z;case v.ModelRef:return"string"==typeof e?e:z;case v.MaterialRef:return null==e||"string"==typeof e?e:z;case v.Texture:case v.Sampler2DNode:case v.BaseActor:case v.Object3D:case v.Material:case v.AudioBuffer:case v.VisualEffect:case v.Curve:case v.ColorLayer:case v.MaskLayer:case v.Prefab:case v.PrefabActor:case v.DataAsset:case v.AnimationClip:case v.Sequence:case v.SequenceData:case v.Struct:return r===v.SequenceData&&V(e)?e:z}return z}function H(e,t){if(Array.isArray(e))return e.length>=t&&null!=I(e,t);if(null!=e&&"object"==typeof e){const r=e;return["x","y","z","w"].slice(0,t).every(e=>null!=O(r[e]))}return!1}function E(e){switch(e){case v.Number:case v.FloatNode:return"number";case v.Boolean:case v.BooleanNode:return"boolean";case v.Vector2:case v.Vec2Node:return"vector2";case v.Vector3:case v.Vec3Node:return"vector3";case v.Vector4:case v.Vec4Node:return"vector4";case v.Color:case v.RgbNode:return"color";case v.Texture:case v.Sampler2DNode:return"texture";case v.Prefab:case v.PrefabActor:return"prefab";case v.DataAsset:return"dataAsset";case v.Struct:return"struct"}}function O(e){if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"==typeof e){const t=parseFloat(e);return Number.isFinite(t)?t:null}if("boolean"==typeof e)return e?1:0;if(Array.isArray(e))return O(e[0]);if(null!=e&&"object"==typeof e){const t=e;return O(t.x??t.r??t.value)}return null}function W(e,t,r){if(r===v.Color||r===v.RgbNode){const r=Y(e);if(null!=r)return I(r.toArray(),t,4===t?1:0)}if(Array.isArray(e))return I(e,t);if("number"==typeof e||"string"==typeof e||"boolean"==typeof e){const r=O(e);return null!=r?new Array(t).fill(r):null}if(null!=e&&"object"==typeof e){const r=e,n=["x","y","z","w"].slice(0,t).map(e=>r[e]);if(n.some(e=>null!=e))return I(n,t);const u=["r","g","b","a"].slice(0,t).map(e=>r[e]);if(u.some(e=>null!=e))return I(u,t,4===t?1:0)}return null}function I(e,t,r=0){const n=[];for(let u=0;u<t;u++){const t=O(e[u]??r);if(null==t)return null;n.push(t)}return n}function X(e){const t=Y(e);return null!=t?"#"+t.getHexString():null}function Y(t){try{if(t instanceof e)return t.clone();if("string"==typeof t)return function(e){return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(e.trim())||/^(rgb|hsl)a?\(/i.test(e.trim())}(t)?new e(t):null;if("number"==typeof t)return Number.isInteger(t)&&t>=0?new e(t):null;if(Array.isArray(t)){const r=I(t,3);return null!=r?(new e).fromArray(r):null}if(null!=t&&"object"==typeof t){const r=t;if(null!=r.r||null!=r.g||null!=r.b){const t=I([r.r,r.g,r.b],3);return null!=t?(new e).fromArray(t):null}if(null!=r.x||null!=r.y||null!=r.z){const t=I([r.x,r.y,r.z],3);return null!=t?(new e).fromArray(t):null}}}catch{return null}return null}function Z(e,t){return null!=e&&"object"==typeof e&&e.constructor?.name===t}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -0,0 +1,7 @@
1
+ import type { AssetId } from './model.js';
2
+ /** Material asset identity. Resolving this parameter does not load a material. */
3
+ export declare class MaterialRef {
4
+ readonly id: AssetId;
5
+ constructor(id: AssetId);
6
+ }
7
+ //# sourceMappingURL=material-ref.d.ts.map
@@ -0,0 +1,4 @@
1
+ export class MaterialRef{constructor(t){this.id=t}}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -1,4 +1,10 @@
1
1
  import { type LatticeDeformation } from './lattice-deformation.js';
2
+ import { type ActorMeshHandle, type ActorMeshRenderOptions } from './actor-mesh-renderer.js';
3
+ import type { MeshMaterialSlot } from '../gameplay/actors/builtin/components/primitive-mesh-component.js';
4
+ export { convertSceneObjectToActor, canConvertSceneObjectToActor } from './scene-object-actor-conversion.js';
5
+ export type { SceneObjectActorConversion } from './scene-object-actor-conversion.js';
6
+ export type { ActorMeshHandle, ActorMeshRenderOptions } from './actor-mesh-renderer.js';
7
+ export type { ActorMaterialHandle, MaterialParameterValue } from './actor-material-parameters.js';
2
8
  export { createLatticeDeformation, latticePoint, isValidLattice, deformLatticeGeometry, LatticeGeometryCache, type LatticeDeformation } from './lattice-deformation.js';
3
9
  import { Subject } from "rxjs";
4
10
  import * as THREE from "three";
@@ -363,6 +369,13 @@ export declare class SceneMaterializer {
363
369
  private actorTypes;
364
370
  private actorProvider;
365
371
  private componentTypes;
372
+ private actorMeshRenderer?;
373
+ private readonly actorMeshTemplates;
374
+ /** Shared mesh preparation for built-in and custom actors using the mesh components. */
375
+ createActorMesh(owner: Object3D, source: SceneObject, materials: readonly MeshMaterialSlot[], batching?: boolean, options?: ActorMeshRenderOptions): Promise<ActorMeshHandle>;
376
+ private actorBatchParameters;
377
+ private actorBatchKey;
378
+ private createActorBatchMaterial;
366
379
  private navigationRevision;
367
380
  private objectMap;
368
381
  private sceneObjectMap;
@@ -544,6 +557,9 @@ export declare class SceneMaterializer {
544
557
  * @returns
545
558
  */
546
559
  private createBatchedMesh;
560
+ /** Shared shader derivation for scenery batches and actor-owned instances. */
561
+ private createBatchingMaterial;
562
+ private initializeBatchingUniforms;
547
563
  private createInstancedMesh;
548
564
  private configureBatchedInstancedMesh;
549
565
  private remove;