@hology/core 0.0.209 → 0.0.210

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.
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{ConvexPolyhedronCollisionShape as a,SpriteShader as s}from"@hology/core";import{Subject as r}from"rxjs";import*as n from"three";import{BoxGeometry as i,BufferGeometry as o,Color as l,Euler as c,Fog as u,FogExp2 as p,Group as d,Material as h,Matrix4 as f,Mesh as m,MeshLambertMaterial as g,MeshPhongMaterial as y,MeshStandardMaterial as w,Matrix3 as b,Object3D as v,PointLight as M,Quaternion as S,Scene as A,Texture as x,Vector2 as j,Vector3 as I,Vector4 as P}from"three";import{attributes as C,batchingUniformFloat as D,batchingUniformVec2 as T,batchingUniformVec3 as O,batchingUniformVec4 as k,bool as V,BooleanExpression as E,BooleanNode as F,colorToNormal as z,float as N,FloatNode as B,ifDefApply as $,mix as _,NodeShaderMaterial as U,rgb as G,rgba as W,RgbNode as L,select as R,standardMaterial as q,Texture2dLookupNode as Y,textureSampler2d as J,textureSampler2dArray as X,UniformBoolNode as Z,UniformFloatNode as H,UniformSampler2dArraySlice as K,UniformVec2Node as Q,UniformVec3Node as ee,UniformVec4Node as te,varying as ae,varyingAttributes as se,varyingTransformed as re,vec2 as ne,Vec2Node as ie,vec3 as oe,Vec3Node as le,vec4 as ce,Vec4Node as ue}from"three-shader-graph";import{Service as pe}from"typedi";import{VfxActor as de}from"../effects/vfx/vfx-actor.js";import{VisualEffect as he}from"../effects/vfx/vfx-param.js";import{Prefab as fe,PrefabOf as me}from"./objects/prefab.js";import{DataAssetRef as ge}from"./objects/data-asset.js";import{BaseActor as ye}from"../gameplay/actors/actor.js";import we from"../gameplay/actors/builtin/index.js";import{ActorComponent as be}from"../gameplay/actors/component.js";import{PhysicsBodyType as ve}from"../gameplay/services/physics/physics-system.js";import{ThreeBlendingMode as Me}from"../effects/vfx/vfx-asset.js";import{withInjectionContext as Se}from"../gameplay/inject.js";import{RenderingView as Ae}from"../rendering.js";import{curveSampler as xe,oneMinus as je,particleUniforms as Ie,Sampler2DNode as Pe}from"../shader-nodes/index.js";import{LambertShader as Ce}from"../shader/builtin/lambert-shader.js";import{LandscapeCompositeShader as De}from"../shader/builtin/landscape-composite-shader";import{LandscapeShader as Te}from"../shader/builtin/landscape-shader.js";import{StandardShader as Oe}from"../shader/builtin/standard-shader.js";import{UnlitShader as ke}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as Ve,getDataAssetDefinitionType as Ee,getParameterDefinitionId as Fe,getParameterDefinitionType as ze,isDataAssetDefinitionAbstract as Ne,isParameterDefinitionAbstract as Be,isParameterDefinitionAssignableTo as $e,isParameterDefinitionStructAssignableTo as _e,shaderParameterUniformName as Ue}from"../shader/parameter.js";import{ArrayMap as Ge,DefaultMap as We,groupBy as Le}from"../utils/collections.js";import{iterateMaterials as Re}from"../utils/materials.js";import{filterChildrenShallow as qe,filterSceneShallow as Ye,findFirstVisibleMesh as Je,findFirstVisibleObject as Xe,traverseAsync as Ze}from"../utils/three/traverse.js";import{AssetMeshInstance as He,AssetResourceLoader as Ke}from"./asset-resource-loader.js";import{AssetsProvider as Qe}from"./assets-provider.js";import{isCollisionMesh as et}from"./collision/collision-shape-import.js";import{BoxCollisionShape as tt,PhysicalShapeMesh as at}from"./collision/collision-shape.js";import{LandscapeManager as st}from"./landscape/landscape-manager.js";import{initLandscape as rt}from"./landscape/landscape.js";import{SectionGrid as nt,smoothNormalsCrossMeshes as it}from"./landscape/utils.js";import{createGrassFoliageMaterial as ot}from"./materials/grass-foliage.js";import{createGrassMaterial as lt}from"./materials/grass.js";import{getMaterialAttribute as ct}from"./materials/utils/material-painting.js";import{SurfaceScatterManager as ut}from"./scatter/surface-scatter-manager.js";import{createWaterMaterial as pt}from"./materials/water.js";import{SerializedParamType as dt}from"./model.js";import{applyRuntimeParamTypeInference as ht,convertConfiguredParamsToRuntimeTypes as ft,convertConfiguredParamValueToRuntimeType as mt,inferRuntimeSerializedParamTypeHint as gt}from"./custom-param-runtime-types.js";import{ShapeLibrary as yt,ShapeLibraryKeys as wt}from"./objects/shapes.js";import{ambientLightName as bt,createSky as vt,defaultSkyMaterial as Mt}from"./sky.js";import{Curve2 as St}from"../utils/curve.js";import{DecalUnlitShader as At}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as xt}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as jt,defaultValueColorLayer as It,defaultValueMaskLayer as Pt,MaskLayer as Ct}from"../shader/color-layer.js";import{LayeredShader as Dt}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as Tt}from"../shader/color-layer";import{FogVolume as Ot}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as kt}from"../utils/three/unscaled-sprite.js";import{ToonShader as Vt}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as Et}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as Ft}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as zt}from"../shader-nodes/pom.js";import{traverseVisibleEvery as Nt}from"../utils/three/traverse";import{RectAreaLightHelper as Bt}from"three/examples/jsm/Addons.js";import{Sequence as $t}from"../effects/sequence/sequence-data.js";import{applyUvTiling as _t}from"./../shader/uv-nodes.js";import{buildShaderGraphMaterial as Ut,shaderGraphMaterialSideToThree as Gt}from"../shader/graph/index.js";export{ht as applyRuntimeParamTypeInference,ft as convertConfiguredParamsToRuntimeTypes,mt as convertConfiguredParamValueToRuntimeType,gt as inferRuntimeSerializedParamTypeHint};const Wt={},Lt=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),Rt=/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(navigator.userAgent.includes("iPhone")||navigator.userAgent.includes("iPad"))&&!!navigator.userAgent.match(/AppleWebKit/)&&!navigator.userAgent.match(/CriOS/);export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,a){this.dataProvider=e,this.assetsService=t,this.assetManagerService=a}get(e,t){return new qt(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}let qt=class{constructor(e,t,a,s,i,o,l,c,u=[]){this.scene=e,this.dataProvider=t,this.assetsService=a,this.assetManagerService=s,this.renderingView=i,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.componentTypes=u,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.idToSceneObject=new Map,this.inEditor=!0,this.updated$=new r,this.removed$=new r,this.error$=new r,this.editorActorParamSnapshot=new Map,this.assets=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.pmremGeneratorResults=new WeakMap,this.prefabInstanceChain=[],this.prefabInstanceExposedActorMap=new Map,this.geometryCache=new Map,this.collisionShapeCache=new Map,this.assetManagerService.materialProvider=async e=>materialFromAsset(this.assets.get(e)??await this.assetsService.getAsset(e),this.renderingView,this.assetsService,this.assetManagerService,this.shaders),this.originalFog=null,t.onCreate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onUpdate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onRemove(e=>{this.remove(e),this.handleSurfaceScatterSceneMutation(e)}),this.createAssetSubscription=a.onCreate.subscribe(e=>{this.assets.set(e.id,e)}),this.updateSubscription=a.onUpdate.subscribe(async t=>{if(this.assets.set(t.id,t),"material"==t.type)e.traverse(e=>{if(e instanceof n.Mesh)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterial(e,e.material[a],t,a);else this.refreshMaterial(e,e.material,t)});else if("mesh"==t.type){this.findByAssetId(t.id).forEach(async e=>{this.remove(e.userData.src);const t=await this.materializeAndInitActor(e.userData.src);this.updated$.next({object:t,source:e.userData.src})});for(const e of this.assets.values())if("prefab"==e.type){if(!e.prefab.objects.some(e=>Ya(e,e=>e.assetId==t.id,this.assets)))continue;this.findByAssetId(e.id).forEach(e=>{this.remove(e.userData.src),this.materializeAndInitActor(e.userData.src)})}this.landscapeManagers.forEach(e=>{const a=e.source?.grass?.layers?.some(e=>e.meshes.some(e=>e.assetId===t.id));a&&e.queueRefreshScatter(this.renderingView?.camera.position??new I,!0)}),null!=this.surfaceScatterManager&&(this.surfaceScatterManager.usesSourceAsset(t.id)||this.surfaceScatterManager.usesScatterAsset(t.id))&&this.surfaceScatterManager.queueRefresh(!0)}else if("prefab"===t.type)this.findByAssetId(t.id).forEach(e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}),(this.surfaceScatterManager?.usesPrefabAsset(t.id)||this.sceneReferencesPrefabAsset(t.id)&&await this.prefabAssetContainsSurfaceScatter(t))&&await this.refreshSurfaceScatterPresence(!0);else if("vfx"===t.type)for(const e of this.dataProvider.getObjects())await ra(e,async e=>{"vfx"===e.type&&e.assetId===t.id&&(this.remove(e),await this.materializeAndInitActor(e))});else if("texture"===t.type)this.scene.traverse(e=>{if(e instanceof m)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterialTextures(e,e.material[a],t,a);else this.refreshMaterialTextures(e,e.material,t)});else if("shaderGraph"===t.type){this.scene.traverse(e=>{if(e instanceof m)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterial(e,e.material[a],t,a);else this.refreshMaterial(e,e.material,t)});for(const e of this.dataProvider.getObjects())await ra(e,async e=>{if("vfx"===e.type&&null!=e.assetId){const a=this.assets.get(e.assetId);null!=a&&this.vfxAssetUsesShaderGraph(a,t.id)&&(this.remove(e),await this.materializeAndInitActor(e))}})}})}async refreshMaterialTextures(e,t,a,s){if("texture"!==a.type)return void console.error("Can not refresh material textures. Asset is not a texture",a);const r=await this.assetManagerService.getTexture(a);if(null!=r)if(t instanceof n.ShaderMaterial)for(const[e,s]of Object.entries(t.uniforms))s.value instanceof n.Texture&&s.value.userData.assetId===a.id&&(t.uniforms[e].value=r);else for(const[e,s]of Object.entries(t))s instanceof n.Texture&&s.userData.assetId===a.id&&(t[e]=r);else console.error("Can not refresh material textures. Texture not found",a)}async getAsset(e){let t=this.assets.get(e);return null==t&&(t=await this.assetsService.getAsset(e),null!=t&&this.assets.set(e,t)),t}async refreshMaterial(e,t,a,s){const r=t?.userData?.assetId;if(r!==a.id){const e=this.assets.get(r);let t=!1;if(null!=e&&("shaderGraph"===a.type&&"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===a.id&&(t=!0),!t&&null!=e.material?.shaderParams))for(const s of Object.values(e.material.shaderParams)){if(s.type===dt.Material&&s.value===a.id){t=!0;break}if(s.type===dt.Array&&"element"in s&&s.element===dt.Material&&s.value.includes(a.id)){t=!0;break}}if(!t)return}const n=await materialFromAsset(this.assets.get(r),this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1),i=n.userData;n.userData=t.userData,n.userData.hasBloom=i.hasBloom,n.userData.reflective=i.reflective,n.userData.outlineParameters=i.outlineParameters,null!=s?ba(e.material[s],n)||(e.material[s]=n):ba(e.material,n)||(e.material=n,e===this.sky&&this.applySkySettings(e.material))}vfxAssetUsesShaderGraph(e,t){return null!=e.vfx&&e.vfx.emitters.some(e=>this.emitterUsesShaderGraph(e,t))}emitterUsesShaderGraph(e,t){const a=e.output;return"shaderGraph"===a.materialSource&&"asset"===a.shaderGraph?.source&&a.shaderGraph.assetId===t||!!e.children&&e.children.some(e=>this.emitterUsesShaderGraph(e,t))}getTopLevelActors(){return Array.from(this.materializedActors.entries()).filter(([e,t])=>!e.includes("/")).map(([,e])=>e)}get actorInstances(){return Array.from(this.materializedActors.values())}async initTextures(){const e=[];if(await Promise.all(this.dataProvider.getObjects().filter(e=>"shape_mesh"===e.type||"asset_mesh"===e.type).filter(e=>null!=e.materialAssignments).flatMap(e=>e.materialAssignments).map(async t=>{const a=this.assets.get(t.materialId);if(null!=a)for(const t of Object.values(a.material.shaderParams??{}))if(t.type===dt.Texture&&"string"==typeof t.value){const a=this.assets.get(t.value),s=await this.assetManagerService.getTexture(a);null!=s&&e.push(s)}})),0!==e.length&&this.renderingView){console.log(`Initializing ${e.length} textures`),console.time("Init textures");for(const t of e)this.renderingView.renderer.initTexture(t);console.timeEnd("Init textures")}}async prefetchAssets(){const e=this.collectAssetMeshIds(this.dataProvider.getObjects());await Promise.all(Array.from(e).map(async e=>{const t=this.assets.get(e);if("mesh"===t?.type)return this.assetManagerService.getMesh(t,{mergeGeomtries:!0})})),this.initTextures()}collectAssetMeshIds(e,t=[],a=new Set){for(const s of e??[])this.collectObjectAssetMeshIds(s,t,a);return a}collectObjectAssetMeshIds(e,t,a){if(this.shouldBeMaterialized(e)&&("asset_mesh"===e.type&&null!=e.assetId&&a.add(e.assetId),null!=e.children&&this.collectAssetMeshIds(e.children,t,a),"prefab"===e.type&&null!=e.assetId&&!t.includes(e.assetId))){const s=this.assets.get(e.assetId);null!=s?.prefab?.objects&&this.collectAssetMeshIds(s.prefab.objects,[...t,e.assetId],a)}}async init(){await this.preInit(),Jt.clear(),Xt.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.refreshSurfaceScatterPresence(!0)}async initVfx(){console.time("Init VFX");const e=new Set,t=[],a=new A;for(const s of this.actorInstances){const r=Wa(s);for(const s of r){const r=s.asset;if(e.has(r.id))continue;e.add(r.id),r.vfx.emitters;const n=await s.create(a);a.add(n.object),a.add(n.particleSystemContainer),n.play(),n.onUpdate(.5),n.stop(),n.pause(),t.push(n)}}const s=this.renderingView.compileAsync(a);this.renderingView.initTextures(a),await s;for(const e of t)e.onEndPlay(),e.disposed.next(!0),e.object.removeFromParent();console.timeEnd("Init VFX")}async initActorsPostInit(e=Array.from(this.materializedActors.entries())){const t=e.map(async([e,t])=>{const a=t.object.userData.src??t.object.userData._src;if("vfx"===a.type)return Promise.resolve();const s="prefab"===a.type?await this.assetsService.getAsset(a.assetId):null,r=e.split("/"),n=r.slice(0,-1),i=n.join("/"),o=(r[r.length-1],new Map);for(const[e,t]of this.materializedActors)if(o.set(e,t),0===i.length)e.includes("/")||o.set(e,t);else if(e.startsWith(i+"/")){const a=e.slice(i.length+1);a.includes("/")||o.set(a,t)}const l={...s?.actor?.params??{},...a.actor?.params??{}},c=[...a.actor?.innerParams??[]];for(let t=n.length-1;t>=0;t--){const a=n.slice(0,t+1).join("/"),s=this.idToSceneObject.get(a);if("prefab"===s?.type&&null!=s.prefab){const n=await this.assetsService.getAsset(s.assetId);if(null!=n){let i=!1,o=a+"/"+n.prefab?.mainActorId;for(;null!=o;){if(o===e){i=!0;break}o=this.prefabInstanceExposedActorMap.get(o)}if(i&&null!=s.prefab.params&&Object.assign(l,ia(s.prefab.params)),null!=s.prefab.innerParams){const e=r.slice(t+1);for(const t of s.prefab.innerParams){const a=ia(t.params);0!==Object.keys(a).length&&(i?c.push({path:oa(t.path,e)?t.path.slice(e.length):t.path,params:a}):oa(t.path,e)&&c.push({path:t.path.slice(e.length),params:a}))}}}}}for(const e of c)await this.applyActorComponentParams(t,e.path.slice(),e.params,o);await this.attachEditorComponents(t,a,o);const u=await prepareClassParameters(l,t.constructor,this.assetsService,this.assetManagerService,o,this.renderingView,this.shaders,this.actorProvider,e=>{const t=i.length>0?i+"/"+e:e;return this.prefabInstanceExposedActorMap.get(t)??null},t);Object.assign(t,u);try{return await this.actorProvider.initActor(t)}catch(e){console.error(`Failed to initiate actor (name="${a.name}", id=${a.id})`,e)}});return Promise.all(t)}async attachEditorComponents(e,t,a){const s=t.actor?.components??[];for(const r of s){const s=this.componentTypes.find(e=>e.name===r.type);if(null==s){console.warn(`Component type '${r.type}' not found for actor ${t.id}`);continue}const n=e.attach(s.type);if(null!=r.params){const e=await prepareClassParameters(r.params,null,this.assetsService,this.assetManagerService,a,this.renderingView,this.shaders,this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null,n);Object.assign(n,e)}for(const e of r.innerParams??[])await this.applyActorComponentParams(n,e.path.slice(),e.params,a)}}addVfxChildActors(e,t=e){}async applyActorComponentParams(e,t,a,s){const r=t.length,n=t.shift();if(0==r){const t=await prepareClassParameters(a,null,this.assetsService,this.assetManagerService,s,this.renderingView,this.shaders,this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null,e);for(const[a,s]of Object.entries(t))null!=s&&(e[a]=s)}else null!=e[n]&&await this.applyActorComponentParams(e[n],t,a,s)}canObjectBeInstanced(e){return e.physics?.type!==ve.dynamic&&"sky"!==e.type&&"global_fog"!==e.type&&"world_env"!==e.type}async canAssetBeInstanced(e){let t=this._canBeInstancedCache.get(e.assetId);if(null==t){const a=await this.createFromAsset(e);if(null==a)return!1;const s=[];a.traverse(e=>{!et(e)&&e.isMesh&&s.push(e)});const r=1==s.length&&0==s[0].children.length,n=!Rt,i=s.every(e=>!Array.isArray(e.material)||1===e.material.length),o=s.some(e=>e instanceof m&&null!=e.geometry.morphAttributes&&Object.keys(e.geometry.morphAttributes).length>0),l=!0;t=s.length>0&&(r||i&&n)&&l&&!o,this._canBeInstancedCache.set(e.assetId,t)}return t}async preInit(){this.renderingView?.onLoop(()=>{null!=this.sky&&this.renderingView.camera.getWorldPosition(this.sky.position)}),await this.preloadAssets()}async preloadAssets(){const e=await this.assetsService.getAssets();for(const t of e)this.assets.set(t.id,t)}shouldBeMaterialized(e){if(!1===e.enabled)return!1;if(null!=this.detailTier&&"asset_mesh"===e.type&&null!=e.assetId){const t=this.assets.get(e.assetId);if(null!=t){const e=t.mesh?.detailTier;if(null!=e)return e<=this.detailTier}}return!0}async initWithInstancing(){await this.preInit(),await this.prefetchAssets(),Jt.clear(),Xt.clear();const e=[],t=new Ge,a=new Ge,s=new Ge;let r=0,i=0,o=0;const u=new Map,p=new We(()=>new Map);for(const n of this.dataProvider.getObjects())await ra(n,async(n,c,d)=>{if(!this.shouldBeMaterialized(n))return;const h="asset_mesh"==n.type&&this.canObjectBeInstanced(n)&&await this.canAssetBeInstanced(n),f="shape_mesh"===n.type&&"landscape"!==n.shape&&n.physics?.type!==ve.dynamic;if(h||f){if(c&&c.children?.length>0){const e=c.children.findIndex(e=>e.id===n.id);e>=0&&c.children.splice(e,1)}if(f){let e=n.shape+JSON.stringify(n.shapeParams??{})+n.castShadow+n.receiveShadow;const t=n.materialAssignments?.at(0)?.materialId,a=null!=t?this.assets.get(t):null;let r=null;if(!1&&null!=a&&"shader"!==a.material.type){if(e+=a.material.type+a.material.shader,null!=a.material.shaderParams){if(e+=Object.entries(a.material.shaderParams).filter(([e,t])=>"color"!=e).map(e=>JSON.stringify(e)).join(),null!=a.material.shaderParams.color){const e=a.material.shaderParams.color;e.type===dt.Color&&null!=e.value&&(r=new l(e.value))}}e+=a.material.outlines,null!=a.material.outlineParams&&(e+=JSON.stringify(a.material.outlineParams)),e+=a.material.reflective,e+=a.material.bloom,e+=a.material.side,e+=a.material.side,e+=a.material.transparent,e+=a.material.alphaTest}else e+=t;s.push(e,{object:{...n,parentTransform:d},color:r}),o++}else{const e=this.assets.get(n.assetId);let s=u.get(n.assetId);if(null==s){const e=await this.createFromAsset(n,{assignMaterials:!1});if(null==e)return;if(s=u.get(n.assetId),null==s){s={useBatchedMesh:null!=Je(e)&&Nt(e,e=>!(e instanceof m)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},u.set(n.assetId,s)}}const o=ua(n.materialAssignments,e.materialAssignments);if(s.useBatchedMesh)await Ze(s.assetMesh,async t=>{if(!(t instanceof m))return;const s=Array.isArray(t.material)?t.material[0]:t.material,i=await this.resolveMaterialForAssignments(s,o,e);if(null!=i){p.get(n.id).set(t.uuid,i);let e=Ia(i);e+=Ma(t,i),a.push(e,{...n,parentTransform:d,meshUUID:t.uuid}),r++}else console.warn("Can not materialize mesh because missing material",n)});else{const e=n.assetId+JSON.stringify(n.materialAssignments??[]);t.push(e,{...n,parentTransform:d}),i++}}}else null==c&&e.push({...n,parentTransform:d})});console.log(`Scene init stats: \n Batched Assets: ${a.size} groups containing in total ${r} objects.\n Instanced Assets: ${t.size} groups containing in total ${i} objects.\n Shapes: ${s.size} batch groups containing in total ${o} objects. \n ${e.length} objects can not be batched. \n `);for(const e of u.values())this.prepareCollisionShapesForInstanced(e.assetMesh);console.time("materialize batches");for(const[e,t]of a.entries()){if(0==t.length)continue;let e;u.get(t[0].assetId).assetMesh;e=this.createBatchedMesh(t,p,u);const a=this.assets.get(t[0].assetId);e.castShadow=t[0].castShadow??a.castShadow??!0,e.receiveShadow=t[0].receiveShadow??a.receiveShadow??!0;const s=new He;s.add(e),s.userData.src=t[0],s.castShadow=!1,s.receiveShadow=!1,this.scene.add(s)}for(const e of t.values()){if(0==e.length)continue;let t;const a=u.get(e[0].assetId).assetMesh;t=await this.createInstancedMesh(e,a);const s=this.assets.get(e[0].assetId);t.castShadow=e[0].castShadow??s.castShadow??!0,t.receiveShadow=e[0].receiveShadow??s.receiveShadow??!0;const r=new He;r.add(t),r.userData.src=e[0],a instanceof He&&(r.collisionShapes=a.collisionShapes),this.prepareCollisionShapesForInstanced(r),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r)}console.timeEnd("materialize batches");for(const e of s.values()){if(0==e.length)continue;const t=e[0].object,a=await this.createFromShape(t),s=Xe(a,e=>!et(e)&&null!=e.geometry),r=s.material.clone();null!=e[0].color&&null!=r.color&&(r.color=new l(16777215));const i=s.geometry;let o,u;!(Rt||r instanceof U||null==i.index)?(o=new n.BatchedMesh(e.length,i.getAttribute("position").count,i.index.count,r),o.perObjectFrustumCulled=!0,u=o.addGeometry(i)):o=new n.InstancedMesh(i,r,e.length),o.castShadow=a.castShadow??!0,o.receiveShadow=s.receiveShadow??!0;for(let t=0;t<e.length;t++){const a=e[t],s=(new n.Matrix4).compose((new I).fromArray(a.object.position),(new S).setFromEuler((new c).fromArray(a.object.rotation)),(new I).fromArray(a.object.scale)),r=(new f).copy(a.object.parentTransform).multiply(s);let i;i=o instanceof n.BatchedMesh?o.addInstance(u):t,o.setMatrixAt(i,r),a.color}for(let t=0;t<e.length;t++){const s=e[t],r=new He;r.userData.src=e[0],a instanceof at&&(r.collisionShapes=[a.collisionShape]),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r),r.add(o),null==o.userData.hasCollision&&(o.userData.hasCollision=[]),o.userData.hasCollision[t]=!!s.object.collisionDetection}}await Promise.all(e.map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.initVfx(),await this.refreshSurfaceScatterPresence(!0)}prepareCollisionShapesForInstanced(e){e instanceof He&&e.collisionShapes.forEach(e=>{e instanceof a&&e.mesh instanceof m&&(e.mesh=e.mesh.geometry)})}testCanBatch(e,t){return!Rt&&(!Array.isArray(e)||1==e.length)&&this.testCanBatchMaterial(e)}testCanBatchMaterial(e){return null!=(Array.isArray(e)?e[0]:e)}createBatchedMesh(e,t,a){const s=new Ge;for(const t of e)null!=t.meshUUID?s.push(t.meshUUID??t.assetId,t):console.warn("Missing mesh uuid for batching");let r=0,i=0,o=0;const c=new Map;for(const[e,t]of s.entries()){const s=t[0].assetId,n=a.get(s);if(null==n){console.warn("Missing batching info for asset id "+s);continue}const l=Xe(n.assetMesh,t=>t instanceof m&&t.uuid===e);if(null==l){console.warn("Missing mesh in batched asset");continue}c.set(e,l);const u=l.geometry.getAttribute("position");null==u&&console.warn("Missing position attribute for batched mesh"),r+=l.geometry.index.count*t.length,i+=u.count*t.length,o+=t.length}const u=["color","map","roughness","roughnessMap","metalness","metalnessMap","opacity","alphaMap","aoMap","aoMapIntensity","normalMap","normalScale","emissive","emissiveIntensity","emissiveMap"],p=new Map,d=new Map,h=[];let f=new n.MeshStandardMaterial({color:"white"});const g=t.get(e[0].id).get(e[0].meshUUID);if(null==g)throw"missing source material";if(g instanceof w&&!(g instanceof n.MeshPhysicalMaterial)){const a=new Set,s=new Map;for(const r of e){const e=t.get(r.id).get(r.meshUUID);if(null==e)throw"missing mat";for(const t of u){let r=e[t];r instanceof n.CompressedArrayTexture&&null!=r.userData.index&&(r=r.userData.index);const i=s.get(t);void 0===i||Ga(r,i)?s.set(t,r):a.add(t)}}for(const e of a){let t;const a=g[e];let s=e;if("number"==typeof a){let a=h.find(e=>e.params.length<4);if(null==a){const t="vp"+h.length;a={name:t,params:[e],node:k(t)},h.push(a)}else a.params.push(e);s=a.name,t=_a(a.node,a.params.length-1)}else if(a instanceof P)t=k(s);else if(a instanceof I||a instanceof l)t=O(s);else if(a instanceof j)t=T(s);else if(a instanceof n.CompressedArrayTexture)s=e+"_i",t=D(s);else if(a instanceof x)continue;p.set(e,t),d.set(e,s)}let r=se.uv;g instanceof Ft&&null!=g.heightMap&&(r=zt(r,J(g.heightMap),N(g.heightScale)));let i=za(p.get("opacity"),B)??N(g.opacity??1);if(null!=g.alphaMap){let e;if(g.alphaMap instanceof n.CompressedArrayTexture){const t=X(g.alphaMap),a=za(p.get("alphaMap"),B)??N(g.alphaMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.alphaMap).sample(r);i=i.multiply(e.r)}let o=W(za(p.get("color"),le)??g.color,i);if(null!=g.map){let e;if(g.map instanceof n.CompressedArrayTexture){const t=X(g.map),a=za(p.get("map"),B)??N(g.map.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.map).sample(_t(r,g.map));o=o.multiply(e),i=i.multiply(e.a)}g.vertexColors&&(o=o.multiply(ce(ae(C.color.rgb),1)));let c=W(za(p.get("emissive"),le)??g.emissive,i);if(null!=g.emissiveMap){let e;if(g.emissiveMap instanceof n.CompressedArrayTexture){const t=X(g.emissiveMap),a=za(p.get("emissiveMap"),B)??N(g.emissiveMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.emissiveMap).sample(_t(r,g.emissiveMap));c=c.multiply(e)}const m=za(p.get("emissiveIntensity"),B)??N(g.emissiveIntensity??1),y=za(p.get("normalScale"),ie)??ne(g.normalScale??new j(1,1));let w=re.normal;if(null!=g.normalMap){let e;if(g.normalMap instanceof n.CompressedArrayTexture){const t=X(g.normalMap),a=za(p.get("normalMap"),B)??N(g.normalMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.normalMap).sample(_t(r,g.normalMap));w=z(e.rgb,y.x)}let b=za(p.get("roughness"),B)??N(g.roughness??1);if(null!=g.roughnessMap){let e;if(g.roughnessMap instanceof n.CompressedArrayTexture){const t=X(g.roughnessMap),a=za(p.get("roughnessMap"),B)??N(g.roughnessMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.roughnessMap).sample(_t(r,g.roughnessMap));b=b.multiply(e.g)}let v=za(p.get("metalness"),B)??N(g.metalness??0);if(null!=g.metalnessMap){let e;if(g.metalnessMap instanceof n.CompressedArrayTexture){const t=X(g.metalnessMap),a=za(p.get("metalnessMap"),B)??N(g.metalnessMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.metalnessMap).sample(_t(r,g.metalnessMap));v=v.multiply(e.b)}let M=N(1);if(null!=g.aoMap){let e;if(g.aoMap instanceof n.CompressedArrayTexture){const t=X(g.aoMap),a=za(p.get("aoMap"),B)??N(g.aoMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.aoMap).sample(_t(r,g.aoMap));M=M.multiply(e.r)}const S=za(p.get("aoMapIntensity"),B)??N(g.aoMapIntensity??0);let A=w;!0!==g.userData.disableAO&&(A=$("DOUBLE_SIDED",A,e=>R(new E("gl_FrontFacing"),e,e.multiplyScalar(-1))));const V=new U({color:q({color:o,roughness:b,metalness:v,ambientOcclusion:M,ambientOcclusionIntensity:S,emissive:c,emissiveIntensity:m,normal:A}),normal:w,roughness:b,emissive:c.rgb,transparent:g.transparent,alphaTest:g.alphaTest,envMap:g.envMap,opacity:i});null!=g.envMap&&(V.uniforms.envMapIntensity={value:g.envMapIntensity},V.uniforms.envMapRotation={value:$a(g.envMapRotation,g.envMap)}),V.envMap=g.envMap,V.side=g.side,f=V}else if(g instanceof U){const a=new Set,s=new Map,r=Object.keys(g.uniforms).filter(e=>!Pa(e));for(const n of e){const e=t.get(n.id).get(n.meshUUID);if(!(e instanceof U))throw new Error("Expected NodeShaderMaterial in node material batch");for(const t of r){const r=e.uniforms[t]?.value,n=s.get(t);void 0===n||Ga(r,n)?s.set(t,r):Da(r)&&Da(n)&&Ta(r)===Ta(n)&&a.add(t)}}const n=new Set(Object.keys(g.uniforms)),i={};for(const e of a){let t,a;const s=g.uniforms[e]?.value;if("number"==typeof s){let s=h.find(e=>e.params.length<4);if(null==s){const t=Oa("vp"+h.length,n);s={name:t,params:[e],node:k(t)},h.push(s)}else s.params.push(e);a=s.name,t=_a(s.node,s.params.length-1)}else if(s instanceof P)a=Oa(e,n),t=k(a);else if(s instanceof I||s instanceof l)a=Oa(e,n),t=O(a);else{if(!(s instanceof j))continue;a=Oa(e,n),t=T(a)}p.set(e,t),d.set(e,a),i[e]=t}if(0===p.size)f=g;else{const e=new U({color:g.outputColor,transform:g.outputTransform??null,position:null==g.outputTransform?g.outputPosition:void 0,normal:g.outputNormal??null,roughness:g.outputRoughness??null,opacity:g.outputOpacity??null,emissive:g.outputEmissive??null,transparent:g.transparent,alphaTest:g.alphaTest,envMap:g.envMap??null,fog:g.fog,lights:g.lights,uniforms:ka(g,new Set(p.keys())),uniformNodes:i});e.uniformNodes=i,y=g,(b=e).name=y.name,b.side=y.side,b.blending=y.blending,b.depthWrite=y.depthWrite,b.depthTest=y.depthTest,b.colorWrite=y.colorWrite,b.toneMapped=y.toneMapped,b.visible=y.visible,b.opacity=y.opacity,b.forceSinglePass=y.forceSinglePass,b.premultipliedAlpha=y.premultipliedAlpha,b.polygonOffset=y.polygonOffset,b.polygonOffsetFactor=y.polygonOffsetFactor,b.polygonOffsetUnits=y.polygonOffsetUnits,b.shadowSide=y.shadowSide,Object.assign(b.defines,y.defines),Object.assign(b.userData,y.userData),b.needsUpdate=!0,f=e}}else{f=g;for(const a of e){const e=t.get(a.id).get(a.meshUUID);if(e!=f){console.error(`Different materials in group for object ${a.id} and mesh uuid ${a.meshUUID}`,{objectMaterial:e,sourceMaterial:g});break}}}var y,b;const v=new Et(o,i,r,f);v.sortObjects=!0===f.transparent,v.perObjectFrustumCulled=!1;for(const e of h)v.initUniform(e.name,4);for(const[e,t]of p.entries()){if(h.some(t=>t.params.includes(e)))continue;let a=1;t instanceof ue||t instanceof le?a=4:t instanceof ie&&(a=2),v.initUniform(d.get(e)??e,a,0)}for(const[e,r]of s.entries()){const s=r[0].assetId,i=c.get(e);if(null==i){console.error(`Missing single asset mesh for mesh uuid ${e} and asset id ${s}`);continue}if(null==i.geometry){console.error("Missing geometry on mesh mesh");continue}const o=v.addGeometry(Sa(i.geometry,g)),u=a.get(s);if(null==u){console.warn("Missing batching info when configuring for asset id "+s);continue}const f=Je(u.assetMesh)?.uuid===e,m=u.assetMesh instanceof He&&f?u.assetMesh.collisionShapes:void 0,y=this.configureBatchedInstancedMesh(r,v,i,o,m);for(let e=0;e<y.length;e++){const a=r[e],s=y[e],i=t.get(a.id).get(a.meshUUID);for(const e of h){let t=Ua.set(0,0,0,0);for(let a=0;a<e.params.length;a++){const s=Ca(i,e.params[a]);"number"==typeof s&&t.setComponent(a,s)}v.setUniformAt(e.name,s,t)}for(let e of p.keys()){if(h.some(t=>t.params.includes(e)))continue;const t=d.get(e)??e;let a=Ca(i,e);if(a instanceof l&&(a=new I(a.r,a.g,a.b)),a instanceof n.CompressedArrayTexture)a=a.userData.index??0;else if(a instanceof x||null==a)continue;v.setUniformAt(t,s,a)}}}return v}async createInstancedMesh(e,t){const a=Xe(t,e=>!et(e)&&null!=e.geometry),s=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(t,ua(e[0].materialAssignments,s.materialAssignments),s),a.updateMatrix();const r=a.geometry.clone(),i=a.material;let o;if(o=new n.InstancedMesh(r,i,e.length),this.configureBatchedInstancedMesh(e,o,a),a.material instanceof h&&o.castShadow&&o.receiveShadow&&Array.isArray(i))for(const e of i);return o}configureBatchedInstancedMesh(e,t,a,s,r){const i=[];a.updateWorldMatrix(!0,!0);for(let o=0;o<e.length;o++){let l=o;t instanceof n.BatchedMesh&&(l=t.addInstance(s)),i.push(l);const u=(new n.Matrix4).compose((new I).fromArray(e[o].position),(new S).setFromEuler((new c).fromArray(e[o].rotation)),(new I).fromArray(e[o].scale)),p=(new f).copy(e[o].parentTransform).multiply(u).multiply(a.matrixWorld);t.setMatrixAt(l,p),null==t.userData.hasCollision&&(t.userData.hasCollision=[]),t.userData.hasCollision[l]=!!e[o].collisionDetection,null!=r&&(null==t.userData.collisionShapes&&(t.userData.collisionShapes=[]),t.userData.collisionShapes[l]=r)}return i}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("world_env"===e.type)this.resetWorldEnv(),this.worldEnvObj=null;else if("actor"==e.type||"vfx"===e.type){const t=this.materializedActors.get(e.id);null!=t?(t.disposed.next(!0),t.onEndPlay()):console.warn("Failed to remove actor",e)}else"prefab"===e.type&&this.materializedActors.forEach((t,a)=>{a.startsWith(e.id)&&(t.disposed.next(!0),t.onEndPlay()),this.materializedActors.delete(a)});const t=this.sceneObjectMap.get(e.id);t?.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter(t=>t.object.userData.src?.id===e.id).forEach(e=>this.components.splice(this.components.indexOf(e,1))),this.landscapeManagers.filter(t=>t.source.id===e.id).forEach(e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))}),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex(t=>t.source.id===e.id);if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return Ye(this.scene,t=>t.userData.src?.assetId==e,e=>null!=e.userData.src)}applyMaterials(e,t,a){return null==t?Promise.resolve([]):Promise.all(t.filter(e=>"null"!==e.materialId).map(t=>this.applyMaterial(e,t,a)))}async applyMaterial(e,t,a){await applyMaterial(e,t,async e=>{const t=await this.getAsset(e);if(null!=t)try{return materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders)}catch(e){console.error("Failed to apply material",e)}else console.warn("Missing material with id "+e)},this._originalMaterials,{textureFlipY:getConvertedFbxToGlbAssignedMaterialTextureFlipY(a)})}async resolveMaterialForAssignments(e,t,a){let s=e,r=null,n=null;const i=getConvertedFbxToGlbAssignedMaterialTextureFlipY(a);for(const e of t??[]){if(!fa(s,e,r,n))continue;const t=await this.getAsset(e.materialId);if(null==t){console.warn("Missing material with id "+e.materialId);continue}let a=await materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0);null!=a&&(a=ga(a,i)),null!=a&&s.id!==a.id&&(r=r??ha(s),n=n??s.name,s=a)}return s}unapplyMaterials(e){e.traverse(async e=>{if(e instanceof m)if(e.material instanceof Array)for(let t=0;t<e.material.length;t++)e.material[t]=this._originalMaterials.get(e.id+"#"+t)??e.material[t];else e.material=this._originalMaterials.get(e.id)??e.material})}updateActors(e){console.log("update actors"),this.actorTypes=e;const t=new Set(Object.values(we));Ye(this.scene,e=>e.userData.src?.id&&"actor"===e.userData.src.type&&this.materializedActors.has(e.userData.src?.id)&&!t.has(e.userData.src.actor.type)).forEach(async e=>{this.remove(e.userData.src),await this.materializeAndInitActor(e.userData.src)})}updateComponents(e){this.componentTypes=e,Ye(this.scene,e=>e.userData.src?.id&&"actor"===e.userData.src.type&&this.materializedActors.has(e.userData.src?.id)&&(e.userData.src.actor?.components?.length??0)>0).forEach(async e=>{this.remove(e.userData.src),await this.materializeAndInitActor(e.userData.src)})}updateShaders(e){this.shaders=e;for(const[e,t]of Jt.entries())t.userData.customShaderName&&Jt.delete(e);this.landscapeManagers.forEach(t=>t.updateShaders(e)),Ye(this.scene,e=>!0).forEach(e=>{e.traverse(async e=>{if(e instanceof m)if(Array.isArray(e.material))for(let t=0;t<e.material.length;t++){const a=e.material[t].userData?.customShaderName;if(null!=a){const a=e.material[t].userData.assetId,s=await this.getAsset(a);null!=s&&this.refreshMaterial(e,e.material[t],s,t)}}else{const t=e.material.userData?.customShaderName;if(null!=t){const t=e.material.userData.assetId,a=await this.getAsset(t);null!=a&&this.refreshMaterial(e,e.material,a)}}})})}async update(e){if("sky"===e.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(e);if("world_env"===e.type&&null!=this.worldEnvObj)return void this.updateWorldEnv(e);const t=this.sceneObjectMap.get(e.id);if(t){let n=!1;if(t.traverseAncestors(e=>{"_hology_transform_group"===e.name&&(n=!0)}),!n){const a=this.findParent(e);null!=a&&a.uuid!=t.uuid?a.attach(t):console.error("Parent is wrong")}if("prefab"!==e.type&&"group"!==e.type){this.unapplyMaterials(t);this.inEditor&&e.hidden&&!1?t.traverse(e=>{e instanceof m&&(e.material.wireframe=!0)}):t.traverse(e=>{e instanceof m&&(e.material.wireframe=!1)})}if("asset_mesh"===e.type&&t.userData.assetId!==e.assetId){this.remove(e);const t=await this.materializeAndInitActor(e);return void this.updated$.next({object:t,source:e})}if("asset_mesh"===e.type){const a=this.assets.get(e.assetId);ua(e.materialAssignments,a.materialAssignments).forEach(e=>this.applyMaterial(t,e,a))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);if(n||(null!=e.position&&t.position.fromArray(e.position),null!=e.scale&&t.scale.fromArray(e.scale),null!=e.rotation&&t.rotation.fromArray(e.rotation)),this.applyVertexMaterials(e,t),"light"==e.type){if("point"==e.light.type){const a=t;a.color=new l(e.light.point.color),a.intensity=e.light.point.intensity,a.decay=e.light.point.decay,a.castShadow=e.light.point.castShadow,a.distance=Math.max(e.light.point.distance,0),a.userData.volumetricIntensity=e.light.point.volumetricIntensity}else if("spot"==e.light.type){const a=t;a.color=new l(e.light.spot.color),a.intensity=e.light.spot.intensity,a.decay=e.light.spot.decay,a.angle=e.light.spot.angle,a.penumbra=e.light.spot.penumbra,a.castShadow=e.light.spot.castShadow,a.distance=Math.max(e.light.spot.distance,0),a.userData.volumetricIntensity=e.light.spot.volumetricIntensity}else if("directional"===e.light.type)this.applyDirectionalLight(e.light.directional,e);else if("ambient"===e.light.type)this.applyDirectionalAmbientLight(t,e.light.ambient,e);else if("rectArea"===e.light.type){const a=t;a.color=new l(e.light.rectArea.color),a.intensity=e.light.rectArea.intensity,null!=e.scale&&(a.width=e.scale[0],a.height=e.scale[1]),a.children.forEach(e=>{e instanceof Bt&&e.update()})}}else if("landscape"===e.shape){const a=this.landscapeManagers.find(t=>t.source.id===e.id),n=null==a||(s=a.source.landscape.options,r=e.landscape.options,s.density!==r.density||s.sections.x!==r.sections.x||s.sections.y!==r.sections.y);if(this.inEditor&&n){this.remove(e);const t=await this.materializeAndInitActor(e);return void this.updated$.next({object:t,source:e})}this.applyHeightMaps(t,e.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter(t=>t.source.id===e.id).forEach(t=>{t.updateSource(e),t.queueRefreshScatter(this.renderingView.camera.position,!0,e=>!0)})}else if("global_fog"===e.type){const t=(this.scene.fog instanceof p?"density":"linear")!==e.fog.type;this.scene.fog=sa(e.fog),t&&(a=this.scene).traverse(e=>{if(e instanceof m){const t=e.material;t instanceof U&&(a.fog instanceof u?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof p&&(t.uniforms.density={value:a.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}}),this.fixFogColor()}else if("actor"===e.type){if(this.materializedActors.has(e.id)){const t=this.materializedActors.get(e.id);if(t instanceof Ot){const a=await prepareClassParameters(e.actor.params,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,[],this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null,t);return void Object.assign(t,a)}const a=this.editorActorParamSnapshot.get(e.id);null!=a&&a===JSON.stringify(e.actor)||n||(this.remove(e),await this.materializeAndInitActor(e))}}else if("shape_mesh"===e.type){const a=await this.createMeshByShape(e.shape,t.material,e.shapeParams);t instanceof at&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}if("shape_mesh"===e.type&&"landscape"!==e.shape)Yt(t,e.castShadow,e.receiveShadow);else if("asset_mesh"===e.type){const a=this.assets.get(e.assetId);if(null==a)return void console.error("Asset not found",e.assetId);const s=e.receiveShadow??!!a.receiveShadow,r=e.castShadow??!!a.castShadow;Yt(t,r,s)}e.name&&e.name.length>0&&(t.name=e.name),this.updated$.next({object:t,source:e})}else{const t=await this.materializeAndInitActor(e);this.updated$.next({object:t,source:e})}var a,s,r;this.renderingView.renderer.shadowMap.needsUpdate=!0}async materializeAndInitActor(e,t=this.findParent(e)){const a=await this.materialize(e,t),s=Array.from(this.materializedActors.entries()).filter(([t])=>t===e.id||t.startsWith(e.id+"/"));return await this.initActorsPostInit(s),a}findParent(e){const t=this.dataProvider.getObjects().flatMap(t=>t.id===e.id?null:qe(t,t=>t.children?.some(t=>t.id===e.id),()=>!0))[0];return null==t?this.scene:null!=t?Ye(this.scene,e=>e.userData?.src?.id===t.id,e=>null!=e.userData?.src)[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new l(this.scene.fog.color))}findMeshWithGeometry(e){let t;return e.traverse(e=>{e instanceof m&&e.geometry&&(t=e)}),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;let a=1;for(const t of e.vertexMaterials)a=Math.max(t.w.length,a);const s=Le(e.vertexMaterials,e=>e.m);t.traverse(e=>{if(e instanceof m){if(null==e.geometry)return;if(va(ct(e,0,!1)),a>0){va(ct(e,0,!1))}}});const r=new Set;for(const[e,n]of s.entries()){const s=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let i=!1;if(null==s||null==s.geometry)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const o=ct(s,0,!0);va(o);for(const e of n)o.setX(e.i,e.w[0]??0),o.setY(e.i,e.w[1]??0),o.setZ(e.i,e.w[2]??0),o.setW(e.i,e.w[3]??0),i=!0;if(a>0){const e=ct(s,4,!0);va(e);for(const t of n)e.setX(t.i,t.w[4]??0),e.setY(t.i,t.w[5]??0),e.setZ(t.i,t.w[6]??0),e.setW(t.i,t.w[7]??0),e.needsUpdate=!0,i=!0}i&&r.add(e)}this.inEditor&&this.landscapeManagers.filter(t=>t.source.id===e.id).forEach(e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,e=>r.has(e.name)))}async materialize(e,t,a=!1,s){const r=this.getNestedActorId(e.id,s);if(this.idToSceneObject.set(r,e),!this.shouldBeMaterialized(e))return;let n,i;switch(e.type){case"asset_mesh":n=await this.createFromAsset(e),n=function(e){if(null==e)return e;e.updateWorldMatrix(!0,!0);const t=[];e.traverse(e=>{e.isSkinnedMesh&&t.push(e)});let a=e;for(const e of t){const t=as(e),s=e.parent;if(null==s){a=t;continue}const r=s.children.indexOf(e);e.removeFromParent(),s.add(t);const n=s.children.indexOf(t);r>=0&&n>=0&&n!==r&&(s.children.splice(n,1),s.children.splice(r,0,t))}return function(e){const t=[];e.traverse(e=>{e.isBone&&t.push(e)});for(const e of t)null!=e.parent&&!e.parent.isBone&&rs(e)&&e.removeFromParent()}(a),a}(n);break;case"shape_mesh":n=await this.createFromShape(e);break;case"light":n=await this.createLight(e);break;case"particles":n=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=sa(e.fog),this.fixFogColor(),n=new d;break;case"sky":this.sky=vt(),this.updateSky(e),n=this.sky;break;case"world_env":this.updateWorldEnv(e),n=new d,this.worldEnvObj=n;break;case"actor":({object:n,actor:i}=await this.createFromActor(e,s));break;case"group":n=new d;break;case"prefab":n=await this.createFromPrefab(e,s,t);break;case"vfx":n=await this.createFromVfx(e,s);break;default:console.warn(`Failed to materialize object. Unknown type '${e.type}'. This might be because the hology/core library is not compatible with the editor version or because of an error in the scene data. Scene object: id=${e.id}, name=${e.name}`)}if(null!=n){if(e.name&&e.name.length>0&&(n.name=e.name),this.applyTransform(e,n),a?n.userData._src=e:n.userData.src=e,null!=i&&(n.userData.actor=i),this.inEditor,this.inEditor,this.objectMap.set(n.uuid,e),this.sceneObjectMap.set(e.id,n),e.physics?.type!==ve.dynamic||null==t||this.inEditor?null==t?this.scene.add(n):null==t||"actor"!==e.type||this.inEditor?t?.add(n):(t.add(n),this.scene?.attach(n),console.log(n)):(t.add(n),n.getWorldPosition(n.position),n.getWorldQuaternion(n.quaternion),n.getWorldScale(n.scale),this.scene?.attach(n)),null!=e.children&&await Promise.all(e.children?.map(e=>this.materialize(e,n,a))),this.inEditor||null!=t||"asset_mesh"!=e.type&&"shape_mesh"!==e.type&&"prefab"!==e.type&&"group"!==e.type||"landscape"===e.shape||null!=e.physics?.type&&e.physics.type==ve.dynamic||aa(n),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,n;console.warn("RenderingView not found in materializer")}}async handleSurfaceScatterSceneMutation(e){const t=this.surfaceScatterManager?.referencesSceneObject(e.id)??!1,a=await this.sceneObjectContainsSurfaceScatter(e);(t||a)&&await this.refreshSurfaceScatterPresence(!0)}async refreshSurfaceScatterPresence(e=!1){return await this.sceneContainsSurfaceScatter()?(null==this.surfaceScatterManager&&(this.surfaceScatterManager=new ut(this.scene,this.dataProvider,this.renderingView,this.assetManagerService,this.assetsService)),this.surfaceScatterManager.queueRefresh(e),!0):(this.disposeSurfaceScatterManager(),!1)}disposeSurfaceScatterManager(){null!=this.surfaceScatterManager&&(this.surfaceScatterManager.clear(),this.surfaceScatterManager.stop(),this.surfaceScatterManager=void 0)}async sceneContainsSurfaceScatter(){return this.sceneObjectsContainSurfaceScatter(this.dataProvider.getObjects())}async sceneObjectsContainSurfaceScatter(e,t=[]){for(const a of e??[])if(await this.sceneObjectContainsSurfaceScatter(a,t))return!0;return!1}async sceneObjectContainsSurfaceScatter(e,t=[]){if("asset_mesh"===e.type&&(e.surfaceScatter?.meshes?.length??0)>0)return!0;if(null!=e.children&&await this.sceneObjectsContainSurfaceScatter(e.children,t))return!0;if("prefab"===e.type&&null!=e.assetId){if(t.includes(e.assetId))return!1;const a=this.assets.get(e.assetId)??await this.assetsService.getAsset(e.assetId),s=a?.prefab?.objects;if(null!=s)return this.sceneObjectsContainSurfaceScatter(s,[...t,e.assetId])}return!1}sceneReferencesPrefabAsset(e){const t=(a=[])=>{for(const s of a??[]){if("prefab"===s.type&&s.assetId===e)return!0;if(t(s.children))return!0}return!1};return t(this.dataProvider.getObjects())}async prefabAssetContainsSurfaceScatter(e){return"prefab"===e.type&&null!=e.prefab?.objects&&this.sceneObjectsContainSurfaceScatter(e.prefab.objects,[e.id])}applyTransform(e,t){null!=e.position&&t.position.fromArray(e.position),null!=e.scale&&t.scale.fromArray(e.scale),null!=e.rotation&&t.rotation.fromArray(e.rotation)}updateWorldEnv(e){this.renderingView.aoPass.enabled=e.worldEnv.ao.enabled,this.renderingView.aoPass.blendIntensity=e.worldEnv.ao.blendIntensity,this.renderingView.aoPass.updateGtaoMaterial(e.worldEnv.ao);const t=e.worldEnv.toneMapping;null!=t&&(this.renderingView.baseToneMapping=t.mapping??0,this.renderingView.baseToneMappingExposure=t.exposure??1,this.renderingView.renderer.toneMapping=this.renderingView.baseToneMapping,this.renderingView.renderer.toneMappingExposure=this.renderingView.baseToneMappingExposure);const a=e.worldEnv.environment;null!=a&&null!=a.textureId?this.assetManagerService.getTexture(this.assets.get(a.textureId)).then(e=>{if(null==e)return void console.error("Failed to load environment texture with id "+a.textureId);if(null==this.pmremGenerator&&(this.pmremGenerator=new n.PMREMGenerator(this.renderingView.renderer),this.pmremGenerator.compileEquirectangularShader()),!this.pmremGeneratorResults.has(e))try{const t=this.pmremGenerator.fromEquirectangular(e).texture;this.pmremGeneratorResults.set(e,t)}catch(e){return void console.error("Failed to generate PMREM for environment texture",e)}const t=this.pmremGeneratorResults.get(e);this.renderingView.scene.environment=t,this.renderingView.scene.environmentIntensity=a.intensity??1}):this.renderingView.scene.environment=null}resetWorldEnv(){this.renderingView.aoPass.enabled=!1,this.renderingView.aoPass.blendIntensity=1,this.renderingView.aoPass.output=0,this.renderingView.baseToneMapping=0,this.renderingView.baseToneMappingExposure=1,this.renderingView.renderer.toneMapping=this.renderingView.baseToneMapping,this.renderingView.renderer.toneMappingExposure=this.renderingView.baseToneMappingExposure}async updateSky(e){null!=this.sky&&(null==e?.sky?.materialId&&this.sky.material!==Mt?(this.sky.material=Mt,this.applySkySettings(this.sky.material)):this.sky.material.userData?.assetId!==e.sky.materialId&&this.updateSkyMaterial(e),null!=e.rotation&&this.sky.rotation.fromArray(e.rotation))}async updateSkyMaterial(e){const t=await this.assetsService.getAsset(e.sky.materialId);if(null==t)return void console.warn(`No material asset found for sky with id ${e.sky.materialId}`);const a=await materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);this.applySkySettings(a),null!=this.sky?this.sky.material=a:console.warn("No sky has been created")}applySkySettings(e){e.side=n.BackSide,(e instanceof w||e instanceof n.MeshBasicMaterial||e instanceof n.ShaderMaterial)&&(e.fog=!1),e.depthTest=!1}async createComponent(e,t,a,s){const r=new Wt[a.path+"/"+a.className],n=t.id+s;r.id=n,r.object=e;for(const e of a.params)null!=e.value&&(r[e.name]=e.value);return this.components.push(r),n}async createFromActor(e,t){const a=this.actorTypes.find(t=>t.name===e.actor?.type)?.type??we[e.actor?.type];if(null==a)return{object:null,actor:null};this.inEditor&&this.editorActorParamSnapshot.set(e.id,JSON.stringify(e.actor));const s=await this.actorProvider.create(a,(new I).fromArray(e.position),(new c).fromArray(e.rotation),!0);return this.materializedActors.set(this.getNestedActorId(e.id,t),s),{object:s?.object,actor:s}}getNestedActorId(e,t){return null!=t?t.sceneObjectChain.join("/")+"/"+e:e}async createFromVfx(e,t){const a=await this.assetsService.getAsset(e.assetId);null==a&&console.error("Could not find asset",e);const s=await this.actorProvider.create(de,(new I).fromArray(e.position),(new c).fromArray(e.rotation),!1);try{await s.fromAsset(a)}catch(e){return console.error("Failed to create VFX asset",e),null}return s.play(),this.materializedActors.set(this.getNestedActorId(e.id,t),s),null!=s&&(s.object.userData.actor=s),s?.object}async createFromShape(e){const t=this.inEditor&&e.hidden;let a;if("landscape"==e.shape)a=this.createLandscape(e),a.traverse(e=>{e instanceof m&&this._originalMaterials.set(e.id,e.material)});else{let s=new w({name:"Default",color:new l("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});!0===e.collider&&(s.opacity=.3,s.color.set(2517460),s.transparent=!0);const r=await this.createMeshByShape(e.shape,s,e.shapeParams);r.castShadow=e.castShadow??!0,r.receiveShadow=e.castShadow??!1,!1===e.collisionDetection&&(r.collisionShape=null),r.physics=e.physics,a=r,this._originalMaterials.set(a.id,r.material),a.traverse(e=>{})}return t||(await Promise.all((e.materialAssignments??[]).filter(e=>null!=e.materialId).map(e=>this.applyMaterial(a,e))),this.applyVertexMaterials(e,a)),a}createLandscape(e){const t=e.landscape?.options;if(null==t)return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new d;const a=rt(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new st(e,this.renderingView,a,this.assetManagerService,this.assetsService,this.shaders,t=>{(e.materialAssignments??[]).filter(e=>null!=e.materialId).forEach(e=>this.applyMaterial(t,e))});return this.landscapeManagers.push(s),s.refreshGeometry(),a}applyHeightMaps(e,t,a=!1){const s=new nt(e.sections);for(const e of t??[]){const t=s.find(e.x,e.y);if(!t)return;const a=t.geometry.getAttribute("position");for(const t of e.points)a.setY(t.i,t.y);a.needsUpdate=!0}const r=e.sections;r.forEach(e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()}),this.inEditor&&!a||setTimeout(()=>it(r),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&wt.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=yt[e].geometry(s);(function(e){return null!=e.index&&e.hasAttribute("position")&&e.hasAttribute("normal")&&e.hasAttribute("uv")})(t)&&t.computeTangents(),this.geometryCache.set(r,t)}this.collisionShapeCache.has(r)||this.collisionShapeCache.set(r,yt[e].collision(s));return new at(this.geometryCache.get(r),t,this.collisionShapeCache.get(r))}if(this.inEditor)throw new Error(`Unsupported shape '${e}'`);console.warn(`Failed to create shape. Unsupported shape '${e}'. This might be because the hology/core library is not compatible with the editor version.`)}async createFromAsset(e,t){const a=this.assets.get(e.assetId)??await this.assetsService.getAsset(e.assetId);if(null==a)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);let{scene:s}=await this.assetManagerService.getMesh(a,{mergeGeomtries:!0});if(!1!==t?.assignMaterials)try{await Promise.all(ua(e.materialAssignments,a.materialAssignments).map(e=>this.applyMaterial(s,e,a)))}catch(t){console.error("Failed to apply material"+t,e)}const r=e.receiveShadow??!!a.receiveShadow,n=e.castShadow??!!a.castShadow;return s.receiveShadow=r,Yt(s,n,r),!1!==e.collisionDetection&&!1!==a.collisionDetection||(s.collisionShapes=[]),null!=e.physics&&!0!==this.inEditor&&(s.physics=e.physics),this.applyVertexMaterials(e,s),s.traverse(e=>{e instanceof m&&"computeBoundsTree"in e.geometry&&null==e.geometry.boundsTree&&e.geometry.computeBoundsTree()}),s.userData.assetId=e.assetId,s}async createFromPrefab(e,t,a){const s=await this.assetsService.getAsset(e.assetId);if(null==s)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);null==t&&(t={sceneObjectChain:[]}),t.sceneObjectChain.push(e.id);const{object:r}=await this.createFromPrefabAsset(s,t,a,e);return t.sceneObjectChain.pop(),r}async createFromPrefabAsset(e,t,a,s,r=!0){const n=new d;null!=s&&this.applyTransform(s,n),null!=a&&a.add(n),await Promise.all(e.prefab.objects.filter(e=>"global_fog"!==e.type&&"world_env"!==e.type).map(e=>this.materialize(e,n,!0,structuredClone(t))));const i=t.sceneObjectChain.join("/"),o=Array.from(this.materializedActors.entries()).filter(([e,a])=>e.startsWith(i)&&e.split("/").length-1===t.sceneObjectChain.length);let l;if(o.forEach(e=>{}),null!=e.prefab?.mainActorId){const a=t.sceneObjectChain.join("/")+"/"+e.prefab.mainActorId;l=this.materializedActors.get(a)}r||await this.initActorsPostInit(o);const c=Array.from(this.materializedActors.entries()).filter(([e,t])=>e.startsWith(i)).map(([,e])=>e);if(null!=e.prefab?.mainActorId&&null!=s){const a=t.sceneObjectChain.join("/"),s=a+"/"+e.prefab.mainActorId;this.prefabInstanceExposedActorMap.set(a,s)}return{object:n,actors:c,mainActor:l}}async createParticleSystem(e){await this.assetsService.getAsset(e.assetId);return new v}async createLight(e){if("point"===e.light.type){const t=new M(e.light.point.color,e.light.point.intensity,e.light.point.distance,e.light.point.decay);if(t.castShadow=e.light.point.castShadow??!0,this.inEditor){const e=(new n.TextureLoader).load("assets/light-bulb-icon.webp"),a=new n.SpriteMaterial({map:e,alphaTest:.5}),s=new kt(a);s.scale.multiplyScalar(.6),t.add(s)}return t}if("spot"===e.light.type){const t=new n.SpotLight(e.light.spot.color,e.light.spot.intensity,e.light.spot.distance,e.light.spot.angle,e.light.spot.penumbra,e.light.spot.decay);if(t.castShadow=e.light.spot.castShadow??!0,t.target=new v,t.target.position.set(0,-1,0),t.add(t.target),this.inEditor){const e=(new n.TextureLoader).load("assets/light-bulb-icon.webp"),a=new n.SpriteMaterial({map:e,alphaTest:.5}),s=new kt(a);s.scale.multiplyScalar(.6),t.add(s),t.add(new n.SpotLightHelper(t))}return t}if("rectArea"===e.light.type){const t=new n.RectAreaLight(e.light.rectArea.color,e.light.rectArea.intensity,e.scale?e.scale[0]:1,e.scale?e.scale[1]:1);if(this.inEditor){const e=(new n.TextureLoader).load("assets/light-bulb-icon.webp"),a=new n.SpriteMaterial({map:e,alphaTest:.5}),s=new kt(a);s.scale.multiplyScalar(.6),t.add(s);const r=new Bt(t);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional,e),new d):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient,e),new d):void 0}applyDirectionalAmbientLight(e,t,a){const s=this.scene.children.find(e=>e.name===bt);null!=s?(s.intensity=t.intensity,s.color.set(t.color),s.groundColor.set(t.color),s.userData.src=a,s.userData.volumetricIntensity=t.volumetricIntensity):console.warn("Couldn't find ambient light")}applyDirectionalLight(e,t){for(const a of this.renderingView.csm.lights)a.intensity=e.intensity,a.color.set(e.color),a.castShadow=e.castShadow,a.userData.src=t,a.userData.volumetricIntensity=e.volumetricIntensity;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.createAssetSubscription.unsubscribe(),this.materializedActors.forEach(e=>e.disposed.next(!0)),this.materializedActors.clear()}};qt=e([pe(),t("design:paramtypes",[A,Object,Qe,Ke,Ae,Array,Array,Object,Array])],qt);export{qt as SceneMaterializer};function Yt(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const Jt=new Map,Xt=new Map,Zt=new g({color:16711935}),Ht=new Map;export async function materialFromAsset(e,t,a,s,r,n=!0){if(null==e||null==e.material)return console.error("Asset or asset material is null",e),Zt;const i=JSON.stringify(e.material)+t?._id,o=n&&!("shaderGraph"===e.material.type&&"asset"===e.material.shaderGraph?.source);if(o&&Jt.has(i))return Jt.get(i);if(o&&Xt.has(i))return await Xt.get(i);const l=_materialFromAsset(i,e,t,a,s,r,o);return o?Xt.set(i,l).get(i):l}export async function _materialFromAsset(e,t,a,r,i,o,c=!0){const u={opacity:t.material.params?.opacity??1,map:null,emissive:t.material.params?.emissive??null,metalness:t.material.params?.metalness??0,flatShading:t.material.params?.flatShading??!1,color:new l(t.material.params?.color),transparent:null!=t.material.params?.opacity&&t.material.params?.opacity<1},p={};if(null!=t.material.params?.map){const e=t.material.params.map,a=await r.getAsset(e);null!=a&&(u.map=await i.getTexture(a))}let d,h,f;switch(t.material.type){case"phong":d=new y({...u,...p});break;case"water":d=pt(u,a);break;case"grassFoliage":d=ot({color:u.color,map:u.map},a);break;case"grass":d=lt({...u,colorTwo:new l(t.material.params.colorTwo),colorThree:new l(t.material.params.colorThree)},a);break;case"shaderGraph":{const e=await async function(e,t){const a=e.material?.shaderGraph;if("local"===a?.source)return a.graph;if("asset"===a?.source){const e=await t.getAsset(a.assetId);return e?.shaderGraph??null}return e.shaderGraph??null}(t,r);if(null==e){console.warn("Missing shader graph for material "+t.name),d=Zt;break}"surface"===e.target&&null!=e.materialOptions?.side&&(h=Gt(e.materialOptions.side)),"decal"===e.target?f=!1:null!=e.materialOptions?.transparent&&(f=e.materialOptions.transparent);try{const s=await prepareShaderGraphParameters(t.material?.shaderParams??{},e,r,i,a,o),n=t.shaderGraphPreviewNodeId,l=t.trailBillboard;d=Ut(e,{parameters:s,previewNodeId:n,trailBillboard:l}),d.userData.customShaderName="asset"===t.material.shaderGraph?.source?`shaderGraph:${t.material.shaderGraph.assetId}`:`shaderGraph:${t.id}`}catch(e){console.log("Shader graph runtime error: "+e,e),d=Zt}break}case"standard":case"unlit":case"toon":case"layered":case"lambert":case"shader":case"landscape":case"landscape-composite":case"decal-unlit":case"decal-standard":case"sprite":const e={standard:Lt?Ce:Oe,lambert:Ce,unlit:ke,toon:Vt,layered:Dt,landscape:Te,"landscape-composite":De,"decal-unlit":At,"decal-standard":xt,sprite:s}[t.material.type]??o.find(e=>e.name==t.material.shader)?.type;if(e){try{let s=new e;const n=await prepareClassParameters(t.material?.shaderParams??{},e,r,i,null,a,o,void 0,void 0,s);Object.assign(s,n),d=s.build()}catch(e){console.log("Shader runtime error: "+e,e),Ht.has(t.material.shader)||Ht.set(t.material.shader,Zt.clone()),d=Ht.get(t.material.shader)}d.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),d=Zt;break;default:throw new Error("Unsupported material type "+t.material.type)}return a?.csm.setupMaterial(d),c&&null!=a&&Jt.set(e,d),d.side=h??t.material.side??d.side??n.FrontSide,d.transparent=(f??t.material.transparent??u.transparent??!1)||d.transparent,d.alphaTest=t.material.alphaTest??d.alphaTest??0,null!=t.material.blending&&(d.blending=Me[t.material.blending]??n.NormalBlending),t.material.bloom&&(d.userData.hasBloom=!0),t.material.reflective&&(d.userData.reflective=!0),!0===t.material.outlines&&(d.userData.outlineParameters={},null!=t.material.outlineParams&&(null!=t.material.outlineParams.color&&(d.userData.outlineParameters.color=new l(t.material.outlineParams.color).toArray()),null!=t.material.outlineParams.thickness&&(d.userData.outlineParameters.thickness=t.material.outlineParams.thickness))),d.userData.assetId=t.id,c&&Xt.delete(e),d}export function prepareCustomParamsFromShaderGraph(e,t={}){return Object.fromEntries((e.parameters??[]).map(e=>{const a=function(e){switch(e){case"float":return dt.FloatNode;case"boolean":return dt.BooleanNode;case"texture":return dt.Sampler2DNode;case"vec2":return dt.Vec2Node;case"vec3":return dt.Vec3Node;case"vec4":return dt.Vec4Node;case"color":return dt.RgbNode}}(e.type),s=t[e.name],r=s?.override??null!=s,n=void 0!==e.defaultValue?e.defaultValue:customParameterDefaultValueByType.get(a),i=!1===r?ca(n):s?.value??ca(n);return[e.name,{type:a,value:i,override:r}]}))}export async function prepareShaderGraphParameters(e,t,a,s,r,n){const i={},o=prepareCustomParamsFromShaderGraph(t,e);for(const[e,t]of Object.entries(o)){const o=await Qt(e,t,a,s,null,r,n);null!=o&&(i[e]=o)}return i}export async function prepareClassParameters(e,t,a,s,r,n,i,o,l,c){const u={},{params:p,skipped:d}=ft(e,{parameterType:t,parameterTarget:c,extractPropertyParameters:Ve,toSerializedParamType:toSerializedParamType});for(const e of d)console.warn(`Skipping stored parameter "${e.key}" because it could not be converted from ${dt[e.sourceType]} to ${dt[e.targetType]}`);for(const[e,t]of Object.entries(p)){if(!1===t.override)continue;const c=await Qt(e,t,a,s,r,n,i,o,void 0,void 0,l);null!=c&&(u[e]=c)}return u}export async function prepareShapeParameters(e,t,a){const s={};for(const[r,n]of Object.entries(e)){const e=await Qt(r,n,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const Kt=new Map;async function Qt(e,t,a,s,r,n,i,o,u=t.value,p=t.type,d,h=(t.type===dt.Struct?t.struct:void 0)){if(null==t||null==u||""===u)return null;switch(p){case dt.Array:if(Array.isArray(u)&&"element"in t)return await Promise.all(u.map(l=>Qt(e,t,a,s,r,n,i,o,l,t.element,d,t.elementStruct)));break;case dt.Number:case dt.FloatNode:let f;if("string"==typeof u?f=parseFloat(u):"number"==typeof u&&(f=u),p===dt.FloatNode){if("object"==typeof u&&"a"in u&&"b"in u){const e=u;if(null==e.a)return null;const t="string"==typeof e.a?parseFloat(e.a):e.a;if(null==e.b)return t;const a="string"==typeof e.b?parseFloat(e.b):e.b,s=function(e){let t=Kt.get(e);return null==t&&(t=xe(St.decode(e)),Kt.set(e,t)),t}(e.easing),r=s.sample(je(Ie.energy));return _(N(t),N(a),r)}return new H(Ue(e),f,void 0,!1)}return f;case dt.Texture:let m=await s.getTexture(await a.getAsset(u));return"envmap"===e.toLowerCase()&&null!=n&&(m=n.getEnvTexture(m)),m;case dt.Sampler2DNode:const g=await a.getAsset(u);if(null!=g?.texture?.textureArrayFileKey){const{texture:t,layerIndex:a}=await s.getTextureArray(g);if(t&&null!=a)return new K(null,t,new H(Ue(e)+"_i",a,void 0,!1))}const y=await s.getTexture(g);return y?J(y):null;case dt.Boolean:return u;case dt.BooleanNode:return new Z(Ue(e),u,void 0,!1);case dt.Vector2:case dt.Vec2Node:if("object"==typeof u){const t=u instanceof Array?(new j).fromArray(u):new j(u.x,u.y);return p===dt.Vec2Node?new Q(Ue(e),t,void 0,!1):t}return null;case dt.Vector3:case dt.Vec3Node:if("object"==typeof u){const t=u instanceof Array?(new I).fromArray(u):new I(u.x,u.y,u.z);return p===dt.Vec3Node?new ee(Ue(e),t,void 0,!1):t}return null;case dt.Vector4:case dt.Vec4Node:if("object"==typeof u){const t=u instanceof Array?(new P).fromArray(u):new P(u.x,u.y,u.z,u.w);return p===dt.Vec4Node?new te(Ue(e),t,void 0,!1):t}return null;case dt.Color:case dt.RgbNode:const w=new l(u);return p===dt.RgbNode?new ee(Ue(e),new I(w.r,w.g,w.b),void 0,!1).rgb:w;case dt.String:return u;case dt.BaseActor:const b=u;if(null==r&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==b)return null;if("object"==typeof b&&null!=b.type&&null!=b.id){if("actor"===b.type)return r?.get(b.id)??null;if("prefab"===b.type){const e=d?d(b.id):null;if(null!=e)return r?.get(e)??null;const t=[];for(const[e,a]of r?.entries()??[])e.startsWith(b.id+"/")&&t.push(a);return 1===t.length?t[0]:null}}if("string"==typeof b){const e=r?.get(b);if(null!=e)return e;const t=d?d(b):null;if(null!=t)return r?.get(t)??null;const a=[];for(const[e,t]of r?.entries()??[])e.startsWith(b+"/")&&a.push(t);return 1===a.length?a[0]:null}return null;case dt.Euler:const v=u;return(new c).fromArray(v);case dt.Object3D:{const e=await a.getAsset(u);return(await s.getMesh(e,{applyMaterials:!0,rescale:!0})).scene}case dt.Material:{if(null==u)return null;const e=await a.getAsset(u);return null==e?(console.warn("Material asset not found for material parameter",u),null):null==e.material?(console.warn("Using a non-material asset for material parameter"),null):await materialFromAsset(e,n,a,s,i)}case dt.AudioBuffer:return await s.getAudio(await a.getAsset(u));case dt.VisualEffect:const M=await a.getAsset(u);if(null==o){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in M)return new he(o,M);console.error("Using a non-vfx asset for visual effect parameter");break;case dt.Prefab:{const e=await a.getAsset(u);return null==e?(console.error("Using a non-prefab asset for prefab parameter",u),null):new fe(e)}case dt.PrefabActor:{const e=await a.getAsset(u);return null==e?(console.error("Using a non-prefab asset for prefab parameter",u),null):new me(new fe(e))}case dt.DataAsset:return materializeDataAssetRef(u,a,s,r,n,i,o,d);case dt.Sequence:{const e=await a.getAsset(u);if("sequence"===e.type&&"sequence"in e)return new $t(e.sequence);console.error("Using a non-sequence asset for sequence parameter");break}case dt.Struct:return async function(e,t,a,s,r,n,i,o,l){const c=ea(e),u=c?.struct??t;if(null==u)return console.warn("Missing parameter definition id for struct parameter"),null;const p=ze(u);if(null==p)return console.warn(`Unknown parameter definition "${u}"`),null;if(Be(u))return console.warn(`Can not instantiate abstract parameter definition "${u}"`),null;if(null!=t&&u!==t&&!_e(u,t))return console.warn(`Parameter definition "${u}" is not assignable to "${t}"`),null;let d;try{d=new p}catch(e){return console.warn(`Failed to instantiate parameter definition "${u}"`,e),null}const h=function(e){const t=ea(e);if(null!=t)return t.value;if(ta(e))return e;if(null!=e&&"object"==typeof e&&ta(e.params))return e.params;return{}}(c?.value??e),f=await prepareClassParameters(h,null,a,s,r,n,i,o,l,d);return Object.assign(d,f),d}(u,h,a,s,r,n,i,o,d);case dt.Curve:return St.decode(u);case dt.ColorLayer:case dt.MaskLayer:if(Tt(u)){const e=await jt.decode(u,async e=>await s.getTexture(await a.getAsset(e))),t=await prepareClassParameters(u.params,null,a,s,void 0,void 0,void 0,void 0,void 0,e);return Object.assign(e,t),e}return console.warn("Expecting color layer but got",u),null;case dt.AnimationClip:{const e="string"==typeof u?u:"object"==typeof u&&null!=u?u.assetId:null;if(null==e)return console.warn("Invalid animation clip asset id value",u),null;return await s.getAnimationClip(await a.getAsset(e))}}return null}export async function materializeDataAssetRef(e,t,a,s,r,n,i,o){const l="string"==typeof e?e:null!=e&&"object"==typeof e?e.assetId??e.id:null;if(null==l||""===l)return null;const c=await t.getAsset(l);if(null==c)return console.warn(`Data asset "${l}" was not found`),null;if("data"!==c.type||null==c.dataAsset)return console.warn("Using a non-data asset for data asset parameter",l),null;const u=c.dataAsset.definition;if(null==u||""===u)return console.warn(`Missing data asset definition id for asset "${c.id}"`),null;if(Ne(u))return console.warn(`Can not instantiate abstract data asset definition "${u}"`),null;const p=Ee(u);if(null==p)return console.warn(`Unknown data asset definition "${u}"`),null;let d;try{d=new p}catch(e){return console.warn(`Failed to instantiate data asset definition "${u}"`,e),null}const h=c.dataAsset.params??{};if("object"!=typeof h||Array.isArray(h))return console.warn(`Invalid data asset params for asset "${c.id}"`),null;try{const e=await prepareClassParameters(h,null,t,a,s,r,n,i,o,d);Object.assign(d,e)}catch(e){return console.warn(`Failed to materialize data asset "${c.id}"`,e),null}return new ge(c,d)}function ea(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"string"==typeof e.struct&&ta(e.value)?e:null}function ta(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&Object.values(e).every(e=>null!=e&&"object"==typeof e&&"type"in e)}function aa(e){e.updateWorldMatrix(!0,!0),e.updateMatrix(),e.traverse(e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1});const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}function sa(e){return"linear"===e.type?new u(new l(e.color),e.near??100,e.far??1e3):"density"===e.type?new p(e.color,e.density):void console.warn("Invalid fog type",e)}new w({color:4229780});async function ra(e,t,a,s){null==s&&(s=(new f).identity());const r=s.clone().multiply(na(e,new n.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await ra(e.children[a],t,e,r);await t(e,a,s)}function na(e,t){return null==e.position||null==e.rotation||null==e.scale?t.identity():t.compose((new I).fromArray(e.position),(new S).setFromEuler((new c).fromArray(e.rotation)),(new I).fromArray(e.scale))}export function toSerializedParamType(e){if(null==e)return;const t=e.constructor.prototype;return t instanceof Number||e===Number?dt.Number:t instanceof B||"function"==typeof e.prototype.isFloat?dt.FloatNode:t instanceof x||e===x||e.isTexture?dt.Texture:t instanceof Pe||e===Pe||e===Y||"function"==typeof e.prototype?.isSampler2D||!0===e.prototype?.isSampler2D?dt.Sampler2DNode:t instanceof Boolean||e===Boolean?dt.Boolean:t instanceof F?dt.BooleanNode:t instanceof l||e==l?dt.Color:t instanceof L||"function"==typeof e.prototype.isRgb?dt.RgbNode:t instanceof j||e==j?dt.Vector2:t instanceof ie||"function"==typeof e.prototype.isVec2?dt.Vec2Node:t instanceof I||e==I?dt.Vector3:t instanceof le||"function"==typeof e.prototype.isVec3?dt.Vec3Node:t instanceof P||e==P?dt.Vector4:t instanceof ue||"function"==typeof e.prototype.isVec4?dt.Vec4Node:t instanceof String||e===String?dt.String:t instanceof ye||e==ye||e.prototype instanceof ye||e.prototype==ye?dt.BaseActor:t instanceof c||e==c?dt.Euler:t instanceof v||e==v?dt.Object3D:t instanceof h||e==h?dt.Material:t instanceof AudioBuffer||e==AudioBuffer?dt.AudioBuffer:t instanceof he||e==he?dt.VisualEffect:t instanceof fe||e==fe?dt.Prefab:t instanceof me||e==me?dt.PrefabActor:t instanceof ge||e==ge?dt.DataAsset:t instanceof St||e==St?dt.Curve:t instanceof jt||e==jt?dt.ColorLayer:t instanceof Ct||e==Ct?dt.MaskLayer:t instanceof n.AnimationClip||e==n.AnimationClip?dt.AnimationClip:t instanceof $t||e==$t||"SequenceData"===e.name||e.prototype&&"tracks"in e.prototype?dt.Sequence:null!=Fe(e)?dt.Struct:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function getCustomParamTypeInfo(e){const t=toSerializedParamType(e.type),a=t===dt.Struct?Fe(e.type):void 0;return!0===e.options.array?{type:dt.Array,element:t,...null!=a?{elementStruct:a}:{}}:{type:t,...null!=a?{struct:a}:{}}}export function prepareCustomParams(e,t,a={},s={}){return Object.fromEntries(e.map(e=>{const r=getCustomParamTypeInfo(e);let n=r;const i=t[e.name],o=!0===s.treatAllAsOptional||!0===e.options.optional,l=s.missingOverrideDefaultsToOverride??!0;let c=i?.override;void 0===c&&null!=i&&o&&l&&(c=!0),void 0===c&&o&&(c=!1);const u=void 0!==a[e.name]||void 0!==e.options.defaultValue,p=function(e,t){if(e.type!==dt.Struct)return{typeInfo:e,value:t};const a=ea(t);if(null==a)return{typeInfo:e,value:t};return{typeInfo:{...e,struct:a.struct},value:a.value}}(n,function(e,t){if(void 0!==t[e.name])return t[e.name];if(void 0!==e.options.defaultValue){const t=serializeCustomParameter(e.type,e.options.defaultValue);return void 0!==t?t:e.options.defaultValue}const a=toSerializedParamType(e.type);if(a===dt.Struct)return Be(e.type)?{}:prepareCustomParamsFromType(e.type,{});return customParameterDefaultValueByType.get(a)}(e,a));n=function(e,t,a){if(e.type!==dt.Struct||a?.type!==dt.Struct||null==a.struct)return e;const s=t.struct??e.struct;if(null==s||a.struct===s||_e(a.struct,s)||null==ze(a.struct))return{...e,struct:a.struct};return e}(p.typeInfo,r,i);const d=!1!==c||e.options.array?i?.value??function(e,t,a){if(!0===e.options.array)return a?ca(t):[];return ca(t)}(e,p.value,u):ca(p.value);return[e.name,{...n,value:d,override:c}]}))}function ia(e){return null==e?{}:Object.fromEntries(Object.entries(e).filter(([,e])=>function(e){return!0===e?.override}(e)))}function oa(e,t){return e.length>=t.length&&t.every((t,a)=>e[a]===t)}export function prepareCustomParamsFromType(e,t,a=null,s={}){const r=Ve(e);if(0===r.length)return{};let n;null!=a?Se(a,()=>{n=a.get(e)}):n=new e;const i={};for(const e of r){const t=n[e.name];if(null!=t){const a=la(e,t);void 0!==a&&(i[e.name]=a)}}return prepareCustomParams(r,t,i,s)}function la(e,t){return!0===e.options.array?Array.isArray(t)?t.map(t=>serializeCustomParameter(e.type,t)??t):[]:serializeCustomParameter(e.type,t)}function ca(e){return null==e?e:Array.isArray(e)?e.map(e=>ca(e)):"object"==typeof e?"function"==typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e)):e}export function serializeCustomParameter(e,t){function a(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case j:return t instanceof j?t.toArray():void a();case I:return t instanceof I?t.toArray():void a();case P:return t instanceof P?t.toArray():void a();case l:return t instanceof l?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new l(t).getHexString():void a();case String:return t;case c:return t instanceof c?t.toArray():void a();case fe:return t instanceof fe?t.asset?.id??null:void a();case ge:return t instanceof ge?t.id:"string"==typeof t?t:void a()}const s=Fe(e);if(null!=s){const r=ea(t);if(null!=r)return r.struct===s?r.value:r;const n=function(e,t){if(null==t||"object"!=typeof t)return e;const a=t.constructor;return null!=Fe(a)&&$e(a,e)?a:e}(e,t),i=Fe(n),o=function(e,t){if(null==t)return null;if(ta(t))return t;if(null!=t&&"object"==typeof t&&ta(t.params))return t.params;if("object"!=typeof t)return;const a=Ve(e),s={};for(const e of a){const a=t[e.name];if(void 0===a)continue;const r=la(e,a);void 0!==r&&(s[e.name]=r)}return prepareCustomParams(a,{},s)}(n,t);return void 0!==o?null!=o&&null!=i&&i!==s?{struct:i,value:o}:o:void a()}if(t&&"object"==typeof t&&"tracks"in t&&"duration"in t)return t}function ua(e,t){return function(e,t,a){const s=[],r=new Set;for(const n of[...e??[],...t??[]]){const e=a(n);r.has(e)||(r.add(e),s.push(n))}return s}((e??[]).filter(e=>pa(e.materialId)),(t??[]).filter(e=>pa(e.materialId)),e=>e.color+e.name)}function pa(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[dt.RgbNode,"#000000"],[dt.Color,"#000000"],[dt.String,""],[dt.Vector4,[0,0,0,0]],[dt.Vec4Node,[0,0,0,0]],[dt.Vector3,[0,0,0]],[dt.Vec3Node,[0,0,0]],[dt.Vector2,[0,0]],[dt.Vec2Node,[0,0]],[dt.Euler,[0,0,0,"XYZ"]],[dt.Array,[]],[dt.DataAsset,null],[dt.ColorLayer,It],[dt.MaskLayer,Pt]]);let da=new l;new l;function ha(e){return null==e?.color?null:(da.set(e.color),"#"+da.getHexString())}function fa(e,t,a,s){const r="string"==typeof t.name&&""!==t.name?t.name:null;if(null!=r)return e.name===r||s===r;const n=ha(e);return null!=n&&(n===t.color||a===t.color)}export function applyMaterial(e,t,a,s,r={}){const i=[];return e.traverse(async e=>{if(e instanceof m||e.isMesh||e instanceof n.SkinnedMesh||e.isSkinnedMesh)for(const t of Re(e.material))t.hasOwnProperty("color")&&i.push(e)}),Promise.all(i.map(async e=>{if(e.material instanceof Array)for(let n=0;n<e.material.length;n++){const i=e.material[n];if(null==i.color||!(i.color instanceof l))continue;const o=ha(i),c=i.name;if(fa(i,t,e.userData["originalColor_"+n],e.userData["originalMaterialName_"+n])){const i=ga(await a(t.materialId),r.textureFlipY),l=e.material[n];null!=i&&l.id!=i.id&&(e.material[n]=i,e.userData["originalColor_"+n]=e.userData["originalColor_"+n]??o,e.userData["originalMaterialName_"+n]=e.userData["originalMaterialName_"+n]??c,null!=s&&s.set(e.id+"#"+n,l))}}else if("color"in e.material){const n=e.material,i=ha(n),o=n.name;if(fa(n,t,e.userData.originalColor,e.userData.originalMaterialName)){const n=ga(await a(t.materialId),r.textureFlipY),l=e.material;null!=n&&(e.material=n,e.userData.originalColor=e.userData.originalColor??i,e.userData.originalMaterialName=e.userData.originalMaterialName??o,null!=s&&(s.has(e.id)||s.set(e.id,l)))}}}))}const ma=new WeakMap;export function getConvertedFbxToGlbAssignedMaterialTextureFlipY(e){const t=e?.mesh?.uvConversion;return"fbx2gltf"===t?.source?!0!==t.flipV&&void 0:!function(e){return"glb"===e?.fileFormat&&!0===e.originalFileKey?.toLowerCase().endsWith(".fbx")}(e)&&void 0}function ga(e,t){if(null==e||null==t||!function(e,t){return function(e){const t=[];for(const[a,s]of Object.entries(e))ya(a,s)&&t.push(s);if(e instanceof n.ShaderMaterial)for(const[a,s]of Object.entries(e.uniforms))ya(a,s.value)&&t.push(s.value);return t}(e).some(e=>e.flipY!==t)}(e,t))return e;let a=ma.get(e);null==a&&(a=new Map,ma.set(e,a));const s=a.get(t);if(null!=s)return s;const r=e.clone();if(function(e,t){for(const a of Object.keys(e)){const s=e[a];ya(a,s)&&(e[a]=wa(s,t))}}(r,t),r instanceof n.ShaderMaterial){for(const[e,a]of Object.entries(r.uniforms))ya(e,a.value)&&(a.value=wa(a.value,t));r.uniformsNeedUpdate=!0}return r.needsUpdate=!0,a.set(t,r),r}function ya(e,t){const a=t;return(t instanceof x||!0===a?.isTexture)&&!e.toLowerCase().includes("envmap")&&!0!==a.isCompressedTexture&&!0!==a.isCompressedArrayTexture}function wa(e,t){if(e.flipY===t)return e;const a=e.clone();return a.flipY=t,a.userData={...e.userData??{}},a.needsUpdate=!0,a}function ba(e,t){if(e instanceof n.ShaderMaterial&&t instanceof n.ShaderMaterial){return e.fragmentShader+e.vertexShader==t.fragmentShader+t.vertexShader&&function(e,t){if(e instanceof n.ShaderMaterial&&t instanceof n.ShaderMaterial){for(const a in e.uniforms){if(null==t.uniforms[a])return!1;if(t.uniforms[a].value!==e.uniforms[a].value)return!1}return!0}return!1}(e,t)}return!1}function va(e){if(null!=e){for(let t=0;t<e.array.length;t++)e.setX(t,0);e.needsUpdate=!0}}function Ma(e,t){const a=Je(e);return null==a?"":function(e,t){const a=Ra(e,t),s=a.sort().map(t=>{const a=e.getAttribute(t),s=a.array??a.data?.array,r=s?.constructor?.name??"";return`${t}:${a.itemSize}:${a.normalized?1:0}:${r}`}).join(",");return`${null!=e.index?"indexed":"nonindexed"}|${s}`}(a.geometry,t)}function Sa(e,t){const a=Ra(e,t);if(a.length===Object.keys(e.attributes).length)return e;const s=new o;s.name=e.name;const r=e.getIndex();null!=r&&s.setIndex(r);for(const t of a)s.setAttribute(t,e.getAttribute(t));for(const t of e.groups)s.addGroup(t.start,t.count,t.materialIndex);return s.setDrawRange(e.drawRange.start,e.drawRange.count),null!=e.boundingBox&&(s.boundingBox=e.boundingBox.clone()),null!=e.boundingSphere&&(s.boundingSphere=e.boundingSphere.clone()),s.userData=e.userData,s}const Aa=new WeakMap,xa="hbat_",ja=new Set(["ambientLightColor","cameraNear","directionalLightShadows","directionalLights","directionalShadowMap","directionalShadowMatrix","fogColor","fogDensity","fogFar","fogNear","hemisphereLights","lightProbe","ltc_1","ltc_2","pointLightShadows","pointLights","pointShadowMap","pointShadowMatrix","receiveShadow","rectAreaLights","shadowFar","spotLightMap","spotLightMatrix","spotLightShadows","spotLights","spotShadowMap"]);function Ia(e){let t=Aa.get(e);return null==t&&(t=function(e){let t=e.type;if(e instanceof U)t+=function(e){let t="nodeShader";t+=e.vertexShader,t+=e.fragmentShader,t+=function(e){if(null==e)return"";let t="";for(const a of Object.keys(e).sort())t+=`${a}:${String(e[a])};`;return t}(e.defines),t+=e.lights?"lights":"",t+=e.fog?"fog":"";for(const a of Object.keys(e.uniforms).sort()){if(Pa(a))continue;const s=e.uniforms[a]?.value;Da(s)||(t+=`u:${a}:${Fa(s)};`)}return t}(e);else if(e instanceof n.MeshStandardMaterial&&!(e instanceof n.MeshPhysicalMaterial)||(t+=e.id+""),(e instanceof n.MeshBasicMaterial||e instanceof n.MeshLambertMaterial||e instanceof w||e instanceof y)&&(null!=e.map&&(t+="c"+e.map?.id),null!=e.aoMap&&(t+="o"+e.aoMap?.id),null!=e.lightMap&&(t+="l"+e.lightMap?.id),null!=e.envMap&&(t+="v"+e.envMap?.id),null!=e.alphaMap&&(t+="a"+e.alphaMap?.id)),e instanceof w&&(null!=e.normalMap&&(t+="n"+e.normalMap?.id),null!=e.roughnessMap&&(t+="r"+e.roughnessMap?.id),null!=e.metalnessMap&&(t+="m"+e.metalnessMap?.id),null!=e.emissiveMap&&(t+="e"+e.emissiveMap?.id)),e instanceof n.MeshPhysicalMaterial&&(null!=e.sheenColorMap&&(t+="sc"+e.sheenColorMap?.id),null!=e.sheenRoughnessMap&&(t+="sr"+e.sheenRoughnessMap?.id)),(e instanceof g||e instanceof y)&&null!=e.specularMap&&(t+="s"+e.specularMap?.id),e instanceof n.MeshToonMaterial&&(null!=e.map&&(t+="c"+e.map?.id),null!=e.aoMap&&(t+="o"+e.aoMap?.id),null!=e.lightMap&&(t+="l"+e.lightMap?.id),null!=e.alphaMap&&(t+="a"+e.alphaMap?.id)),e instanceof Ft&&null!=e.heightMap&&(t+="h"+e.heightMap?.id),e instanceof n.ShaderMaterial){t+=e.vertexShader,t+=e.fragmentShader;for(const a in e.uniforms){const s=e.uniforms[a];s&&s.value&&s.value.isTexture&&null!=s.value.id&&(t+="t:"+a+":"+s.value.id)}}null!=e.userData.outlineParameters&&(t+=e.userData.outlineParameters.color,t+=e.userData.outlineParameters.thickness);return t+=e.side,t+=e.transparent?"t":"",t+=e.vertexColors?"vc":"",t+=e.depthWrite?"dw":"",t+=e.depthTest?"dt":"",t+=e.alphaTest?"at":"",t}(e),Aa.set(e,t)),t}function Pa(e){return ja.has(e)||e.startsWith("hology_")}function Ca(e,t){return e instanceof U?e.uniforms[t]?.value:e[t]}function Da(e){return"number"==typeof e||e instanceof j||e instanceof I||e instanceof P||e instanceof l}function Ta(e){return"number"==typeof e?1:e instanceof j?2:4}function Oa(e,t){const a=e.replace(/[^A-Za-z0-9_]/g,"_");let s=xa+a;for(;t.has(s);)s=xa+s;return t.add(s),s}function ka(e,t){const a={};for(const[s,r]of Object.entries(e.uniforms))t.has(s)||(a[s]={value:r.value});return a}const Va=new WeakMap;let Ea=1;function Fa(e){if(null==e)return"null";if(e instanceof x||!0===e?.isTexture)return`texture:${e.id}`;if(e instanceof n.Matrix3||e instanceof n.Matrix4)return e.toArray().join(",");if("boolean"==typeof e||"number"==typeof e||"string"==typeof e)return String(e);if(Array.isArray(e)&&e.every(e=>null==e||["boolean","number","string"].includes(typeof e)))return JSON.stringify(e);if("object"==typeof e){let t=Va.get(e);return null==t&&(t=Ea++,Va.set(e,t)),`object:${t}`}return String(e)}function za(e,t){if(null==e)return null;if(!(e instanceof t))throw new Error(`Value is not an instance of ${t.name}`);return e}const Na=new f,Ba=new c;function $a(e,t){return Ba.copy(e),Ba.x*=-1,Ba.y*=-1,Ba.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(Ba.y*=-1,Ba.z*=-1),(new n.Matrix3).setFromMatrix4(Na.makeRotationFromEuler(Ba))}function _a(e,t){switch(t){case 0:return e.x;case 1:return e.y;case 2:return e.z;case 3:return e.w}}const Ua=new P;function Ga(e,t){return e===t||null==e==(null==t)&&("number"==typeof e&&"number"==typeof t?e===t||isNaN(e)&&isNaN(t):e instanceof n.Color&&t instanceof n.Color?e.r===t.r&&e.g===t.g&&e.b===t.b:e instanceof j&&t instanceof j?e.x===t.x&&e.y===t.y:e instanceof I&&t instanceof I?e.x===t.x&&e.y===t.y&&e.z===t.z:e instanceof P&&t instanceof P&&(e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w))}function Wa(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof he?t.push(s):s instanceof be&&t.push(...Wa(s));return t}const La=new WeakMap;function Ra(e,t){return Object.keys(e.attributes).filter(a=>function(e,t,a){if("position"===a)return!0;if(t instanceof U)return function(e,t){return qa(e.vertexShader,t)}(t,a);if(t instanceof n.ShaderMaterial)return function(e,t){if("uv1"===t||"uv2"===t||"uv3"===t)return qa(e.vertexShader,t);return!0}(t,a);if("uv1"===a)return!1;if("color"===a&&function(e){let t=La.get(e);if(null!=t)return t;const a=e.getAttribute("color");if(null==a)t=!1;else{t=!0;for(let e=0;e<a.count;e++){for(let s=0;s<3;s++)if(1!==a.getComponent(e,s)){t=!1;break}if(!t)break}}return La.set(e,t),t}(e))return!1;if("uv2"===a)return null!=t.lightMap||null!=t.aoMap;return!0}(e,t,a))}function qa(e,t){return new RegExp(`(^|[^A-Za-z0-9_])${a=t,a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}([^A-Za-z0-9_]|$)`).test(e);var a}function Ya(e,t,a){if(t(e))return e;for(const s of e.children??[]){const e=Ya(s,t,a);if(null!=e)return e}if(null!=a&&"prefab"===e.type){const s=a.get(e.assetId);if(null!=s){const e=s.prefab.objects.find(e=>Ya(e,t,a));if(null!=e)return e}}return null}const Ja=new I,Xa=new I,Za=new I,Ha=new P,Ka=new P,Qa=new f,es=new f,ts=new b;function as(e){e.updateWorldMatrix(!0,!1);const t=e.geometry.clone(),a=t.getAttribute("position"),s=t.getAttribute("normal"),r=t.getAttribute("tangent");if(null!=a){for(let t=0;t<a.count;t++)Ja.fromBufferAttribute(a,t),e.applyBoneTransform(t,Ja),a.setXYZ(t,Ja.x,Ja.y,Ja.z);a.needsUpdate=!0}if(null!=s||null!=r){const a=t.getAttribute("skinIndex"),n=t.getAttribute("skinWeight");if(null!=a&&null!=n){for(let t=0;t<a.count;t++)ss(e,t,es),null!=s&&(Xa.fromBufferAttribute(s,t),ts.getNormalMatrix(es),Xa.applyMatrix3(ts).normalize(),s.setXYZ(t,Xa.x,Xa.y,Xa.z)),null!=r&&(Za.fromBufferAttribute(r,t),Za.transformDirection(es),r.setXYZ(t,Za.x,Za.y,Za.z));null!=s&&(s.needsUpdate=!0),null!=r&&(r.needsUpdate=!0)}}t.deleteAttribute("skinIndex"),t.deleteAttribute("skinWeight"),t.computeBoundingBox(),t.computeBoundingSphere();const n=new m(t,e.material);return n.copy(e,!1),n.geometry=t,n.material=e.material,n.userData={...e.userData},n}function ss(e,t,a){const s=e.geometry,r=s.getAttribute("skinIndex"),n=s.getAttribute("skinWeight"),i=e.skeleton;Ha.fromBufferAttribute(r,t),Ka.fromBufferAttribute(n,t),a.identity().multiplyScalar(0);for(let e=0;e<4;e++){const t=Ka.getComponent(e);if(0===t)continue;const s=Ha.getComponent(e);Qa.multiplyMatrices(i.bones[s].matrixWorld,i.boneInverses[s]);for(let e=0;e<16;e++)a.elements[e]+=Qa.elements[e]*t}return a.premultiply(e.bindMatrixInverse).multiply(e.bindMatrix),a}function rs(e){let t=!0;return e.traverse(a=>{a===e||a.isBone||(t=!1)}),t}/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{ConvexPolyhedronCollisionShape as a,SpriteShader as s}from"@hology/core";import{Subject as r}from"rxjs";import*as n from"three";import{BoxGeometry as i,BufferGeometry as o,Color as l,Euler as c,Fog as u,FogExp2 as p,Group as d,Material as h,Matrix4 as f,Mesh as m,MeshLambertMaterial as g,MeshPhongMaterial as y,MeshStandardMaterial as w,Matrix3 as b,Object3D as v,PointLight as M,Quaternion as S,Scene as A,Texture as x,Vector2 as j,Vector3 as I,Vector4 as P}from"three";import{attributes as D,batchingUniformFloat as C,batchingUniformVec2 as T,batchingUniformVec3 as O,batchingUniformVec4 as k,bool as V,BooleanExpression as E,BooleanNode as F,colorToNormal as z,float as N,FloatNode as B,ifDefApply as $,mix as _,NodeShaderMaterial as U,rgb as G,rgba as W,RgbNode as L,select as R,standardMaterial as q,Texture2dLookupNode as Y,textureSampler2d as J,textureSampler2dArray as X,UniformBoolNode as Z,UniformFloatNode as H,UniformSampler2dArraySlice as K,UniformVec2Node as Q,UniformVec3Node as ee,UniformVec4Node as te,varying as ae,varyingAttributes as se,varyingTransformed as re,vec2 as ne,Vec2Node as ie,vec3 as oe,Vec3Node as le,vec4 as ce,Vec4Node as ue}from"three-shader-graph";import{Service as pe}from"typedi";import{VfxActor as de}from"../effects/vfx/vfx-actor.js";import{VisualEffect as he}from"../effects/vfx/vfx-param.js";import{Prefab as fe,PrefabOf as me}from"./objects/prefab.js";import{DataAssetRef as ge}from"./objects/data-asset.js";import{BaseActor as ye}from"../gameplay/actors/actor.js";import we from"../gameplay/actors/builtin/index.js";import{ActorComponent as be}from"../gameplay/actors/component.js";import{PhysicsBodyType as ve}from"../gameplay/services/physics/physics-system.js";import{ThreeBlendingMode as Me}from"../effects/vfx/vfx-asset.js";import{withInjectionContext as Se}from"../gameplay/inject.js";import{RenderingView as Ae}from"../rendering.js";import{curveSampler as xe,oneMinus as je,particleUniforms as Ie,Sampler2DNode as Pe}from"../shader-nodes/index.js";import{LambertShader as De}from"../shader/builtin/lambert-shader.js";import{LandscapeCompositeShader as Ce}from"../shader/builtin/landscape-composite-shader";import{LandscapeShader as Te}from"../shader/builtin/landscape-shader.js";import{StandardShader as Oe}from"../shader/builtin/standard-shader.js";import{UnlitShader as ke}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as Ve,getDataAssetDefinitionType as Ee,getParameterDefinitionId as Fe,getParameterDefinitionType as ze,isDataAssetDefinitionAbstract as Ne,isParameterDefinitionAbstract as Be,isParameterDefinitionAssignableTo as $e,isParameterDefinitionStructAssignableTo as _e,shaderParameterUniformName as Ue}from"../shader/parameter.js";import{ArrayMap as Ge,DefaultMap as We,groupBy as Le}from"../utils/collections.js";import{iterateMaterials as Re}from"../utils/materials.js";import{filterChildrenShallow as qe,filterSceneShallow as Ye,findFirstVisibleMesh as Je,findFirstVisibleObject as Xe,traverseAsync as Ze}from"../utils/three/traverse.js";import{AssetMeshInstance as He,AssetResourceLoader as Ke}from"./asset-resource-loader.js";import{AssetsProvider as Qe}from"./assets-provider.js";import{isCollisionMesh as et}from"./collision/collision-shape-import.js";import{BoxCollisionShape as tt,PhysicalShapeMesh as at}from"./collision/collision-shape.js";import{LandscapeManager as st}from"./landscape/landscape-manager.js";import{initLandscape as rt}from"./landscape/landscape.js";import{SectionGrid as nt,smoothNormalsCrossMeshes as it}from"./landscape/utils.js";import{createGrassFoliageMaterial as ot}from"./materials/grass-foliage.js";import{createGrassMaterial as lt}from"./materials/grass.js";import{getMaterialAttribute as ct}from"./materials/utils/material-painting.js";import{SurfaceScatterManager as ut}from"./scatter/surface-scatter-manager.js";import{createWaterMaterial as pt}from"./materials/water.js";import{SerializedParamType as dt}from"./model.js";import{applyRuntimeParamTypeInference as ht,convertConfiguredParamsToRuntimeTypes as ft,convertConfiguredParamValueToRuntimeType as mt,inferRuntimeSerializedParamTypeHint as gt}from"./custom-param-runtime-types.js";import{ShapeLibrary as yt,ShapeLibraryKeys as wt}from"./objects/shapes.js";import{ambientLightName as bt,createSky as vt,defaultSkyMaterial as Mt}from"./sky.js";import{Curve2 as St}from"../utils/curve.js";import{DecalUnlitShader as At}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as xt}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as jt,defaultValueColorLayer as It,defaultValueMaskLayer as Pt,MaskLayer as Dt}from"../shader/color-layer.js";import{LayeredShader as Ct}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as Tt}from"../shader/color-layer";import{FogVolume as Ot}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as kt}from"../utils/three/unscaled-sprite.js";import{ToonShader as Vt}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as Et}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as Ft}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as zt}from"../shader-nodes/pom.js";import{traverseVisibleEvery as Nt}from"../utils/three/traverse";import{RectAreaLightHelper as Bt}from"three/examples/jsm/Addons.js";import{Sequence as $t}from"../effects/sequence/sequence-data.js";import{applyUvTiling as _t}from"./../shader/uv-nodes.js";import{buildShaderGraphMaterial as Ut,shaderGraphMaterialSideToThree as Gt}from"../shader/graph/index.js";export{ht as applyRuntimeParamTypeInference,ft as convertConfiguredParamsToRuntimeTypes,mt as convertConfiguredParamValueToRuntimeType,gt as inferRuntimeSerializedParamTypeHint};const Wt={},Lt=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),Rt=/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(navigator.userAgent.includes("iPhone")||navigator.userAgent.includes("iPad"))&&!!navigator.userAgent.match(/AppleWebKit/)&&!navigator.userAgent.match(/CriOS/);export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,a){this.dataProvider=e,this.assetsService=t,this.assetManagerService=a}get(e,t){return new qt(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}let qt=class{constructor(e,t,a,s,i,o,l,c,u=[]){this.scene=e,this.dataProvider=t,this.assetsService=a,this.assetManagerService=s,this.renderingView=i,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.componentTypes=u,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.idToSceneObject=new Map,this.inEditor=!0,this.updated$=new r,this.removed$=new r,this.error$=new r,this.editorActorParamSnapshot=new Map,this.assets=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.pmremGeneratorResults=new WeakMap,this.prefabInstanceChain=[],this.prefabInstanceExposedActorMap=new Map,this.geometryCache=new Map,this.collisionShapeCache=new Map,this.assetManagerService.materialProvider=async e=>materialFromAsset(this.assets.get(e)??await this.assetsService.getAsset(e),this.renderingView,this.assetsService,this.assetManagerService,this.shaders),this.originalFog=null,t.onCreate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onUpdate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onRemove(e=>{this.remove(e),this.handleSurfaceScatterSceneMutation(e)}),this.createAssetSubscription=a.onCreate.subscribe(e=>{this.assets.set(e.id,e)}),this.updateSubscription=a.onUpdate.subscribe(async t=>{if(this.assets.set(t.id,t),"material"==t.type)e.traverse(e=>{if(e instanceof n.Mesh)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterial(e,e.material[a],t,a);else this.refreshMaterial(e,e.material,t)});else if("mesh"==t.type){this.findByAssetId(t.id).forEach(async e=>{this.remove(e.userData.src);const t=await this.materializeAndInitActor(e.userData.src);this.updated$.next({object:t,source:e.userData.src})});for(const e of this.assets.values())if("prefab"==e.type){if(!e.prefab.objects.some(e=>Ja(e,e=>e.assetId==t.id,this.assets)))continue;this.findByAssetId(e.id).forEach(e=>{this.remove(e.userData.src),this.materializeAndInitActor(e.userData.src)})}this.landscapeManagers.forEach(e=>{const a=e.source?.grass?.layers?.some(e=>e.meshes.some(e=>e.assetId===t.id));a&&e.queueRefreshScatter(this.renderingView?.camera.position??new I,!0)}),null!=this.surfaceScatterManager&&(this.surfaceScatterManager.usesSourceAsset(t.id)||this.surfaceScatterManager.usesScatterAsset(t.id))&&this.surfaceScatterManager.queueRefresh(!0)}else if("prefab"===t.type)this.findByAssetId(t.id).forEach(e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}),(this.surfaceScatterManager?.usesPrefabAsset(t.id)||this.sceneReferencesPrefabAsset(t.id)&&await this.prefabAssetContainsSurfaceScatter(t))&&await this.refreshSurfaceScatterPresence(!0);else if("vfx"===t.type)for(const e of this.dataProvider.getObjects())await ra(e,async e=>{"vfx"===e.type&&e.assetId===t.id&&(this.remove(e),await this.materializeAndInitActor(e))});else if("texture"===t.type)this.scene.traverse(e=>{if(e instanceof m)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterialTextures(e,e.material[a],t,a);else this.refreshMaterialTextures(e,e.material,t)});else if("shaderGraph"===t.type){this.scene.traverse(e=>{if(e instanceof m)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterial(e,e.material[a],t,a);else this.refreshMaterial(e,e.material,t)});for(const e of this.dataProvider.getObjects())await ra(e,async e=>{if("vfx"===e.type&&null!=e.assetId){const a=this.assets.get(e.assetId);null!=a&&this.vfxAssetUsesShaderGraph(a,t.id)&&(this.remove(e),await this.materializeAndInitActor(e))}})}})}async refreshMaterialTextures(e,t,a,s){if("texture"!==a.type)return void console.error("Can not refresh material textures. Asset is not a texture",a);const r=await this.assetManagerService.getTexture(a);if(null!=r)if(t instanceof n.ShaderMaterial)for(const[e,s]of Object.entries(t.uniforms))s.value instanceof n.Texture&&s.value.userData.assetId===a.id&&(t.uniforms[e].value=r);else for(const[e,s]of Object.entries(t))s instanceof n.Texture&&s.userData.assetId===a.id&&(t[e]=r);else console.error("Can not refresh material textures. Texture not found",a)}async getAsset(e){let t=this.assets.get(e);return null==t&&(t=await this.assetsService.getAsset(e),null!=t&&this.assets.set(e,t)),t}async refreshMaterial(e,t,a,s){const r=t?.userData?.assetId;if(r!==a.id){const e=this.assets.get(r);let t=!1;if(null!=e&&("shaderGraph"===a.type&&"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===a.id&&(t=!0),!t&&null!=e.material?.shaderParams))for(const s of Object.values(e.material.shaderParams)){if(s.type===dt.Material&&s.value===a.id){t=!0;break}if(s.type===dt.Array&&"element"in s&&s.element===dt.Material&&s.value.includes(a.id)){t=!0;break}}if(!t)return}const n=await materialFromAsset(this.assets.get(r),this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1),i=n.userData;n.userData=t.userData,n.userData.hasBloom=i.hasBloom,n.userData.reflective=i.reflective,n.userData.outlineParameters=i.outlineParameters,null!=s?va(e.material[s],n)||(e.material[s]=n):va(e.material,n)||(e.material=n,e===this.sky&&this.applySkySettings(e.material))}vfxAssetUsesShaderGraph(e,t){return null!=e.vfx&&e.vfx.emitters.some(e=>this.emitterUsesShaderGraph(e,t))}emitterUsesShaderGraph(e,t){const a=e.output;return"shaderGraph"===a.materialSource&&"asset"===a.shaderGraph?.source&&a.shaderGraph.assetId===t||!!e.children&&e.children.some(e=>this.emitterUsesShaderGraph(e,t))}getTopLevelActors(){return Array.from(this.materializedActors.entries()).filter(([e,t])=>!e.includes("/")).map(([,e])=>e)}get actorInstances(){return Array.from(this.materializedActors.values())}async initTextures(){const e=new Set,t=[];if(await Promise.all(this.collectMaterialAssignments(this.dataProvider.getObjects()).map(async a=>{const s=this.assets.get(a.materialId);if(null!=s?.material)for(const a of Object.values(s.material.shaderParams??{}))if(a.type===dt.Texture&&"string"==typeof a.value){const s=this.assets.get(a.value);if(null==s)continue;const r=await this.assetManagerService.getTexture(s);if(null!=r&&t.push(r),null!=s.texture?.textureArrayFileKey&&!e.has(s.texture?.textureArrayFileKey)){const a=await this.assetManagerService.getTextureArray(s);null!=a?.texture&&(t.push(a.texture),e.add(s.texture.textureArrayFileKey))}}})),0!==t.length&&this.renderingView){console.log(`Initializing ${t.length} textures`),console.time("Init textures");for(const e of t)this.renderingView.renderer.initTexture(e);console.timeEnd("Init textures")}}async prefetchAssets(){const e=this.collectAssetMeshIds(this.dataProvider.getObjects());await Promise.all(Array.from(e).map(async e=>{const t=this.assets.get(e);if("mesh"===t?.type)return this.assetManagerService.getMesh(t,{mergeGeomtries:!0})})),this.initTextures()}collectAssetMeshIds(e,t=[],a=new Set){for(const s of e??[])this.collectObjectAssetMeshIds(s,t,a);return a}collectObjectAssetMeshIds(e,t,a){if(this.shouldBeMaterialized(e)&&("asset_mesh"===e.type&&null!=e.assetId&&a.add(e.assetId),null!=e.children&&this.collectAssetMeshIds(e.children,t,a),"prefab"===e.type&&null!=e.assetId&&!t.includes(e.assetId))){const s=this.assets.get(e.assetId);null!=s?.prefab?.objects&&this.collectAssetMeshIds(s.prefab.objects,[...t,e.assetId],a)}}collectMaterialAssignments(e,t=[],a=[]){for(const s of e??[])this.collectObjectMaterialAssignments(s,t,a);return a}collectObjectMaterialAssignments(e,t,a){if(this.shouldBeMaterialized(e)&&("shape_mesh"!==e.type&&"asset_mesh"!==e.type||null==e.materialAssignments||a.push(...e.materialAssignments),null!=e.children&&this.collectMaterialAssignments(e.children,t,a),"prefab"===e.type&&null!=e.assetId&&!t.includes(e.assetId))){const s=this.assets.get(e.assetId);null!=s?.prefab?.objects&&this.collectMaterialAssignments(s.prefab.objects,[...t,e.assetId],a)}}async init(){await this.preInit(),Jt.clear(),Xt.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.refreshSurfaceScatterPresence(!0)}async initVfx(){console.time("Init VFX");const e=new Set,t=[],a=new A;for(const s of this.actorInstances){const r=La(s);for(const s of r){const r=s.asset;if(e.has(r.id))continue;e.add(r.id),r.vfx.emitters;const n=await s.create(a);a.add(n.object),a.add(n.particleSystemContainer),n.play(),n.onUpdate(.5),n.stop(),n.pause(),t.push(n)}}const s=this.renderingView.compileAsync(a);this.renderingView.initTextures(a),await s;for(const e of t)e.onEndPlay(),e.disposed.next(!0),e.object.removeFromParent();console.timeEnd("Init VFX")}async initActorsPostInit(e=Array.from(this.materializedActors.entries())){const t=e.map(async([e,t])=>{const a=t.object.userData.src??t.object.userData._src;if("vfx"===a.type)return Promise.resolve();const s="prefab"===a.type?await this.assetsService.getAsset(a.assetId):null,r=e.split("/"),n=r.slice(0,-1),i=n.join("/"),o=(r[r.length-1],new Map);for(const[e,t]of this.materializedActors)if(o.set(e,t),0===i.length)e.includes("/")||o.set(e,t);else if(e.startsWith(i+"/")){const a=e.slice(i.length+1);a.includes("/")||o.set(a,t)}const l={...s?.actor?.params??{},...a.actor?.params??{}},c=[...a.actor?.innerParams??[]];for(let t=n.length-1;t>=0;t--){const a=n.slice(0,t+1).join("/"),s=this.idToSceneObject.get(a);if("prefab"===s?.type&&null!=s.prefab){const n=await this.assetsService.getAsset(s.assetId);if(null!=n){let i=!1,o=a+"/"+n.prefab?.mainActorId;for(;null!=o;){if(o===e){i=!0;break}o=this.prefabInstanceExposedActorMap.get(o)}if(i&&null!=s.prefab.params&&Object.assign(l,ia(s.prefab.params)),null!=s.prefab.innerParams){const e=r.slice(t+1);for(const t of s.prefab.innerParams){const a=ia(t.params);0!==Object.keys(a).length&&(i?c.push({path:oa(t.path,e)?t.path.slice(e.length):t.path,params:a}):oa(t.path,e)&&c.push({path:t.path.slice(e.length),params:a}))}}}}}for(const e of c)await this.applyActorComponentParams(t,e.path.slice(),e.params,o);await this.attachEditorComponents(t,a,o);const u=await prepareClassParameters(l,t.constructor,this.assetsService,this.assetManagerService,o,this.renderingView,this.shaders,this.actorProvider,e=>{const t=i.length>0?i+"/"+e:e;return this.prefabInstanceExposedActorMap.get(t)??null},t);Object.assign(t,u);try{return await this.actorProvider.initActor(t)}catch(e){console.error(`Failed to initiate actor (name="${a.name}", id=${a.id})`,e)}});return Promise.all(t)}async attachEditorComponents(e,t,a){const s=t.actor?.components??[];for(const r of s){const s=this.componentTypes.find(e=>e.name===r.type);if(null==s){console.warn(`Component type '${r.type}' not found for actor ${t.id}`);continue}const n=e.attach(s.type);if(null!=r.params){const e=await prepareClassParameters(r.params,null,this.assetsService,this.assetManagerService,a,this.renderingView,this.shaders,this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null,n);Object.assign(n,e)}for(const e of r.innerParams??[])await this.applyActorComponentParams(n,e.path.slice(),e.params,a)}}addVfxChildActors(e,t=e){}async applyActorComponentParams(e,t,a,s){const r=t.length,n=t.shift();if(0==r){const t=await prepareClassParameters(a,null,this.assetsService,this.assetManagerService,s,this.renderingView,this.shaders,this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null,e);for(const[a,s]of Object.entries(t))null!=s&&(e[a]=s)}else null!=e[n]&&await this.applyActorComponentParams(e[n],t,a,s)}canObjectBeInstanced(e){return e.physics?.type!==ve.dynamic&&"sky"!==e.type&&"global_fog"!==e.type&&"world_env"!==e.type}async canAssetBeInstanced(e){let t=this._canBeInstancedCache.get(e.assetId);if(null==t){const a=await this.createFromAsset(e);if(null==a)return!1;const s=[];a.traverse(e=>{!et(e)&&e.isMesh&&s.push(e)});const r=1==s.length&&0==s[0].children.length,n=!Rt,i=s.every(e=>!Array.isArray(e.material)||1===e.material.length),o=s.some(e=>e instanceof m&&null!=e.geometry.morphAttributes&&Object.keys(e.geometry.morphAttributes).length>0),l=!0;t=s.length>0&&(r||i&&n)&&l&&!o,this._canBeInstancedCache.set(e.assetId,t)}return t}async preInit(){this.renderingView?.onLoop(()=>{null!=this.sky&&this.renderingView.camera.getWorldPosition(this.sky.position)}),await this.preloadAssets()}async preloadAssets(){const e=await this.assetsService.getAssets();for(const t of e)this.assets.set(t.id,t)}shouldBeMaterialized(e){if(!1===e.enabled)return!1;if(null!=this.detailTier&&"asset_mesh"===e.type&&null!=e.assetId){const t=this.assets.get(e.assetId);if(null!=t){const e=t.mesh?.detailTier;if(null!=e)return e<=this.detailTier}}return!0}async initWithInstancing(){await this.preInit(),await this.prefetchAssets(),Jt.clear(),Xt.clear();const e=[],t=new Ge,a=new Ge,s=new Ge;let r=0,i=0,o=0;const u=new Map,p=new We(()=>new Map);for(const n of this.dataProvider.getObjects())await ra(n,async(n,c,d)=>{if(!this.shouldBeMaterialized(n))return;const h="asset_mesh"==n.type&&this.canObjectBeInstanced(n)&&await this.canAssetBeInstanced(n),f="shape_mesh"===n.type&&"landscape"!==n.shape&&n.physics?.type!==ve.dynamic;if(h||f){if(c&&c.children?.length>0){const e=c.children.findIndex(e=>e.id===n.id);e>=0&&c.children.splice(e,1)}if(f){let e=n.shape+JSON.stringify(n.shapeParams??{})+n.castShadow+n.receiveShadow;const t=n.materialAssignments?.at(0)?.materialId,a=null!=t?this.assets.get(t):null;let r=null;if(!1&&null!=a&&"shader"!==a.material.type){if(e+=a.material.type+a.material.shader,null!=a.material.shaderParams){if(e+=Object.entries(a.material.shaderParams).filter(([e,t])=>"color"!=e).map(e=>JSON.stringify(e)).join(),null!=a.material.shaderParams.color){const e=a.material.shaderParams.color;e.type===dt.Color&&null!=e.value&&(r=new l(e.value))}}e+=a.material.outlines,null!=a.material.outlineParams&&(e+=JSON.stringify(a.material.outlineParams)),e+=a.material.reflective,e+=a.material.bloom,e+=a.material.side,e+=a.material.side,e+=a.material.transparent,e+=a.material.alphaTest}else e+=t;s.push(e,{object:{...n,parentTransform:d},color:r}),o++}else{const e=this.assets.get(n.assetId);null==e&&console.log("Can't find asset with id "+n.assetId);let s=u.get(n.assetId);if(null==s){const e=await this.createFromAsset(n,{assignMaterials:!1});if(null==e)return;if(s=u.get(n.assetId),null==s){s={useBatchedMesh:null!=Je(e)&&Nt(e,e=>!(e instanceof m)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},u.set(n.assetId,s)}}const o=ua(n.materialAssignments,e.materialAssignments);if(s.useBatchedMesh)await Ze(s.assetMesh,async t=>{if(!(t instanceof m))return;const s=Array.isArray(t.material)?t.material[0]:t.material,i=await this.resolveMaterialForAssignments(s,o,e);if(null!=i){p.get(n.id).set(t.uuid,i);let e=Pa(i);e+=Sa(t,i),a.push(e,{...n,parentTransform:d,meshUUID:t.uuid}),r++}else console.warn("Can not materialize mesh because missing material",n)});else{const e=n.assetId+JSON.stringify(n.materialAssignments??[]);t.push(e,{...n,parentTransform:d}),i++}}}else null==c&&e.push({...n,parentTransform:d})});console.log(`Scene init stats: \n Batched Assets: ${a.size} groups containing in total ${r} objects.\n Instanced Assets: ${t.size} groups containing in total ${i} objects.\n Shapes: ${s.size} batch groups containing in total ${o} objects. \n ${e.length} objects can not be batched. \n `);for(const e of u.values())this.prepareCollisionShapesForInstanced(e.assetMesh);console.time("materialize batches");for(const[e,t]of a.entries()){if(0==t.length)continue;let e;u.get(t[0].assetId).assetMesh;e=this.createBatchedMesh(t,p,u);const a=this.assets.get(t[0].assetId);e.castShadow=t[0].castShadow??a.castShadow??!0,e.receiveShadow=t[0].receiveShadow??a.receiveShadow??!0;const s=new He;s.add(e),s.userData.src=t[0],s.castShadow=!1,s.receiveShadow=!1,this.scene.add(s)}for(const e of t.values()){if(0==e.length)continue;let t;const a=u.get(e[0].assetId).assetMesh;t=await this.createInstancedMesh(e,a);const s=this.assets.get(e[0].assetId);t.castShadow=e[0].castShadow??s.castShadow??!0,t.receiveShadow=e[0].receiveShadow??s.receiveShadow??!0;const r=new He;r.add(t),r.userData.src=e[0],a instanceof He&&(r.collisionShapes=a.collisionShapes),this.prepareCollisionShapesForInstanced(r),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r)}console.timeEnd("materialize batches");for(const e of s.values()){if(0==e.length)continue;const t=e[0].object,a=await this.createFromShape(t),s=Xe(a,e=>!et(e)&&null!=e.geometry),r=ya(s.material);null!=e[0].color&&null!=r.color&&(r.color=new l(16777215));const i=s.geometry;let o,u;!(Rt||r instanceof U||null==i.index)?(o=new n.BatchedMesh(e.length,i.getAttribute("position").count,i.index.count,r),o.perObjectFrustumCulled=!0,u=o.addGeometry(i)):o=new n.InstancedMesh(i,r,e.length),o.castShadow=a.castShadow??!0,o.receiveShadow=s.receiveShadow??!0;for(let t=0;t<e.length;t++){const a=e[t],s=(new n.Matrix4).compose((new I).fromArray(a.object.position),(new S).setFromEuler((new c).fromArray(a.object.rotation)),(new I).fromArray(a.object.scale)),r=(new f).copy(a.object.parentTransform).multiply(s);let i;i=o instanceof n.BatchedMesh?o.addInstance(u):t,o.setMatrixAt(i,r),a.color}for(let t=0;t<e.length;t++){const s=e[t],r=new He;r.userData.src=e[0],a instanceof at&&(r.collisionShapes=[a.collisionShape]),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r),r.add(o),null==o.userData.hasCollision&&(o.userData.hasCollision=[]),o.userData.hasCollision[t]=!!s.object.collisionDetection}}await Promise.all(e.map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.initVfx(),await this.refreshSurfaceScatterPresence(!0)}prepareCollisionShapesForInstanced(e){e instanceof He&&e.collisionShapes.forEach(e=>{e instanceof a&&e.mesh instanceof m&&(e.mesh=e.mesh.geometry)})}testCanBatch(e,t){return!Rt&&(!Array.isArray(e)||1==e.length)&&this.testCanBatchMaterial(e)}testCanBatchMaterial(e){return null!=(Array.isArray(e)?e[0]:e)}createBatchedMesh(e,t,a){const s=new Ge;for(const t of e)null!=t.meshUUID?s.push(t.meshUUID??t.assetId,t):console.warn("Missing mesh uuid for batching");let r=0,i=0,o=0;const c=new Map;for(const[e,t]of s.entries()){const s=t[0].assetId,n=a.get(s);if(null==n){console.warn("Missing batching info for asset id "+s);continue}const l=Xe(n.assetMesh,t=>t instanceof m&&t.uuid===e);if(null==l){console.warn("Missing mesh in batched asset");continue}c.set(e,l);const u=l.geometry.getAttribute("position");null==u&&console.warn("Missing position attribute for batched mesh"),r+=l.geometry.index.count*t.length,i+=u.count*t.length,o+=t.length}const u=["color","map","roughness","roughnessMap","metalness","metalnessMap","opacity","alphaMap","aoMap","aoMapIntensity","normalMap","normalScale","emissive","emissiveIntensity","emissiveMap"],p=new Map,d=new Map,h=[];let f=new n.MeshStandardMaterial({color:"white"});const g=t.get(e[0].id).get(e[0].meshUUID);if(null==g)throw"missing source material";if(g instanceof w&&!(g instanceof n.MeshPhysicalMaterial)){const a=new Set,s=new Map;for(const r of e){const e=t.get(r.id).get(r.meshUUID);if(null==e)throw"missing mat";for(const t of u){let r=e[t];r instanceof n.CompressedArrayTexture&&null!=r.userData.index&&(r=r.userData.index);const i=s.get(t);void 0===i||Wa(r,i)?s.set(t,r):a.add(t)}}for(const e of a){let t;const a=g[e];let s=e;if("number"==typeof a){let a=h.find(e=>e.params.length<4);if(null==a){const t="vp"+h.length;a={name:t,params:[e],node:k(t)},h.push(a)}else a.params.push(e);s=a.name,t=Ua(a.node,a.params.length-1)}else if(a instanceof P)t=k(s);else if(a instanceof I||a instanceof l)t=O(s);else if(a instanceof j)t=T(s);else if(a instanceof n.CompressedArrayTexture)s=e+"_i",t=C(s);else if(a instanceof x)continue;p.set(e,t),d.set(e,s)}let r=se.uv;g instanceof Ft&&null!=g.heightMap&&(r=zt(r,J(g.heightMap),N(g.heightScale)));let i=Na(p.get("opacity"),B)??N(g.opacity??1);if(null!=g.alphaMap){let e;if(g.alphaMap instanceof n.CompressedArrayTexture){const t=X(g.alphaMap),a=Na(p.get("alphaMap"),B)??N(g.alphaMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.alphaMap).sample(r);i=i.multiply(e.r)}let o=W(Na(p.get("color"),le)??g.color,i);if(null!=g.map){let e;if(g.map instanceof n.CompressedArrayTexture){const t=X(g.map),a=Na(p.get("map"),B)??N(g.map.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.map).sample(_t(r,g.map));o=o.multiply(e),i=i.multiply(e.a)}g.vertexColors&&(o=o.multiply(ce(ae(D.color.rgb),1)));let c=W(Na(p.get("emissive"),le)??g.emissive,i);if(null!=g.emissiveMap){let e;if(g.emissiveMap instanceof n.CompressedArrayTexture){const t=X(g.emissiveMap),a=Na(p.get("emissiveMap"),B)??N(g.emissiveMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.emissiveMap).sample(_t(r,g.emissiveMap));c=c.multiply(e)}const m=Na(p.get("emissiveIntensity"),B)??N(g.emissiveIntensity??1),y=Na(p.get("normalScale"),ie)??ne(g.normalScale??new j(1,1));let w=re.normal;if(null!=g.normalMap){let e;if(g.normalMap instanceof n.CompressedArrayTexture){const t=X(g.normalMap),a=Na(p.get("normalMap"),B)??N(g.normalMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.normalMap).sample(_t(r,g.normalMap));w=z(e.rgb,y.x)}let b=Na(p.get("roughness"),B)??N(g.roughness??1);if(null!=g.roughnessMap){let e;if(g.roughnessMap instanceof n.CompressedArrayTexture){const t=X(g.roughnessMap),a=Na(p.get("roughnessMap"),B)??N(g.roughnessMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.roughnessMap).sample(_t(r,g.roughnessMap));b=b.multiply(e.g)}let v=Na(p.get("metalness"),B)??N(g.metalness??0);if(null!=g.metalnessMap){let e;if(g.metalnessMap instanceof n.CompressedArrayTexture){const t=X(g.metalnessMap),a=Na(p.get("metalnessMap"),B)??N(g.metalnessMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.metalnessMap).sample(_t(r,g.metalnessMap));v=v.multiply(e.b)}let M=N(1);if(null!=g.aoMap){let e;if(g.aoMap instanceof n.CompressedArrayTexture){const t=X(g.aoMap),a=Na(p.get("aoMap"),B)??N(g.aoMap.userData.index??0);e=t.sample(oe(r.x,r.y,a))}else e=J(g.aoMap).sample(_t(r,g.aoMap));M=M.multiply(e.r)}const S=Na(p.get("aoMapIntensity"),B)??N(g.aoMapIntensity??0);let A=w;!0!==g.userData.disableAO&&(A=$("DOUBLE_SIDED",A,e=>R(new E("gl_FrontFacing"),e,e.multiplyScalar(-1))));const V=new U({color:q({color:o,roughness:b,metalness:v,ambientOcclusion:M,ambientOcclusionIntensity:S,emissive:c,emissiveIntensity:m,normal:A}),normal:w,roughness:b,emissive:c.rgb,transparent:g.transparent,alphaTest:g.alphaTest,envMap:g.envMap,opacity:i});null!=g.envMap&&(V.uniforms.envMapIntensity={value:g.envMapIntensity},V.uniforms.envMapRotation={value:_a(g.envMapRotation,g.envMap)}),V.envMap=g.envMap,V.side=g.side,f=V}else if(g instanceof U){const a=new Set,s=new Map,r=Object.keys(g.uniforms).filter(e=>!Da(e));for(const n of e){const e=t.get(n.id).get(n.meshUUID);if(!(e instanceof U))throw new Error("Expected NodeShaderMaterial in node material batch");for(const t of r){const r=e.uniforms[t]?.value,n=s.get(t);void 0===n||Wa(r,n)?s.set(t,r):Ta(r)&&Ta(n)&&Oa(r)===Oa(n)&&a.add(t)}}const n=new Set(Object.keys(g.uniforms)),i={};for(const e of a){let t,a;const s=g.uniforms[e]?.value;if("number"==typeof s){let s=h.find(e=>e.params.length<4);if(null==s){const t=ka("vp"+h.length,n);s={name:t,params:[e],node:k(t)},h.push(s)}else s.params.push(e);a=s.name,t=Ua(s.node,s.params.length-1)}else if(s instanceof P)a=ka(e,n),t=k(a);else if(s instanceof I||s instanceof l)a=ka(e,n),t=O(a);else{if(!(s instanceof j))continue;a=ka(e,n),t=T(a)}p.set(e,t),d.set(e,a),i[e]=t}if(0===p.size)f=g;else{const e=new U({color:g.outputColor,transform:g.outputTransform??null,position:null==g.outputTransform?g.outputPosition:void 0,normal:g.outputNormal??null,roughness:g.outputRoughness??null,opacity:g.outputOpacity??null,emissive:g.outputEmissive??null,transparent:g.transparent,alphaTest:g.alphaTest,envMap:g.envMap??null,fog:g.fog,lights:g.lights,uniforms:Va(g,new Set(p.keys())),uniformNodes:i});e.uniformNodes=i,y=g,(b=e).name=y.name,b.side=y.side,b.blending=y.blending,b.depthWrite=y.depthWrite,b.depthTest=y.depthTest,b.colorWrite=y.colorWrite,b.toneMapped=y.toneMapped,b.visible=y.visible,b.opacity=y.opacity,b.forceSinglePass=y.forceSinglePass,b.premultipliedAlpha=y.premultipliedAlpha,b.polygonOffset=y.polygonOffset,b.polygonOffsetFactor=y.polygonOffsetFactor,b.polygonOffsetUnits=y.polygonOffsetUnits,b.shadowSide=y.shadowSide,Object.assign(b.defines,y.defines),Object.assign(b.userData,y.userData),b.needsUpdate=!0,f=e}}else{f=g;for(const a of e){const e=t.get(a.id).get(a.meshUUID);if(e!=f){console.error(`Different materials in group for object ${a.id} and mesh uuid ${a.meshUUID}`,{objectMaterial:e,sourceMaterial:g});break}}}var y,b;const v=new Et(o,i,r,f);for(const e of h)v.initUniform(e.name,4);for(const[e,t]of p.entries()){if(h.some(t=>t.params.includes(e)))continue;let a=1;t instanceof ue||t instanceof le?a=4:t instanceof ie&&(a=2),v.initUniform(d.get(e)??e,a,0)}for(const[e,r]of s.entries()){const s=r[0].assetId,i=c.get(e);if(null==i){console.error(`Missing single asset mesh for mesh uuid ${e} and asset id ${s}`);continue}if(null==i.geometry){console.error("Missing geometry on mesh mesh");continue}const o=v.addGeometry(Aa(i.geometry,g)),u=a.get(s);if(null==u){console.warn("Missing batching info when configuring for asset id "+s);continue}const f=Je(u.assetMesh)?.uuid===e,m=u.assetMesh instanceof He&&f?u.assetMesh.collisionShapes:void 0,y=this.configureBatchedInstancedMesh(r,v,i,o,m);for(let e=0;e<y.length;e++){const a=r[e],s=y[e],i=t.get(a.id).get(a.meshUUID),o=i.userData.surface;null!=o&&(v.surfaceByInstance[s]=o);for(const e of h){let t=Ga.set(0,0,0,0);for(let a=0;a<e.params.length;a++){const s=Ca(i,e.params[a]);"number"==typeof s&&t.setComponent(a,s)}v.setUniformAt(e.name,s,t)}for(let e of p.keys()){if(h.some(t=>t.params.includes(e)))continue;const t=d.get(e)??e;let a=Ca(i,e);if(a instanceof l&&(a=new I(a.r,a.g,a.b)),a instanceof n.CompressedArrayTexture)a=a.userData.index??0;else if(a instanceof x||null==a)continue;v.setUniformAt(t,s,a)}}}return v}async createInstancedMesh(e,t){const a=Xe(t,e=>!et(e)&&null!=e.geometry),s=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(t,ua(e[0].materialAssignments,s.materialAssignments),s),a.updateMatrix();const r=a.geometry.clone(),i=a.material;let o;if(o=new n.InstancedMesh(r,i,e.length),this.configureBatchedInstancedMesh(e,o,a),a.material instanceof h&&o.castShadow&&o.receiveShadow&&Array.isArray(i))for(const e of i);return o}configureBatchedInstancedMesh(e,t,a,s,r){const i=[];a.updateWorldMatrix(!0,!0);for(let o=0;o<e.length;o++){let l=o;t instanceof n.BatchedMesh&&(l=t.addInstance(s)),i.push(l);const u=(new n.Matrix4).compose((new I).fromArray(e[o].position),(new S).setFromEuler((new c).fromArray(e[o].rotation)),(new I).fromArray(e[o].scale)),p=(new f).copy(e[o].parentTransform).multiply(u).multiply(a.matrixWorld);t.setMatrixAt(l,p),null==t.userData.hasCollision&&(t.userData.hasCollision=[]),t.userData.hasCollision[l]=!!e[o].collisionDetection,null!=r&&(null==t.userData.collisionShapes&&(t.userData.collisionShapes=[]),t.userData.collisionShapes[l]=r)}return i}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("world_env"===e.type)this.resetWorldEnv(),this.worldEnvObj=null;else if("actor"==e.type||"vfx"===e.type){const t=this.materializedActors.get(e.id);null!=t?(t.disposed.next(!0),t.onEndPlay()):console.warn("Failed to remove actor",e)}else"prefab"===e.type&&this.materializedActors.forEach((t,a)=>{a.startsWith(e.id)&&(t.disposed.next(!0),t.onEndPlay()),this.materializedActors.delete(a)});const t=this.sceneObjectMap.get(e.id);t?.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter(t=>t.object.userData.src?.id===e.id).forEach(e=>this.components.splice(this.components.indexOf(e,1))),this.landscapeManagers.filter(t=>t.source.id===e.id).forEach(e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))}),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex(t=>t.source.id===e.id);if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return Ye(this.scene,t=>t.userData.src?.assetId==e,e=>null!=e.userData.src)}applyMaterials(e,t,a){return null==t?Promise.resolve([]):Promise.all(t.filter(e=>"null"!==e.materialId).map(t=>this.applyMaterial(e,t,a)))}async applyMaterial(e,t,a){await applyMaterial(e,t,async e=>{const t=await this.getAsset(e);if(null!=t)try{return materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders)}catch(e){console.error("Failed to apply material",e)}else console.warn("Missing material with id "+e)},this._originalMaterials,{textureFlipY:getConvertedFbxToGlbAssignedMaterialTextureFlipY(a)})}async resolveMaterialForAssignments(e,t,a){let s=e,r=null,n=null;const i=getConvertedFbxToGlbAssignedMaterialTextureFlipY(a);for(const e of t??[]){if(!fa(s,e,r,n))continue;const t=await this.getAsset(e.materialId);if(null==t){console.warn("Missing material with id "+e.materialId);continue}let a=await materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0);null!=a&&(a=ga(a,i)),null!=a&&s.id!==a.id&&(r=r??ha(s),n=n??s.name,s=a)}return s}unapplyMaterials(e){e.traverse(async e=>{if(e instanceof m)if(e.material instanceof Array)for(let t=0;t<e.material.length;t++)e.material[t]=this._originalMaterials.get(e.id+"#"+t)??e.material[t];else e.material=this._originalMaterials.get(e.id)??e.material})}updateActors(e){console.log("update actors"),this.actorTypes=e;const t=new Set(Object.values(we));Ye(this.scene,e=>e.userData.src?.id&&"actor"===e.userData.src.type&&this.materializedActors.has(e.userData.src?.id)&&!t.has(e.userData.src.actor.type)).forEach(async e=>{this.remove(e.userData.src),await this.materializeAndInitActor(e.userData.src)})}updateComponents(e){this.componentTypes=e,Ye(this.scene,e=>e.userData.src?.id&&"actor"===e.userData.src.type&&this.materializedActors.has(e.userData.src?.id)&&(e.userData.src.actor?.components?.length??0)>0).forEach(async e=>{this.remove(e.userData.src),await this.materializeAndInitActor(e.userData.src)})}updateShaders(e){this.shaders=e;for(const[e,t]of Jt.entries())t.userData.customShaderName&&Jt.delete(e);this.landscapeManagers.forEach(t=>t.updateShaders(e)),Ye(this.scene,e=>!0).forEach(e=>{e.traverse(async e=>{if(e instanceof m)if(Array.isArray(e.material))for(let t=0;t<e.material.length;t++){const a=e.material[t].userData?.customShaderName;if(null!=a){const a=e.material[t].userData.assetId,s=await this.getAsset(a);null!=s&&this.refreshMaterial(e,e.material[t],s,t)}}else{const t=e.material.userData?.customShaderName;if(null!=t){const t=e.material.userData.assetId,a=await this.getAsset(t);null!=a&&this.refreshMaterial(e,e.material,a)}}})})}async update(e){if("sky"===e.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(e);if("world_env"===e.type&&null!=this.worldEnvObj)return void this.updateWorldEnv(e);const t=this.sceneObjectMap.get(e.id);if(t){let n=!1;if(t.traverseAncestors(e=>{"_hology_transform_group"===e.name&&(n=!0)}),!n){const a=this.findParent(e);null!=a&&a.uuid!=t.uuid?a.attach(t):console.error("Parent is wrong")}if("prefab"!==e.type&&"group"!==e.type){this.unapplyMaterials(t);this.inEditor&&e.hidden&&!1?t.traverse(e=>{e instanceof m&&(e.material.wireframe=!0)}):t.traverse(e=>{e instanceof m&&(e.material.wireframe=!1)})}if("asset_mesh"===e.type&&t.userData.assetId!==e.assetId){this.remove(e);const t=await this.materializeAndInitActor(e);return void this.updated$.next({object:t,source:e})}if("asset_mesh"===e.type){const a=this.assets.get(e.assetId);ua(e.materialAssignments,a.materialAssignments).forEach(e=>this.applyMaterial(t,e,a))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);if(n||(null!=e.position&&t.position.fromArray(e.position),null!=e.scale&&t.scale.fromArray(e.scale),null!=e.rotation&&t.rotation.fromArray(e.rotation)),this.applyVertexMaterials(e,t),"light"==e.type){if("point"==e.light.type){const a=t;a.color=new l(e.light.point.color),a.intensity=e.light.point.intensity,a.decay=e.light.point.decay,a.castShadow=e.light.point.castShadow,a.distance=Math.max(e.light.point.distance,0),a.userData.volumetricIntensity=e.light.point.volumetricIntensity}else if("spot"==e.light.type){const a=t;a.color=new l(e.light.spot.color),a.intensity=e.light.spot.intensity,a.decay=e.light.spot.decay,a.angle=e.light.spot.angle,a.penumbra=e.light.spot.penumbra,a.castShadow=e.light.spot.castShadow,a.distance=Math.max(e.light.spot.distance,0),a.userData.volumetricIntensity=e.light.spot.volumetricIntensity}else if("directional"===e.light.type)this.applyDirectionalLight(e.light.directional,e);else if("ambient"===e.light.type)this.applyDirectionalAmbientLight(t,e.light.ambient,e);else if("rectArea"===e.light.type){const a=t;a.color=new l(e.light.rectArea.color),a.intensity=e.light.rectArea.intensity,null!=e.scale&&(a.width=e.scale[0],a.height=e.scale[1]),a.children.forEach(e=>{e instanceof Bt&&e.update()})}}else if("landscape"===e.shape){const a=this.landscapeManagers.find(t=>t.source.id===e.id),n=null==a||(s=a.source.landscape.options,r=e.landscape.options,s.density!==r.density||s.sections.x!==r.sections.x||s.sections.y!==r.sections.y);if(this.inEditor&&n){this.remove(e);const t=await this.materializeAndInitActor(e);return void this.updated$.next({object:t,source:e})}this.applyHeightMaps(t,e.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter(t=>t.source.id===e.id).forEach(t=>{t.updateSource(e),t.queueRefreshScatter(this.renderingView.camera.position,!0,e=>!0)})}else if("global_fog"===e.type){const t=(this.scene.fog instanceof p?"density":"linear")!==e.fog.type;this.scene.fog=sa(e.fog),t&&(a=this.scene).traverse(e=>{if(e instanceof m){const t=e.material;t instanceof U&&(a.fog instanceof u?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof p&&(t.uniforms.density={value:a.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}}),this.fixFogColor()}else if("actor"===e.type){if(this.materializedActors.has(e.id)){const t=this.materializedActors.get(e.id);if(t instanceof Ot){const a=await prepareClassParameters(e.actor.params,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,[],this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null,t);return void Object.assign(t,a)}const a=this.editorActorParamSnapshot.get(e.id);null!=a&&a===JSON.stringify(e.actor)||n||(this.remove(e),await this.materializeAndInitActor(e))}}else if("shape_mesh"===e.type){const a=await this.createMeshByShape(e.shape,t.material,e.shapeParams);t instanceof at&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}if("shape_mesh"===e.type&&"landscape"!==e.shape)Yt(t,e.castShadow,e.receiveShadow);else if("asset_mesh"===e.type){const a=this.assets.get(e.assetId);if(null==a)return void console.error("Asset not found",e.assetId);const s=e.receiveShadow??!!a.receiveShadow,r=e.castShadow??!!a.castShadow;Yt(t,r,s)}e.name&&e.name.length>0&&(t.name=e.name),this.updated$.next({object:t,source:e})}else{const t=await this.materializeAndInitActor(e);this.updated$.next({object:t,source:e})}var a,s,r;this.renderingView.renderer.shadowMap.needsUpdate=!0}async materializeAndInitActor(e,t=this.findParent(e)){const a=await this.materialize(e,t),s=Array.from(this.materializedActors.entries()).filter(([t])=>t===e.id||t.startsWith(e.id+"/"));return await this.initActorsPostInit(s),a}findParent(e){const t=this.dataProvider.getObjects().flatMap(t=>t.id===e.id?null:qe(t,t=>t.children?.some(t=>t.id===e.id),()=>!0))[0];return null==t?this.scene:null!=t?Ye(this.scene,e=>e.userData?.src?.id===t.id,e=>null!=e.userData?.src)[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new l(this.scene.fog.color))}findMeshWithGeometry(e){let t;return e.traverse(e=>{e instanceof m&&e.geometry&&(t=e)}),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;let a=1;for(const t of e.vertexMaterials)a=Math.max(t.w.length,a);const s=Le(e.vertexMaterials,e=>e.m);t.traverse(e=>{if(e instanceof m){if(null==e.geometry)return;if(Ma(ct(e,0,!1)),a>0){Ma(ct(e,0,!1))}}});const r=new Set;for(const[e,n]of s.entries()){const s=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let i=!1;if(null==s||null==s.geometry)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const o=ct(s,0,!0);Ma(o);for(const e of n)o.setX(e.i,e.w[0]??0),o.setY(e.i,e.w[1]??0),o.setZ(e.i,e.w[2]??0),o.setW(e.i,e.w[3]??0),i=!0;if(a>0){const e=ct(s,4,!0);Ma(e);for(const t of n)e.setX(t.i,t.w[4]??0),e.setY(t.i,t.w[5]??0),e.setZ(t.i,t.w[6]??0),e.setW(t.i,t.w[7]??0),e.needsUpdate=!0,i=!0}i&&r.add(e)}this.inEditor&&this.landscapeManagers.filter(t=>t.source.id===e.id).forEach(e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,e=>r.has(e.name)))}async materialize(e,t,a=!1,s){const r=this.getNestedActorId(e.id,s);if(this.idToSceneObject.set(r,e),!this.shouldBeMaterialized(e))return;let n,i;switch(e.type){case"asset_mesh":n=await this.createFromAsset(e),n=function(e){if(null==e)return e;e.updateWorldMatrix(!0,!0);const t=[];e.traverse(e=>{e.isSkinnedMesh&&t.push(e)});let a=e;for(const e of t){const t=ss(e),s=e.parent;if(null==s){a=t;continue}const r=s.children.indexOf(e);e.removeFromParent(),s.add(t);const n=s.children.indexOf(t);r>=0&&n>=0&&n!==r&&(s.children.splice(n,1),s.children.splice(r,0,t))}return function(e){const t=[];e.traverse(e=>{e.isBone&&t.push(e)});for(const e of t)null!=e.parent&&!e.parent.isBone&&ns(e)&&e.removeFromParent()}(a),a}(n);break;case"shape_mesh":n=await this.createFromShape(e);break;case"light":n=await this.createLight(e);break;case"particles":n=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=sa(e.fog),this.fixFogColor(),n=new d;break;case"sky":this.sky=vt(),this.updateSky(e),n=this.sky;break;case"world_env":this.updateWorldEnv(e),n=new d,this.worldEnvObj=n;break;case"actor":({object:n,actor:i}=await this.createFromActor(e,s));break;case"group":n=new d;break;case"prefab":n=await this.createFromPrefab(e,s,t);break;case"vfx":n=await this.createFromVfx(e,s);break;default:console.warn(`Failed to materialize object. Unknown type '${e.type}'. This might be because the hology/core library is not compatible with the editor version or because of an error in the scene data. Scene object: id=${e.id}, name=${e.name}`)}if(null!=n){if(e.name&&e.name.length>0&&(n.name=e.name),this.applyTransform(e,n),a?n.userData._src=e:n.userData.src=e,null!=i&&(n.userData.actor=i),this.inEditor,this.inEditor,this.objectMap.set(n.uuid,e),this.sceneObjectMap.set(e.id,n),e.physics?.type!==ve.dynamic||null==t||this.inEditor?null==t?this.scene.add(n):null==t||"actor"!==e.type||this.inEditor?t?.add(n):(t.add(n),this.scene?.attach(n),console.log(n)):(t.add(n),n.getWorldPosition(n.position),n.getWorldQuaternion(n.quaternion),n.getWorldScale(n.scale),this.scene?.attach(n)),null!=e.children&&await Promise.all(e.children?.map(e=>this.materialize(e,n,a))),this.inEditor||null!=t||"asset_mesh"!=e.type&&"shape_mesh"!==e.type&&"prefab"!==e.type&&"group"!==e.type||"landscape"===e.shape||null!=e.physics?.type&&e.physics.type==ve.dynamic||aa(n),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,n;console.warn("RenderingView not found in materializer")}}async handleSurfaceScatterSceneMutation(e){const t=this.surfaceScatterManager?.referencesSceneObject(e.id)??!1,a=await this.sceneObjectContainsSurfaceScatter(e);(t||a)&&await this.refreshSurfaceScatterPresence(!0)}async refreshSurfaceScatterPresence(e=!1){return await this.sceneContainsSurfaceScatter()?(null==this.surfaceScatterManager&&(this.surfaceScatterManager=new ut(this.scene,this.dataProvider,this.renderingView,this.assetManagerService,this.assetsService)),this.surfaceScatterManager.queueRefresh(e),!0):(this.disposeSurfaceScatterManager(),!1)}disposeSurfaceScatterManager(){null!=this.surfaceScatterManager&&(this.surfaceScatterManager.clear(),this.surfaceScatterManager.stop(),this.surfaceScatterManager=void 0)}async sceneContainsSurfaceScatter(){return this.sceneObjectsContainSurfaceScatter(this.dataProvider.getObjects())}async sceneObjectsContainSurfaceScatter(e,t=[]){for(const a of e??[])if(await this.sceneObjectContainsSurfaceScatter(a,t))return!0;return!1}async sceneObjectContainsSurfaceScatter(e,t=[]){if("asset_mesh"===e.type&&(e.surfaceScatter?.meshes?.length??0)>0)return!0;if(null!=e.children&&await this.sceneObjectsContainSurfaceScatter(e.children,t))return!0;if("prefab"===e.type&&null!=e.assetId){if(t.includes(e.assetId))return!1;const a=this.assets.get(e.assetId)??await this.assetsService.getAsset(e.assetId),s=a?.prefab?.objects;if(null!=s)return this.sceneObjectsContainSurfaceScatter(s,[...t,e.assetId])}return!1}sceneReferencesPrefabAsset(e){const t=(a=[])=>{for(const s of a??[]){if("prefab"===s.type&&s.assetId===e)return!0;if(t(s.children))return!0}return!1};return t(this.dataProvider.getObjects())}async prefabAssetContainsSurfaceScatter(e){return"prefab"===e.type&&null!=e.prefab?.objects&&this.sceneObjectsContainSurfaceScatter(e.prefab.objects,[e.id])}applyTransform(e,t){null!=e.position&&t.position.fromArray(e.position),null!=e.scale&&t.scale.fromArray(e.scale),null!=e.rotation&&t.rotation.fromArray(e.rotation)}updateWorldEnv(e){this.renderingView.aoPass.enabled=e.worldEnv.ao.enabled,this.renderingView.aoPass.blendIntensity=e.worldEnv.ao.blendIntensity,this.renderingView.aoPass.updateGtaoMaterial(e.worldEnv.ao);const t=e.worldEnv.toneMapping;null!=t&&(this.renderingView.baseToneMapping=t.mapping??0,this.renderingView.baseToneMappingExposure=t.exposure??1,this.renderingView.renderer.toneMapping=this.renderingView.baseToneMapping,this.renderingView.renderer.toneMappingExposure=this.renderingView.baseToneMappingExposure);const a=e.worldEnv.environment;null!=a&&null!=a.textureId?this.assetManagerService.getTexture(this.assets.get(a.textureId)).then(e=>{if(null==e)return void console.error("Failed to load environment texture with id "+a.textureId);if(null==this.pmremGenerator&&(this.pmremGenerator=new n.PMREMGenerator(this.renderingView.renderer),this.pmremGenerator.compileEquirectangularShader()),!this.pmremGeneratorResults.has(e))try{const t=this.pmremGenerator.fromEquirectangular(e).texture;this.pmremGeneratorResults.set(e,t)}catch(e){return void console.error("Failed to generate PMREM for environment texture",e)}const t=this.pmremGeneratorResults.get(e);this.renderingView.scene.environment=t,this.renderingView.scene.environmentIntensity=a.intensity??1}):this.renderingView.scene.environment=null}resetWorldEnv(){this.renderingView.aoPass.enabled=!1,this.renderingView.aoPass.blendIntensity=1,this.renderingView.aoPass.output=0,this.renderingView.baseToneMapping=0,this.renderingView.baseToneMappingExposure=1,this.renderingView.renderer.toneMapping=this.renderingView.baseToneMapping,this.renderingView.renderer.toneMappingExposure=this.renderingView.baseToneMappingExposure}async updateSky(e){null!=this.sky&&(null==e?.sky?.materialId&&this.sky.material!==Mt?(this.sky.material=Mt,this.applySkySettings(this.sky.material)):this.sky.material.userData?.assetId!==e.sky.materialId&&this.updateSkyMaterial(e),null!=e.rotation&&this.sky.rotation.fromArray(e.rotation))}async updateSkyMaterial(e){const t=await this.assetsService.getAsset(e.sky.materialId);if(null==t)return void console.warn(`No material asset found for sky with id ${e.sky.materialId}`);const a=await materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);this.applySkySettings(a),null!=this.sky?this.sky.material=a:console.warn("No sky has been created")}applySkySettings(e){e.side=n.BackSide,(e instanceof w||e instanceof n.MeshBasicMaterial||e instanceof n.ShaderMaterial)&&(e.fog=!1),e.depthTest=!1}async createComponent(e,t,a,s){const r=new Wt[a.path+"/"+a.className],n=t.id+s;r.id=n,r.object=e;for(const e of a.params)null!=e.value&&(r[e.name]=e.value);return this.components.push(r),n}async createFromActor(e,t){const a=this.actorTypes.find(t=>t.name===e.actor?.type)?.type??we[e.actor?.type];if(null==a)return{object:null,actor:null};this.inEditor&&this.editorActorParamSnapshot.set(e.id,JSON.stringify(e.actor));const s=await this.actorProvider.create(a,(new I).fromArray(e.position),(new c).fromArray(e.rotation),!0);return this.materializedActors.set(this.getNestedActorId(e.id,t),s),{object:s?.object,actor:s}}getNestedActorId(e,t){return null!=t?t.sceneObjectChain.join("/")+"/"+e:e}async createFromVfx(e,t){const a=await this.assetsService.getAsset(e.assetId);null==a&&console.error("Could not find asset",e);const s=await this.actorProvider.create(de,(new I).fromArray(e.position),(new c).fromArray(e.rotation),!1);try{await s.fromAsset(a)}catch(e){return console.error("Failed to create VFX asset",e),null}return s.play(),this.materializedActors.set(this.getNestedActorId(e.id,t),s),null!=s&&(s.object.userData.actor=s),s?.object}async createFromShape(e){const t=this.inEditor&&e.hidden;let a;if("landscape"==e.shape)a=this.createLandscape(e),a.traverse(e=>{e instanceof m&&this._originalMaterials.set(e.id,e.material)});else{let s=new w({name:"Default",color:new l("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});!0===e.collider&&(s.opacity=.3,s.color.set(2517460),s.transparent=!0);const r=await this.createMeshByShape(e.shape,s,e.shapeParams);r.castShadow=e.castShadow??!0,r.receiveShadow=e.castShadow??!1,!1===e.collisionDetection&&(r.collisionShape=null),r.physics=e.physics,a=r,this._originalMaterials.set(a.id,r.material),a.traverse(e=>{})}return t||(await Promise.all((e.materialAssignments??[]).filter(e=>null!=e.materialId).map(e=>this.applyMaterial(a,e))),this.applyVertexMaterials(e,a)),a}createLandscape(e){const t=e.landscape?.options;if(null==t)return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new d;const a=rt(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new st(e,this.renderingView,a,this.assetManagerService,this.assetsService,this.shaders,t=>{(e.materialAssignments??[]).filter(e=>null!=e.materialId).forEach(e=>this.applyMaterial(t,e))});return this.landscapeManagers.push(s),s.refreshGeometry(),a}applyHeightMaps(e,t,a=!1){const s=new nt(e.sections);for(const e of t??[]){const t=s.find(e.x,e.y);if(!t)return;const a=t.geometry.getAttribute("position");for(const t of e.points)a.setY(t.i,t.y);a.needsUpdate=!0}const r=e.sections;r.forEach(e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()}),this.inEditor&&!a||setTimeout(()=>it(r),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&wt.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=yt[e].geometry(s);(function(e){return null!=e.index&&e.hasAttribute("position")&&e.hasAttribute("normal")&&e.hasAttribute("uv")})(t)&&t.computeTangents(),this.geometryCache.set(r,t)}this.collisionShapeCache.has(r)||this.collisionShapeCache.set(r,yt[e].collision(s));return new at(this.geometryCache.get(r),t,this.collisionShapeCache.get(r))}if(this.inEditor)throw new Error(`Unsupported shape '${e}'`);console.warn(`Failed to create shape. Unsupported shape '${e}'. This might be because the hology/core library is not compatible with the editor version.`)}async createFromAsset(e,t){const a=this.assets.get(e.assetId)??await this.assetsService.getAsset(e.assetId);if(null==a)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);let{scene:s}=await this.assetManagerService.getMesh(a,{mergeGeomtries:!0});if(!1!==t?.assignMaterials)try{await Promise.all(ua(e.materialAssignments,a.materialAssignments).map(e=>this.applyMaterial(s,e,a)))}catch(t){console.error("Failed to apply material"+t,e)}const r=e.receiveShadow??!!a.receiveShadow,n=e.castShadow??!!a.castShadow;return s.receiveShadow=r,Yt(s,n,r),!1!==e.collisionDetection&&!1!==a.collisionDetection||(s.collisionShapes=[]),null!=e.physics&&!0!==this.inEditor&&(s.physics=e.physics),this.applyVertexMaterials(e,s),s.traverse(e=>{e instanceof m&&"computeBoundsTree"in e.geometry&&null==e.geometry.boundsTree&&e.geometry.computeBoundsTree()}),s.userData.assetId=e.assetId,s}async createFromPrefab(e,t,a){const s=await this.assetsService.getAsset(e.assetId);if(null==s)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);null==t&&(t={sceneObjectChain:[]}),t.sceneObjectChain.push(e.id);const{object:r}=await this.createFromPrefabAsset(s,t,a,e);return t.sceneObjectChain.pop(),r}async createFromPrefabAsset(e,t,a,s,r=!0){const n=new d;null!=s&&this.applyTransform(s,n),null!=a&&a.add(n),await Promise.all(e.prefab.objects.filter(e=>"global_fog"!==e.type&&"world_env"!==e.type).map(e=>this.materialize(e,n,!0,structuredClone(t))));const i=t.sceneObjectChain.join("/"),o=Array.from(this.materializedActors.entries()).filter(([e,a])=>e.startsWith(i)&&e.split("/").length-1===t.sceneObjectChain.length);let l;if(o.forEach(e=>{}),null!=e.prefab?.mainActorId){const a=t.sceneObjectChain.join("/")+"/"+e.prefab.mainActorId;l=this.materializedActors.get(a)}r||await this.initActorsPostInit(o);const c=Array.from(this.materializedActors.entries()).filter(([e,t])=>e.startsWith(i)).map(([,e])=>e);if(null!=e.prefab?.mainActorId&&null!=s){const a=t.sceneObjectChain.join("/"),s=a+"/"+e.prefab.mainActorId;this.prefabInstanceExposedActorMap.set(a,s)}return{object:n,actors:c,mainActor:l}}async createParticleSystem(e){await this.assetsService.getAsset(e.assetId);return new v}async createLight(e){if("point"===e.light.type){const t=new M(e.light.point.color,e.light.point.intensity,e.light.point.distance,e.light.point.decay);if(t.castShadow=e.light.point.castShadow??!0,this.inEditor){const e=(new n.TextureLoader).load("assets/light-bulb-icon.webp"),a=new n.SpriteMaterial({map:e,alphaTest:.5}),s=new kt(a);s.scale.multiplyScalar(.6),t.add(s)}return t}if("spot"===e.light.type){const t=new n.SpotLight(e.light.spot.color,e.light.spot.intensity,e.light.spot.distance,e.light.spot.angle,e.light.spot.penumbra,e.light.spot.decay);if(t.castShadow=e.light.spot.castShadow??!0,t.target=new v,t.target.position.set(0,-1,0),t.add(t.target),this.inEditor){const e=(new n.TextureLoader).load("assets/light-bulb-icon.webp"),a=new n.SpriteMaterial({map:e,alphaTest:.5}),s=new kt(a);s.scale.multiplyScalar(.6),t.add(s),t.add(new n.SpotLightHelper(t))}return t}if("rectArea"===e.light.type){const t=new n.RectAreaLight(e.light.rectArea.color,e.light.rectArea.intensity,e.scale?e.scale[0]:1,e.scale?e.scale[1]:1);if(this.inEditor){const e=(new n.TextureLoader).load("assets/light-bulb-icon.webp"),a=new n.SpriteMaterial({map:e,alphaTest:.5}),s=new kt(a);s.scale.multiplyScalar(.6),t.add(s);const r=new Bt(t);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional,e),new d):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient,e),new d):void 0}applyDirectionalAmbientLight(e,t,a){const s=this.scene.children.find(e=>e.name===bt);null!=s?(s.intensity=t.intensity,s.color.set(t.color),s.groundColor.set(t.color),s.userData.src=a,s.userData.volumetricIntensity=t.volumetricIntensity):console.warn("Couldn't find ambient light")}applyDirectionalLight(e,t){for(const a of this.renderingView.csm.lights)a.intensity=e.intensity,a.color.set(e.color),a.castShadow=e.castShadow,a.userData.src=t,a.userData.volumetricIntensity=e.volumetricIntensity;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.createAssetSubscription.unsubscribe(),this.materializedActors.forEach(e=>e.disposed.next(!0)),this.materializedActors.clear()}};qt=e([pe(),t("design:paramtypes",[A,Object,Qe,Ke,Ae,Array,Array,Object,Array])],qt);export{qt as SceneMaterializer};function Yt(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const Jt=new Map,Xt=new Map,Zt=new g({color:16711935}),Ht=new Map;export async function materialFromAsset(e,t,a,s,r,n=!0){if(null==e||null==e.material)return console.error("Asset or asset material is null",e),Zt;const i=JSON.stringify(e.material)+t?._id,o=n&&!("shaderGraph"===e.material.type&&"asset"===e.material.shaderGraph?.source);if(o&&Jt.has(i))return Jt.get(i);if(o&&Xt.has(i))return await Xt.get(i);const l=_materialFromAsset(i,e,t,a,s,r,o);return o?Xt.set(i,l).get(i):l}export async function _materialFromAsset(e,t,a,r,i,o,c=!0){const u={opacity:t.material.params?.opacity??1,map:null,emissive:t.material.params?.emissive??null,metalness:t.material.params?.metalness??0,flatShading:t.material.params?.flatShading??!1,color:new l(t.material.params?.color),transparent:null!=t.material.params?.opacity&&t.material.params?.opacity<1},p={};if(null!=t.material.params?.map){const e=t.material.params.map,a=await r.getAsset(e);null!=a&&(u.map=await i.getTexture(a))}let d,h,f;switch(t.material.type){case"phong":d=new y({...u,...p});break;case"water":d=pt(u,a);break;case"grassFoliage":d=ot({color:u.color,map:u.map},a);break;case"grass":d=lt({...u,colorTwo:new l(t.material.params.colorTwo),colorThree:new l(t.material.params.colorThree)},a);break;case"shaderGraph":{const e=await async function(e,t){const a=e.material?.shaderGraph;if("local"===a?.source)return a.graph;if("asset"===a?.source){const e=await t.getAsset(a.assetId);return e?.shaderGraph??null}return e.shaderGraph??null}(t,r);if(null==e){console.warn("Missing shader graph for material "+t.name),d=Zt;break}"surface"===e.target&&null!=e.materialOptions?.side&&(h=Gt(e.materialOptions.side)),"decal"===e.target?f=!1:null!=e.materialOptions?.transparent&&(f=e.materialOptions.transparent);try{const s=await prepareShaderGraphParameters(t.material?.shaderParams??{},e,r,i,a,o),n=t.shaderGraphPreviewNodeId,l=t.trailBillboard;d=Ut(e,{parameters:s,previewNodeId:n,trailBillboard:l}),d.userData.customShaderName="asset"===t.material.shaderGraph?.source?`shaderGraph:${t.material.shaderGraph.assetId}`:`shaderGraph:${t.id}`}catch(e){console.log("Shader graph runtime error: "+e,e),d=Zt}break}case"standard":case"unlit":case"toon":case"layered":case"lambert":case"shader":case"landscape":case"landscape-composite":case"decal-unlit":case"decal-standard":case"sprite":const e={standard:Lt?De:Oe,lambert:De,unlit:ke,toon:Vt,layered:Ct,landscape:Te,"landscape-composite":Ce,"decal-unlit":At,"decal-standard":xt,sprite:s}[t.material.type]??o.find(e=>e.name==t.material.shader)?.type;if(e){try{let s=new e;const n=await prepareClassParameters(t.material?.shaderParams??{},e,r,i,null,a,o,void 0,void 0,s);Object.assign(s,n),d=s.build()}catch(e){console.log("Shader runtime error: "+e,e),Ht.has(t.material.shader)||Ht.set(t.material.shader,Zt.clone()),d=Ht.get(t.material.shader)}d.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),d=Zt;break;default:throw new Error("Unsupported material type "+t.material.type)}if(a?.csm.setupMaterial(d),d.side=h??t.material.side??d.side??n.FrontSide,d.transparent=(f??t.material.transparent??u.transparent??!1)||d.transparent,d.alphaTest=t.material.alphaTest??d.alphaTest??0,null!=t.material.blending&&(d.blending=Me[t.material.blending]??n.NormalBlending),t.material.bloom&&(d.userData.hasBloom=!0),t.material.reflective&&(d.userData.reflective=!0),!0===t.material.outlines&&(d.userData.outlineParameters={},null!=t.material.outlineParams&&(null!=t.material.outlineParams.color&&(d.userData.outlineParameters.color=new l(t.material.outlineParams.color).toArray()),null!=t.material.outlineParams.thickness&&(d.userData.outlineParameters.thickness=t.material.outlineParams.thickness))),null!=t.material.surfaceAssetId&&""!==t.material.surfaceAssetId){const e=await materializeDataAssetRef(t.material.surfaceAssetId,r,i,void 0,a,o);null!=e&&(d.userData.surface=e.value)}return d.userData.assetId=t.id,c&&null!=a&&Jt.set(e,d),c&&Xt.delete(e),d}export function prepareCustomParamsFromShaderGraph(e,t={}){return Object.fromEntries((e.parameters??[]).map(e=>{const a=function(e){switch(e){case"float":return dt.FloatNode;case"boolean":return dt.BooleanNode;case"texture":return dt.Sampler2DNode;case"vec2":return dt.Vec2Node;case"vec3":return dt.Vec3Node;case"vec4":return dt.Vec4Node;case"color":return dt.RgbNode}}(e.type),s=t[e.name],r=s?.override??null!=s,n=void 0!==e.defaultValue?e.defaultValue:customParameterDefaultValueByType.get(a),i=!1===r?ca(n):s?.value??ca(n);return[e.name,{type:a,value:i,override:r}]}))}export async function prepareShaderGraphParameters(e,t,a,s,r,n){const i={},o=prepareCustomParamsFromShaderGraph(t,e);for(const[e,t]of Object.entries(o)){const o=await Qt(e,t,a,s,null,r,n);null!=o&&(i[e]=o)}return i}export async function prepareClassParameters(e,t,a,s,r,n,i,o,l,c){const u={},{params:p,skipped:d}=ft(e,{parameterType:t,parameterTarget:c,extractPropertyParameters:Ve,toSerializedParamType:toSerializedParamType});for(const e of d)console.warn(`Skipping stored parameter "${e.key}" because it could not be converted from ${dt[e.sourceType]} to ${dt[e.targetType]}`);for(const[e,t]of Object.entries(p)){if(!1===t.override)continue;const c=await Qt(e,t,a,s,r,n,i,o,void 0,void 0,l);null!=c&&(u[e]=c)}return u}export async function prepareShapeParameters(e,t,a){const s={};for(const[r,n]of Object.entries(e)){const e=await Qt(r,n,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const Kt=new Map;async function Qt(e,t,a,s,r,n,i,o,u=t.value,p=t.type,d,h=(t.type===dt.Struct?t.struct:void 0)){if(null==t||null==u||""===u)return null;switch(p){case dt.Array:if(Array.isArray(u)&&"element"in t)return await Promise.all(u.map(l=>Qt(e,t,a,s,r,n,i,o,l,t.element,d,t.elementStruct)));break;case dt.Number:case dt.FloatNode:let f;if("string"==typeof u?f=parseFloat(u):"number"==typeof u&&(f=u),p===dt.FloatNode){if("object"==typeof u&&"a"in u&&"b"in u){const e=u;if(null==e.a)return null;const t="string"==typeof e.a?parseFloat(e.a):e.a;if(null==e.b)return t;const a="string"==typeof e.b?parseFloat(e.b):e.b,s=function(e){let t=Kt.get(e);return null==t&&(t=xe(St.decode(e)),Kt.set(e,t)),t}(e.easing),r=s.sample(je(Ie.energy));return _(N(t),N(a),r)}return new H(Ue(e),f,void 0,!1)}return f;case dt.Texture:let m=await s.getTexture(await a.getAsset(u));return"envmap"===e.toLowerCase()&&null!=n&&(m=n.getEnvTexture(m)),m;case dt.Sampler2DNode:const g=await a.getAsset(u);if(null!=g?.texture?.textureArrayFileKey){const{texture:t,layerIndex:a}=await s.getTextureArray(g);if(t&&null!=a)return new K(null,t,new H(Ue(e)+"_i",a,void 0,!1))}const y=await s.getTexture(g);return y?J(y):null;case dt.Boolean:return u;case dt.BooleanNode:return new Z(Ue(e),u,void 0,!1);case dt.Vector2:case dt.Vec2Node:if("object"==typeof u){const t=u instanceof Array?(new j).fromArray(u):new j(u.x,u.y);return p===dt.Vec2Node?new Q(Ue(e),t,void 0,!1):t}return null;case dt.Vector3:case dt.Vec3Node:if("object"==typeof u){const t=u instanceof Array?(new I).fromArray(u):new I(u.x,u.y,u.z);return p===dt.Vec3Node?new ee(Ue(e),t,void 0,!1):t}return null;case dt.Vector4:case dt.Vec4Node:if("object"==typeof u){const t=u instanceof Array?(new P).fromArray(u):new P(u.x,u.y,u.z,u.w);return p===dt.Vec4Node?new te(Ue(e),t,void 0,!1):t}return null;case dt.Color:case dt.RgbNode:const w=new l(u);return p===dt.RgbNode?new ee(Ue(e),new I(w.r,w.g,w.b),void 0,!1).rgb:w;case dt.String:return u;case dt.BaseActor:const b=u;if(null==r&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==b)return null;if("object"==typeof b&&null!=b.type&&null!=b.id){if("actor"===b.type)return r?.get(b.id)??null;if("prefab"===b.type){const e=d?d(b.id):null;if(null!=e)return r?.get(e)??null;const t=[];for(const[e,a]of r?.entries()??[])e.startsWith(b.id+"/")&&t.push(a);return 1===t.length?t[0]:null}}if("string"==typeof b){const e=r?.get(b);if(null!=e)return e;const t=d?d(b):null;if(null!=t)return r?.get(t)??null;const a=[];for(const[e,t]of r?.entries()??[])e.startsWith(b+"/")&&a.push(t);return 1===a.length?a[0]:null}return null;case dt.Euler:const v=u;return(new c).fromArray(v);case dt.Object3D:{const e=await a.getAsset(u);return(await s.getMesh(e,{applyMaterials:!0,rescale:!0})).scene}case dt.Material:{if(null==u)return null;const e=await a.getAsset(u);return null==e?(console.warn("Material asset not found for material parameter",u),null):null==e.material?(console.warn("Using a non-material asset for material parameter"),null):await materialFromAsset(e,n,a,s,i)}case dt.AudioBuffer:return await s.getAudio(await a.getAsset(u));case dt.VisualEffect:const M=await a.getAsset(u);if(null==o){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in M)return new he(o,M);console.error("Using a non-vfx asset for visual effect parameter");break;case dt.Prefab:{const e=await a.getAsset(u);return null==e?(console.error("Using a non-prefab asset for prefab parameter",u),null):new fe(e)}case dt.PrefabActor:{const e=await a.getAsset(u);return null==e?(console.error("Using a non-prefab asset for prefab parameter",u),null):new me(new fe(e))}case dt.DataAsset:return materializeDataAssetRef(u,a,s,r,n,i,o,d);case dt.Sequence:{const e=await a.getAsset(u);if("sequence"===e.type&&"sequence"in e)return new $t(e.sequence);console.error("Using a non-sequence asset for sequence parameter");break}case dt.Struct:return async function(e,t,a,s,r,n,i,o,l){const c=ea(e),u=c?.struct??t;if(null==u)return console.warn("Missing parameter definition id for struct parameter"),null;const p=ze(u);if(null==p)return console.warn(`Unknown parameter definition "${u}"`),null;if(Be(u))return console.warn(`Can not instantiate abstract parameter definition "${u}"`),null;if(null!=t&&u!==t&&!_e(u,t))return console.warn(`Parameter definition "${u}" is not assignable to "${t}"`),null;let d;try{d=new p}catch(e){return console.warn(`Failed to instantiate parameter definition "${u}"`,e),null}const h=function(e){const t=ea(e);if(null!=t)return t.value;if(ta(e))return e;if(null!=e&&"object"==typeof e&&ta(e.params))return e.params;return{}}(c?.value??e),f=await prepareClassParameters(h,null,a,s,r,n,i,o,l,d);return Object.assign(d,f),d}(u,h,a,s,r,n,i,o,d);case dt.Curve:return St.decode(u);case dt.ColorLayer:case dt.MaskLayer:if(Tt(u)){const e=await jt.decode(u,async e=>await s.getTexture(await a.getAsset(e))),t=await prepareClassParameters(u.params,null,a,s,void 0,void 0,void 0,void 0,void 0,e);return Object.assign(e,t),e}return console.warn("Expecting color layer but got",u),null;case dt.AnimationClip:{const e="string"==typeof u?u:"object"==typeof u&&null!=u?u.assetId:null;if(null==e)return console.warn("Invalid animation clip asset id value",u),null;return await s.getAnimationClip(await a.getAsset(e))}}return null}export async function materializeDataAssetRef(e,t,a,s,r,n,i,o){const l="string"==typeof e?e:null!=e&&"object"==typeof e?e.assetId??e.id:null;if(null==l||""===l)return null;const c=await t.getAsset(l);if(null==c)return console.warn(`Data asset "${l}" was not found`),null;if("data"!==c.type||null==c.dataAsset)return console.warn("Using a non-data asset for data asset parameter",l),null;const u=c.dataAsset.definition;if(null==u||""===u)return console.warn(`Missing data asset definition id for asset "${c.id}"`),null;if(Ne(u))return console.warn(`Can not instantiate abstract data asset definition "${u}"`),null;const p=Ee(u);if(null==p)return console.warn(`Unknown data asset definition "${u}"`),null;let d;try{d=new p}catch(e){return console.warn(`Failed to instantiate data asset definition "${u}"`,e),null}const h=c.dataAsset.params??{};if("object"!=typeof h||Array.isArray(h))return console.warn(`Invalid data asset params for asset "${c.id}"`),null;try{const e=await prepareClassParameters(h,null,t,a,s,r,n,i,o,d);Object.assign(d,e)}catch(e){return console.warn(`Failed to materialize data asset "${c.id}"`,e),null}return new ge(c,d)}function ea(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"string"==typeof e.struct&&ta(e.value)?e:null}function ta(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&Object.values(e).every(e=>null!=e&&"object"==typeof e&&"type"in e)}function aa(e){e.updateWorldMatrix(!0,!0),e.updateMatrix(),e.traverse(e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1});const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}function sa(e){return"linear"===e.type?new u(new l(e.color),e.near??100,e.far??1e3):"density"===e.type?new p(e.color,e.density):void console.warn("Invalid fog type",e)}new w({color:4229780});async function ra(e,t,a,s){null==s&&(s=(new f).identity());const r=s.clone().multiply(na(e,new n.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await ra(e.children[a],t,e,r);await t(e,a,s)}function na(e,t){return null==e.position||null==e.rotation||null==e.scale?t.identity():t.compose((new I).fromArray(e.position),(new S).setFromEuler((new c).fromArray(e.rotation)),(new I).fromArray(e.scale))}export function toSerializedParamType(e){if(null==e)return;const t=e.constructor.prototype;return t instanceof Number||e===Number?dt.Number:t instanceof B||"function"==typeof e.prototype.isFloat?dt.FloatNode:t instanceof x||e===x||e.isTexture?dt.Texture:t instanceof Pe||e===Pe||e===Y||"function"==typeof e.prototype?.isSampler2D||!0===e.prototype?.isSampler2D?dt.Sampler2DNode:t instanceof Boolean||e===Boolean?dt.Boolean:t instanceof F?dt.BooleanNode:t instanceof l||e==l?dt.Color:t instanceof L||"function"==typeof e.prototype.isRgb?dt.RgbNode:t instanceof j||e==j?dt.Vector2:t instanceof ie||"function"==typeof e.prototype.isVec2?dt.Vec2Node:t instanceof I||e==I?dt.Vector3:t instanceof le||"function"==typeof e.prototype.isVec3?dt.Vec3Node:t instanceof P||e==P?dt.Vector4:t instanceof ue||"function"==typeof e.prototype.isVec4?dt.Vec4Node:t instanceof String||e===String?dt.String:t instanceof ye||e==ye||e.prototype instanceof ye||e.prototype==ye?dt.BaseActor:t instanceof c||e==c?dt.Euler:t instanceof v||e==v?dt.Object3D:t instanceof h||e==h?dt.Material:t instanceof AudioBuffer||e==AudioBuffer?dt.AudioBuffer:t instanceof he||e==he?dt.VisualEffect:t instanceof fe||e==fe?dt.Prefab:t instanceof me||e==me?dt.PrefabActor:t instanceof ge||e==ge?dt.DataAsset:t instanceof St||e==St?dt.Curve:t instanceof jt||e==jt?dt.ColorLayer:t instanceof Dt||e==Dt?dt.MaskLayer:t instanceof n.AnimationClip||e==n.AnimationClip?dt.AnimationClip:t instanceof $t||e==$t||"SequenceData"===e.name||e.prototype&&"tracks"in e.prototype?dt.Sequence:null!=Fe(e)?dt.Struct:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function getCustomParamTypeInfo(e){const t=toSerializedParamType(e.type),a=t===dt.Struct?Fe(e.type):void 0;return!0===e.options.array?{type:dt.Array,element:t,...null!=a?{elementStruct:a}:{}}:{type:t,...null!=a?{struct:a}:{}}}export function prepareCustomParams(e,t,a={},s={}){return Object.fromEntries(e.map(e=>{const r=getCustomParamTypeInfo(e);let n=r;const i=t[e.name],o=!0===s.treatAllAsOptional||!0===e.options.optional,l=s.missingOverrideDefaultsToOverride??!0;let c=i?.override;void 0===c&&null!=i&&o&&l&&(c=!0),void 0===c&&o&&(c=!1);const u=void 0!==a[e.name]||void 0!==e.options.defaultValue,p=function(e,t){if(e.type!==dt.Struct)return{typeInfo:e,value:t};const a=ea(t);if(null==a)return{typeInfo:e,value:t};return{typeInfo:{...e,struct:a.struct},value:a.value}}(n,function(e,t){if(void 0!==t[e.name])return t[e.name];if(void 0!==e.options.defaultValue){const t=serializeCustomParameter(e.type,e.options.defaultValue);return void 0!==t?t:e.options.defaultValue}const a=toSerializedParamType(e.type);if(a===dt.Struct)return Be(e.type)?{}:prepareCustomParamsFromType(e.type,{});return customParameterDefaultValueByType.get(a)}(e,a));n=function(e,t,a){if(e.type!==dt.Struct||a?.type!==dt.Struct||null==a.struct)return e;const s=t.struct??e.struct;if(null==s||a.struct===s||_e(a.struct,s)||null==ze(a.struct))return{...e,struct:a.struct};return e}(p.typeInfo,r,i);const d=!1!==c||e.options.array?i?.value??function(e,t,a){if(!0===e.options.array)return a?ca(t):[];return ca(t)}(e,p.value,u):ca(p.value);return[e.name,{...n,value:d,override:c}]}))}function ia(e){return null==e?{}:Object.fromEntries(Object.entries(e).filter(([,e])=>function(e){return!0===e?.override}(e)))}function oa(e,t){return e.length>=t.length&&t.every((t,a)=>e[a]===t)}export function prepareCustomParamsFromType(e,t,a=null,s={}){const r=Ve(e);if(0===r.length)return{};let n;null!=a?Se(a,()=>{n=a.get(e)}):n=new e;const i={};for(const e of r){const t=n[e.name];if(null!=t){const a=la(e,t);void 0!==a&&(i[e.name]=a)}}return prepareCustomParams(r,t,i,s)}function la(e,t){return!0===e.options.array?Array.isArray(t)?t.map(t=>serializeCustomParameter(e.type,t)??t):[]:serializeCustomParameter(e.type,t)}function ca(e){return null==e?e:Array.isArray(e)?e.map(e=>ca(e)):"object"==typeof e?"function"==typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e)):e}export function serializeCustomParameter(e,t){function a(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case j:return t instanceof j?t.toArray():void a();case I:return t instanceof I?t.toArray():void a();case P:return t instanceof P?t.toArray():void a();case l:return t instanceof l?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new l(t).getHexString():void a();case String:return t;case c:return t instanceof c?t.toArray():void a();case fe:return t instanceof fe?t.asset?.id??null:void a();case ge:return t instanceof ge?t.id:"string"==typeof t?t:void a()}const s=Fe(e);if(null!=s){const r=ea(t);if(null!=r)return r.struct===s?r.value:r;const n=function(e,t){if(null==t||"object"!=typeof t)return e;const a=t.constructor;return null!=Fe(a)&&$e(a,e)?a:e}(e,t),i=Fe(n),o=function(e,t){if(null==t)return null;if(ta(t))return t;if(null!=t&&"object"==typeof t&&ta(t.params))return t.params;if("object"!=typeof t)return;const a=Ve(e),s={};for(const e of a){const a=t[e.name];if(void 0===a)continue;const r=la(e,a);void 0!==r&&(s[e.name]=r)}return prepareCustomParams(a,{},s)}(n,t);return void 0!==o?null!=o&&null!=i&&i!==s?{struct:i,value:o}:o:void a()}if(t&&"object"==typeof t&&"tracks"in t&&"duration"in t)return t}function ua(e,t){return function(e,t,a){const s=[],r=new Set;for(const n of[...e??[],...t??[]]){const e=a(n);r.has(e)||(r.add(e),s.push(n))}return s}((e??[]).filter(e=>pa(e.materialId)),(t??[]).filter(e=>pa(e.materialId)),e=>e.color+e.name)}function pa(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[dt.RgbNode,"#000000"],[dt.Color,"#000000"],[dt.String,""],[dt.Vector4,[0,0,0,0]],[dt.Vec4Node,[0,0,0,0]],[dt.Vector3,[0,0,0]],[dt.Vec3Node,[0,0,0]],[dt.Vector2,[0,0]],[dt.Vec2Node,[0,0]],[dt.Euler,[0,0,0,"XYZ"]],[dt.Array,[]],[dt.DataAsset,null],[dt.ColorLayer,It],[dt.MaskLayer,Pt]]);let da=new l;new l;function ha(e){return null==e?.color?null:(da.set(e.color),"#"+da.getHexString())}function fa(e,t,a,s){const r="string"==typeof t.name&&""!==t.name?t.name:null;if(null!=r)return e.name===r||s===r;const n=ha(e);return null!=n&&(n===t.color||a===t.color)}export function applyMaterial(e,t,a,s,r={}){const i=[];return e.traverse(async e=>{if(e instanceof m||e.isMesh||e instanceof n.SkinnedMesh||e.isSkinnedMesh)for(const t of Re(e.material))t.hasOwnProperty("color")&&i.push(e)}),Promise.all(i.map(async e=>{if(e.material instanceof Array)for(let n=0;n<e.material.length;n++){const i=e.material[n];if(null==i.color||!(i.color instanceof l))continue;const o=ha(i),c=i.name;if(fa(i,t,e.userData["originalColor_"+n],e.userData["originalMaterialName_"+n])){const i=ga(await a(t.materialId),r.textureFlipY),l=e.material[n];null!=i&&l.id!=i.id&&(e.material[n]=i,e.userData["originalColor_"+n]=e.userData["originalColor_"+n]??o,e.userData["originalMaterialName_"+n]=e.userData["originalMaterialName_"+n]??c,null!=s&&s.set(e.id+"#"+n,l))}}else if("color"in e.material){const n=e.material,i=ha(n),o=n.name;if(fa(n,t,e.userData.originalColor,e.userData.originalMaterialName)){const n=ga(await a(t.materialId),r.textureFlipY),l=e.material;null!=n&&(e.material=n,e.userData.originalColor=e.userData.originalColor??i,e.userData.originalMaterialName=e.userData.originalMaterialName??o,null!=s&&(s.has(e.id)||s.set(e.id,l)))}}}))}const ma=new WeakMap;export function getConvertedFbxToGlbAssignedMaterialTextureFlipY(e){const t=e?.mesh?.uvConversion;return"fbx2gltf"===t?.source?!0!==t.flipV&&void 0:!function(e){return"glb"===e?.fileFormat&&!0===e.originalFileKey?.toLowerCase().endsWith(".fbx")}(e)&&void 0}function ga(e,t){if(null==e||null==t||!function(e,t){return function(e){const t=[];for(const[a,s]of Object.entries(e))wa(a,s)&&t.push(s);if(e instanceof n.ShaderMaterial)for(const[a,s]of Object.entries(e.uniforms))wa(a,s.value)&&t.push(s.value);return t}(e).some(e=>e.flipY!==t)}(e,t))return e;let a=ma.get(e);null==a&&(a=new Map,ma.set(e,a));const s=a.get(t);if(null!=s)return s;const r=ya(e);if(function(e,t){for(const a of Object.keys(e)){const s=e[a];wa(a,s)&&(e[a]=ba(s,t))}}(r,t),r instanceof n.ShaderMaterial){for(const[e,a]of Object.entries(r.uniforms))wa(e,a.value)&&(a.value=ba(a.value,t));r.uniformsNeedUpdate=!0}return r.needsUpdate=!0,a.set(t,r),r}function ya(e){const t=e.clone();return t.userData={...e.userData??{}},t}function wa(e,t){const a=t;return(t instanceof x||!0===a?.isTexture)&&!e.toLowerCase().includes("envmap")&&!0!==a.isCompressedTexture&&!0!==a.isCompressedArrayTexture}function ba(e,t){if(e.flipY===t)return e;const a=e.clone();return a.flipY=t,a.userData={...e.userData??{}},a.needsUpdate=!0,a}function va(e,t){if(e instanceof n.ShaderMaterial&&t instanceof n.ShaderMaterial){return e.fragmentShader+e.vertexShader==t.fragmentShader+t.vertexShader&&function(e,t){if(e instanceof n.ShaderMaterial&&t instanceof n.ShaderMaterial){for(const a in e.uniforms){if(null==t.uniforms[a])return!1;if(t.uniforms[a].value!==e.uniforms[a].value)return!1}return!0}return!1}(e,t)}return!1}function Ma(e){if(null!=e){for(let t=0;t<e.array.length;t++)e.setX(t,0);e.needsUpdate=!0}}function Sa(e,t){const a=Je(e);return null==a?"":function(e,t){const a=qa(e,t),s=a.sort().map(t=>{const a=e.getAttribute(t),s=a.array??a.data?.array,r=s?.constructor?.name??"";return`${t}:${a.itemSize}:${a.normalized?1:0}:${r}`}).join(",");return`${null!=e.index?"indexed":"nonindexed"}|${s}`}(a.geometry,t)}function Aa(e,t){const a=qa(e,t);if(a.length===Object.keys(e.attributes).length)return e;const s=new o;s.name=e.name;const r=e.getIndex();null!=r&&s.setIndex(r);for(const t of a)s.setAttribute(t,e.getAttribute(t));for(const t of e.groups)s.addGroup(t.start,t.count,t.materialIndex);return s.setDrawRange(e.drawRange.start,e.drawRange.count),null!=e.boundingBox&&(s.boundingBox=e.boundingBox.clone()),null!=e.boundingSphere&&(s.boundingSphere=e.boundingSphere.clone()),s.userData=e.userData,s}const xa=new WeakMap,ja="hbat_",Ia=new Set(["ambientLightColor","cameraNear","directionalLightShadows","directionalLights","directionalShadowMap","directionalShadowMatrix","fogColor","fogDensity","fogFar","fogNear","hemisphereLights","lightProbe","ltc_1","ltc_2","pointLightShadows","pointLights","pointShadowMap","pointShadowMatrix","receiveShadow","rectAreaLights","shadowFar","spotLightMap","spotLightMatrix","spotLightShadows","spotLights","spotShadowMap"]);function Pa(e){let t=xa.get(e);return null==t&&(t=function(e){let t=e.type;if(e instanceof U)t+=function(e){let t="nodeShader";t+=e.vertexShader,t+=e.fragmentShader,t+=function(e){if(null==e)return"";let t="";for(const a of Object.keys(e).sort())t+=`${a}:${String(e[a])};`;return t}(e.defines),t+=e.lights?"lights":"",t+=e.fog?"fog":"";for(const a of Object.keys(e.uniforms).sort()){if(Da(a))continue;const s=e.uniforms[a]?.value;Ta(s)||(t+=`u:${a}:${za(s)};`)}return t}(e);else if(e instanceof n.MeshStandardMaterial&&!(e instanceof n.MeshPhysicalMaterial)||(t+=e.id+""),(e instanceof n.MeshBasicMaterial||e instanceof n.MeshLambertMaterial||e instanceof w||e instanceof y)&&(null!=e.map&&(t+="c"+e.map?.id),null!=e.aoMap&&(t+="o"+e.aoMap?.id),null!=e.lightMap&&(t+="l"+e.lightMap?.id),null!=e.envMap&&(t+="v"+e.envMap?.id),null!=e.alphaMap&&(t+="a"+e.alphaMap?.id)),e instanceof w&&(null!=e.normalMap&&(t+="n"+e.normalMap?.id),null!=e.roughnessMap&&(t+="r"+e.roughnessMap?.id),null!=e.metalnessMap&&(t+="m"+e.metalnessMap?.id),null!=e.emissiveMap&&(t+="e"+e.emissiveMap?.id)),e instanceof n.MeshPhysicalMaterial&&(null!=e.sheenColorMap&&(t+="sc"+e.sheenColorMap?.id),null!=e.sheenRoughnessMap&&(t+="sr"+e.sheenRoughnessMap?.id)),(e instanceof g||e instanceof y)&&null!=e.specularMap&&(t+="s"+e.specularMap?.id),e instanceof n.MeshToonMaterial&&(null!=e.map&&(t+="c"+e.map?.id),null!=e.aoMap&&(t+="o"+e.aoMap?.id),null!=e.lightMap&&(t+="l"+e.lightMap?.id),null!=e.alphaMap&&(t+="a"+e.alphaMap?.id)),e instanceof Ft&&null!=e.heightMap&&(t+="h"+e.heightMap?.id),e instanceof n.ShaderMaterial){t+=e.vertexShader,t+=e.fragmentShader;for(const a in e.uniforms){const s=e.uniforms[a];s&&s.value&&s.value.isTexture&&null!=s.value.id&&(t+="t:"+a+":"+s.value.id)}}null!=e.userData.outlineParameters&&(t+=e.userData.outlineParameters.color,t+=e.userData.outlineParameters.thickness);return t+=e.side,t+=e.transparent?"t":"",t+=e.vertexColors?"vc":"",t+=e.depthWrite?"dw":"",t+=e.depthTest?"dt":"",t+=e.alphaTest?"at":"",t}(e),xa.set(e,t)),t}function Da(e){return Ia.has(e)||e.startsWith("hology_")}function Ca(e,t){return e instanceof U?e.uniforms[t]?.value:e[t]}function Ta(e){return"number"==typeof e||e instanceof j||e instanceof I||e instanceof P||e instanceof l}function Oa(e){return"number"==typeof e?1:e instanceof j?2:4}function ka(e,t){const a=e.replace(/[^A-Za-z0-9_]/g,"_");let s=ja+a;for(;t.has(s);)s=ja+s;return t.add(s),s}function Va(e,t){const a={};for(const[s,r]of Object.entries(e.uniforms))t.has(s)||(a[s]={value:r.value});return a}const Ea=new WeakMap;let Fa=1;function za(e){if(null==e)return"null";if(e instanceof x||!0===e?.isTexture)return`texture:${e.id}`;if(e instanceof n.Matrix3||e instanceof n.Matrix4)return e.toArray().join(",");if("boolean"==typeof e||"number"==typeof e||"string"==typeof e)return String(e);if(Array.isArray(e)&&e.every(e=>null==e||["boolean","number","string"].includes(typeof e)))return JSON.stringify(e);if("object"==typeof e){let t=Ea.get(e);return null==t&&(t=Fa++,Ea.set(e,t)),`object:${t}`}return String(e)}function Na(e,t){if(null==e)return null;if(!(e instanceof t))throw new Error(`Value is not an instance of ${t.name}`);return e}const Ba=new f,$a=new c;function _a(e,t){return $a.copy(e),$a.x*=-1,$a.y*=-1,$a.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&($a.y*=-1,$a.z*=-1),(new n.Matrix3).setFromMatrix4(Ba.makeRotationFromEuler($a))}function Ua(e,t){switch(t){case 0:return e.x;case 1:return e.y;case 2:return e.z;case 3:return e.w}}const Ga=new P;function Wa(e,t){return e===t||null==e==(null==t)&&("number"==typeof e&&"number"==typeof t?e===t||isNaN(e)&&isNaN(t):e instanceof n.Color&&t instanceof n.Color?e.r===t.r&&e.g===t.g&&e.b===t.b:e instanceof j&&t instanceof j?e.x===t.x&&e.y===t.y:e instanceof I&&t instanceof I?e.x===t.x&&e.y===t.y&&e.z===t.z:e instanceof P&&t instanceof P&&(e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w))}function La(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof he?t.push(s):s instanceof be&&t.push(...La(s));return t}const Ra=new WeakMap;function qa(e,t){return Object.keys(e.attributes).filter(a=>function(e,t,a){if("position"===a)return!0;if(t instanceof U)return function(e,t){return Ya(e.vertexShader,t)}(t,a);if(t instanceof n.ShaderMaterial)return function(e,t){if("uv1"===t||"uv2"===t||"uv3"===t)return Ya(e.vertexShader,t);return!0}(t,a);if("uv1"===a)return!1;if("color"===a&&function(e){let t=Ra.get(e);if(null!=t)return t;const a=e.getAttribute("color");if(null==a)t=!1;else{t=!0;for(let e=0;e<a.count;e++){for(let s=0;s<3;s++)if(1!==a.getComponent(e,s)){t=!1;break}if(!t)break}}return Ra.set(e,t),t}(e))return!1;if("uv2"===a)return null!=t.lightMap||null!=t.aoMap;return!0}(e,t,a))}function Ya(e,t){return new RegExp(`(^|[^A-Za-z0-9_])${a=t,a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}([^A-Za-z0-9_]|$)`).test(e);var a}function Ja(e,t,a){if(t(e))return e;for(const s of e.children??[]){const e=Ja(s,t,a);if(null!=e)return e}if(null!=a&&"prefab"===e.type){const s=a.get(e.assetId);if(null!=s){const e=s.prefab.objects.find(e=>Ja(e,t,a));if(null!=e)return e}}return null}const Xa=new I,Za=new I,Ha=new I,Ka=new P,Qa=new P,es=new f,ts=new f,as=new b;function ss(e){e.updateWorldMatrix(!0,!1);const t=e.geometry.clone(),a=t.getAttribute("position"),s=t.getAttribute("normal"),r=t.getAttribute("tangent");if(null!=a){for(let t=0;t<a.count;t++)Xa.fromBufferAttribute(a,t),e.applyBoneTransform(t,Xa),a.setXYZ(t,Xa.x,Xa.y,Xa.z);a.needsUpdate=!0}if(null!=s||null!=r){const a=t.getAttribute("skinIndex"),n=t.getAttribute("skinWeight");if(null!=a&&null!=n){for(let t=0;t<a.count;t++)rs(e,t,ts),null!=s&&(Za.fromBufferAttribute(s,t),as.getNormalMatrix(ts),Za.applyMatrix3(as).normalize(),s.setXYZ(t,Za.x,Za.y,Za.z)),null!=r&&(Ha.fromBufferAttribute(r,t),Ha.transformDirection(ts),r.setXYZ(t,Ha.x,Ha.y,Ha.z));null!=s&&(s.needsUpdate=!0),null!=r&&(r.needsUpdate=!0)}}t.deleteAttribute("skinIndex"),t.deleteAttribute("skinWeight"),t.computeBoundingBox(),t.computeBoundingSphere();const n=new m(t,e.material);return n.copy(e,!1),n.geometry=t,n.material=e.material,n.userData={...e.userData},n}function rs(e,t,a){const s=e.geometry,r=s.getAttribute("skinIndex"),n=s.getAttribute("skinWeight"),i=e.skeleton;Ka.fromBufferAttribute(r,t),Qa.fromBufferAttribute(n,t),a.identity().multiplyScalar(0);for(let e=0;e<4;e++){const t=Qa.getComponent(e);if(0===t)continue;const s=Ka.getComponent(e);es.multiplyMatrices(i.bones[s].matrixWorld,i.boneInverses[s]);for(let e=0;e<16;e++)a.elements[e]+=es.elements[e]*t}return a.premultiply(e.bindMatrixInverse).multiply(e.bindMatrix),a}function ns(e){let t=!0;return e.traverse(a=>{a===e||a.isBone||(t=!1)}),t}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -245,6 +245,7 @@ export type Asset = {
245
245
  thickness: number;
246
246
  opacity: number;
247
247
  };
248
+ surfaceAssetId?: string;
248
249
  };
249
250
  /** Mesh settings only for asset type mesh */
250
251
  mesh?: {
@@ -0,0 +1,4 @@
1
+ import type { BaseSurfaceDefinition } from "../data/surface-definition";
2
+ import { Intersection } from "three";
3
+ export declare function findSurfaceDefinition(intersection: Intersection): BaseSurfaceDefinition | null;
4
+ //# sourceMappingURL=surface-query.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{Mesh as t,Vector3 as e}from"three";import{BatchedMesh2 as r}from"./batched-mesh-2";export function findSurfaceDefinition(e){const u=e.object;if(null==u||!(u instanceof t)||null==u.material)return;const o=Array.isArray(u.material)?u.material[e.face.materialIndex]:u.material;if(null==o)return null;if(u instanceof r){const t=u.surfaceByInstance?.[e.batchId];if(null!=t)return t}let l;return l=function(t,e,r){if(null==t.userData.surfaceByLayer||!e.hasAttribute("material"))return null;const u=function(t,e){const r=t.object,u=e.getAttribute("position"),o=e.index,l=t.faceIndex,f=o?o.getX(3*l+0):3*l+0,c=o?o.getX(3*l+1):3*l+1,s=o?o.getX(3*l+2):3*l+2;n.fromBufferAttribute(u,f).applyMatrix4(r.matrixWorld),a.fromBufferAttribute(u,c).applyMatrix4(r.matrixWorld),i.fromBufferAttribute(u,s).applyMatrix4(r.matrixWorld);const m=t.point,d=m.distanceToSquared(n),p=m.distanceToSquared(a),b=m.distanceToSquared(i),y=d<p?d<b?f:s:p<b?c:s,x=e.getAttribute("material"),g=e.getAttribute("material2"),A=4;let B=0;const h=.5;if(null!=x)for(let t=0;t<A;t++){x.getComponent(y,t)>h&&(B=t+1)}if(null!=g)for(let t=0;t<A;t++){g.getComponent(y,t)>h&&(B=t+5)}return B}(r,e);return t.userData.surfaceByLayer[u]}(o,u.geometry,e),null!=l?l:o.userData.surface}const n=new e,a=new e,i=new e;/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -10,6 +10,7 @@ export declare class LandscapeCompositeShader extends NodeShader {
10
10
  enableSlope: boolean;
11
11
  slopeMaterial: Material;
12
12
  slopeAngle: number;
13
+ build(): Material;
13
14
  output(): NodeShaderOutput;
14
15
  }
15
16
  //# sourceMappingURL=landscape-composite-shader.d.ts.map
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as s}from"tslib";import{Material as t,MathUtils as a,MeshBasicMaterial as o,MeshLambertMaterial as l,MeshStandardMaterial as i}from"three";import{cos as n,float as r,mix as p,rgb as h,standardMaterial as u,step as m,varyingAttributes as c,SimplexNoiseNode as d,varying as y,uniforms as M,vec4 as f,attributes as g,smoothstep as S,textureSampler2d as b,rgba as v,NodeShaderMaterial as A,varyingTransformed as w,colorToNormal as C}from"three-shader-graph";import{LayerMixMode as L,mixColorsByLayer as N}from"../../shader-nodes/layers.js";import{Parameter as j}from"../parameter.js";import{NodeShader as x}from"../shader.js";import{ParallaxStandardMaterial as R}from"./standard-shader.js";import{parallaxOcclusionMapping as T}from"../../shader-nodes/pom.js";import{applyUvTiling as O}from"./../../shader/uv-nodes.js";const P=y(M.modelMatrix.multiplyVec(f(g.position,1)).xz),k=new i({color:"gray"});export class LandscapeCompositeShader extends x{constructor(){super(...arguments),this.layers=[],this.transition=L.soft,this.noiseScale=1,this.noiseAmount=.2,this.softness=.3,this.enableSlope=!1,this.slopeAngle=35}output(){if(0===this.layers.length)return{color:u({color:h("gray")}),landscape:!0};for(let e=0;e<this.layers.length;e++){null==this.layers[e]&&(console.warn("One of the layers in the landscape composite shader is null or undefined. This layer will be rendered as gray. Please make sure to assign a material to all layers.",this.layers),this.layers[e]=k);this.layers[e]instanceof i||this.layers[e]instanceof l||this.layers[e]instanceof o||this.layers[e]instanceof A||(console.warn("One of the layers in the landscape composite shader is not a supported material. This layer will be rendered as gray. Please use a supported material.",this.layers[e]),this.layers[e]=k)}const e=new Map,s=new z,t=c.uv;function y(s,t){let a=t;if(s instanceof R&&null!=s.heightMap){let o=e.get(s);null==o&&(o=T(t,b(s.heightMap),r(s.heightScale??1)),e.set(s,o)),a=o}return a}const M=this.layers.map(e=>{if(e instanceof i||e instanceof l||e instanceof o){let s=v(e.color,1);return null!=e.map&&(s=s.multiply(b(e.map).sample(y(e,O(t,e.map))))),s}return e instanceof A&&null!=e.outputAlbedo?e.outputAlbedo.rgba(1):v("white")}),f=this.layers.map(e=>{if(e instanceof i||e instanceof l){if(null!=e.normalMap)return C(b(e.normalMap).sample(y(e,O(t,e.normalMap))),e.normalScale?.x??1)}else if(e instanceof A&&null!=e.outputNormal)return e.outputNormal;return w.normal}),g=this.layers.map(e=>{let a=r(1);return e instanceof i?(a=r(e.roughness??1),null!=e.roughnessMap&&(a=a.multiply(s.get(e.roughnessMap,y(e,O(t,e.roughnessMap))).g))):e instanceof A&&null!=e.outputRoughness&&(a=e.outputRoughness),a}),j=this.layers.map(e=>{let a=r(0);return e instanceof i?(a=r(e.metalness??0),null!=e.metalnessMap&&(a=a.multiply(s.get(e.metalnessMap,y(e,O(t,e.metalnessMap))).b))):e instanceof A&&null!=e.outputMetalness&&(a=e.outputMetalness),a});let x,B,H,V;if(this.enableSlope&&null!=this.slopeMaterial)if(this.slopeMaterial instanceof i){const e=y(this.slopeMaterial,t);x=v(this.slopeMaterial.color,1),null!=this.slopeMaterial.map&&(x=x.multiply(s.get(this.slopeMaterial.map,O(e,this.slopeMaterial.map)))),B=w.normal,null!=this.slopeMaterial.normalMap&&(B=C(s.get(this.slopeMaterial.normalMap,O(e,this.slopeMaterial.normalMap)),this.slopeMaterial.normalScale?.x??1)),H=r(this.slopeMaterial.roughness??1),null!=this.slopeMaterial.roughnessMap&&(H=H.multiply(s.get(this.slopeMaterial.roughnessMap,O(e,this.slopeMaterial.roughnessMap)).g)),V=r(this.slopeMaterial.metalness??0),null!=this.slopeMaterial.metalnessMap&&(V=V.multiply(s.get(this.slopeMaterial.metalnessMap,O(e,this.slopeMaterial.metalnessMap)).b))}else this.slopeMaterial instanceof A&&(x=this.slopeMaterial.outputAlbedo.rgba(1)??v("white"),B=this.slopeMaterial.outputNormal??w.normal,H=this.slopeMaterial.outputRoughness??r(1),V=this.slopeMaterial.outputMetalness??r(0));const q=(e,s)=>{const t=N({layerColors:e.slice(0,8),noiseScale:this.noiseScale,noiseAmount:this.noiseAmount,mode:this.transition,decay:this.softness}),o=r(this.noiseAmount).multiply(r(.1)),l=r(this.noiseScale),i=new d(P.multiplyScalar(l)).multiply(r(2)).subtract(r(1)).multiply(o),h=r(a.degToRad(this.slopeAngle)).add(i.multiply(r(.1)));let u=p(t,s,m(h,n(c.normal.y)));if(this.transition==L.soft){const e=h,a=r(this.softness).divide(r(2)),o=e.subtract(a),l=e.add(a);u=p(t,s,S(o,l,n(c.normal.y)))}return this.enableSlope&&null!=s?u:t},D=q(M,x),E=q(f,B),F=q(g,H),G=q(j,V);return{color:u({color:D,normal:E,roughness:F,metalness:G}),landscape:!0}}}e([j({type:t}),s("design:type",Array)],LandscapeCompositeShader.prototype,"layers",void 0),e([j({options:[{value:L.hard,name:"Hard"},{value:L.soft,name:"Soft"}]}),s("design:type",Number)],LandscapeCompositeShader.prototype,"transition",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"noiseScale",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"noiseAmount",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"softness",void 0),e([j(),s("design:type",Boolean)],LandscapeCompositeShader.prototype,"enableSlope",void 0),e([j(),s("design:type",t)],LandscapeCompositeShader.prototype,"slopeMaterial",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"slopeAngle",void 0);class z{constructor(){this.cache=new Map}get(e,s){return this.cache.has(e)||this.cache.set(e,b(e).sample(s)),this.cache.get(e)}}/*
1
+ import{__decorate as e,__metadata as s}from"tslib";import{Material as t,MathUtils as a,MeshBasicMaterial as o,MeshLambertMaterial as l,MeshStandardMaterial as i}from"three";import{cos as r,float as n,mix as p,rgb as h,standardMaterial as u,step as m,varyingAttributes as c,SimplexNoiseNode as d,varying as y,uniforms as f,vec4 as M,attributes as g,smoothstep as b,textureSampler2d as S,rgba as v,NodeShaderMaterial as A,varyingTransformed as w,colorToNormal as C}from"three-shader-graph";import{LayerMixMode as L,mixColorsByLayer as N}from"../../shader-nodes/layers.js";import{Parameter as j}from"../parameter.js";import{NodeShader as x}from"../shader.js";import{ParallaxStandardMaterial as R}from"./standard-shader.js";import{parallaxOcclusionMapping as T}from"../../shader-nodes/pom.js";import{applyUvTiling as B}from"./../../shader/uv-nodes.js";const D=y(f.modelMatrix.multiplyVec(M(g.position,1)).xz),O=new i({color:"gray"});export class LandscapeCompositeShader extends x{constructor(){super(...arguments),this.layers=[],this.transition=L.soft,this.noiseScale=1,this.noiseAmount=.2,this.softness=.3,this.enableSlope=!1,this.slopeAngle=35}build(){const e=super.build();return e.userData.surfaceByLayer=this.layers.map(e=>e?.userData.surface),e}output(){if(0===this.layers.length)return{color:u({color:h("gray")}),landscape:!0};for(let e=0;e<this.layers.length;e++){null==this.layers[e]&&(console.warn("One of the layers in the landscape composite shader is null or undefined. This layer will be rendered as gray. Please make sure to assign a material to all layers.",this.layers),this.layers[e]=O);this.layers[e]instanceof i||this.layers[e]instanceof l||this.layers[e]instanceof o||this.layers[e]instanceof A||(console.warn("One of the layers in the landscape composite shader is not a supported material. This layer will be rendered as gray. Please use a supported material.",this.layers[e]),this.layers[e]=O)}const e=new Map,s=new P,t=c.uv;function y(s,t){let a=t;if(s instanceof R&&null!=s.heightMap){let o=e.get(s);null==o&&(o=T(t,S(s.heightMap),n(s.heightScale??1)),e.set(s,o)),a=o}return a}const f=this.layers.map(e=>{if(e instanceof i||e instanceof l||e instanceof o){let s=v(e.color,1);return null!=e.map&&(s=s.multiply(S(e.map).sample(y(e,B(t,e.map))))),s}return e instanceof A&&null!=e.outputAlbedo?e.outputAlbedo.rgba(1):v("white")}),M=this.layers.map(e=>{if(e instanceof i||e instanceof l){if(null!=e.normalMap)return C(S(e.normalMap).sample(y(e,B(t,e.normalMap))),e.normalScale?.x??1)}else if(e instanceof A&&null!=e.outputNormal)return e.outputNormal;return w.normal}),g=this.layers.map(e=>{let a=n(1);return e instanceof i?(a=n(e.roughness??1),null!=e.roughnessMap&&(a=a.multiply(s.get(e.roughnessMap,y(e,B(t,e.roughnessMap))).g))):e instanceof A&&null!=e.outputRoughness&&(a=e.outputRoughness),a}),j=this.layers.map(e=>{let a=n(0);return e instanceof i?(a=n(e.metalness??0),null!=e.metalnessMap&&(a=a.multiply(s.get(e.metalnessMap,y(e,B(t,e.metalnessMap))).b))):e instanceof A&&null!=e.outputMetalness&&(a=e.outputMetalness),a});let x,k,z,H;if(this.enableSlope&&null!=this.slopeMaterial)if(this.slopeMaterial instanceof i){const e=y(this.slopeMaterial,t);x=v(this.slopeMaterial.color,1),null!=this.slopeMaterial.map&&(x=x.multiply(s.get(this.slopeMaterial.map,B(e,this.slopeMaterial.map)))),k=w.normal,null!=this.slopeMaterial.normalMap&&(k=C(s.get(this.slopeMaterial.normalMap,B(e,this.slopeMaterial.normalMap)),this.slopeMaterial.normalScale?.x??1)),z=n(this.slopeMaterial.roughness??1),null!=this.slopeMaterial.roughnessMap&&(z=z.multiply(s.get(this.slopeMaterial.roughnessMap,B(e,this.slopeMaterial.roughnessMap)).g)),H=n(this.slopeMaterial.metalness??0),null!=this.slopeMaterial.metalnessMap&&(H=H.multiply(s.get(this.slopeMaterial.metalnessMap,B(e,this.slopeMaterial.metalnessMap)).b))}else this.slopeMaterial instanceof A&&(x=this.slopeMaterial.outputAlbedo.rgba(1)??v("white"),k=this.slopeMaterial.outputNormal??w.normal,z=this.slopeMaterial.outputRoughness??n(1),H=this.slopeMaterial.outputMetalness??n(0));const V=(e,s)=>{const t=N({layerColors:e.slice(0,8),noiseScale:this.noiseScale,noiseAmount:this.noiseAmount,mode:this.transition,decay:this.softness}),o=n(this.noiseAmount).multiply(n(.1)),l=n(this.noiseScale),i=new d(D.multiplyScalar(l)).multiply(n(2)).subtract(n(1)).multiply(o),h=n(a.degToRad(this.slopeAngle)).add(i.multiply(n(.1)));let u=p(t,s,m(h,r(c.normal.y)));if(this.transition==L.soft){const e=h,a=n(this.softness).divide(n(2)),o=e.subtract(a),l=e.add(a);u=p(t,s,b(o,l,r(c.normal.y)))}return this.enableSlope&&null!=s?u:t},q=V(f,x),E=V(M,k),F=V(g,z),G=V(j,H);return{color:u({color:q,normal:E,roughness:F,metalness:G}),landscape:!0}}}e([j({type:t}),s("design:type",Array)],LandscapeCompositeShader.prototype,"layers",void 0),e([j({options:[{value:L.hard,name:"Hard"},{value:L.soft,name:"Soft"}]}),s("design:type",Number)],LandscapeCompositeShader.prototype,"transition",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"noiseScale",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"noiseAmount",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"softness",void 0),e([j(),s("design:type",Boolean)],LandscapeCompositeShader.prototype,"enableSlope",void 0),e([j(),s("design:type",t)],LandscapeCompositeShader.prototype,"slopeMaterial",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"slopeAngle",void 0);class P{constructor(){this.cache=new Map}get(e,s){return this.cache.has(e)||this.cache.set(e,S(e).sample(s)),this.cache.get(e)}}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */