@hology/core 0.0.274 → 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.
- package/dist/effects/sequence/sequence-player.d.ts +1 -0
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/gameplay/actors/builtin/components/index.d.ts +6 -0
- package/dist/gameplay/actors/builtin/components/index.js +1 -1
- package/dist/gameplay/actors/builtin/components/primitive-mesh-component.d.ts +66 -0
- package/dist/gameplay/actors/builtin/components/primitive-mesh-component.js +4 -0
- package/dist/gameplay/actors/builtin/index.d.ts +6 -0
- package/dist/gameplay/actors/builtin/index.js +1 -1
- package/dist/gameplay/actors/builtin/light-actor.d.ts +54 -0
- package/dist/gameplay/actors/builtin/light-actor.js +4 -0
- package/dist/gameplay/actors/builtin/mesh-actor.d.ts +9 -0
- package/dist/gameplay/actors/builtin/mesh-actor.js +4 -0
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.d.ts +5 -0
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/index.d.ts +1 -0
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/rendering-host.d.ts +1 -0
- package/dist/gameplay/rendering-host.js +1 -1
- package/dist/gameplay/services/asset-loader.d.ts +3 -0
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/rendering/node-material-webgpu-resolver.d.ts +5 -1
- package/dist/rendering/node-material-webgpu-resolver.js +1 -1
- package/dist/rendering/post-process-color.d.ts +9 -0
- package/dist/rendering/post-process-color.js +4 -0
- package/dist/rendering/sdfgi-settings.d.ts +8 -0
- package/dist/rendering/sdfgi-settings.js +4 -0
- package/dist/rendering/sdfgi-surface-material.d.ts +8 -0
- package/dist/rendering/sdfgi-surface-material.js +4 -0
- package/dist/rendering/webgl-backend.d.ts +243 -9
- package/dist/rendering/webgl-backend.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.d.ts +14 -3
- package/dist/rendering/webgpu-experimental-backend.js +1 -1
- package/dist/rendering.d.ts +56 -208
- package/dist/rendering.js +1 -1
- package/dist/scene/actor-material-parameters.d.ts +19 -0
- package/dist/scene/actor-material-parameters.js +4 -0
- package/dist/scene/actor-mesh-provider.d.ts +2 -0
- package/dist/scene/actor-mesh-provider.js +4 -0
- package/dist/scene/actor-mesh-renderer.d.ts +40 -0
- package/dist/scene/actor-mesh-renderer.js +4 -0
- package/dist/scene/asset-resource-loader.d.ts +2 -0
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/batched-mesh-2.js +1 -1
- package/dist/scene/custom-param-deserialize.js +1 -1
- package/dist/scene/custom-param-runtime-types.js +1 -1
- package/dist/scene/material-ref.d.ts +7 -0
- package/dist/scene/material-ref.js +4 -0
- package/dist/scene/materializer.d.ts +18 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +4 -1
- package/dist/scene/model.js +1 -1
- package/dist/scene/runtime-bundled-backend-service.d.ts +1 -0
- package/dist/scene/runtime-bundled-backend-service.js +1 -1
- package/dist/scene/scene-data-service.js +1 -1
- package/dist/scene/scene-object-actor-conversion.d.ts +10 -0
- package/dist/scene/scene-object-actor-conversion.js +4 -0
- package/dist/shader/parameter.d.ts +5 -2
- package/dist/shader-nodes/particle.d.ts +2 -2
- package/dist/shader-nodes/surface-reflection.d.ts +1 -0
- package/dist/shader-nodes/surface-reflection.js +1 -1
- package/dist/test/actor-mesh-renderer.test.d.ts +2 -0
- package/dist/test/actor-mesh-renderer.test.js +4 -0
- package/dist/test/actor-persistence-runtime.test.js +1 -1
- package/dist/test/asset-resource-loader-converted-fbx.test.js +1 -1
- package/dist/test/asset-resource-loader-skinned-merge.test.js +1 -1
- package/dist/test/landscape-static-draw-sets.test.js +1 -1
- package/dist/test/node-material-webgpu-resolver.test.js +1 -1
- package/dist/test/physics-ray-object.test.js +1 -1
- package/dist/test/primitive-actors.test.d.ts +2 -0
- package/dist/test/primitive-actors.test.js +4 -0
- package/dist/test/rendering-host.test.js +1 -1
- package/dist/test/runtime-bundled-backend-service.test.d.ts +2 -0
- package/dist/test/runtime-bundled-backend-service.test.js +4 -0
- package/dist/test/scene-object-actor-conversion.test.d.ts +2 -0
- package/dist/test/scene-object-actor-conversion.test.js +4 -0
- package/dist/test/sdfgi-settings.test.d.ts +2 -0
- package/dist/test/sdfgi-settings.test.js +4 -0
- package/dist/test/shader-graph.test.js +1 -1
- package/dist/test/surface-reflection.test.js +1 -1
- package/dist/test/webgl-backend.test.d.ts +2 -0
- package/dist/test/webgl-backend.test.js +4 -0
- package/dist/utils/async.d.ts +2 -0
- package/dist/utils/async.js +1 -1
- package/dist/utils/mesh.js +1 -1
- package/package.json +3 -3
- 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(!
|
|
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
|
|
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
|
*/
|
|
@@ -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";
|
|
@@ -175,6 +181,8 @@ export type SceneObjectShape = {
|
|
|
175
181
|
physics?: SceneObjectPhysicsSettings;
|
|
176
182
|
} & SceneObject;
|
|
177
183
|
export type SceneWorldEnvironmentSettings = {
|
|
184
|
+
/** Omitted in legacy scenes to inherit the project's GI behavior. */
|
|
185
|
+
globalIllumination?: import('../rendering/sdfgi-settings.js').SceneSDFGISettings;
|
|
178
186
|
ao: {
|
|
179
187
|
enabled: boolean;
|
|
180
188
|
blendIntensity: number;
|
|
@@ -361,6 +369,13 @@ export declare class SceneMaterializer {
|
|
|
361
369
|
private actorTypes;
|
|
362
370
|
private actorProvider;
|
|
363
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;
|
|
364
379
|
private navigationRevision;
|
|
365
380
|
private objectMap;
|
|
366
381
|
private sceneObjectMap;
|
|
@@ -542,6 +557,9 @@ export declare class SceneMaterializer {
|
|
|
542
557
|
* @returns
|
|
543
558
|
*/
|
|
544
559
|
private createBatchedMesh;
|
|
560
|
+
/** Shared shader derivation for scenery batches and actor-owned instances. */
|
|
561
|
+
private createBatchingMaterial;
|
|
562
|
+
private initializeBatchingUniforms;
|
|
545
563
|
private createInstancedMesh;
|
|
546
564
|
private configureBatchedInstancedMesh;
|
|
547
565
|
private remove;
|