@hology/core 0.0.211 → 0.0.212
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/effects/vfx/initializsers.d.ts +8 -1
- package/dist/effects/vfx/initializsers.js +1 -1
- package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
- package/dist/effects/vfx/vfx-defs.d.ts +10 -1
- package/dist/effects/vfx/vfx-defs.js +1 -1
- package/dist/effects/vfx/vfx-renderers.d.ts +1 -0
- package/dist/effects/vfx/vfx-renderers.js +1 -1
- package/dist/gameplay/actors/actor.d.ts +23 -1
- package/dist/gameplay/actors/actor.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +23 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-like.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-policy.d.ts +26 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-policy.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +145 -55
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +125 -0
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/old-character-movement.d.ts +100 -0
- package/dist/gameplay/actors/builtin/components/character/old-character-movement.js +4 -0
- package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
- package/dist/gameplay/actors/builtin/components/index.js +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/actors/component.js +1 -1
- package/dist/gameplay/actors/controller/actor-controller.d.ts +16 -0
- package/dist/gameplay/actors/controller/actor-controller.js +4 -0
- package/dist/gameplay/actors/factory.d.ts +3 -0
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.d.ts +4 -0
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/actors/internal/component-init.js +1 -1
- package/dist/gameplay/ai/behavior-tree/move.d.ts +2 -2
- package/dist/gameplay/index.d.ts +3 -1
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.d.ts +4 -0
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/net/browser/index.d.ts +147 -0
- package/dist/gameplay/net/browser/index.js +4 -0
- package/dist/gameplay/net/index.d.ts +7 -0
- package/dist/gameplay/net/index.js +4 -0
- package/dist/gameplay/net/net-connection.d.ts +25 -0
- package/dist/gameplay/net/net-connection.js +4 -0
- package/dist/gameplay/net/net-session.d.ts +70 -0
- package/dist/gameplay/net/net-session.js +4 -0
- package/dist/gameplay/net/service/net-actor-role.d.ts +12 -0
- package/dist/gameplay/net/service/net-actor-role.js +4 -0
- package/dist/gameplay/net/service/net-decorator.d.ts +29 -0
- package/dist/gameplay/net/service/net-decorator.js +4 -0
- package/dist/gameplay/net/service/net-serializer.d.ts +15 -0
- package/dist/gameplay/net/service/net-serializer.js +4 -0
- package/dist/gameplay/net/service/net-service.d.ts +171 -0
- package/dist/gameplay/net/service/net-service.js +4 -0
- package/dist/gameplay/net/service/net-utils.d.ts +8 -0
- package/dist/gameplay/net/service/net-utils.js +4 -0
- package/dist/gameplay/net/service/replication.d.ts +31 -0
- package/dist/gameplay/net/service/replication.js +4 -0
- package/dist/gameplay/net/service/rpc-decorator.d.ts +21 -0
- package/dist/gameplay/net/service/rpc-decorator.js +4 -0
- package/dist/gameplay/net/service/rpc.d.ts +35 -0
- package/dist/gameplay/net/service/rpc.js +4 -0
- package/dist/gameplay/services/asset-loader.d.ts +3 -2
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +2 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/world.d.ts +13 -2
- package/dist/gameplay/services/world.js +1 -1
- package/dist/rendering/color-pass.js +1 -1
- package/dist/rendering.d.ts +2 -0
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/batched-mesh-2.d.ts +9 -0
- package/dist/scene/batched-mesh-2.js +1 -1
- package/dist/scene/bootstrap.d.ts +2 -0
- package/dist/scene/bootstrap.js +1 -1
- package/dist/scene/materializer.d.ts +4 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/storage/storage.d.ts +1 -1
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/toon-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/color-layer.js +1 -1
- package/dist/shader/parameter.d.ts +1 -1
- package/dist/shader/parameter.js +1 -1
- package/dist/shader-nodes/depth.js +1 -1
- package/dist/shader-nodes/scene-sample.js +1 -1
- package/dist/test/batched-mesh-2.test.d.ts +2 -0
- package/dist/test/batched-mesh-2.test.js +4 -0
- package/dist/test/browser-net-session.test.d.ts +2 -0
- package/dist/test/browser-net-session.test.js +4 -0
- package/dist/test/first-person-camera-component.test.js +1 -1
- package/dist/test/net-character-movement.test.d.ts +2 -0
- package/dist/test/net-character-movement.test.js +4 -0
- package/dist/test/net-property-snapshot.test.d.ts +2 -0
- package/dist/test/net-property-snapshot.test.js +4 -0
- package/dist/test/sequence-animation-retiming.test.js +1 -1
- package/dist/test/vfx-random-color-initializer.test.d.ts +2 -0
- package/dist/test/vfx-random-color-initializer.test.js +4 -0
- package/dist/test/world-prefab-spawn.test.d.ts +2 -0
- package/dist/test/world-prefab-spawn.test.js +4 -0
- package/dist/utils/three/placeholder-texture.d.ts +3 -0
- package/dist/utils/three/placeholder-texture.js +4 -0
- package/package.json +9 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -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 O,batchingUniformVec3 as T,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 Oe}from"../shader/builtin/landscape-shader.js";import{StandardShader as Te}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{PaintedScatterManager as ut}from"./scatter/painted-scatter-manager.js";import{SurfaceScatterManager as pt}from"./scatter/surface-scatter-manager.js";import{createWaterMaterial as dt}from"./materials/water.js";import{SerializedParamType as ht}from"./model.js";import{applyRuntimeParamTypeInference as ft,convertConfiguredParamsToRuntimeTypes as mt,convertConfiguredParamValueToRuntimeType as gt,inferRuntimeSerializedParamTypeHint as yt}from"./custom-param-runtime-types.js";import{ShapeLibrary as wt,ShapeLibraryKeys as bt}from"./objects/shapes.js";import{ambientLightName as vt,createSky as Mt,defaultSkyMaterial as St}from"./sky.js";import{Curve2 as At}from"../utils/curve.js";import{DecalUnlitShader as xt}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as jt}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as It,defaultValueColorLayer as Pt,defaultValueMaskLayer as Ct,MaskLayer as Dt}from"../shader/color-layer.js";import{LayeredShader as Ot}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as Tt}from"../shader/color-layer";import{FogVolume as kt}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as Vt}from"../utils/three/unscaled-sprite.js";import{ToonShader as Et}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as Ft}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as zt}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as Nt}from"../shader-nodes/pom.js";import{traverseVisibleEvery as Bt}from"../utils/three/traverse";import{RectAreaLightHelper as $t}from"three/examples/jsm/Addons.js";import{Sequence as _t}from"../effects/sequence/sequence-data.js";import{applyUvTiling as Ut}from"./../shader/uv-nodes.js";import{buildShaderGraphMaterial as Gt,shaderGraphMaterialSideToThree as Wt}from"../shader/graph/index.js";export{ft as applyRuntimeParamTypeInference,mt as convertConfiguredParamsToRuntimeTypes,gt as convertConfiguredParamValueToRuntimeType,yt as inferRuntimeSerializedParamTypeHint};const Lt={},Rt=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),qt=/^((?!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 Yt(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}let Yt=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.handlePaintedScatterSceneMutation(e),this.handleSurfaceScatterSceneMutation(e)}),t.onUpdate(e=>{this.update(e),this.handlePaintedScatterSceneMutation(e),this.handleSurfaceScatterSceneMutation(e)}),t.onRemove(e=>{this.remove(e),this.handlePaintedScatterSceneMutation(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=>Xa(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),this.paintedScatterManager?.usesScatterAsset(t.id)&&this.paintedScatterManager.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),(this.paintedScatterManager?.usesPrefabAsset(t.id)||this.sceneReferencesPrefabAsset(t.id)&&await this.prefabAssetContainsPaintedScatter(t))&&await this.refreshPaintedScatterPresence(!0);else if("vfx"===t.type)for(const e of this.dataProvider.getObjects())await na(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 na(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===ht.Material&&s.value===a.id){t=!0;break}if(s.type===ht.Array&&"element"in s&&s.element===ht.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?Ma(e.material[s],n)||(e.material[s]=n):Ma(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===ht.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(),Xt.clear(),Zt.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.refreshPaintedScatterPresence(!0),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=Ra(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,oa(s.prefab.params)),null!=s.prefab.innerParams){const e=r.slice(t+1);for(const t of s.prefab.innerParams){const a=oa(t.params);0!==Object.keys(a).length&&(i?c.push({path:la(t.path,e)?t.path.slice(e.length):t.path,params:a}):la(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=!qt,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(),Xt.clear(),Zt.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 na(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===ht.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)&&Bt(e,e=>!(e instanceof m)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},u.set(n.assetId,s)}}const o=pa(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=Ca(i);e+=Aa(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=wa(s.material);null!=e[0].color&&null!=r.color&&(r.color=new l(16777215));const i=s.geometry;let o,u;!(qt||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.refreshPaintedScatterPresence(!0),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!qt&&(!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||La(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=Ga(a.node,a.params.length-1)}else if(a instanceof P)t=k(s);else if(a instanceof I||a instanceof l)t=T(s);else if(a instanceof j)t=O(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 zt&&null!=g.heightMap&&(r=Nt(r,J(g.heightMap),N(g.heightScale)));let i=Ba(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=Ba(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(Ba(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=Ba(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(Ut(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(Ba(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=Ba(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(Ut(r,g.emissiveMap));c=c.multiply(e)}const m=Ba(p.get("emissiveIntensity"),B)??N(g.emissiveIntensity??1),y=Ba(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=Ba(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(Ut(r,g.normalMap));w=z(e.rgb,y.x)}let b=Ba(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=Ba(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(Ut(r,g.roughnessMap));b=b.multiply(e.g)}let v=Ba(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=Ba(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(Ut(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=Ba(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(Ut(r,g.aoMap));M=M.multiply(e.r)}const S=Ba(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:Ua(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||La(r,n)?s.set(t,r):Ta(r)&&Ta(n)&&ka(r)===ka(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=Va("vp"+h.length,n);s={name:t,params:[e],node:k(t)},h.push(s)}else s.params.push(e);a=s.name,t=Ga(s.node,s.params.length-1)}else if(s instanceof P)a=Va(e,n),t=k(a);else if(s instanceof I||s instanceof l)a=Va(e,n),t=T(a);else{if(!(s instanceof j))continue;a=Va(e,n),t=O(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:Ea(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 Ft(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(xa(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=Wa.set(0,0,0,0);for(let a=0;a<e.params.length;a++){const s=Oa(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=Oa(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,pa(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(!ma(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=ya(a,i)),null!=a&&s.id!==a.id&&(r=r??fa(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 Xt.entries())t.userData.customShaderName&&Xt.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);pa(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 $t&&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=ra(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 kt){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)Jt(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;Jt(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(Sa(ct(e,0,!1)),a>0){Sa(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);Sa(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);Sa(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=rs(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&&is(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=ra(e.fog),this.fixFogColor(),n=new d;break;case"sky":this.sky=Mt(),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":case"scatter":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||sa(n),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,n;console.warn("RenderingView not found in materializer")}}async handlePaintedScatterSceneMutation(e){const t=this.paintedScatterManager?.referencesSceneObject(e.id)??!1,a=await this.sceneObjectContainsPaintedScatter(e);(t||a)&&await this.refreshPaintedScatterPresence(!1)}async refreshPaintedScatterPresence(e=!1){return await this.sceneContainsPaintedScatter()?(null==this.paintedScatterManager&&(this.paintedScatterManager=new ut(this.scene,this.dataProvider,this.renderingView,this.assetManagerService,this.assetsService)),this.paintedScatterManager.queueRefresh(e),!0):(this.disposePaintedScatterManager(),!1)}disposePaintedScatterManager(){null!=this.paintedScatterManager&&(this.paintedScatterManager.clear(),this.paintedScatterManager.stop(),this.paintedScatterManager=void 0)}async sceneContainsPaintedScatter(){return this.sceneObjectsContainPaintedScatter(this.dataProvider.getObjects())}async sceneObjectsContainPaintedScatter(e,t=[]){for(const a of e??[])if(await this.sceneObjectContainsPaintedScatter(a,t))return!0;return!1}async sceneObjectContainsPaintedScatter(e,t=[]){if("scatter"===e.type&&(e.paintedScatter?.cells?.some(e=>(e.instances?.length??0)>0)||(e.paintedScatter?.palette?.length??0)>0))return!0;if(null!=e.children&&await this.sceneObjectsContainPaintedScatter(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.sceneObjectsContainPaintedScatter(s,[...t,e.assetId])}return!1}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 pt(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])}async prefabAssetContainsPaintedScatter(e){return"prefab"===e.type&&null!=e.prefab?.objects&&this.sceneObjectsContainPaintedScatter(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!==St?(this.sky.material=St,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 Lt[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&&bt.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=wt[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,wt[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(pa(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,Jt(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 Vt(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 Vt(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 Vt(a);s.scale.multiplyScalar(.6),t.add(s);const r=new $t(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===vt);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.disposePaintedScatterManager(),this.disposeSurfaceScatterManager(),this.materializedActors.forEach(e=>e.disposed.next(!0)),this.materializedActors.clear()}};Yt=e([pe(),t("design:paramtypes",[A,Object,Qe,Ke,Ae,Array,Array,Object,Array])],Yt);export{Yt as SceneMaterializer};function Jt(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const Xt=new Map,Zt=new Map,Ht=new g({color:16711935}),Kt=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),Ht;const i=JSON.stringify(e.material)+t?._id,o=n&&!("shaderGraph"===e.material.type&&"asset"===e.material.shaderGraph?.source);if(o&&Xt.has(i))return Xt.get(i);if(o&&Zt.has(i))return await Zt.get(i);const l=_materialFromAsset(i,e,t,a,s,r,o);return o?Zt.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=dt(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=Ht;break}"surface"===e.target&&null!=e.materialOptions?.side&&(h=Wt(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=Gt(e,{parameters:s,previewNodeId:n,trailBillboard:l,alphaTest:t.material.alphaTest}),d.userData.customShaderName="asset"===t.material.shaderGraph?.source?`shaderGraph:${t.material.shaderGraph.assetId}`:`shaderGraph:${t.id}`}catch(e){console.warn("Shader graph runtime error: "+e,e),d=Ht}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:Rt?Ce:Te,lambert:Ce,unlit:ke,toon:Et,layered:Ot,landscape:Oe,"landscape-composite":De,"decal-unlit":xt,"decal-standard":jt,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),Kt.has(t.material.shader)||Kt.set(t.material.shader,Ht.clone()),d=Kt.get(t.material.shader)}d.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),d=Ht;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&&Xt.set(e,d),c&&Zt.delete(e),d}export function prepareCustomParamsFromShaderGraph(e,t={}){return Object.fromEntries((e.parameters??[]).map(e=>{const a=function(e){switch(e){case"float":return ht.FloatNode;case"boolean":return ht.BooleanNode;case"texture":return ht.Sampler2DNode;case"vec2":return ht.Vec2Node;case"vec3":return ht.Vec3Node;case"vec4":return ht.Vec4Node;case"color":return ht.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?ua(n):s?.value??ua(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 ea(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}=mt(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 ${ht[e.sourceType]} to ${ht[e.targetType]}`);for(const[e,t]of Object.entries(p)){if(!1===t.override)continue;const c=await ea(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 ea(r,n,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const Qt=new Map;async function ea(e,t,a,s,r,n,i,o,u=t.value,p=t.type,d,h=(t.type===ht.Struct?t.struct:void 0)){if(null==t||null==u||""===u)return null;switch(p){case ht.Array:if(Array.isArray(u)&&"element"in t)return await Promise.all(u.map(l=>ea(e,t,a,s,r,n,i,o,l,t.element,d,t.elementStruct)));break;case ht.Number:case ht.FloatNode:let f;if("string"==typeof u?f=parseFloat(u):"number"==typeof u&&(f=u),p===ht.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=Qt.get(e);return null==t&&(t=xe(At.decode(e)),Qt.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 ht.Texture:let m=await s.getTexture(await a.getAsset(u));return"envmap"===e.toLowerCase()&&null!=n&&(m=n.getEnvTexture(m)),m;case ht.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 ht.Boolean:return u;case ht.BooleanNode:return new Z(Ue(e),u,void 0,!1);case ht.Vector2:case ht.Vec2Node:if("object"==typeof u){const t=u instanceof Array?(new j).fromArray(u):new j(u.x,u.y);return p===ht.Vec2Node?new Q(Ue(e),t,void 0,!1):t}return null;case ht.Vector3:case ht.Vec3Node:if("object"==typeof u){const t=u instanceof Array?(new I).fromArray(u):new I(u.x,u.y,u.z);return p===ht.Vec3Node?new ee(Ue(e),t,void 0,!1):t}return null;case ht.Vector4:case ht.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===ht.Vec4Node?new te(Ue(e),t,void 0,!1):t}return null;case ht.Color:case ht.RgbNode:const w=new l(u);return p===ht.RgbNode?new ee(Ue(e),new I(w.r,w.g,w.b),void 0,!1).rgb:w;case ht.String:return u;case ht.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 ht.Euler:const v=u;return(new c).fromArray(v);case ht.Object3D:{const e=await a.getAsset(u);return(await s.getMesh(e,{applyMaterials:!0,rescale:!0})).scene}case ht.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 ht.AudioBuffer:return await s.getAudio(await a.getAsset(u));case ht.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 ht.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 ht.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 ht.DataAsset:return materializeDataAssetRef(u,a,s,r,n,i,o,d);case ht.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 ht.Struct:return async function(e,t,a,s,r,n,i,o,l){const c=ta(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=ta(e);if(null!=t)return t.value;if(aa(e))return e;if(null!=e&&"object"==typeof e&&aa(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 ht.Curve:return At.decode(u);case ht.ColorLayer:case ht.MaskLayer:if(Tt(u)){const e=await It.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 ht.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 ta(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"string"==typeof e.struct&&aa(e.value)?e:null}function aa(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&Object.values(e).every(e=>null!=e&&"object"==typeof e&&"type"in e)}function sa(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 ra(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 na(e,t,a,s){null==s&&(s=(new f).identity());const r=s.clone().multiply(ia(e,new n.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await na(e.children[a],t,e,r);await t(e,a,s)}function ia(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?ht.Number:t instanceof B||"function"==typeof e.prototype.isFloat?ht.FloatNode:t instanceof x||e===x||e.isTexture?ht.Texture:t instanceof Pe||e===Pe||e===Y||"function"==typeof e.prototype?.isSampler2D||!0===e.prototype?.isSampler2D?ht.Sampler2DNode:t instanceof Boolean||e===Boolean?ht.Boolean:t instanceof F?ht.BooleanNode:t instanceof l||e==l?ht.Color:t instanceof L||"function"==typeof e.prototype.isRgb?ht.RgbNode:t instanceof j||e==j?ht.Vector2:t instanceof ie||"function"==typeof e.prototype.isVec2?ht.Vec2Node:t instanceof I||e==I?ht.Vector3:t instanceof le||"function"==typeof e.prototype.isVec3?ht.Vec3Node:t instanceof P||e==P?ht.Vector4:t instanceof ue||"function"==typeof e.prototype.isVec4?ht.Vec4Node:t instanceof String||e===String?ht.String:t instanceof ye||e==ye||e.prototype instanceof ye||e.prototype==ye?ht.BaseActor:t instanceof c||e==c?ht.Euler:t instanceof v||e==v?ht.Object3D:t instanceof h||e==h?ht.Material:t instanceof AudioBuffer||e==AudioBuffer?ht.AudioBuffer:t instanceof he||e==he?ht.VisualEffect:t instanceof fe||e==fe?ht.Prefab:t instanceof me||e==me?ht.PrefabActor:t instanceof ge||e==ge?ht.DataAsset:t instanceof At||e==At?ht.Curve:t instanceof It||e==It?ht.ColorLayer:t instanceof Dt||e==Dt?ht.MaskLayer:t instanceof n.AnimationClip||e==n.AnimationClip?ht.AnimationClip:t instanceof _t||e==_t||"SequenceData"===e.name||e.prototype&&"tracks"in e.prototype?ht.Sequence:null!=Fe(e)?ht.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===ht.Struct?Fe(e.type):void 0;return!0===e.options.array?{type:ht.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!==ht.Struct)return{typeInfo:e,value:t};const a=ta(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===ht.Struct)return Be(e.type)?{}:prepareCustomParamsFromType(e.type,{});return customParameterDefaultValueByType.get(a)}(e,a));n=function(e,t,a){if(e.type!==ht.Struct||a?.type!==ht.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?ua(t):[];return ua(t)}(e,p.value,u):ua(p.value);return[e.name,{...n,value:d,override:c}]}))}function oa(e){return null==e?{}:Object.fromEntries(Object.entries(e).filter(([,e])=>function(e){return!0===e?.override}(e)))}function la(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=ca(e,t);void 0!==a&&(i[e.name]=a)}}return prepareCustomParams(r,t,i,s)}function ca(e,t){return!0===e.options.array?Array.isArray(t)?t.map(t=>serializeCustomParameter(e.type,t)??t):[]:serializeCustomParameter(e.type,t)}function ua(e){return null==e?e:Array.isArray(e)?e.map(e=>ua(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=ta(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(aa(t))return t;if(null!=t&&"object"==typeof t&&aa(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=ca(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 pa(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=>da(e.materialId)),(t??[]).filter(e=>da(e.materialId)),e=>e.color+e.name)}function da(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[ht.RgbNode,"#000000"],[ht.Color,"#000000"],[ht.String,""],[ht.Vector4,[0,0,0,0]],[ht.Vec4Node,[0,0,0,0]],[ht.Vector3,[0,0,0]],[ht.Vec3Node,[0,0,0]],[ht.Vector2,[0,0]],[ht.Vec2Node,[0,0]],[ht.Euler,[0,0,0,"XYZ"]],[ht.Array,[]],[ht.DataAsset,null],[ht.ColorLayer,Pt],[ht.MaskLayer,Ct]]);let ha=new l;new l;function fa(e){return null==e?.color?null:(ha.set(e.color),"#"+ha.getHexString())}function ma(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=fa(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=fa(i),c=i.name;if(ma(i,t,e.userData["originalColor_"+n],e.userData["originalMaterialName_"+n])){const i=ya(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=fa(n),o=n.name;if(ma(n,t,e.userData.originalColor,e.userData.originalMaterialName)){const n=ya(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 ga=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 ya(e,t){if(null==e||null==t||!function(e,t){return function(e){const t=[];for(const[a,s]of Object.entries(e))ba(a,s)&&t.push(s);if(e instanceof n.ShaderMaterial)for(const[a,s]of Object.entries(e.uniforms))ba(a,s.value)&&t.push(s.value);return t}(e).some(e=>e.flipY!==t)}(e,t))return e;let a=ga.get(e);null==a&&(a=new Map,ga.set(e,a));const s=a.get(t);if(null!=s)return s;const r=wa(e);if(function(e,t){for(const a of Object.keys(e)){const s=e[a];ba(a,s)&&(e[a]=va(s,t))}}(r,t),r instanceof n.ShaderMaterial){for(const[e,a]of Object.entries(r.uniforms))ba(e,a.value)&&(a.value=va(a.value,t));r.uniformsNeedUpdate=!0}return r.needsUpdate=!0,a.set(t,r),r}function wa(e){const t=e.clone();return t.userData={...e.userData??{}},t}function ba(e,t){const a=t;return(t instanceof x||!0===a?.isTexture)&&!e.toLowerCase().includes("envmap")&&!0!==a.isCompressedTexture&&!0!==a.isCompressedArrayTexture}function va(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 Ma(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 Sa(e){if(null!=e){for(let t=0;t<e.array.length;t++)e.setX(t,0);e.needsUpdate=!0}}function Aa(e,t){const a=Je(e);return null==a?"":function(e,t){const a=Ya(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 xa(e,t){const a=Ya(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 ja=new WeakMap,Ia="hbat_",Pa=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 Ca(e){let t=ja.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}:${Na(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 zt&&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),ja.set(e,t)),t}function Da(e){return Pa.has(e)||e.startsWith("hology_")}function Oa(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 ka(e){return"number"==typeof e?1:e instanceof j?2:4}function Va(e,t){const a=e.replace(/[^A-Za-z0-9_]/g,"_");let s=Ia+a;for(;t.has(s);)s=Ia+s;return t.add(s),s}function Ea(e,t){const a={};for(const[s,r]of Object.entries(e.uniforms))t.has(s)||(a[s]={value:r.value});return a}const Fa=new WeakMap;let za=1;function Na(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=Fa.get(e);return null==t&&(t=za++,Fa.set(e,t)),`object:${t}`}return String(e)}function Ba(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 $a=new f,_a=new c;function Ua(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($a.makeRotationFromEuler(_a))}function Ga(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 Wa=new P;function La(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 Ra(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof he?t.push(s):s instanceof be&&t.push(...Ra(s));return t}const qa=new WeakMap;function Ya(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 Ja(e.vertexShader,t)}(t,a);if(t instanceof n.ShaderMaterial)return function(e,t){if("uv1"===t||"uv2"===t||"uv3"===t)return Ja(e.vertexShader,t);return!0}(t,a);if("uv1"===a)return!1;if("color"===a&&function(e){let t=qa.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 qa.set(e,t),t}(e))return!1;if("uv2"===a)return null!=t.lightMap||null!=t.aoMap;return!0}(e,t,a))}function Ja(e,t){return new RegExp(`(^|[^A-Za-z0-9_])${a=t,a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}([^A-Za-z0-9_]|$)`).test(e);var a}function Xa(e,t,a){if(t(e))return e;for(const s of e.children??[]){const e=Xa(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=>Xa(e,t,a));if(null!=e)return e}}return null}const Za=new I,Ha=new I,Ka=new I,Qa=new P,es=new P,ts=new f,as=new f,ss=new b;function rs(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++)Za.fromBufferAttribute(a,t),e.applyBoneTransform(t,Za),a.setXYZ(t,Za.x,Za.y,Za.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++)ns(e,t,as),null!=s&&(Ha.fromBufferAttribute(s,t),ss.getNormalMatrix(as),Ha.applyMatrix3(ss).normalize(),s.setXYZ(t,Ha.x,Ha.y,Ha.z)),null!=r&&(Ka.fromBufferAttribute(r,t),Ka.transformDirection(as),r.setXYZ(t,Ka.x,Ka.y,Ka.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 ns(e,t,a){const s=e.geometry,r=s.getAttribute("skinIndex"),n=s.getAttribute("skinWeight"),i=e.skeleton;Qa.fromBufferAttribute(r,t),es.fromBufferAttribute(n,t),a.identity().multiplyScalar(0);for(let e=0;e<4;e++){const t=es.getComponent(e);if(0===t)continue;const s=Qa.getComponent(e);ts.multiplyMatrices(i.bones[s].matrixWorld,i.boneInverses[s]);for(let e=0;e<16;e++)a.elements[e]+=ts.elements[e]*t}return a.premultiply(e.bindMatrixInverse).multiply(e.bindMatrix),a}function is(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 C,batchingUniformFloat as D,batchingUniformVec2 as O,batchingUniformVec3 as T,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 R,select as L,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{$actorOptions as ye,BaseActor as we}from"../gameplay/actors/actor.js";import be from"../gameplay/actors/builtin/index.js";import{ActorComponent as ve}from"../gameplay/actors/component.js";import{PhysicsBodyType as Me}from"../gameplay/services/physics/physics-system.js";import{NetMode as Se}from"../gameplay/net/net-session.js";import{NetRole as Ae}from"../gameplay/net/service/net-actor-role.js";import{ThreeBlendingMode as xe}from"../effects/vfx/vfx-asset.js";import{withInjectionContext as je}from"../gameplay/inject.js";import{RenderingView as Ie}from"../rendering.js";import{curveSampler as Pe,oneMinus as Ce,particleUniforms as De,Sampler2DNode as Oe}from"../shader-nodes/index.js";import{LambertShader as Te}from"../shader/builtin/lambert-shader.js";import{LandscapeCompositeShader as ke}from"../shader/builtin/landscape-composite-shader";import{LandscapeShader as Ve}from"../shader/builtin/landscape-shader.js";import{StandardShader as Ee}from"../shader/builtin/standard-shader.js";import{UnlitShader as Fe}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as ze,getDataAssetDefinitionType as Ne,getParameterDefinitionId as Be,getParameterDefinitionType as $e,isDataAssetDefinitionAbstract as _e,isParameterDefinitionAbstract as Ue,isParameterDefinitionAssignableTo as Ge,isParameterDefinitionStructAssignableTo as We,shaderParameterUniformName as Re}from"../shader/parameter.js";import{ArrayMap as Le,DefaultMap as qe,groupBy as Ye}from"../utils/collections.js";import{iterateMaterials as Je}from"../utils/materials.js";import{filterChildrenShallow as Xe,filterSceneShallow as Ze,findFirstVisibleMesh as He,findFirstVisibleObject as Ke,traverseAsync as Qe}from"../utils/three/traverse.js";import{AssetMeshInstance as et,AssetResourceLoader as tt}from"./asset-resource-loader.js";import{AssetsProvider as at}from"./assets-provider.js";import{isCollisionMesh as st}from"./collision/collision-shape-import.js";import{BoxCollisionShape as rt,PhysicalShapeMesh as nt}from"./collision/collision-shape.js";import{LandscapeManager as it}from"./landscape/landscape-manager.js";import{initLandscape as ot}from"./landscape/landscape.js";import{SectionGrid as lt,smoothNormalsCrossMeshes as ct}from"./landscape/utils.js";import{createGrassFoliageMaterial as ut}from"./materials/grass-foliage.js";import{createGrassMaterial as pt}from"./materials/grass.js";import{getMaterialAttribute as dt}from"./materials/utils/material-painting.js";import{PaintedScatterManager as ht}from"./scatter/painted-scatter-manager.js";import{SurfaceScatterManager as ft}from"./scatter/surface-scatter-manager.js";import{createWaterMaterial as mt}from"./materials/water.js";import{SerializedParamType as gt}from"./model.js";import{applyRuntimeParamTypeInference as yt,convertConfiguredParamsToRuntimeTypes as wt,convertConfiguredParamValueToRuntimeType as bt,inferRuntimeSerializedParamTypeHint as vt}from"./custom-param-runtime-types.js";import{ShapeLibrary as Mt,ShapeLibraryKeys as St}from"./objects/shapes.js";import{ambientLightName as At,createSky as xt,defaultSkyMaterial as jt}from"./sky.js";import{Curve2 as It}from"../utils/curve.js";import{DecalUnlitShader as Pt}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as Ct}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as Dt,defaultValueColorLayer as Ot,defaultValueMaskLayer as Tt,MaskLayer as kt}from"../shader/color-layer.js";import{LayeredShader as Vt}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as Et}from"../shader/color-layer";import{FogVolume as Ft}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as zt}from"../utils/three/unscaled-sprite.js";import{ToonShader as Nt}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as Bt}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as $t}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as _t}from"../shader-nodes/pom.js";import{traverseVisibleEvery as Ut}from"../utils/three/traverse";import{RectAreaLightHelper as Gt}from"three/examples/jsm/Addons.js";import{Sequence as Wt}from"../effects/sequence/sequence-data.js";import{applyUvTiling as Rt}from"./../shader/uv-nodes.js";import{buildShaderGraphMaterial as Lt,shaderGraphMaterialSideToThree as qt}from"../shader/graph/index.js";export{yt as applyRuntimeParamTypeInference,wt as convertConfiguredParamsToRuntimeTypes,bt as convertConfiguredParamValueToRuntimeType,vt as inferRuntimeSerializedParamTypeHint};const Yt={},Jt=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),Xt=/^((?!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 Zt(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}let Zt=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.netMode=Se.none,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.handlePaintedScatterSceneMutation(e),this.handleSurfaceScatterSceneMutation(e)}),t.onUpdate(e=>{this.update(e),this.handlePaintedScatterSceneMutation(e),this.handleSurfaceScatterSceneMutation(e)}),t.onRemove(e=>{this.remove(e),this.handlePaintedScatterSceneMutation(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=>Ka(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),this.paintedScatterManager?.usesScatterAsset(t.id)&&this.paintedScatterManager.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),(this.paintedScatterManager?.usesPrefabAsset(t.id)||this.sceneReferencesPrefabAsset(t.id)&&await this.prefabAssetContainsPaintedScatter(t))&&await this.refreshPaintedScatterPresence(!0);else if("vfx"===t.type)for(const e of this.dataProvider.getObjects())await la(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 la(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===gt.Material&&s.value===a.id){t=!0;break}if(s.type===gt.Array&&"element"in s&&s.element===gt.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?xa(e.material[s],n)||(e.material[s]=n):xa(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===gt.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(),Kt.clear(),Qt.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.refreshPaintedScatterPresence(!0),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=Ja(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,ua(s.prefab.params)),null!=s.prefab.innerParams){const e=r.slice(t+1);for(const t of s.prefab.innerParams){const a=ua(t.params);0!==Object.keys(a).length&&(i?c.push({path:pa(t.path,e)?t.path.slice(e.length):t.path,params:a}):pa(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!==Me.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=>{!st(e)&&e.isMesh&&s.push(e)});const r=1==s.length&&0==s[0].children.length,n=!Xt,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(),Kt.clear(),Qt.clear();const e=[],t=new Le,a=new Le,s=new Le;let r=0,i=0,o=0;const u=new Map,p=new qe(()=>new Map);for(const n of this.dataProvider.getObjects())await la(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!==Me.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===gt.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!=He(e)&&Ut(e,e=>!(e instanceof m)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},u.set(n.assetId,s)}}const o=fa(n.materialAssignments,e.materialAssignments);if(s.useBatchedMesh)await Qe(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=Ta(i);e+=Ia(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 instanceof Bt&&e.perInstanceCastShadow||(e.castShadow=us(t,a?.castShadow??!1)),e.receiveShadow=ps(t,a?.receiveShadow??!1);const s=new et;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=us(e,s?.castShadow??!1),t.receiveShadow=ps(e,s?.receiveShadow??!1);const r=new et;r.add(t),r.userData.src=e[0],a instanceof et&&(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=Ke(a,e=>!st(e)&&null!=e.geometry),r=Ma(s.material);null!=e[0].color&&null!=r.color&&(r.color=new l(16777215));const i=s.geometry;let o,u;!(Xt||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??!1;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 et;r.userData.src=e[0],a instanceof nt&&(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.refreshPaintedScatterPresence(!0),await this.refreshSurfaceScatterPresence(!0)}prepareCollisionShapesForInstanced(e){e instanceof et&&e.collisionShapes.forEach(e=>{e instanceof a&&e.mesh instanceof m&&(e.mesh=e.mesh.geometry)})}setScene(e){this.scene=e}testCanBatch(e,t){return!Xt&&(!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 Le;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=Ke(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||Ya(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=La(a.node,a.params.length-1)}else if(a instanceof P)t=k(s);else if(a instanceof I||a instanceof l)t=T(s);else if(a instanceof j)t=O(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 $t&&null!=g.heightMap&&(r=_t(r,J(g.heightMap),N(g.heightScale)));let i=Ua(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=Ua(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(Ua(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=Ua(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(Rt(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(Ua(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=Ua(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(Rt(r,g.emissiveMap));c=c.multiply(e)}const m=Ua(p.get("emissiveIntensity"),B)??N(g.emissiveIntensity??1),y=Ua(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=Ua(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(Rt(r,g.normalMap));w=z(e.rgb,y.x)}let b=Ua(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=Ua(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(Rt(r,g.roughnessMap));b=b.multiply(e.g)}let v=Ua(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=Ua(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(Rt(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=Ua(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(Rt(r,g.aoMap));M=M.multiply(e.r)}const S=Ua(p.get("aoMapIntensity"),B)??N(g.aoMapIntensity??0);let A=w;!0!==g.userData.disableAO&&(A=$("DOUBLE_SIDED",A,e=>L(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:Ra(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=>!ka(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||Ya(r,n)?s.set(t,r):Ea(r)&&Ea(n)&&Fa(r)===Fa(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=za("vp"+h.length,n);s={name:t,params:[e],node:k(t)},h.push(s)}else s.params.push(e);a=s.name,t=La(s.node,s.params.length-1)}else if(s instanceof P)a=za(e,n),t=k(a);else if(s instanceof I||s instanceof l)a=za(e,n),t=T(a);else{if(!(s instanceof j))continue;a=za(e,n),t=O(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:Na(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 Bt(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(Pa(i.geometry,g)),u=this.assets.get(s),f=a.get(s);if(null==f){console.warn("Missing batching info when configuring for asset id "+s);continue}const m=He(f.assetMesh)?.uuid===e,y=f.assetMesh instanceof et&&m?f.assetMesh.collisionShapes:void 0,w=this.configureBatchedInstancedMesh(r,v,i,o,y);for(let e=0;e<w.length;e++){const a=r[e],s=w[e];v.setCastShadowAt(s,a.castShadow??u?.castShadow??!1);const 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=qa.set(0,0,0,0);for(let a=0;a<e.params.length;a++){const s=Va(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=Va(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=Ke(t,e=>!st(e)&&null!=e.geometry),s=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(t,fa(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 Ze(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(!wa(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=va(a,i)),null!=a&&s.id!==a.id&&(r=r??ya(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(be));Ze(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,Ze(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 Kt.entries())t.userData.customShaderName&&Kt.delete(e);this.landscapeManagers.forEach(t=>t.updateShaders(e)),Ze(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);fa(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 Gt&&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=oa(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 Ft){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 nt&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}if("shape_mesh"===e.type&&"landscape"!==e.shape)Ht(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;Ht(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:Xe(t,t=>t.children?.some(t=>t.id===e.id),()=>!0))[0];return null==t?this.scene:null!=t?Ze(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=Ye(e.vertexMaterials,e=>e.m);t.traverse(e=>{if(e instanceof m){if(null==e.geometry)return;if(ja(dt(e,0,!1)),a>0){ja(dt(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=dt(s,0,!0);ja(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=dt(s,4,!0);ja(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=os(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&&cs(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=oa(e.fog),this.fixFogColor(),n=new d;break;case"sky":this.sky=xt(),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":case"scatter":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!==Me.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==Me.dynamic||ia(n),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,n;console.warn("RenderingView not found in materializer")}}async handlePaintedScatterSceneMutation(e){const t=this.paintedScatterManager?.referencesSceneObject(e.id)??!1,a=await this.sceneObjectContainsPaintedScatter(e);(t||a)&&await this.refreshPaintedScatterPresence(!1)}async refreshPaintedScatterPresence(e=!1){return await this.sceneContainsPaintedScatter()?(null==this.paintedScatterManager&&(this.paintedScatterManager=new ht(this.scene,this.dataProvider,this.renderingView,this.assetManagerService,this.assetsService)),this.paintedScatterManager.queueRefresh(e),!0):(this.disposePaintedScatterManager(),!1)}disposePaintedScatterManager(){null!=this.paintedScatterManager&&(this.paintedScatterManager.clear(),this.paintedScatterManager.stop(),this.paintedScatterManager=void 0)}async sceneContainsPaintedScatter(){return this.sceneObjectsContainPaintedScatter(this.dataProvider.getObjects())}async sceneObjectsContainPaintedScatter(e,t=[]){for(const a of e??[])if(await this.sceneObjectContainsPaintedScatter(a,t))return!0;return!1}async sceneObjectContainsPaintedScatter(e,t=[]){if("scatter"===e.type&&(e.paintedScatter?.cells?.some(e=>(e.instances?.length??0)>0)||(e.paintedScatter?.palette?.length??0)>0))return!0;if(null!=e.children&&await this.sceneObjectsContainPaintedScatter(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.sceneObjectsContainPaintedScatter(s,[...t,e.assetId])}return!1}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 ft(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])}async prefabAssetContainsPaintedScatter(e){return"prefab"===e.type&&null!=e.prefab?.objects&&this.sceneObjectsContainPaintedScatter(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!==jt?(this.sky.material=jt,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 Yt[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??be[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),r=this.getNestedActorId(e.id,t);return s.__netSceneId=r,this.applyInitialMaterializedNetRole(s),this.materializedActors.set(r,s),{object:s?.object,actor:s}}applyInitialMaterializedNetRole(e){if(this.inEditor||this.netMode===Se.none)return;const t=e.constructor[ye];!0!==t?.replicate?this.netMode===Se.client&&(e.netRole=Ae.none):e.netRole=this.netMode===Se.client?Ae.simulatedProxy:Ae.authority}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.receiveShadow??!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=ot(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new it(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 lt(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(()=>ct(r),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&St.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=Mt[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,Mt[e].collision(s));return new nt(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(fa(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,Ht(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 zt(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 zt(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 zt(a);s.scale.multiplyScalar(.6),t.add(s);const r=new Gt(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===At);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.disposePaintedScatterManager(),this.disposeSurfaceScatterManager(),this.materializedActors.forEach(e=>e.disposed.next(!0)),this.materializedActors.clear()}};Zt=e([pe(),t("design:paramtypes",[A,Object,at,tt,Ie,Array,Array,Object,Array])],Zt);export{Zt as SceneMaterializer};function Ht(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const Kt=new Map,Qt=new Map,ea=new g({color:16711935}),ta=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),ea;const i=JSON.stringify(e.material)+t?._id,o=n&&!("shaderGraph"===e.material.type&&"asset"===e.material.shaderGraph?.source);if(o&&Kt.has(i))return Kt.get(i);if(o&&Qt.has(i))return await Qt.get(i);const l=_materialFromAsset(i,e,t,a,s,r,o);return o?Qt.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=mt(u,a);break;case"grassFoliage":d=ut({color:u.color,map:u.map},a);break;case"grass":d=pt({...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=ea;break}"surface"===e.target&&null!=e.materialOptions?.side&&(h=qt(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=Lt(e,{parameters:s,previewNodeId:n,trailBillboard:l,alphaTest:t.material.alphaTest}),d.userData.customShaderName="asset"===t.material.shaderGraph?.source?`shaderGraph:${t.material.shaderGraph.assetId}`:`shaderGraph:${t.id}`}catch(e){console.warn("Shader graph runtime error: "+e,e),d=ea}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:Jt?Te:Ee,lambert:Te,unlit:Fe,toon:Nt,layered:Vt,landscape:Ve,"landscape-composite":ke,"decal-unlit":Pt,"decal-standard":Ct,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),ta.has(t.material.shader)||ta.set(t.material.shader,ea.clone()),d=ta.get(t.material.shader)}d.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),d=ea;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=xe[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&&Kt.set(e,d),c&&Qt.delete(e),d}export function prepareCustomParamsFromShaderGraph(e,t={}){return Object.fromEntries((e.parameters??[]).map(e=>{const a=function(e){switch(e){case"float":return gt.FloatNode;case"boolean":return gt.BooleanNode;case"texture":return gt.Sampler2DNode;case"vec2":return gt.Vec2Node;case"vec3":return gt.Vec3Node;case"vec4":return gt.Vec4Node;case"color":return gt.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?ha(n):s?.value??ha(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 sa(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}=wt(e,{parameterType:t,parameterTarget:c,extractPropertyParameters:ze,toSerializedParamType:toSerializedParamType});for(const e of d)console.warn(`Skipping stored parameter "${e.key}" because it could not be converted from ${gt[e.sourceType]} to ${gt[e.targetType]}`);for(const[e,t]of Object.entries(p)){if(!1===t.override)continue;const c=await sa(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 sa(r,n,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const aa=new Map;async function sa(e,t,a,s,r,n,i,o,u=t.value,p=t.type,d,h=(t.type===gt.Struct?t.struct:void 0)){if(null==t||null==u||""===u)return null;switch(p){case gt.Array:if(Array.isArray(u)&&"element"in t)return await Promise.all(u.map(l=>sa(e,t,a,s,r,n,i,o,l,t.element,d,t.elementStruct)));break;case gt.Number:case gt.FloatNode:let f;if("string"==typeof u?f=parseFloat(u):"number"==typeof u&&(f=u),p===gt.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=aa.get(e);return null==t&&(t=Pe(It.decode(e)),aa.set(e,t)),t}(e.easing),r=s.sample(Ce(De.energy));return _(N(t),N(a),r)}return new H(Re(e),f,void 0,!1)}return f;case gt.Texture:let m=await s.getTexture(await a.getAsset(u));return"envmap"===e.toLowerCase()&&null!=n&&(m=n.getEnvTexture(m)),m;case gt.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(Re(e)+"_i",a,void 0,!1))}const y=await s.getTexture(g);return y?J(y):null;case gt.Boolean:return u;case gt.BooleanNode:return new Z(Re(e),u,void 0,!1);case gt.Vector2:case gt.Vec2Node:if("object"==typeof u){const t=u instanceof Array?(new j).fromArray(u):new j(u.x,u.y);return p===gt.Vec2Node?new Q(Re(e),t,void 0,!1):t}return null;case gt.Vector3:case gt.Vec3Node:if("object"==typeof u){const t=u instanceof Array?(new I).fromArray(u):new I(u.x,u.y,u.z);return p===gt.Vec3Node?new ee(Re(e),t,void 0,!1):t}return null;case gt.Vector4:case gt.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===gt.Vec4Node?new te(Re(e),t,void 0,!1):t}return null;case gt.Color:case gt.RgbNode:const w=new l(u);return p===gt.RgbNode?new ee(Re(e),new I(w.r,w.g,w.b),void 0,!1).rgb:w;case gt.String:return u;case gt.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 gt.Euler:const v=u;return(new c).fromArray(v);case gt.Object3D:{const e=await a.getAsset(u);return(await s.getMesh(e,{applyMaterials:!0,rescale:!0})).scene}case gt.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 gt.AudioBuffer:return await s.getAudio(await a.getAsset(u));case gt.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 gt.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 gt.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 gt.DataAsset:return materializeDataAssetRef(u,a,s,r,n,i,o,d);case gt.Sequence:{const e=await a.getAsset(u);if("sequence"===e.type&&"sequence"in e)return new Wt(e.sequence);console.error("Using a non-sequence asset for sequence parameter");break}case gt.Struct:return async function(e,t,a,s,r,n,i,o,l){const c=ra(e),u=c?.struct??t;if(null==u)return console.warn("Missing parameter definition id for struct parameter"),null;const p=$e(u);if(null==p)return console.warn(`Unknown parameter definition "${u}"`),null;if(Ue(u))return console.warn(`Can not instantiate abstract parameter definition "${u}"`),null;if(null!=t&&u!==t&&!We(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=ra(e);if(null!=t)return t.value;if(na(e))return e;if(null!=e&&"object"==typeof e&&na(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 gt.Curve:return It.decode(u);case gt.ColorLayer:case gt.MaskLayer:if(Et(u)){const e=await Dt.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 gt.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(_e(u))return console.warn(`Can not instantiate abstract data asset definition "${u}"`),null;const p=Ne(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 ra(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&"string"==typeof e.struct&&na(e.value)?e:null}function na(e){return null!=e&&"object"==typeof e&&!Array.isArray(e)&&Object.values(e).every(e=>null!=e&&"object"==typeof e&&"type"in e)}function ia(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 oa(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 la(e,t,a,s){null==s&&(s=(new f).identity());const r=s.clone().multiply(ca(e,new n.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await la(e.children[a],t,e,r);await t(e,a,s)}function ca(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?gt.Number:t instanceof B||"function"==typeof e.prototype.isFloat?gt.FloatNode:t instanceof x||e===x||e.isTexture?gt.Texture:t instanceof Oe||e===Oe||e===Y||"function"==typeof e.prototype?.isSampler2D||!0===e.prototype?.isSampler2D?gt.Sampler2DNode:t instanceof Boolean||e===Boolean?gt.Boolean:t instanceof F?gt.BooleanNode:t instanceof l||e==l?gt.Color:t instanceof R||"function"==typeof e.prototype.isRgb?gt.RgbNode:t instanceof j||e==j?gt.Vector2:t instanceof ie||"function"==typeof e.prototype.isVec2?gt.Vec2Node:t instanceof I||e==I?gt.Vector3:t instanceof le||"function"==typeof e.prototype.isVec3?gt.Vec3Node:t instanceof P||e==P?gt.Vector4:t instanceof ue||"function"==typeof e.prototype.isVec4?gt.Vec4Node:t instanceof String||e===String?gt.String:t instanceof we||e==we||e.prototype instanceof we||e.prototype==we?gt.BaseActor:t instanceof c||e==c?gt.Euler:t instanceof v||e==v?gt.Object3D:t instanceof h||e==h?gt.Material:t instanceof AudioBuffer||e==AudioBuffer?gt.AudioBuffer:t instanceof he||e==he?gt.VisualEffect:t instanceof fe||e==fe?gt.Prefab:t instanceof me||e==me?gt.PrefabActor:t instanceof ge||e==ge?gt.DataAsset:t instanceof It||e==It?gt.Curve:t instanceof Dt||e==Dt?gt.ColorLayer:t instanceof kt||e==kt?gt.MaskLayer:t instanceof n.AnimationClip||e==n.AnimationClip?gt.AnimationClip:t instanceof Wt||e==Wt||"SequenceData"===e.name||e.prototype&&"tracks"in e.prototype?gt.Sequence:null!=Be(e)?gt.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===gt.Struct?Be(e.type):void 0;return!0===e.options.array?{type:gt.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!==gt.Struct)return{typeInfo:e,value:t};const a=ra(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===gt.Struct)return Ue(e.type)?{}:prepareCustomParamsFromType(e.type,{});return customParameterDefaultValueByType.get(a)}(e,a));n=function(e,t,a){if(e.type!==gt.Struct||a?.type!==gt.Struct||null==a.struct)return e;const s=t.struct??e.struct;if(null==s||a.struct===s||We(a.struct,s)||null==$e(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?ha(t):[];return ha(t)}(e,p.value,u):ha(p.value);return[e.name,{...n,value:d,override:c}]}))}function ua(e){return null==e?{}:Object.fromEntries(Object.entries(e).filter(([,e])=>function(e){return!0===e?.override}(e)))}function pa(e,t){return e.length>=t.length&&t.every((t,a)=>e[a]===t)}export function prepareCustomParamsFromType(e,t,a=null,s={}){const r=ze(e);if(0===r.length)return{};let n;null!=a?je(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=da(e,t);void 0!==a&&(i[e.name]=a)}}return prepareCustomParams(r,t,i,s)}function da(e,t){return!0===e.options.array?Array.isArray(t)?t.map(t=>serializeCustomParameter(e.type,t)??t):[]:serializeCustomParameter(e.type,t)}function ha(e){return null==e?e:Array.isArray(e)?e.map(e=>ha(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=Be(e);if(null!=s){const r=ra(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!=Be(a)&&Ge(a,e)?a:e}(e,t),i=Be(n),o=function(e,t){if(null==t)return null;if(na(t))return t;if(null!=t&&"object"==typeof t&&na(t.params))return t.params;if("object"!=typeof t)return;const a=ze(e),s={};for(const e of a){const a=t[e.name];if(void 0===a)continue;const r=da(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 fa(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=>ma(e.materialId)),(t??[]).filter(e=>ma(e.materialId)),e=>e.color+e.name)}function ma(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[gt.RgbNode,"#000000"],[gt.Color,"#000000"],[gt.String,""],[gt.Vector4,[0,0,0,0]],[gt.Vec4Node,[0,0,0,0]],[gt.Vector3,[0,0,0]],[gt.Vec3Node,[0,0,0]],[gt.Vector2,[0,0]],[gt.Vec2Node,[0,0]],[gt.Euler,[0,0,0,"XYZ"]],[gt.Array,[]],[gt.DataAsset,null],[gt.ColorLayer,Ot],[gt.MaskLayer,Tt]]);let ga=new l;new l;function ya(e){return null==e?.color?null:(ga.set(e.color),"#"+ga.getHexString())}function wa(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=ya(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 Je(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=ya(i),c=i.name;if(wa(i,t,e.userData["originalColor_"+n],e.userData["originalMaterialName_"+n])){const i=va(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=ya(n),o=n.name;if(wa(n,t,e.userData.originalColor,e.userData.originalMaterialName)){const n=va(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 ba=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 va(e,t){if(null==e||null==t||!function(e,t){return function(e){const t=[];for(const[a,s]of Object.entries(e))Sa(a,s)&&t.push(s);if(e instanceof n.ShaderMaterial)for(const[a,s]of Object.entries(e.uniforms))Sa(a,s.value)&&t.push(s.value);return t}(e).some(e=>e.flipY!==t)}(e,t))return e;let a=ba.get(e);null==a&&(a=new Map,ba.set(e,a));const s=a.get(t);if(null!=s)return s;const r=Ma(e);if(function(e,t){for(const a of Object.keys(e)){const s=e[a];Sa(a,s)&&(e[a]=Aa(s,t))}}(r,t),r instanceof n.ShaderMaterial){for(const[e,a]of Object.entries(r.uniforms))Sa(e,a.value)&&(a.value=Aa(a.value,t));r.uniformsNeedUpdate=!0}return r.needsUpdate=!0,a.set(t,r),r}function Ma(e){const t=e.clone();return t.userData={...e.userData??{}},t}function Sa(e,t){const a=t;return(t instanceof x||!0===a?.isTexture)&&!e.toLowerCase().includes("envmap")&&!0!==a.isCompressedTexture&&!0!==a.isCompressedArrayTexture}function Aa(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 xa(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 ja(e){if(null!=e){for(let t=0;t<e.array.length;t++)e.setX(t,0);e.needsUpdate=!0}}function Ia(e,t){const a=He(e);return null==a?"":function(e,t){const a=Za(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 Pa(e,t){const a=Za(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 Ca=new WeakMap,Da="hbat_",Oa=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 Ta(e){let t=Ca.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(ka(a))continue;const s=e.uniforms[a]?.value;Ea(s)||(t+=`u:${a}:${_a(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 $t&&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),Ca.set(e,t)),t}function ka(e){return Oa.has(e)||e.startsWith("hology_")}function Va(e,t){return e instanceof U?e.uniforms[t]?.value:e[t]}function Ea(e){return"number"==typeof e||e instanceof j||e instanceof I||e instanceof P||e instanceof l}function Fa(e){return"number"==typeof e?1:e instanceof j?2:4}function za(e,t){const a=e.replace(/[^A-Za-z0-9_]/g,"_");let s=Da+a;for(;t.has(s);)s=Da+s;return t.add(s),s}function Na(e,t){const a={};for(const[s,r]of Object.entries(e.uniforms))t.has(s)||(a[s]={value:r.value});return a}const Ba=new WeakMap;let $a=1;function _a(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=Ba.get(e);return null==t&&(t=$a++,Ba.set(e,t)),`object:${t}`}return String(e)}function Ua(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 Ga=new f,Wa=new c;function Ra(e,t){return Wa.copy(e),Wa.x*=-1,Wa.y*=-1,Wa.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(Wa.y*=-1,Wa.z*=-1),(new n.Matrix3).setFromMatrix4(Ga.makeRotationFromEuler(Wa))}function La(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 qa=new P;function Ya(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 Ja(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof he?t.push(s):s instanceof ve&&t.push(...Ja(s));return t}const Xa=new WeakMap;function Za(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 Ha(e.vertexShader,t)}(t,a);if(t instanceof n.ShaderMaterial)return function(e,t){if("uv1"===t||"uv2"===t||"uv3"===t)return Ha(e.vertexShader,t);return!0}(t,a);if("uv1"===a)return!1;if("color"===a&&function(e){let t=Xa.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 Xa.set(e,t),t}(e))return!1;if("uv2"===a)return null!=t.lightMap||null!=t.aoMap;return!0}(e,t,a))}function Ha(e,t){return new RegExp(`(^|[^A-Za-z0-9_])${a=t,a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}([^A-Za-z0-9_]|$)`).test(e);var a}function Ka(e,t,a){if(t(e))return e;for(const s of e.children??[]){const e=Ka(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=>Ka(e,t,a));if(null!=e)return e}}return null}const Qa=new I,es=new I,ts=new I,as=new P,ss=new P,rs=new f,ns=new f,is=new b;function os(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++)Qa.fromBufferAttribute(a,t),e.applyBoneTransform(t,Qa),a.setXYZ(t,Qa.x,Qa.y,Qa.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++)ls(e,t,ns),null!=s&&(es.fromBufferAttribute(s,t),is.getNormalMatrix(ns),es.applyMatrix3(is).normalize(),s.setXYZ(t,es.x,es.y,es.z)),null!=r&&(ts.fromBufferAttribute(r,t),ts.transformDirection(ns),r.setXYZ(t,ts.x,ts.y,ts.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 ls(e,t,a){const s=e.geometry,r=s.getAttribute("skinIndex"),n=s.getAttribute("skinWeight"),i=e.skeleton;as.fromBufferAttribute(r,t),ss.fromBufferAttribute(n,t),a.identity().multiplyScalar(0);for(let e=0;e<4;e++){const t=ss.getComponent(e);if(0===t)continue;const s=as.getComponent(e);rs.multiplyMatrices(i.bones[s].matrixWorld,i.boneInverses[s]);for(let e=0;e<16;e++)a.elements[e]+=rs.elements[e]*t}return a.premultiply(e.bindMatrixInverse).multiply(e.bindMatrix),a}function cs(e){let t=!0;return e.traverse(a=>{a===e||a.isBone||(t=!1)}),t}function us(e,t){let a=t??!1,s=!0;for(const t of e)if(!1!==t.castShadow){s=!1;break}for(const t of e)if(!0===t.castShadow)return!0;return a&&!s}function ps(e,t){let a=t??!1,s=!0;for(const t of e)if(!1!==t.receiveShadow){s=!1;break}if(s)return!1;for(const t of e)if(!0===t.receiveShadow)return!0;return a&&!s}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -42,7 +42,7 @@ export declare class ObjectStorage<T extends StorageEntity> {
|
|
|
42
42
|
* @param from Relative path
|
|
43
43
|
* @param to Relative path that the given folder should be put into
|
|
44
44
|
*/
|
|
45
|
-
moveToFolder(object: T, to: string): Promise<
|
|
45
|
+
moveToFolder(object: T, to: string): Promise<T>;
|
|
46
46
|
getAbsolutePath(relativePath?: string): string;
|
|
47
47
|
getResourceAbsolutePath(relativePath?: string): string;
|
|
48
48
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{randomUUID as e}from"../../utils/uuid.js";import{pathJoin as t}from"../../utils/files.js";import{EMPTY as a,filter as i,firstValueFrom as n,from as s,map as r,merge as h,mergeAll as o,mergeMap as l,Observable as c,of as d,startWith as u,Subject as p,switchMap as f,tap as w}from"rxjs";import{sleepDelay as m}from"../../utils/async.js";const y={},v={},x={},b={};null==y.read&&window.require&&(Object.assign(y,window.require("fs")),Object.assign(v,y.promises),Object.assign(x,window.require("path")),Object.assign(b,window.require("chokidar")));const j=null!=y.existsSync;let g=0,I=0;const P=[];async function F(e){await function(){if(g<32)return g++,Promise.resolve();return new Promise(e=>P.push(e))}();try{return await e()}finally{!function(){const e=P[I];if(null==e)return P.length=0,I=0,void g--;I++,I>64&&2*I>P.length&&(P.splice(0,I),I=0);e()}()}}function O(e){return F(()=>v.readFile(e))}function S(){if(j){const e="--path=",t=window.process.argv.find(t=>t.startsWith(e));return t?t.substring(e.length):""}return""}const C=/^[A-Z]:/;function A(...e){return 0===e.length?"":C.test(e[0])||j?x.join(...e):t(...e)}export class ObjectStorage{get pathResources(){return A(this.path+"-resources")}constructor(e,t,a=defaultSerializer){this.name=e,this.filePathFn=t,this.serializer=a,this.basePathUpdates=new p,this.basePath=this.basePathUpdates.pipe(r(e=>A(S(),e)),w(e=>{this.path=A(e,this.name),this.cachedIndex=null,this.loadingIndex=null,k(this.path),this.determineIfMetaFileShouldBeCreated()})),this.loaded=n(this.basePath),this.cachedIndex=null,this.loadingIndex=null,this.shouldCreateIndex=!1}setBasePath(e){this.basePathUpdates.next(e)}async determineIfMetaFileShouldBeCreated(){if(j)try{const e=["vite.renderer.config.ts","vite.config.ts"];for(const t of e){const e=A(S(),t);if(!await z(e))continue;if((await O(e)).toString().includes("hologyBuild"))return void(this.shouldCreateIndex=!1)}this.shouldCreateIndex=!0}catch(e){console.warn("Failed to read vite config to determine if meta files should be created")}}async createFolder(e,t=""){D(),await v.mkdir(x.join(this.path,t,e),{recursive:!0})}async deleteFolderForceDangerous(e){await v.rm(x.join(this.path,e),{recursive:!0,force:!0})}async moveFolder(e,t){if(D(),""==e)return void console.warn("Can not move a folder in root");const a=x.resolve(x.join(this.path,t),x.basename(e));if(await K(a)){if(a!==x.resolve(this.path,e))throw new Error("Can not move to directory as a file already exists with the same name")}else{if(function(e,t){const a=x.resolve(e),i=x.resolve(t),n=x.normalize(a)+x.sep;return(x.normalize(i)+x.sep).startsWith(n)}(x.join(this.path,e),x.join(this.path,t)))throw new Error("Can not move a folder into a folder it contains");await v.rename(x.join(this.path,e),a)}}async renameFolder(e,t){await v.rename(x.join(this.path,e),x.resolve(x.dirname(x.join(this.path,e)),t))}async moveToFolder(e,t){if(D(),e.path===t)return;await this.assertObjectFilePathAvailable({...e,path:t},e.id);const a=this.privateObjectPath({...e,path:t});await v.rename(this.privateObjectPath(e),a)}getAbsolutePath(e=""){return x.join(this.path,e)}getResourceAbsolutePath(e=""){return x.join(this.pathResources,e)}watchFolders(){return s(this.loaded).pipe(f(()=>s(k(this.path))),f(()=>this.watchDir(this.path).pipe(i(e=>!e.filename.endsWith(".json")),u(null),f(()=>s(v.readdir(this.path,{recursive:!0,withFileTypes:!0}))),r(e=>Array.from(new Set(e.filter(e=>e.isDirectory()).map(e=>x.relative(this.path,x.join(e.parentPath,e.name)).replace(/^\.$/,"")).values()))))))}watch(){D();const e=s(this.loaded).pipe(f(()=>s(k(this.pathResources))),f(()=>this.watchDir(this.pathResources)),l(e=>{if(null==e||!["add","change","unlink"].includes(e.event))return a;const t=x.basename(e.filename);return s(this.getAll()).pipe(l(e=>{const i=e.filter(e=>e.fileKey===t);return 0===i.length?a:s(i).pipe(l(e=>{const t=this.privateObjectRelativePath(e);return s(this.readFileIfExists(t)).pipe(r(a=>({event:"change",object:a,path:e.path,filename:t})))}))}))})),t=s(this.loaded).pipe(f(()=>this.watchDir(this.path)),l(e=>{const t={event:e.event,path:x.dirname(e.filename).replace(/^\.$/,""),filename:x.basename(e.filename)};return e.filename.endsWith(".json")?"unlink"!==e.event?s(this.readFileIfExists(e.filename)).pipe(w(e=>{null!=e&&(null==this.cachedIndex&&(this.cachedIndex={}),this.cachedIndex[e.id]={id:e.id,name:e.name??e.id,path:e.path},this.persistIndex())}),r(e=>({object:e,...t}))):d({object:null,...t}).pipe(w(()=>{const t=Object.keys(this.cachedIndex??{}).find(t=>this.privateObjectRelativePath(this.cachedIndex[t])===e.filename);t&&this.removeIndexEntry(t)})):"change"===e.event?s(this.reloadSubdirectory(e.filename)).pipe(o(),r(e=>({object:e,...t}))):a}));return h(t,e)}async reloadSubdirectory(e){return(await this.getAll(e)).filter(t=>t.path.startsWith(e))}async readFileIfExists(e){const t=A(this.path,e);for(let a=0;a<3;a++)try{const a=await O(t);return{...JSON.parse(a.toString()),path:x.dirname(e).replace(/^\.$/,""),filename:x.basename(e)}}catch(e){if(2===a)return console.error("Could not read file at "+t,e),null;await m(50*(a+1))}return null}async getAll(e){if(j){await this.loaded,await k(this.path);const t=await this.getObjectFilePaths(e??""),a=null==e||""===e,i=[];for(let e=0;e<t.length;e+=32){const a=Math.min(32,t.length-e),n=await Promise.all(Array.from({length:a},(a,i)=>{const n=t[e+i];return O(A(this.path,n)).then(e=>({...JSON.parse(e.toString()),path:x.dirname(n).replace(/^\.$/,""),filename:x.basename(n)}))}));i.push(...n)}return a&&(this.cachedIndex=R(i),await this.persistIndex()),i}const t=await this.loadIndex();return Promise.all(Object.keys(t).map(e=>this.get(e)))}async getObjectFilePaths(e){const t=this.path,a=x.join(t,e),i=[];return await async function e(a){const n=await v.readdir(a,{withFileTypes:!0});for(const s of n){const n=x.join(a,s.name);s.isDirectory()?await e(n):s.isFile()&&s.name.endsWith(".json")&&!/^[\._]/.test(s.name)&&i.push(x.relative(t,n))}}(a),i}async get(e){const t=await this.loadIndex(),a=t[e]??Object.values(t).find(t=>t.name===e);if(null==a)return;const i=this.privateObjectPath(a);if(!j)return(await fetch(i)).json();return await z(i)?{...JSON.parse((await O(i)).toString()),path:a.path??"",filename:x.basename(this.privateObjectRelativePath(a))}:null}async save(e){if(D(),await this.loaded,null==e.path){const t=(await this.loadIndex())[e.id];null!=t?.path&&(e={...e,path:t.path})}return await this.assertObjectFilePathAvailable(e,e.id),await v.writeFile(this.privateObjectPath(e),this.serialize(e)),await this.addOrUpdateIndexEntry(e),e}async rename(e,t){const a={...e,name:t};await this.assertObjectFilePathAvailable(a,e.id);const i=this.privateObjectPath(e),n=this.privateObjectPath(a);try{await v.rename(i,n)}catch(e){console.error(e),console.warn("Rename failed, retrying",{currentPath:i,newPath:n}),await m(400),await v.rename(i,n)}return await this.save(a),a}async delete(e){await v.unlink(this.privateObjectPath(e)),this.removeIndexEntry(e.id)}async create(t){D(),await this.loaded,t.id=e();const a=this.privateObjectPath(t);if(await this.assertObjectFilePathAvailable(t),await K(a))throw Error(`Can not create because a file already exists at ${a}`);return await v.writeFile(a,this.serialize(t)),await this.addOrUpdateIndexEntry(t),t}prepareCreate(t){return D(),t.id=e(),t}serialize(e){return this.serializer(e)}async addOrUpdateIndexEntry(e){null==this.cachedIndex&&await this.loadIndex(),this.cachedIndex[e.id]={id:e.id,name:e.name??e.id,path:e.path},await this.persistIndex()}removeIndexEntry(e){null!=this.cachedIndex&&delete this.cachedIndex[e],this.persistIndex()}async persistIndex(){j&&this.shouldCreateIndex&&null!=this.cachedIndex&&await v.writeFile(this.indexFilePath,JSON.stringify(this.cachedIndex,null,2))}get indexFilePath(){return A(this.path,"_meta.json")}async loadIndex(){if(null!=this.cachedIndex)return this.cachedIndex;this.loadingIndex??(this.loadingIndex=this.createIndex());try{return await this.loadingIndex}finally{this.loadingIndex=null}}async createIndex(){if(j){const e=await this.getAll();this.cachedIndex=R(e),await this.persistIndex()}else this.cachedIndex=await(await fetch(this.indexFilePath)).json();return this.cachedIndex}async ensureResourceDir(){await k(A(this.path+"-resources"))}async saveFile(e,t){return D(),await k(A(this.path+"-resources")),v.copyFile(t.path,A(this.path+"-resources",e.fileKey))}async saveExtraFile(e,t){return D(),await k(A(this.path+"-resources")),v.copyFile(e,A(this.path+"-resources",t))}getAssetPath(e){return window&&"function"==typeof window.require?window.require("path").join(this.path+"-resources",e.fileKey):A(this.path+"-resources",e.fileKey)}async replaceFile(e,t){if(await z(t))return v.copyFile(t,A(this.path+"-resources",e.fileKey));console.error("Failed to replace file using path "+t)}async deleteFile(e){if(null==e)return;D();const t=A(this.path+"-resources",e);return await z(t)?v.unlink(t):void 0}privateObjectPath(e){return A(this.path,this.privateObjectRelativePath(e))}privateObjectRelativePath(e){return this.filePathFn?A(e.path??"",this.filePathFn(e)):A(e.path??"",tokenizeName(e.name??e.id)+".json")}async assertObjectFilePathAvailable(e,t){const a=await this.findObjectFilePathCollision(e,t);if(null!=a)throw Error(`Can not save "${e.name??e.id}" because "${a.name}" already uses the same storage file name. Use a name that differs beyond letter casing.`)}async findObjectFilePathCollision(e,t){const a=E(this.privateObjectRelativePath(e)),i=await this.loadIndex();return Object.values(i).find(e=>e.id!==t&&E(this.privateObjectRelativePath(e))===a)??null}watchDir(e){return new c(t=>{if("win32"===process.platform&&j){const a=y.watch(e,{recursive:!0},(a,i)=>{if(i){const n=x.join(e,i);y.access(n,y.constants.F_OK,e=>{const n=e?"unlink":"rename"===a?"add":"change";t.next({event:n,filename:i})})}});return()=>a.close()}const a=b.watch(e,{cwd:e,ignoreInitial:!0,disableGlobbing:!0});return a.on("all",(e,a,i)=>{t.next({event:e,filename:a})}),a.on("error",()=>{}),()=>{a.close()}})}}export function tokenizeName(e){return e.trim().replace(/\s/g,"_").replace(/[^a-z0-9_\-\.]/gi,"")}function E(e){return e.replace(/\\/g,"/").toLowerCase()}function R(e){const t={};for(const a of e)t[a.id]={id:a.id,name:a.name??a.id,path:a.path};return t}async function k(e){j&&(await z(e)||await v.mkdir(e,{recursive:!0}))}function z(e){return!!j&&new Promise(function(t,a){y.exists(e,function(e){t(e)})})}function D(){if(!j)throw new Error("Must have direct access to filesystem")}async function K(e){try{await v.access(e,v.constants.F_OK)}catch(e){return!1}return!0}export function defaultSerializer(e){const t={...e};return delete t.path,delete t.filename,JSON.stringify(t,null,2)}/*
|
|
1
|
+
import{randomUUID as e}from"../../utils/uuid.js";import{pathJoin as t}from"../../utils/files.js";import{EMPTY as a,filter as i,firstValueFrom as n,from as s,map as r,merge as h,mergeAll as o,mergeMap as l,Observable as c,of as d,startWith as u,Subject as p,switchMap as f,tap as w}from"rxjs";import{sleepDelay as m}from"../../utils/async.js";const y={},v={},x={},b={};null==y.read&&window.require&&(Object.assign(y,window.require("fs")),Object.assign(v,y.promises),Object.assign(x,window.require("path")),Object.assign(b,window.require("chokidar")));const j=null!=y.existsSync;let g=0,I=0;const P=[];async function F(e){await function(){if(g<32)return g++,Promise.resolve();return new Promise(e=>P.push(e))}();try{return await e()}finally{!function(){const e=P[I];if(null==e)return P.length=0,I=0,void g--;I++,I>64&&2*I>P.length&&(P.splice(0,I),I=0);e()}()}}function O(e){return F(()=>v.readFile(e))}function S(){if(j){const e="--path=",t=window.process.argv.find(t=>t.startsWith(e));return t?t.substring(e.length):""}return""}const C=/^[A-Z]:/;function E(...e){return 0===e.length?"":C.test(e[0])||j?x.join(...e):t(...e)}export class ObjectStorage{get pathResources(){return E(this.path+"-resources")}constructor(e,t,a=defaultSerializer){this.name=e,this.filePathFn=t,this.serializer=a,this.basePathUpdates=new p,this.basePath=this.basePathUpdates.pipe(r(e=>E(S(),e)),w(e=>{this.path=E(e,this.name),this.cachedIndex=null,this.loadingIndex=null,k(this.path),this.determineIfMetaFileShouldBeCreated()})),this.loaded=n(this.basePath),this.cachedIndex=null,this.loadingIndex=null,this.shouldCreateIndex=!1}setBasePath(e){this.basePathUpdates.next(e)}async determineIfMetaFileShouldBeCreated(){if(j)try{const e=["vite.renderer.config.ts","vite.config.ts"];for(const t of e){const e=E(S(),t);if(!await z(e))continue;if((await O(e)).toString().includes("hologyBuild"))return void(this.shouldCreateIndex=!1)}this.shouldCreateIndex=!0}catch(e){console.warn("Failed to read vite config to determine if meta files should be created")}}async createFolder(e,t=""){D(),await v.mkdir(x.join(this.path,t,e),{recursive:!0})}async deleteFolderForceDangerous(e){await v.rm(x.join(this.path,e),{recursive:!0,force:!0})}async moveFolder(e,t){if(D(),""==e)return void console.warn("Can not move a folder in root");const a=x.resolve(x.join(this.path,t),x.basename(e));if(await U(a)){if(a!==x.resolve(this.path,e))throw new Error("Can not move to directory as a file already exists with the same name")}else{if(function(e,t){const a=x.resolve(e),i=x.resolve(t),n=x.normalize(a)+x.sep;return(x.normalize(i)+x.sep).startsWith(n)}(x.join(this.path,e),x.join(this.path,t)))throw new Error("Can not move a folder into a folder it contains");await v.rename(x.join(this.path,e),a)}}async renameFolder(e,t){await v.rename(x.join(this.path,e),x.resolve(x.dirname(x.join(this.path,e)),t))}async moveToFolder(e,t){if(D(),(e.path??"")===t)return e;const a={...e,path:t};await this.assertObjectFilePathAvailable(a,e.id);const i=this.privateObjectPath(a);return await v.rename(this.privateObjectPath(e),i),await this.addOrUpdateIndexEntry(a),a}getAbsolutePath(e=""){return x.join(this.path,e)}getResourceAbsolutePath(e=""){return x.join(this.pathResources,e)}watchFolders(){return s(this.loaded).pipe(f(()=>s(k(this.path))),f(()=>this.watchDir(this.path).pipe(i(e=>!e.filename.endsWith(".json")),u(null),f(()=>s(v.readdir(this.path,{recursive:!0,withFileTypes:!0}))),r(e=>Array.from(new Set(e.filter(e=>e.isDirectory()).map(e=>x.relative(this.path,x.join(e.parentPath,e.name)).replace(/^\.$/,"")).values()))))))}watch(){D();const e=s(this.loaded).pipe(f(()=>s(k(this.pathResources))),f(()=>this.watchDir(this.pathResources)),l(e=>{if(null==e||!["add","change","unlink"].includes(e.event))return a;const t=x.basename(e.filename);return s(this.getAll()).pipe(l(e=>{const i=e.filter(e=>e.fileKey===t);return 0===i.length?a:s(i).pipe(l(e=>{const t=this.privateObjectRelativePath(e);return s(this.readFileIfExists(t)).pipe(r(a=>({event:"change",object:a,path:e.path,filename:t})))}))}))})),t=s(this.loaded).pipe(f(()=>this.watchDir(this.path)),l(e=>{const t={event:e.event,path:x.dirname(e.filename).replace(/^\.$/,""),filename:x.basename(e.filename)};return e.filename.endsWith(".json")?"unlink"!==e.event?s(this.readFileIfExists(e.filename)).pipe(w(e=>{null!=e&&(null==this.cachedIndex&&(this.cachedIndex={}),this.cachedIndex[e.id]={id:e.id,name:e.name??e.id,path:e.path},this.persistIndex())}),r(e=>({object:e,...t}))):d({object:null,...t}).pipe(w(()=>{const t=Object.keys(this.cachedIndex??{}).find(t=>this.privateObjectRelativePath(this.cachedIndex[t])===e.filename);t&&this.removeIndexEntry(t)})):"change"===e.event?s(this.reloadSubdirectory(e.filename)).pipe(o(),r(e=>({object:e,...t}))):a}));return h(t,e)}async reloadSubdirectory(e){return(await this.getAll(e)).filter(t=>t.path.startsWith(e))}async readFileIfExists(e){const t=E(this.path,e);for(let a=0;a<3;a++)try{const a=await O(t);return{...JSON.parse(a.toString()),path:x.dirname(e).replace(/^\.$/,""),filename:x.basename(e)}}catch(e){if(2===a)return console.error("Could not read file at "+t,e),null;await m(50*(a+1))}return null}async getAll(e){if(j){await this.loaded,await k(this.path);const t=await this.getObjectFilePaths(e??""),a=null==e||""===e,i=[];for(let e=0;e<t.length;e+=32){const a=Math.min(32,t.length-e),n=await Promise.all(Array.from({length:a},(a,i)=>{const n=t[e+i];return O(E(this.path,n)).then(e=>({...JSON.parse(e.toString()),path:x.dirname(n).replace(/^\.$/,""),filename:x.basename(n)}))}));i.push(...n)}return a&&(this.cachedIndex=R(i),await this.persistIndex()),i}const t=await this.loadIndex();return Promise.all(Object.keys(t).map(e=>this.get(e)))}async getObjectFilePaths(e){const t=this.path,a=x.join(t,e),i=[];return await async function e(a){const n=await v.readdir(a,{withFileTypes:!0});for(const s of n){const n=x.join(a,s.name);s.isDirectory()?await e(n):s.isFile()&&s.name.endsWith(".json")&&!/^[\._]/.test(s.name)&&i.push(x.relative(t,n))}}(a),i}async get(e){const t=await this.loadIndex(),a=t[e]??Object.values(t).find(t=>t.name===e);if(null==a)return;const i=this.privateObjectPath(a);if(!j)return(await fetch(i)).json();return await z(i)?{...JSON.parse((await O(i)).toString()),path:a.path??"",filename:x.basename(this.privateObjectRelativePath(a))}:null}async save(e){if(D(),await this.loaded,null==e.path){const t=(await this.loadIndex())[e.id];null!=t?.path&&(e={...e,path:t.path})}return await this.assertObjectFilePathAvailable(e,e.id),await v.writeFile(this.privateObjectPath(e),this.serialize(e)),await this.addOrUpdateIndexEntry(e),e}async rename(e,t){const a={...e,name:t};await this.assertObjectFilePathAvailable(a,e.id);const i=this.privateObjectPath(e),n=this.privateObjectPath(a);try{await v.rename(i,n)}catch(e){console.error(e),console.warn("Rename failed, retrying",{currentPath:i,newPath:n}),await m(400),await v.rename(i,n)}return await this.save(a),a}async delete(e){await v.unlink(this.privateObjectPath(e)),this.removeIndexEntry(e.id)}async create(t){D(),await this.loaded,t.id=e();const a=this.privateObjectPath(t);if(await this.assertObjectFilePathAvailable(t),await U(a))throw Error(`Can not create because a file already exists at ${a}`);return await v.writeFile(a,this.serialize(t)),await this.addOrUpdateIndexEntry(t),t}prepareCreate(t){return D(),t.id=e(),t}serialize(e){return this.serializer(e)}async addOrUpdateIndexEntry(e){null==this.cachedIndex&&await this.loadIndex(),this.cachedIndex[e.id]={id:e.id,name:e.name??e.id,path:e.path},await this.persistIndex()}removeIndexEntry(e){null!=this.cachedIndex&&delete this.cachedIndex[e],this.persistIndex()}async persistIndex(){j&&this.shouldCreateIndex&&null!=this.cachedIndex&&await v.writeFile(this.indexFilePath,JSON.stringify(this.cachedIndex,null,2))}get indexFilePath(){return E(this.path,"_meta.json")}async loadIndex(){if(null!=this.cachedIndex)return this.cachedIndex;this.loadingIndex??(this.loadingIndex=this.createIndex());try{return await this.loadingIndex}finally{this.loadingIndex=null}}async createIndex(){if(j){const e=await this.getAll();this.cachedIndex=R(e),await this.persistIndex()}else this.cachedIndex=await(await fetch(this.indexFilePath)).json();return this.cachedIndex}async ensureResourceDir(){await k(E(this.path+"-resources"))}async saveFile(e,t){return D(),await k(E(this.path+"-resources")),v.copyFile(t.path,E(this.path+"-resources",e.fileKey))}async saveExtraFile(e,t){return D(),await k(E(this.path+"-resources")),v.copyFile(e,E(this.path+"-resources",t))}getAssetPath(e){return window&&"function"==typeof window.require?window.require("path").join(this.path+"-resources",e.fileKey):E(this.path+"-resources",e.fileKey)}async replaceFile(e,t){if(await z(t))return v.copyFile(t,E(this.path+"-resources",e.fileKey));console.error("Failed to replace file using path "+t)}async deleteFile(e){if(null==e)return;D();const t=E(this.path+"-resources",e);return await z(t)?v.unlink(t):void 0}privateObjectPath(e){return E(this.path,this.privateObjectRelativePath(e))}privateObjectRelativePath(e){return this.filePathFn?E(e.path??"",this.filePathFn(e)):E(e.path??"",tokenizeName(e.name??e.id)+".json")}async assertObjectFilePathAvailable(e,t){const a=await this.findObjectFilePathCollision(e,t);if(null!=a)throw Error(`Can not save "${e.name??e.id}" because "${a.name}" already uses the same storage file name. Use a name that differs beyond letter casing.`)}async findObjectFilePathCollision(e,t){const a=A(this.privateObjectRelativePath(e)),i=await this.loadIndex();return Object.values(i).find(e=>e.id!==t&&A(this.privateObjectRelativePath(e))===a)??null}watchDir(e){return new c(t=>{if("win32"===process.platform&&j){const a=y.watch(e,{recursive:!0},(a,i)=>{if(i){const n=x.join(e,i);y.access(n,y.constants.F_OK,e=>{const n=e?"unlink":"rename"===a?"add":"change";t.next({event:n,filename:i})})}});return()=>a.close()}const a=b.watch(e,{cwd:e,ignoreInitial:!0,disableGlobbing:!0});return a.on("all",(e,a,i)=>{t.next({event:e,filename:a})}),a.on("error",()=>{}),()=>{a.close()}})}}export function tokenizeName(e){return e.trim().replace(/\s/g,"_").replace(/[^a-z0-9_\-\.]/gi,"")}function A(e){return e.replace(/\\/g,"/").toLowerCase()}function R(e){const t={};for(const a of e)t[a.id]={id:a.id,name:a.name??a.id,path:a.path};return t}async function k(e){j&&(await z(e)||await v.mkdir(e,{recursive:!0}))}function z(e){return!!j&&new Promise(function(t,a){y.exists(e,function(e){t(e)})})}function D(){if(!j)throw new Error("Must have direct access to filesystem")}async function U(e){try{await v.access(e,v.constants.F_OK)}catch(e){return!1}return!0}export function defaultSerializer(e){const t={...e};return delete t.path,delete t.filename,JSON.stringify(t,null,2)}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|