@hology/core 0.0.68 → 0.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{Subject as e}from"rxjs";import*as t from"three";import{BoxGeometry as a,Color as s,Euler as r,Fog as i,FogExp2 as n,Group as o,Material as l,Matrix4 as c,Mesh as h,MeshLambertMaterial as m,MeshPhongMaterial as d,MeshStandardMaterial as p,Object3D as u,PointLight as f,Quaternion as y,SphereGeometry as g,Texture as w,Vector2 as S,Vector3 as v,Vector4 as A}from"three";import b,{SpriteRenderer as M}from"three-nebula";import{bool as x,BooleanNode as j,float as I,FloatNode as P,NodeShaderMaterial as D,rgb as N,RgbNode as E,Texture2dLookupNode as V,textureSampler2d as C,vec2 as F,Vec2Node as k,vec3 as z,Vec3Node as O,vec4 as _}from"three-shader-graph";import{VfxActor as B}from"../effects/vfx/vfx-actor.js";import{VisualEffect as T}from"../effects/vfx/vfx-param.js";import{BaseActor as $}from"../gameplay/actors/actor.js";import U from"../gameplay/actors/builtin/index.js";import{PhysicsBodyType as W,withInjectionContext as L}from"../gameplay/index.js";import{Sampler2DNode as R}from"../shader-nodes/index.js";import{LambertShader as J}from"../shader/builtin/lambert-shader.js";import{StandardShader as H}from"../shader/builtin/standard-shader.js";import{UnlitShader as X}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as q}from"../shader/parameter.js";import{ArrayMap as G,groupBy as Y}from"../utils/collections.js";import{iterateMaterials as Z}from"../utils/materials.js";import{filterChildrenShallow as Q,filterSceneShallow as K,findFirstVisibleObject as ee}from"../utils/three/traverse.js";import{AssetMeshInstance as te}from"./asset-resource-loader.js";import{isCollisionMesh as ae}from"./collision/collision-shape-import.js";import{BoxCollisionShape as se,PhysicalShapeMesh as re}from"./collision/collision-shape.js";import{LandscapeManager as ie}from"./landscape/landscape-manager.js";import{initLandscape as ne}from"./landscape/landscape.js";import{SectionGrid as oe,smoothNormalsCrossMeshes as le}from"./landscape/utils.js";import{createGrassFoliageMaterial as ce}from"./materials/grass-foliage.js";import{createGrassMaterial as he}from"./materials/grass.js";import{getMaterialAttribute as me}from"./materials/utils/material-painting.js";import{createWaterMaterial as de}from"./materials/water.js";import{SerializedParamType as pe}from"./model.js";import{ShapeLibrary as ue,ShapeLibraryKeys as fe}from"./objects/shapes.js";import{ambientLightName as ye,createSky as ge,defaultSkyMaterial as we}from"./sky.js";import{LandscapeShader as Se}from"../shader/builtin/landscape-shader.js";const ve={};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 SceneMaterializer(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}export class SceneMaterializer{constructor(a,s,r,i,n,o,l,c){this.scene=a,this.dataProvider=s,this.assetsService=r,this.assetManagerService=i,this.renderingView=n,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new e,this.removed$=new e,this.error$=new e,this.editorActorParamSnapshot=new Map,this.assets=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.geometryCache=new Map,this.collisionShapeCache=new Map,this.originalFog=null,s.onUpdate((e=>this.update(e))),s.onRemove((e=>this.remove(e))),this.createAssetSubscription=r.onCreate.subscribe((e=>{this.assets.set(e.id,e)})),this.updateSubscription=r.onUpdate.subscribe((async e=>{this.assets.set(e.id,e),"material"==e.type?a.traverse((a=>{if(a instanceof t.Mesh)if(Array.isArray(a.material))for(let t=0;t<a.material.length;t++)this.refreshMaterial(a,a.material[t],e,t);else this.refreshMaterial(a,a.material,e)})):"mesh"==e.type?(this.findByAssetId(e.id).forEach((t=>{Ve(t.userData.src.materialAssignments,e.materialAssignments).forEach((e=>{this.applyMaterial(t,e)}))})),this.landscapeManagers.forEach((t=>{t.source.grass.layers.some((t=>t.meshes.some((t=>t.assetId===e.id))))&&t.queueRefreshScatter(this.renderingView?.camera.position??new v,!0)}))):"prefab"===e.type&&this.findByAssetId(e.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))}async refreshMaterial(e,t,a,s){if(t?.userData?.assetId!==a.id)return;const r=await materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0);r.userData=t.userData,null!=s?Fe(e.material[s],r)||(e.material[s]=r):Fe(e.material,r)||(e.material=r)}get actorInstances(){return Array.from(this.materializedActors.values())}async prefetchAssets(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));await Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>{if(null!=e)return this.assetManagerService.getMesh(e)})))))}async init(){await this.preInit(),be.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),await this.initActorsPostInit()}initActorsPostInit(e=this.actorInstances){const t=e.map((async e=>{const t=e.object.userData.src;if("vfx"===t.type)return Promise.resolve();const a=await this.assetsService.getAsset(t.assetId),s={...a?.actor?.params??{},...t.actor?.params??{}};for(const a of t.actor.innerParams??[])await this.applyActorComponentParams(e,a.path.slice(),a.params);const r=await je(s,e.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders,this.actorProvider);Object.assign(e,r);try{return await this.actorProvider.initActor(e)}catch(e){console.error(`Failed to initiate actor (name="${t.name}", id=${t.id})`,e)}}));return Promise.all(t)}addVfxChildActors(e,t=e){}async applyActorComponentParams(e,t,a){const s=t.length,r=t.shift();if(0==s){const t=await je(a,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[a,s]of Object.entries(t))null!=s&&(e[a]=s)}else null!=e[r]&&await this.applyActorComponentParams(e[r],t,a)}canObjectBeInstanced(e){return e.physics?.type!==W.dynamic&&"sky"!==e.type&&"global_fog"!==e.type}async canAssetBeInstanced(e){if(!this._canBeInstancedCache.has(e.assetId)){const t=await this.createFromAsset(e);if(null==t)return!1;const a=[];t.traverse((e=>{!ae(e)&&e.isMesh&&a.push(e)}));const s=1==a.length&&0==a[0].children.length,r=a[0]instanceof h&&null!=a[0].geometry.morphAttributes&&Object.keys(a[0].geometry.morphAttributes).length>0,i=!0;this._canBeInstancedCache.set(e.assetId,s&&i&&!r)}return this._canBeInstancedCache.get(e.assetId)}async preInit(){this.renderingView?.onLoop((()=>{null!=this.sky&&this.renderingView.camera.getWorldPosition(this.sky.position)})),this.assetsService.getAssets().then((e=>{for(const t of e)this.assets.set(t.id,t)}))}async initWithInstancing(){await this.preInit(),await this.prefetchAssets();const e=[],a=new G,i=new G;for(const t of this.dataProvider.getObjects())await Ee(t,(async(t,r,n)=>{const o="asset_mesh"==t.type&&this.canObjectBeInstanced(t)&&await this.canAssetBeInstanced(t),l="shape_mesh"===t.type&&"landscape"!==t.shape&&t.physics?.type!==W.dynamic;if(o||l)if(r&&r.children?.length>0&&r.children.splice(r.children.findIndex((e=>e.id===t.id)),1),l){let e=t.shape+JSON.stringify(t.shapeParams??{})+t.castShadow+t.receiveShadow;const a=t.materialAssignments?.at(0)?.materialId,r=null!=a?this.assets.get(a):null;let o=null;if(null!=r&&"shader"!==r.material.type){if(e+=r.material.type+r.material.shader,null!=r.material.shaderParams){if(e+=Object.entries(r.material.shaderParams).filter((([e,t])=>"color"!=e)).map((e=>JSON.stringify(e))).join(),null!=r.material.shaderParams.color){const e=r.material.shaderParams.color;e.type===pe.Color&&null!=e.value&&(o=new s(e.value))}}}else e+=a;i.push(e,{object:{...t,parentTransform:n},color:o})}else{const e=t.assetId+JSON.stringify(t.materialAssignments??[]);a.push(e,{...t,parentTransform:n})}else null==r&&e.push({...t,parentTransform:n})}));for(const e of a.values()){if(0==e.length)continue;const t=await this.createFromAsset(e[0]);if(null==t)continue;const a=await this.createInstancedMesh(e,t),s=new te;s.add(a),s.userData.src=e[0],t instanceof te&&(s.collisionShapes=t.collisionShapes),s.castShadow=!1,s.receiveShadow=!1,this.scene.add(s)}for(const e of i.values()){if(0==e.length)continue;const a=e[0].object,i=await this.createFromShape(a),n=ee(i,(e=>!ae(e)&&null!=e.geometry)),o=n.material.clone();null!=e[0].color&&null!=o.color&&(o.color=new s(16777215));const l=n.geometry,h=new t.InstancedMesh(l,o,e.length);for(let a=0;a<e.length;a++){const s=e[a],o=(new t.Matrix4).compose((new v).fromArray(s.object.position),(new y).setFromEuler((new r).fromArray(s.object.rotation)),(new v).fromArray(s.object.scale)),l=(new c).copy(s.object.parentTransform).multiply(o);h.setMatrixAt(a,l),null!=s.color&&h.setColorAt(a,s.color),h.castShadow=i.castShadow??!0,h.receiveShadow=n.receiveShadow??!0;const m=new te;m.add(h),m.userData.src=e[0],i instanceof re&&(m.collisionShapes=[i.collisionShape]),m.castShadow=!1,m.receiveShadow=!1,this.scene.add(m)}}await Promise.all(e.map((e=>this.materialize(e)))),await this.initActorsPostInit()}async createInstancedMesh(e,a){const s=ee(a,(e=>!ae(e)&&null!=e.geometry)),i=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(a,Ve(e[0].materialAssignments,i.materialAssignments)),s.updateMatrix();const n=s.geometry.clone().applyMatrix4(s.matrix),o=new t.InstancedMesh(n,s.material,e.length);s.material instanceof l&&(o.material.side=t.FrontSide);for(let a=0;a<e.length;a++){const s=(new t.Matrix4).compose((new v).fromArray(e[a].position),(new y).setFromEuler((new r).fromArray(e[a].rotation)),(new v).fromArray(e[a].scale)),i=(new c).copy(e[a].parentTransform).multiply(s);o.setMatrixAt(a,i)}return o.castShadow=e[0].castShadow??i.castShadow??!0,o.receiveShadow=e[0].receiveShadow??i.receiveShadow??!0,o}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t?(t.disposed.next(!0),t.onEndPlay()):console.warn("Failed to remove actor",e)}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 K(this.scene,(t=>t.userData.src?.assetId==e),(e=>null!=e.userData.src))}applyMaterials(e,t){return null==t?Promise.resolve([]):Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}async applyMaterial(e,t){await applyMaterial(e,t,(e=>{const t=this.assets.get(e);if(null!=t)return materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders)}),this._originalMaterials)}unapplyMaterials(e){e.traverse((async e=>{if(e instanceof h)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(U));K(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)}))}updateShaders(e){this.shaders=e;for(const[e,t]of be.entries())t.userData.customShaderName&&be.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),K(this.scene,(e=>!0)).forEach((e=>{e.traverse((async e=>{if(e instanceof h)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=this.assets.get(e.material[t].userData.assetId);this.refreshMaterial(e,e.material[t],a,t)}}else{const t=e.material.userData?.customShaderName;if(null!=t){const t=this.assets.get(e.material.userData.assetId);this.refreshMaterial(e,e.material,t)}}}))}))}async update(e){if("sky"===e.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(e);const t=this.sceneObjectMap.get(e.id);if(t){let r=!1;if(t.traverseAncestors((e=>{"_hology_transform_group"===e.name&&(r=!0)})),!r){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 h&&(e.material.wireframe=!0)})):t.traverse((e=>{e instanceof h&&(e.material.wireframe=!1)}))}if("asset_mesh"===e.type){const a=this.assets.get(e.assetId);Ve(e.materialAssignments,a.materialAssignments).forEach((e=>this.applyMaterial(t,e)))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);if(r||(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 s(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)}else"directional"===e.light.type?this.applyDirectionalLight(e.light.directional):"ambient"===e.light.type&&this.applyDirectionalAmbientLight(t,e.light.ambient);else if("landscape"===e.shape){const a=this.landscapeManagers.find((t=>t.source.id===e.id)).source.landscape.options.density!==e.landscape.options.density;if(this.inEditor&&a){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((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))))}else if("global_fog"===e.type){const t=(this.scene.fog instanceof n?"density":"linear")!==e.fog.type;this.scene.fog=De(e.fog),t&&(a=this.scene).traverse((e=>{if(e instanceof h){const t=e.material;t instanceof D&&(a.fog instanceof i?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof n&&(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.editorActorParamSnapshot.get(e.id);null!=t&&t===JSON.stringify(e.actor)||(console.log("Rematerializing actor because parameters changed"),r||(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 re&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}("asset_mesh"===e.type||"shape_mesh"===e.type&&"landscape"!==e.shape)&&Ae(t,e.castShadow,e.receiveShadow),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}async materializeAndInitActor(e,t=this.findParent(e)){console.log("materialize actor and init");const a=await this.materialize(e,t);return Ee(e,(async e=>{if("actor"===e.type){const t=this.materializedActors.get(e.id);null!=t?await this.initActorsPostInit([t]):console.error(`Something went wrong when creating actor ${e.id}`)}})),a}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:Q(t,(t=>t.children?.some((t=>t.id===e.id))),(()=>!0))))[0];return null==t?this.scene:null!=t?K(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 s(this.scene.fog.color))}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof h&&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=Y(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof h){const t=me(e,0,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}if(a>4){const t=me(e,4,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}}));const r=new Set;for(const[e,i]of s.entries()){const s=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let n=!1;if(null==s)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const o=me(s,0,!0);ke(o);for(const e of i)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),n=!0;if(a>4){const e=me(s,4,!0);ke(e);for(const t of i)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),n=!0}n&&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,s=!1){let r;switch(e.type){case"asset_mesh":r=await this.createFromAsset(e);break;case"shape_mesh":r=await this.createFromShape(e);break;case"light":r=await this.createLight(e);break;case"particles":r=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=De(e.fog),this.fixFogColor(),r=new o;break;case"sky":this.sky=ge(),this.updateSky(e),r=this.sky;break;case"actor":r=await this.createFromActor(e);break;case"group":r=new o;break;case"prefab":r=await this.createFromPrefabAsset(e);break;case"vfx":r=await this.createFromVfx(e);break;default:if(this.inEditor)throw new Error("unknown type "+e.type);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.`)}if(null!=r){if(e.name&&e.name.length>0&&(r.name=e.name),null!=e.position&&r.position.fromArray(e.position),null!=e.scale&&r.scale.fromArray(e.scale),null!=e.rotation&&r.rotation.fromArray(e.rotation),s||(r.userData.src=e),this.inEditor,this.inEditor){let e=null;r instanceof re&&(e=function(e){if(e instanceof se)return new h(new a(...e.offset.toArray()),Ne);return null}(r.collisionShape)),null!=e&&(e.layers.disable(0),e.layers.enable(18),e.scale.multiplyScalar(1.1),r.add(e))}return this.objectMap.set(r.uuid,e),this.sceneObjectMap.set(e.id,r),e.physics?.type!==W.dynamic||null==t||this.inEditor?null==t?this.scene.add(r):t?.add(r):(t.add(r),r.getWorldPosition(r.position),r.getWorldQuaternion(r.quaternion),r.getWorldScale(r.scale),this.scene?.attach(r)),null!=e.children&&await Promise.all(e.children?.map((e=>this.materialize(e,r,s)))),this.inEditor||"asset_mesh"!=e.type&&"shape_mesh"!==e.type||null!=e.physics?.type&&e.physics.type==W.dynamic||Pe(r),r}}async updateSky(e){if(null==e?.sky?.materialId)return void(this.sky.material=we);const a=await this.assetsService.getAsset(e.sky.materialId),s=await materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);s.side=t.BackSide,null!=this.sky?this.sky.material=s:console.warn("No sky has been created")}async createComponent(e,t,a,s){const r=new ve[a.path+"/"+a.className],i=t.id+s;r.id=i,r.object=e;for(const e of a.params)null!=e.value&&(r[e.name]=e.value);return this.components.push(r),i}async createFromActor(e){const t=this.actorTypes.find((t=>t.name===e.actor?.type))?.type??U[e.actor?.type];if(null==t)return null;this.inEditor&&this.editorActorParamSnapshot.set(e.id,JSON.stringify(e.actor));const a=await this.actorProvider.create(t,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!0);return this.materializedActors.set(e.id,a),a?.object}async createFromVfx(e){const t=await this.assetsService.getAsset(e.assetId);null==t&&console.error("Could not find asset",e);const a=await this.actorProvider.create(B,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!1);return await a.fromAsset(t),a.play(),this.materializedActors.set(e.id,a),a?.object}cleanup(){this.materializedActors.clear()}async createFromShape(e){const t=this.inEditor&&e.hidden;let a;if("landscape"==e.shape)a=this.createLandscape(e),a.traverse((e=>{e instanceof h&&this._originalMaterials.set(e.id,e.material)}));else{let r=new p({name:"Default",color:new s("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});const i=await this.createMeshByShape(e.shape,r,e.shapeParams);i.castShadow=e.castShadow??!0,i.receiveShadow=e.castShadow??!1,e.collisionDetection||(i.collisionShape=null),i.physics=e.physics,a=i,this._originalMaterials.set(a.id,i.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 o;const a=ne(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new ie(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 oe(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((()=>le(r)),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&fe.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);return this.geometryCache.has(r)||this.geometryCache.set(r,ue[e].geometry(s)),this.collisionShapeCache.has(r)||this.collisionShapeCache.set(r,ue[e].collision(s)),new re(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){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);let{scene:a}=await this.assetManagerService.getMesh(t,{mergeGeomtries:!0});Ve(e.materialAssignments,t.materialAssignments).forEach((e=>this.applyMaterial(a,e)));const s=e.receiveShadow??!!t.receiveShadow??!0,r=e.castShadow??!!t.castShadow??!1;return a.receiveShadow=s,Ae(a,r,s),e.collisionDetection||(a.collisionShapes=[]),null!=e.physics&&!0!==this.inEditor&&(a.physics=e.physics),this.applyVertexMaterials(e,a),a.traverse((e=>{e instanceof h&&"computeBoundsTree"in e.geometry&&null==e.geometry.boundsTree&&e.geometry.computeBoundsTree()})),a}async createFromPrefabAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);const a=new o;return t.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,a,!0))),a}async createParticleSystem(e){const a=await this.assetsService.getAsset(e.assetId),s=new u;return await b.fromJSONAsync(a.particleSystem,t).then((e=>{const a=new M(s,t);e.addRenderer(a),this.renderingView.onLoop((t=>e.update()))})),s}async createLight(e){if("point"===e.light.type){const t=new f(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 g(.3,10,10),a=new p({color:new s(16771709)}),r=new h(e,a);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional),new o):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient),new o):void 0}applyDirectionalAmbientLight(e,t){const a=this.scene.children.find((e=>e.name===ye));null!=a?(a.intensity=t.intensity,a.color.set(t.color),a.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.createAssetSubscription.unsubscribe(),this.materializedActors.forEach((e=>e.disposed.next(!0)))}}function Ae(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse((e=>{e.castShadow=t,e.receiveShadow=a}))}const be=new Map,Me=new m({color:16711935}),xe=new Map;export async function materialFromAsset(e,a,r,i,n,o=!0){const l=JSON.stringify(e.material);if(o&&be.has(l))return be.get(l);const c={opacity:e.material.params.opacity,map:null,emissive:e.material.params.emissive??null,metalness:e.material.params.metalness??0,flatShading:e.material.params.flatShading??!1,color:new s(e.material.params.color),transparent:null!=e.material.params.opacity&&e.material.params.opacity<1},h={};if(null!=e.material.params.map){const t=e.material.params.map,a=await r.getAsset(t);null!=a&&(c.map=await i.getTexture(a))}let m;switch(e.material.type){case"phong":m=new d({...c,...h});break;case"water":m=de(c,a);break;case"grassFoliage":m=ce({color:c.color,map:c.map},a);break;case"grass":m=he({...c,colorTwo:new s(e.material.params.colorTwo),colorThree:new s(e.material.params.colorThree)},a);break;case"standard":case"unlit":case"lambert":case"shader":case"landscape":const t={standard:H,lambert:J,unlit:X,landscape:Se}[e.material.type]??n.find((t=>t.name==e.material.shader))?.type;if(t){const s=new t,o=await je(e.material?.shaderParams??{},t,r,i,null,a,n);Object.assign(s,o);try{m=s.build()}catch(t){console.log("Shader runtime error: "+t),xe.has(e.material.shader)||xe.set(e.material.shader,Me.clone()),m=xe.get(e.material.shader)}m.userData.customShaderName=e.material.shader}else console.warn("Missing shader implementation with name "+e.material.shader),m=Me;break;default:throw new Error("Unsupported material type"+e.material.type)}return a?.csm.setupMaterial(m),o&&be.set(l,m),m.side=e.material.side??m.side??t.FrontSide,m.transparent=(e.material.transparent??c.transparent??!1)||m.transparent,e.material.bloom&&(m.userData.hasBloom=!0),m.userData.assetId=e.id,m}async function je(e,t,a,s,r,i,n,o){const l={};for(const[t,c]of Object.entries(e)){const e=await Ie(c,a,s,r,i,n,o);null!=e&&(l[t]=e)}return l}export async function prepareShapeParameters(e){const t={};for(const[a,s]of Object.entries(e)){const e=await Ie(s,null,null,null);null!=e&&(t[a]=e)}return t}async function Ie(e,t,a,i,n,o,l){if(pe.String,null==e||null==e.value||""===e.value)return null;const c=e.value;switch(e.type){case pe.Number:case pe.FloatNode:let h="string"==typeof c?parseFloat(c):c;return e.type===pe.FloatNode?I(h):h;case pe.Texture:return await a.getTexture(await t.getAsset(c));case pe.Sampler2DNode:return C(await a.getTexture(await t.getAsset(c)));case pe.Boolean:return c;case pe.BooleanNode:return x(c);case pe.Vector2:case pe.Vec2Node:if("object"==typeof c){const t=c instanceof Array?(new S).fromArray(c):new S(c.x,c.y);return e.type===pe.Vec2Node?F(t):t}return null;case pe.Vector3:case pe.Vec3Node:if("object"==typeof c){const t=c instanceof Array?(new v).fromArray(c):new v(c.x,c.y,c.z);return e.type===pe.Vec3Node?z(t):t}return null;case pe.Color:case pe.RgbNode:const m=new s(c);return e.type===pe.RgbNode?N(m):m;case pe.String:return c;case pe.BaseActor:const d=c;return null==i&&console.warn("Class parameters can not be prepared as actors are not passed in"),i?.get(d);case pe.Euler:const p=c;return(new r).fromArray(p);case pe.Object3D:return(await a.getMesh(await t.getAsset(c))).scene;case pe.Material:return await materialFromAsset(await t.getAsset(c),n,t,a,o);case pe.AudioBuffer:return await a.getAudio(await t.getAsset(c));case pe.VisualEffect:const u=await t.getAsset(c);if(null==l){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in u)return new T(l,u);console.error("Using a non-vfx asset for visual effect parameter")}return null}function Pe(e){e.updateWorldMatrix(!1,!0),e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}function De(e){return"linear"===e.type?new i(new s(e.color),e.near??100,e.far??1e3):"density"===e.type?new n(e.color,e.density):void console.warn("Invalid fog type",e)}const Ne=new p({color:4229780});async function Ee(e,a,s,i){null==i&&(i=(new c).identity()),await a(e,s,i);const n=i.clone().multiply(function(e,t){if(null==e.position||null==e.rotation||null==e.scale)return t.identity();return t.compose((new v).fromArray(e.position),(new y).setFromEuler((new r).fromArray(e.rotation)),(new v).fromArray(e.scale))}(e,new t.Matrix4));return Promise.all((e.children??[]).map((t=>Ee(t,a,e,n))))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?pe.Number:t instanceof P||"function"==typeof e.prototype.isFloat?pe.FloatNode:t instanceof w||e===w||e.isTexture?pe.Texture:t instanceof R||e===V?pe.Sampler2DNode:t instanceof Boolean||e===Boolean?pe.Boolean:t instanceof j?pe.BooleanNode:t instanceof s||e==s?pe.Color:t instanceof E||"function"==typeof e.prototype.isRgb?pe.RgbNode:t instanceof S||e==S?pe.Vector2:t instanceof k||"function"==typeof e.prototype.isVec2?pe.Vec2Node:t instanceof v||e==v?pe.Vector3:t instanceof O||"function"==typeof e.prototype.isVec3?pe.Vec3Node:t instanceof String||e===String?pe.String:t instanceof $||e==$||e.prototype instanceof $||e.prototype==$?pe.BaseActor:t instanceof r||e==r?pe.Euler:t instanceof u||e==u?pe.Object3D:t instanceof l||e==l?pe.Material:t instanceof AudioBuffer||e==AudioBuffer?pe.AudioBuffer:t instanceof T||e==T?pe.VisualEffect:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,a={}){return Object.fromEntries(e.map((e=>[e.name,{type:toSerializedParamType(e.type),value:t[e.name]?.value??a[e.name]??customParameterDefaultValueByType.get(toSerializedParamType(e.type))}])))}export function prepareCustomParamsFromType(e,t,a=null){const s=q(e);if(0===s.length)return{};let r;null!=a?L(a,(()=>{r=a.get(e)})):r=new e;const i={};for(const e of s){const t=r[e.name];if(null!=t){const a=serializeCustomParameter(e.type,t);null!=a&&(i[e.name]=a)}}return prepareCustomParams(s,t,i)}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 S:return t instanceof S?t.toArray():void a();case v:return t instanceof v?t.toArray():void a();case A:return t instanceof A?t.toArray():void a();case s:return t instanceof s?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new s(t).getHexString():void a();case String:return t;case r:return t instanceof r?t.toArray():void a()}}function Ve(e,t){return function(e,t,a){const s=[],r=new Set;for(const i of[...e??[],...t??[]]){const e=a(i);r.has(e)||(r.add(e),s.push(i))}return s}((e??[]).filter((e=>Ce(e.materialId))),(t??[]).filter((e=>Ce(e.materialId))),(e=>e.color+e.name))}function Ce(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[pe.RgbNode,"#000000"],[pe.Color,"#000000"],[pe.Vector4,[0,0,0,0]],[pe.Vec4Node,[0,0,0,0]],[pe.Vector3,[0,0,0]],[pe.Vec3Node,[0,0,0]],[pe.Vector2,[0,0]],[pe.Vec2Node,[0,0]],[pe.Euler,[0,0,0,"XYZ"]]]);export function applyMaterial(e,a,r,i){const n=[];return e.traverse((async e=>{if(e instanceof h||e.isMesh||e instanceof t.SkinnedMesh||e.isSkinnedMesh)for(const t of Z(e.material))t.hasOwnProperty("color")&&n.push(e)})),Promise.all(n.map((async e=>{if(e.material instanceof Array)for(let t=0;t<e.material.length;t++){const n=e.material[t];if(null==n.color||!(n.color instanceof s))continue;const o="#"+n.color.getHexString(),l=n.name;if(o===a.color&&(n.name===a.name||null==a.name)||e.userData["originalColor_"+t]===a.color&&e.userData["originalMaterialName_"+t]===a.name){const s=await r(a.materialId),n=e.material[t];null!=s&&(e.material[t]=s,e.userData["originalColor_"+t]=e.userData["originalColor_"+t]??o,e.userData["originalMaterialName_"+t]=e.userData["originalMaterialName_"+t]??l,null!=i&&i.set(e.id+"#"+t,n))}}else if("color"in e.material){const t="#"+e.material.color.getHexString(),s=e.material.name;if(t===a.color&&(e.material.name===a.name||null==a.name)||e.userData.originalColor===a.color&&e.userData.originalName===a.name){const n=await r(a.materialId),o=e.material;null!=n&&(e.material=n,e.userData.originalColor=e.userData.originalColor??t,e.userData.originalMaterialName=e.userData.originalMaterialName??s,null!=i&&(i.has(e.id)||i.set(e.id,o)))}}})))}function Fe(e,a){if(e instanceof t.ShaderMaterial&&a instanceof t.ShaderMaterial){return e.fragmentShader+e.vertexShader==a.fragmentShader+a.vertexShader&&function(e,a){if(e instanceof t.ShaderMaterial&&a instanceof t.ShaderMaterial){for(const t in e.uniforms){if(null==a.uniforms[t])return!1;if(a.uniforms[t].value!==e.uniforms[t].value)return console.log("Different values",a.uniforms[t].value,e.uniforms[t].value),!1}return!0}return!1}(e,a)}return!1}function ke(e){for(let t=0;t<e.array.length;t++)e.setX(t,0)}
1
+ import{Subject as e}from"rxjs";import*as t from"three";import{BoxGeometry as a,Color as s,Euler as r,Fog as i,FogExp2 as n,Group as o,Material as l,Matrix4 as c,Mesh as h,MeshLambertMaterial as m,MeshPhongMaterial as d,MeshStandardMaterial as p,Object3D as u,PointLight as f,Quaternion as y,SphereGeometry as g,Texture as w,Vector2 as S,Vector3 as v,Vector4 as A}from"three";import b,{SpriteRenderer as M}from"three-nebula";import{bool as x,BooleanNode as j,float as I,FloatNode as P,NodeShaderMaterial as D,rgb as N,RgbNode as E,Texture2dLookupNode as V,textureSampler2d as C,vec2 as F,Vec2Node as k,vec3 as z,Vec3Node as O,vec4 as _}from"three-shader-graph";import{VfxActor as B}from"../effects/vfx/vfx-actor.js";import{VisualEffect as T}from"../effects/vfx/vfx-param.js";import{BaseActor as $}from"../gameplay/actors/actor.js";import U from"../gameplay/actors/builtin/index.js";import{PhysicsBodyType as W,withInjectionContext as L}from"../gameplay/index.js";import{Sampler2DNode as R}from"../shader-nodes/index.js";import{LambertShader as J}from"../shader/builtin/lambert-shader.js";import{StandardShader as H}from"../shader/builtin/standard-shader.js";import{UnlitShader as X}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as q}from"../shader/parameter.js";import{ArrayMap as G,groupBy as Y}from"../utils/collections.js";import{iterateMaterials as Z}from"../utils/materials.js";import{filterChildrenShallow as Q,filterSceneShallow as K,findFirstVisibleObject as ee}from"../utils/three/traverse.js";import{AssetMeshInstance as te}from"./asset-resource-loader.js";import{isCollisionMesh as ae}from"./collision/collision-shape-import.js";import{BoxCollisionShape as se,PhysicalShapeMesh as re}from"./collision/collision-shape.js";import{LandscapeManager as ie}from"./landscape/landscape-manager.js";import{initLandscape as ne}from"./landscape/landscape.js";import{SectionGrid as oe,smoothNormalsCrossMeshes as le}from"./landscape/utils.js";import{createGrassFoliageMaterial as ce}from"./materials/grass-foliage.js";import{createGrassMaterial as he}from"./materials/grass.js";import{getMaterialAttribute as me}from"./materials/utils/material-painting.js";import{createWaterMaterial as de}from"./materials/water.js";import{SerializedParamType as pe}from"./model.js";import{ShapeLibrary as ue,ShapeLibraryKeys as fe}from"./objects/shapes.js";import{ambientLightName as ye,createSky as ge,defaultSkyMaterial as we}from"./sky.js";import{LandscapeShader as Se}from"../shader/builtin/landscape-shader.js";const ve={};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 SceneMaterializer(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}export class SceneMaterializer{constructor(a,s,r,i,n,o,l,c){this.scene=a,this.dataProvider=s,this.assetsService=r,this.assetManagerService=i,this.renderingView=n,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new e,this.removed$=new e,this.error$=new e,this.editorActorParamSnapshot=new Map,this.assets=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.geometryCache=new Map,this.collisionShapeCache=new Map,this.originalFog=null,s.onUpdate((e=>this.update(e))),s.onRemove((e=>this.remove(e))),this.createAssetSubscription=r.onCreate.subscribe((e=>{this.assets.set(e.id,e)})),this.updateSubscription=r.onUpdate.subscribe((async e=>{this.assets.set(e.id,e),"material"==e.type?a.traverse((a=>{if(a instanceof t.Mesh)if(Array.isArray(a.material))for(let t=0;t<a.material.length;t++)this.refreshMaterial(a,a.material[t],e,t);else this.refreshMaterial(a,a.material,e)})):"mesh"==e.type?(this.findByAssetId(e.id).forEach((t=>{Ve(t.userData.src.materialAssignments,e.materialAssignments).forEach((e=>{this.applyMaterial(t,e)}))})),this.landscapeManagers.forEach((t=>{t.source.grass.layers.some((t=>t.meshes.some((t=>t.assetId===e.id))))&&t.queueRefreshScatter(this.renderingView?.camera.position??new v,!0)}))):"prefab"===e.type&&this.findByAssetId(e.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))}async refreshMaterial(e,t,a,s){if(t?.userData?.assetId!==a.id)return;const r=await materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0);r.userData=t.userData,null!=s?Fe(e.material[s],r)||(e.material[s]=r):Fe(e.material,r)||(e.material=r)}get actorInstances(){return Array.from(this.materializedActors.values())}async prefetchAssets(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));await Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>{if(null!=e)return this.assetManagerService.getMesh(e)})))))}async init(){await this.preInit(),be.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),await this.initActorsPostInit()}initActorsPostInit(e=this.actorInstances){const t=e.map((async e=>{const t=e.object.userData.src;if("vfx"===t.type)return Promise.resolve();const a=await this.assetsService.getAsset(t.assetId),s={...a?.actor?.params??{},...t.actor?.params??{}};for(const a of t.actor.innerParams??[])await this.applyActorComponentParams(e,a.path.slice(),a.params);const r=await je(s,e.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders,this.actorProvider);Object.assign(e,r);try{return await this.actorProvider.initActor(e)}catch(e){console.error(`Failed to initiate actor (name="${t.name}", id=${t.id})`,e)}}));return Promise.all(t)}addVfxChildActors(e,t=e){}async applyActorComponentParams(e,t,a){const s=t.length,r=t.shift();if(0==s){const t=await je(a,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[a,s]of Object.entries(t))null!=s&&(e[a]=s)}else null!=e[r]&&await this.applyActorComponentParams(e[r],t,a)}canObjectBeInstanced(e){return e.physics?.type!==W.dynamic&&"sky"!==e.type&&"global_fog"!==e.type}async canAssetBeInstanced(e){if(!this._canBeInstancedCache.has(e.assetId)){const t=await this.createFromAsset(e);if(null==t)return!1;const a=[];t.traverse((e=>{!ae(e)&&e.isMesh&&a.push(e)}));const s=1==a.length&&0==a[0].children.length,r=a[0]instanceof h&&null!=a[0].geometry.morphAttributes&&Object.keys(a[0].geometry.morphAttributes).length>0,i=!0;this._canBeInstancedCache.set(e.assetId,s&&i&&!r)}return this._canBeInstancedCache.get(e.assetId)}async preInit(){this.renderingView?.onLoop((()=>{null!=this.sky&&this.renderingView.camera.getWorldPosition(this.sky.position)})),this.assetsService.getAssets().then((e=>{for(const t of e)this.assets.set(t.id,t)}))}async initWithInstancing(){await this.preInit(),await this.prefetchAssets();const e=[],a=new G,i=new G;for(const t of this.dataProvider.getObjects())await Ee(t,(async(t,r,n)=>{const o="asset_mesh"==t.type&&this.canObjectBeInstanced(t)&&await this.canAssetBeInstanced(t),l="shape_mesh"===t.type&&"landscape"!==t.shape&&t.physics?.type!==W.dynamic;if(o||l)if(r&&r.children?.length>0&&r.children.splice(r.children.findIndex((e=>e.id===t.id)),1),l){let e=t.shape+JSON.stringify(t.shapeParams??{})+t.castShadow+t.receiveShadow;const a=t.materialAssignments?.at(0)?.materialId,r=null!=a?this.assets.get(a):null;let o=null;if(null!=r&&"shader"!==r.material.type){if(e+=r.material.type+r.material.shader,null!=r.material.shaderParams){if(e+=Object.entries(r.material.shaderParams).filter((([e,t])=>"color"!=e)).map((e=>JSON.stringify(e))).join(),null!=r.material.shaderParams.color){const e=r.material.shaderParams.color;e.type===pe.Color&&null!=e.value&&(o=new s(e.value))}}}else e+=a;i.push(e,{object:{...t,parentTransform:n},color:o})}else{const e=t.assetId+JSON.stringify(t.materialAssignments??[]);a.push(e,{...t,parentTransform:n})}else null==r&&e.push({...t,parentTransform:n})}));for(const e of a.values()){if(0==e.length)continue;const t=await this.createFromAsset(e[0]);if(null==t)continue;const a=await this.createInstancedMesh(e,t),s=new te;s.add(a),s.userData.src=e[0],t instanceof te&&(s.collisionShapes=t.collisionShapes),s.castShadow=!1,s.receiveShadow=!1,this.scene.add(s)}for(const e of i.values()){if(0==e.length)continue;const a=e[0].object,i=await this.createFromShape(a),n=ee(i,(e=>!ae(e)&&null!=e.geometry)),o=n.material.clone();null!=e[0].color&&null!=o.color&&(o.color=new s(16777215));const l=n.geometry,h=new t.InstancedMesh(l,o,e.length);for(let a=0;a<e.length;a++){const s=e[a],o=(new t.Matrix4).compose((new v).fromArray(s.object.position),(new y).setFromEuler((new r).fromArray(s.object.rotation)),(new v).fromArray(s.object.scale)),l=(new c).copy(s.object.parentTransform).multiply(o);h.setMatrixAt(a,l),null!=s.color&&h.setColorAt(a,s.color),h.castShadow=i.castShadow??!0,h.receiveShadow=n.receiveShadow??!0;const m=new te;m.add(h),m.userData.src=e[0],i instanceof re&&(m.collisionShapes=[i.collisionShape]),m.castShadow=!1,m.receiveShadow=!1,this.scene.add(m)}}await Promise.all(e.map((e=>this.materialize(e)))),await this.initActorsPostInit()}async createInstancedMesh(e,a){const s=ee(a,(e=>!ae(e)&&null!=e.geometry)),i=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(a,Ve(e[0].materialAssignments,i.materialAssignments)),s.updateMatrix();const n=s.geometry.clone().applyMatrix4(s.matrix),o=new t.InstancedMesh(n,s.material,e.length);s.material instanceof l&&(o.material.side=t.FrontSide);for(let a=0;a<e.length;a++){const s=(new t.Matrix4).compose((new v).fromArray(e[a].position),(new y).setFromEuler((new r).fromArray(e[a].rotation)),(new v).fromArray(e[a].scale)),i=(new c).copy(e[a].parentTransform).multiply(s);o.setMatrixAt(a,i)}return o.castShadow=e[0].castShadow??i.castShadow??!0,o.receiveShadow=e[0].receiveShadow??i.receiveShadow??!0,o}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t?(t.disposed.next(!0),t.onEndPlay()):console.warn("Failed to remove actor",e)}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 K(this.scene,(t=>t.userData.src?.assetId==e),(e=>null!=e.userData.src))}applyMaterials(e,t){return null==t?Promise.resolve([]):Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}async applyMaterial(e,t){await applyMaterial(e,t,(e=>{const t=this.assets.get(e);if(null!=t)return materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders)}),this._originalMaterials)}unapplyMaterials(e){e.traverse((async e=>{if(e instanceof h)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(U));K(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)}))}updateShaders(e){this.shaders=e;for(const[e,t]of be.entries())t.userData.customShaderName&&be.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),K(this.scene,(e=>!0)).forEach((e=>{e.traverse((async e=>{if(e instanceof h)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=this.assets.get(e.material[t].userData.assetId);this.refreshMaterial(e,e.material[t],a,t)}}else{const t=e.material.userData?.customShaderName;if(null!=t){const t=this.assets.get(e.material.userData.assetId);this.refreshMaterial(e,e.material,t)}}}))}))}async update(e){if("sky"===e.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(e);const t=this.sceneObjectMap.get(e.id);if(t){let r=!1;if(t.traverseAncestors((e=>{"_hology_transform_group"===e.name&&(r=!0)})),!r){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 h&&(e.material.wireframe=!0)})):t.traverse((e=>{e instanceof h&&(e.material.wireframe=!1)}))}if("asset_mesh"===e.type){const a=this.assets.get(e.assetId);Ve(e.materialAssignments,a.materialAssignments).forEach((e=>this.applyMaterial(t,e)))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);if(r||(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 s(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)}else"directional"===e.light.type?this.applyDirectionalLight(e.light.directional):"ambient"===e.light.type&&this.applyDirectionalAmbientLight(t,e.light.ambient);else if("landscape"===e.shape){const a=this.landscapeManagers.find((t=>t.source.id===e.id)).source.landscape.options.density!==e.landscape.options.density;if(this.inEditor&&a){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((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))))}else if("global_fog"===e.type){const t=(this.scene.fog instanceof n?"density":"linear")!==e.fog.type;this.scene.fog=De(e.fog),t&&(a=this.scene).traverse((e=>{if(e instanceof h){const t=e.material;t instanceof D&&(a.fog instanceof i?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof n&&(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.editorActorParamSnapshot.get(e.id);null!=t&&t===JSON.stringify(e.actor)||(console.log("Rematerializing actor because parameters changed"),r||(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 re&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}("asset_mesh"===e.type||"shape_mesh"===e.type&&"landscape"!==e.shape)&&Ae(t,e.castShadow,e.receiveShadow),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}async materializeAndInitActor(e,t=this.findParent(e)){console.log("materialize actor and init");const a=await this.materialize(e,t);return Ee(e,(async e=>{if("actor"===e.type){const t=this.materializedActors.get(e.id);null!=t?await this.initActorsPostInit([t]):console.error(`Something went wrong when creating actor ${e.id}`)}})),a}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:Q(t,(t=>t.children?.some((t=>t.id===e.id))),(()=>!0))))[0];return null==t?this.scene:null!=t?K(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 s(this.scene.fog.color))}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof h&&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=Y(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof h){if(null==e.geometry)return;const t=me(e,0,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}if(a>0){const t=me(e,5,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}}));const r=new Set;for(const[e,i]of s.entries()){const s=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let n=!1;if(null==s||null==s.geometry)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const o=me(s,0,!0);ke(o);for(const e of i)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),n=!0;if(a>0){const e=me(s,4,!0);ke(e);for(const t of i)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),n=!0}n&&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,s=!1){let r;switch(e.type){case"asset_mesh":r=await this.createFromAsset(e);break;case"shape_mesh":r=await this.createFromShape(e);break;case"light":r=await this.createLight(e);break;case"particles":r=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=De(e.fog),this.fixFogColor(),r=new o;break;case"sky":this.sky=ge(),this.updateSky(e),r=this.sky;break;case"actor":r=await this.createFromActor(e);break;case"group":r=new o;break;case"prefab":r=await this.createFromPrefabAsset(e);break;case"vfx":r=await this.createFromVfx(e);break;default:if(this.inEditor)throw new Error("unknown type "+e.type);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.`)}if(null!=r){if(e.name&&e.name.length>0&&(r.name=e.name),null!=e.position&&r.position.fromArray(e.position),null!=e.scale&&r.scale.fromArray(e.scale),null!=e.rotation&&r.rotation.fromArray(e.rotation),s||(r.userData.src=e),this.inEditor,this.inEditor){let e=null;r instanceof re&&(e=function(e){if(e instanceof se)return new h(new a(...e.offset.toArray()),Ne);return null}(r.collisionShape)),null!=e&&(e.layers.disable(0),e.layers.enable(18),e.scale.multiplyScalar(1.1),r.add(e))}return this.objectMap.set(r.uuid,e),this.sceneObjectMap.set(e.id,r),e.physics?.type!==W.dynamic||null==t||this.inEditor?null==t?this.scene.add(r):t?.add(r):(t.add(r),r.getWorldPosition(r.position),r.getWorldQuaternion(r.quaternion),r.getWorldScale(r.scale),this.scene?.attach(r)),null!=e.children&&await Promise.all(e.children?.map((e=>this.materialize(e,r,s)))),this.inEditor||"asset_mesh"!=e.type&&"shape_mesh"!==e.type||null!=e.physics?.type&&e.physics.type==W.dynamic||Pe(r),r}}async updateSky(e){if(null==e?.sky?.materialId)return void(this.sky.material=we);const a=await this.assetsService.getAsset(e.sky.materialId),s=await materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);s.side=t.BackSide,null!=this.sky?this.sky.material=s:console.warn("No sky has been created")}async createComponent(e,t,a,s){const r=new ve[a.path+"/"+a.className],i=t.id+s;r.id=i,r.object=e;for(const e of a.params)null!=e.value&&(r[e.name]=e.value);return this.components.push(r),i}async createFromActor(e){const t=this.actorTypes.find((t=>t.name===e.actor?.type))?.type??U[e.actor?.type];if(null==t)return null;this.inEditor&&this.editorActorParamSnapshot.set(e.id,JSON.stringify(e.actor));const a=await this.actorProvider.create(t,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!0);return this.materializedActors.set(e.id,a),a?.object}async createFromVfx(e){const t=await this.assetsService.getAsset(e.assetId);null==t&&console.error("Could not find asset",e);const a=await this.actorProvider.create(B,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!1);return await a.fromAsset(t),a.play(),this.materializedActors.set(e.id,a),a?.object}cleanup(){this.materializedActors.clear()}async createFromShape(e){const t=this.inEditor&&e.hidden;let a;if("landscape"==e.shape)a=this.createLandscape(e),a.traverse((e=>{e instanceof h&&this._originalMaterials.set(e.id,e.material)}));else{let r=new p({name:"Default",color:new s("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});const i=await this.createMeshByShape(e.shape,r,e.shapeParams);i.castShadow=e.castShadow??!0,i.receiveShadow=e.castShadow??!1,e.collisionDetection||(i.collisionShape=null),i.physics=e.physics,a=i,this._originalMaterials.set(a.id,i.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 o;const a=ne(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new ie(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 oe(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((()=>le(r)),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&fe.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);return this.geometryCache.has(r)||this.geometryCache.set(r,ue[e].geometry(s)),this.collisionShapeCache.has(r)||this.collisionShapeCache.set(r,ue[e].collision(s)),new re(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){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);let{scene:a}=await this.assetManagerService.getMesh(t,{mergeGeomtries:!0});Ve(e.materialAssignments,t.materialAssignments).forEach((e=>this.applyMaterial(a,e)));const s=e.receiveShadow??!!t.receiveShadow??!0,r=e.castShadow??!!t.castShadow??!1;return a.receiveShadow=s,Ae(a,r,s),e.collisionDetection||(a.collisionShapes=[]),null!=e.physics&&!0!==this.inEditor&&(a.physics=e.physics),this.applyVertexMaterials(e,a),a.traverse((e=>{e instanceof h&&"computeBoundsTree"in e.geometry&&null==e.geometry.boundsTree&&e.geometry.computeBoundsTree()})),a}async createFromPrefabAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);const a=new o;return t.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,a,!0))),a}async createParticleSystem(e){const a=await this.assetsService.getAsset(e.assetId),s=new u;return await b.fromJSONAsync(a.particleSystem,t).then((e=>{const a=new M(s,t);e.addRenderer(a),this.renderingView.onLoop((t=>e.update()))})),s}async createLight(e){if("point"===e.light.type){const t=new f(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 g(.3,10,10),a=new p({color:new s(16771709)}),r=new h(e,a);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional),new o):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient),new o):void 0}applyDirectionalAmbientLight(e,t){const a=this.scene.children.find((e=>e.name===ye));null!=a?(a.intensity=t.intensity,a.color.set(t.color),a.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.createAssetSubscription.unsubscribe(),this.materializedActors.forEach((e=>e.disposed.next(!0)))}}function Ae(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse((e=>{e.castShadow=t,e.receiveShadow=a}))}const be=new Map,Me=new m({color:16711935}),xe=new Map;export async function materialFromAsset(e,a,r,i,n,o=!0){const l=JSON.stringify(e.material);if(o&&be.has(l))return be.get(l);const c={opacity:e.material.params.opacity,map:null,emissive:e.material.params.emissive??null,metalness:e.material.params.metalness??0,flatShading:e.material.params.flatShading??!1,color:new s(e.material.params.color),transparent:null!=e.material.params.opacity&&e.material.params.opacity<1},h={};if(null!=e.material.params.map){const t=e.material.params.map,a=await r.getAsset(t);null!=a&&(c.map=await i.getTexture(a))}let m;switch(e.material.type){case"phong":m=new d({...c,...h});break;case"water":m=de(c,a);break;case"grassFoliage":m=ce({color:c.color,map:c.map},a);break;case"grass":m=he({...c,colorTwo:new s(e.material.params.colorTwo),colorThree:new s(e.material.params.colorThree)},a);break;case"standard":case"unlit":case"lambert":case"shader":case"landscape":const t={standard:H,lambert:J,unlit:X,landscape:Se}[e.material.type]??n.find((t=>t.name==e.material.shader))?.type;if(t){const s=new t,o=await je(e.material?.shaderParams??{},t,r,i,null,a,n);Object.assign(s,o);try{m=s.build()}catch(t){console.log("Shader runtime error: "+t),xe.has(e.material.shader)||xe.set(e.material.shader,Me.clone()),m=xe.get(e.material.shader)}m.userData.customShaderName=e.material.shader}else console.warn("Missing shader implementation with name "+e.material.shader),m=Me;break;default:throw new Error("Unsupported material type"+e.material.type)}return a?.csm.setupMaterial(m),o&&be.set(l,m),m.side=e.material.side??m.side??t.FrontSide,m.transparent=(e.material.transparent??c.transparent??!1)||m.transparent,e.material.bloom&&(m.userData.hasBloom=!0),m.userData.assetId=e.id,m}async function je(e,t,a,s,r,i,n,o){const l={};for(const[t,c]of Object.entries(e)){const e=await Ie(c,a,s,r,i,n,o);null!=e&&(l[t]=e)}return l}export async function prepareShapeParameters(e){const t={};for(const[a,s]of Object.entries(e)){const e=await Ie(s,null,null,null);null!=e&&(t[a]=e)}return t}async function Ie(e,t,a,i,n,o,l){if(pe.String,null==e||null==e.value||""===e.value)return null;const c=e.value;switch(e.type){case pe.Number:case pe.FloatNode:let h="string"==typeof c?parseFloat(c):c;return e.type===pe.FloatNode?I(h):h;case pe.Texture:return await a.getTexture(await t.getAsset(c));case pe.Sampler2DNode:return C(await a.getTexture(await t.getAsset(c)));case pe.Boolean:return c;case pe.BooleanNode:return x(c);case pe.Vector2:case pe.Vec2Node:if("object"==typeof c){const t=c instanceof Array?(new S).fromArray(c):new S(c.x,c.y);return e.type===pe.Vec2Node?F(t):t}return null;case pe.Vector3:case pe.Vec3Node:if("object"==typeof c){const t=c instanceof Array?(new v).fromArray(c):new v(c.x,c.y,c.z);return e.type===pe.Vec3Node?z(t):t}return null;case pe.Color:case pe.RgbNode:const m=new s(c);return e.type===pe.RgbNode?N(m):m;case pe.String:return c;case pe.BaseActor:const d=c;return null==i&&console.warn("Class parameters can not be prepared as actors are not passed in"),i?.get(d);case pe.Euler:const p=c;return(new r).fromArray(p);case pe.Object3D:return(await a.getMesh(await t.getAsset(c))).scene;case pe.Material:return await materialFromAsset(await t.getAsset(c),n,t,a,o);case pe.AudioBuffer:return await a.getAudio(await t.getAsset(c));case pe.VisualEffect:const u=await t.getAsset(c);if(null==l){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in u)return new T(l,u);console.error("Using a non-vfx asset for visual effect parameter")}return null}function Pe(e){e.updateWorldMatrix(!1,!0),e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}function De(e){return"linear"===e.type?new i(new s(e.color),e.near??100,e.far??1e3):"density"===e.type?new n(e.color,e.density):void console.warn("Invalid fog type",e)}const Ne=new p({color:4229780});async function Ee(e,a,s,i){null==i&&(i=(new c).identity()),await a(e,s,i);const n=i.clone().multiply(function(e,t){if(null==e.position||null==e.rotation||null==e.scale)return t.identity();return t.compose((new v).fromArray(e.position),(new y).setFromEuler((new r).fromArray(e.rotation)),(new v).fromArray(e.scale))}(e,new t.Matrix4));return Promise.all((e.children??[]).map((t=>Ee(t,a,e,n))))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?pe.Number:t instanceof P||"function"==typeof e.prototype.isFloat?pe.FloatNode:t instanceof w||e===w||e.isTexture?pe.Texture:t instanceof R||e===V?pe.Sampler2DNode:t instanceof Boolean||e===Boolean?pe.Boolean:t instanceof j?pe.BooleanNode:t instanceof s||e==s?pe.Color:t instanceof E||"function"==typeof e.prototype.isRgb?pe.RgbNode:t instanceof S||e==S?pe.Vector2:t instanceof k||"function"==typeof e.prototype.isVec2?pe.Vec2Node:t instanceof v||e==v?pe.Vector3:t instanceof O||"function"==typeof e.prototype.isVec3?pe.Vec3Node:t instanceof String||e===String?pe.String:t instanceof $||e==$||e.prototype instanceof $||e.prototype==$?pe.BaseActor:t instanceof r||e==r?pe.Euler:t instanceof u||e==u?pe.Object3D:t instanceof l||e==l?pe.Material:t instanceof AudioBuffer||e==AudioBuffer?pe.AudioBuffer:t instanceof T||e==T?pe.VisualEffect:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,a={}){return Object.fromEntries(e.map((e=>[e.name,{type:toSerializedParamType(e.type),value:t[e.name]?.value??a[e.name]??customParameterDefaultValueByType.get(toSerializedParamType(e.type))}])))}export function prepareCustomParamsFromType(e,t,a=null){const s=q(e);if(0===s.length)return{};let r;null!=a?L(a,(()=>{r=a.get(e)})):r=new e;const i={};for(const e of s){const t=r[e.name];if(null!=t){const a=serializeCustomParameter(e.type,t);null!=a&&(i[e.name]=a)}}return prepareCustomParams(s,t,i)}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 S:return t instanceof S?t.toArray():void a();case v:return t instanceof v?t.toArray():void a();case A:return t instanceof A?t.toArray():void a();case s:return t instanceof s?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new s(t).getHexString():void a();case String:return t;case r:return t instanceof r?t.toArray():void a()}}function Ve(e,t){return function(e,t,a){const s=[],r=new Set;for(const i of[...e??[],...t??[]]){const e=a(i);r.has(e)||(r.add(e),s.push(i))}return s}((e??[]).filter((e=>Ce(e.materialId))),(t??[]).filter((e=>Ce(e.materialId))),(e=>e.color+e.name))}function Ce(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[pe.RgbNode,"#000000"],[pe.Color,"#000000"],[pe.Vector4,[0,0,0,0]],[pe.Vec4Node,[0,0,0,0]],[pe.Vector3,[0,0,0]],[pe.Vec3Node,[0,0,0]],[pe.Vector2,[0,0]],[pe.Vec2Node,[0,0]],[pe.Euler,[0,0,0,"XYZ"]]]);export function applyMaterial(e,a,r,i){const n=[];return e.traverse((async e=>{if(e instanceof h||e.isMesh||e instanceof t.SkinnedMesh||e.isSkinnedMesh)for(const t of Z(e.material))t.hasOwnProperty("color")&&n.push(e)})),Promise.all(n.map((async e=>{if(e.material instanceof Array)for(let t=0;t<e.material.length;t++){const n=e.material[t];if(null==n.color||!(n.color instanceof s))continue;const o="#"+n.color.getHexString(),l=n.name;if(o===a.color&&(n.name===a.name||null==a.name)||e.userData["originalColor_"+t]===a.color&&e.userData["originalMaterialName_"+t]===a.name){const s=await r(a.materialId),n=e.material[t];null!=s&&(e.material[t]=s,e.userData["originalColor_"+t]=e.userData["originalColor_"+t]??o,e.userData["originalMaterialName_"+t]=e.userData["originalMaterialName_"+t]??l,null!=i&&i.set(e.id+"#"+t,n))}}else if("color"in e.material){const t="#"+e.material.color.getHexString(),s=e.material.name;if(t===a.color&&(e.material.name===a.name||null==a.name)||e.userData.originalColor===a.color&&e.userData.originalName===a.name){const n=await r(a.materialId),o=e.material;null!=n&&(e.material=n,e.userData.originalColor=e.userData.originalColor??t,e.userData.originalMaterialName=e.userData.originalMaterialName??s,null!=i&&(i.has(e.id)||i.set(e.id,o)))}}})))}function Fe(e,a){if(e instanceof t.ShaderMaterial&&a instanceof t.ShaderMaterial){return e.fragmentShader+e.vertexShader==a.fragmentShader+a.vertexShader&&function(e,a){if(e instanceof t.ShaderMaterial&&a instanceof t.ShaderMaterial){for(const t in e.uniforms){if(null==a.uniforms[t])return!1;if(a.uniforms[t].value!==e.uniforms[t].value)return console.log("Different values",a.uniforms[t].value,e.uniforms[t].value),!1}return!0}return!1}(e,a)}return!1}function ke(e){for(let t=0;t<e.array.length;t++)e.setX(t,0)}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hology/core",
3
- "version": "0.0.68",
3
+ "version": "0.0.70",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",