@hology/core 0.0.202 → 0.0.203
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/vfx/vfx-actor.d.ts +2 -0
- package/dist/effects/vfx/vfx-actor.js +1 -1
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/scene/landscape/utils.d.ts +8 -0
- package/dist/scene/landscape/utils.js +1 -1
- package/dist/scene/materializer.js +1 -1
- package/dist/shader/graph/compiler.d.ts +2 -0
- package/dist/shader/graph/compiler.js +1 -1
- package/dist/shader/graph/model.d.ts +1 -1
- package/dist/shader/graph/registry.js +1 -1
- package/dist/test/landscape-expansion.test.d.ts +2 -0
- package/dist/test/landscape-expansion.test.js +4 -0
- package/dist/test/shader-graph.test.js +1 -1
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -31,6 +31,8 @@ export declare class VfxActor extends BaseActor {
|
|
|
31
31
|
stop(): void;
|
|
32
32
|
applyClipEndBehavior(behavior: VfxClipEndBehavior | undefined, remainingLifeSeconds?: number): void;
|
|
33
33
|
restart(): void;
|
|
34
|
+
private restartEmitter;
|
|
35
|
+
private removeEmitterParticlesRecursive;
|
|
34
36
|
private _worldPos;
|
|
35
37
|
private _worldRot;
|
|
36
38
|
private _worldEul;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t}from"tslib";import*as s from"three";import{Rate as e}from"@hology/nebula";import{Actor as i,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as o}from"../../gameplay/inject.js";import{AssetLoader as a}from"../../gameplay/services/asset-loader.js";import{ViewController as n}from"../../gameplay/services/render.js";import{World as
|
|
1
|
+
import{__decorate as t}from"tslib";import*as s from"three";import{Rate as e}from"@hology/nebula";import{Actor as i,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as o}from"../../gameplay/inject.js";import{AssetLoader as a}from"../../gameplay/services/asset-loader.js";import{ViewController as n}from"../../gameplay/services/render.js";import{World as m}from"../../gameplay/services/world.js";import{DelayRate as h}from"./rates.js";import{materializeVfx as l}from"./vfx-materializer.js";import{PhysicsSystem as p}from"../../gameplay/services/physics/physics-system.js";import{ShaderProvider as c}from"../../gameplay/services/shader-provider.js";import{AssetResourceLoader as d}from"../../scene/asset-resource-loader.js";import{AssetsProvider as u}from"../../scene/assets-provider.js";import{VfxInputRuntime as y}from"./vfx-input-runtime.js";let f=class extends r{constructor(){super(...arguments),this.timescale=1,this.paused=!0,this.assetLoader=o(a),this.assetManagerService=o(d),this.assetService=o(u),this.world=o(m),this.view=o(n),this.physics=o(p),this.shaderProvider=o(c),this.inputRuntime=new y,this.inputOverrides=new Map,this._worldPos=new s.Vector3,this._worldRot=new s.Quaternion,this._worldEul=new s.Euler,this.max=0}async fromAsset(t,s){if("vfx"!==t.type)throw"Asset must be a VFX asset but is "+t.type;null!=this.system&&(this.system.destroy(),this.system.emitters.forEach(t=>t.reset())),this.sourceAsset=t,this.disposeSystem&&this.disposeSystem(),this.world.scene.add(this.object),this.inputRuntime.setDefinitions(this.sourceAsset.vfx.inputs??[]);for(const[t,s]of this.inputOverrides)this.inputRuntime.setInput(t,s);null!=s&&this.setInputs(s);const{system:e,dispose:i,container:r}=await l(this.sourceAsset,this.object,{getAsset:t=>this.assetLoader.getAsset(t),getMaterial:t=>this.assetLoader.getMaterialByAssetId(t),getTexture:t=>this.assetLoader.getTextureByAssetId(t),getMesh:t=>this.assetLoader.getModelByAssetId(t).then(t=>t.scene)},this.view,this.physics,this.shaderProvider,this.assetService,this.assetManagerService,this.inputRuntime);this.system=e,this.disposeSystem=i,this.particleSystemContainer=r,this.object.visible=!1,this.object.matrixAutoUpdate=!1,this.object.matrixWorldAutoUpdate=!1,this.particleSystemContainer.matrixAutoUpdate=!1,this.particleSystemContainer.matrixWorldAutoUpdate=!1}setInput(t,e){this.inputOverrides.set(t,function(t){if(t instanceof s.Vector3||t instanceof s.Color)return t.clone();if(Array.isArray(t))return[...t];return t}(e)),this.inputRuntime.setInput(t,e)}setInputs(t){for(const[s,e]of Object.entries(t))this.setInput(s,e)}play(){null==this.particleSystemContainer.parent&&this.world.scene.add(this.particleSystemContainer),this.object.matrixAutoUpdate=!0,this.object.matrixWorldAutoUpdate=!0,this.particleSystemContainer.matrixAutoUpdate=!0,this.particleSystemContainer.matrixWorldAutoUpdate=!0,this.object.visible=!0,this.paused=!1;this.system.emitters.every(t=>t.dead)&&this.restart()}pause(){this.paused=!0}stop(){this.system.emitters.forEach(t=>{this.stopEmitterEmission(t)})}applyClipEndBehavior(t,s){const e=t??"finish";if("finish"!==e){if(null!=this.system&&null!=this.system.emitters)for(const t of this.system.emitters)this.applyEmitterClipEndBehavior(t,e,s)}else this.stop()}restart(){if(null!=this.system&&null!=this.system.emitters)for(const t of this.system.emitters)this.restartEmitter(t)}restartEmitter(t){const s=t.rate;s instanceof h?s.restart():s instanceof e&&(s.nextTime=0),null==t.clearParticlesRecursive?this.removeEmitterParticlesRecursive(t):t.clearParticlesRecursive()}removeEmitterParticlesRecursive(t){const s=t.childEmitters??[];for(const t of s)this.removeEmitterParticlesRecursive(t);t.removeAllParticles?.()}onUpdate(t){this.paused||(this.object.getWorldPosition(this._worldPos),this.object.getWorldQuaternion(this._worldRot),this._worldEul.setFromQuaternion(this._worldRot),this.system?.emitters.forEach(t=>{"world"===t._space&&(t.setPosition(this._worldPos),t.setRotation(this._worldEul))}),this.updateSystem(t*this.timescale))}getParticleCount(){return this.system?.getCount()??0}onEndPlay(){this.stop(),null!=this.disposeSystem&&this.disposeSystem()}updateSystem(t){this.system?.update(t)}applyEmitterClipEndBehavior(t,s,e,i=!1){this.stopEmitterEmission(t,i);const r=t.particles??[];if("kill"===s)t.removeAllParticles?.();else{const t=Math.max(0,e??0);for(const s of r)s.life=Math.min(s.life,s.age+t)}const o=t.childEmitters??[];for(const t of o)this.applyEmitterClipEndBehavior(t,s,e,!0)}stopEmitterEmission(t,s=!1){const i=t.rate;i instanceof e&&(i.nextTime=1/0),s&&t.stopEmit?.()}};f=t([i()],f);export{f as VfxActor};/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e,{Behaviour as t,Body as a,Emitter as r,Rate as s}from"@hology/nebula";import*as n from"three";import{Object3D as i}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as u,UniformFloatNode as p,UniformVec3Node as d,Vec3ExpressionNode as h,Vec4Node as m,attributeFloat as f,attributeVec3 as y,attributeVec4 as w,attributes as g,clamp as b,float as v,glslFunction as A,lambertMaterial as E,log as M,pow as x,rgb as I,rgba as S,smoothstep as T,standardMaterial as P,textureSampler2d as B,uniformFloat as C,uniforms as R,varying as k,varyingAttributes as j,varyingVec3 as G,varyingVec4 as V}from"three-shader-graph";import{prepareClassParameters as D,prepareShaderGraphParameters as F,prepareShapeParameters as z}from"../../scene/materializer.js";import{SerializedParamType as O}from"../../scene/model.js";import{ShapeLibrary as L}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as Q,linearEyeDepth as W}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as H,particleTimeUniformName as U,particleUniforms as q,particleVelcoityUniformName as J}from"../../shader-nodes/particle.js";import{sampleFlipbook as N}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as X}from"./initializsers.js";import{DelayRate as K,OnceRate as Y}from"./rates.js";import{StretchedSprite as _}from"./stretched-sprite.js";import{ThreeBlendingMode as Z}from"./vfx-asset.js";import{VfxBehaviourLibrary as $,VfxInitializserLibrary as ee}from"./vfx-defs.js";import{MultiRenderer as te}from"./vfx-renderers.js";import{WorldCollisionBehaviour as ae}from"./vfx-collision-behaviour.js";import{getSpritePosition as re,SpriteNodeShaderMaterial as se}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ne}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as ie}from"../../shader/builtin/decal-standard-shader.js";import{createBoundBehaviour as oe,createBoundInitializer as le}from"./vfx-binding-runtime.js";import{buildShaderGraphMaterial as ce}from"../../shader/graph/index.js";export async function materializeVfx(t,a,r,s,o,l,c,u,p){let d=a;for(;null!=d.parent;)d=d.parent;const h=new i;h.name="particle system local",a.add(h);const m=new i;m.name="particle system world";const f=new te(m,h,n,s),y=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await ue(e,r,c,u,y,o,l,p);return t.setParentRecursive(y),t.emit()}))).forEach(e=>y.addEmitter(e)),y.addRenderer(f).emit({onEnd:()=>{}}),{container:m,system:y,dispose:()=>{m.removeFromParent(),h.removeFromParent(),f.dispose()}}}async function ue(e,t,r,u,v,x,I,P){const G=function(e){let t;switch(e.rate.type){case"continuous":t=new K(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new Y(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new s(0,1/0)}return t}(e);let D;switch(e.output.type){case"decal":D=new a(await async function(e,t,a,r,s){if("shaderGraph"===me(e)){const t=await he(e,"decal",a,r,s);if(null!=t){const a=new n.Mesh(new n.BoxGeometry(1,1,1),t);return null!=e.renderOrder&&(a.renderOrder=e.renderOrder),a}}const i=!1!==e.unlit?new ne:new ie;i.color=new n.Color(e.color),i instanceof ne?i.intensity=e.intensity??1:i.emissiveIntensity=e.intensity??1;if(e.colorMap){const a=await t.getTexture(e.colorMap);i.colorMap=a}if(e.alphaMap){const a=await t.getTexture(e.alphaMap);i.alphaMap=a}const o=i.build();o.blending=Z[e.blendingMode]??n.NormalBlending,o.transparent=!0,o.side=n.BackSide,o.depthTest=!1,null!=o&&!0===e.bloom&&(o.userData.hasBloom=!0);o.defines.IS_PARTICLE="";const l=new n.BoxGeometry(1,1,1),c=new n.Mesh(l,o);null!=e.renderOrder&&(c.renderOrder=e.renderOrder);return c}(e.output,t,r,u,I));break;case"sprite":D=new a(await async function(e,t,a,r,s){let i=null;const o=me(e);"shaderGraph"===o&&(i=await he(e,"sprite",a,r,s));null==i&&"shader"===o&&null!=e.shader&&(i=await de(e,t,s));null==i&&(i=await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):pe,r=B(a);let s=r.sample(j.uv);e.flipbook?.enabled&&(s=N(r,g.uv,e.flipbook.columns,e.flipbook.rows,q.time,e.flipbook.fps,e.flipbook.mode));const i=new p("rotation",0),o=new d("color").rgb,l=C("opacity",1),c=W.subtract(Q).divide(W);let u=l;switch(e.opacityChannel??"red"){case"none":break;case"red":u=u.multiply(s.r);break;case"alpha":u=u.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=b(c,0,1e3);u=u.multiply(T(0,.2*e.softness,t))}const h=re(i),m=S(o.multiply(s.rgb).multiplyScalar(e.intensity??1),u);var f=new se({color:m,emissive:m.rgb.multiplyScalar(u),transparent:!0,position:h,alphaTest:1e-4,uniforms:{color:{value:new n.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=Z[e.blendingMode]??n.NormalBlending,f}(e,t));fe(i,e);const l=new n.Mesh(new n.PlaneGeometry(1,1),i);return l.name="sprite",l}(e.output,t,r,u,I));break;case"stretchedSprite":D=new a(await async function(e,t){"shaderGraph"===me(e)&&console.warn("Shader graph materials are not supported for stretched sprite VFX outputs yet. Falling back to the default stretched sprite material.");const a=null!=e.texture?await t.getTexture(e.texture):pe,r=B(a).sample(j.uv),s=V(new l("color")),i=s.rgb.multiply(r.rgb);let o=s.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(r.r);break;case"alpha":o=o.multiply(r.a)}if("number"==typeof e.softness&&e.softness>0){const t=W.subtract(Q).divide(M(W)),a=b(t,0,1e3);o=o.multiply(T(0,.2*e.softness,a))}const c=A(m,{position:g.position,offset:y("offset"),modelViewMatrix:R.modelViewMatrix,velocity:w("velocity"),size:y("size"),rotation:f("rotation")},"\n float lengthFactor = velocity.w;\n float avgSize = (size.x + size.y) * 0.5;\n\n vec4 mvPosition = modelViewMatrix * vec4( offset , 1.0 );\n vec3 viewVelocity = normalMatrix * velocity.xyz;\n float vlength = length(viewVelocity); \n mvPosition.xyz += position.y * normalize(cross(mvPosition.xyz, viewVelocity)) * avgSize; \n mvPosition.xyz -= (position.x + 0.5) * viewVelocity * (1.0 + lengthFactor / vlength) * avgSize;\n return projectionMatrix * mvPosition;\n ");var u=new se({color:S(i.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:c,uniforms:{color:{value:new n.Color(e.color)}}});null!=u&&!0===e.bloom&&(u.userData.hasBloom=!0);u.blending=Z[e.blendingMode]??n.NormalBlending;const p=new _(new n.PlaneGeometry(1,1),u);return p.scaleFactor=e.scale,p}(e.output,t));break;case"shape":D=new a(await async function(e,t,a,r,s){if(null==e.shape)return console.log("Shape is null"),new i;const l=L[e.shape];if(null==l)return console.error(`No shape with type ${e.shape}`),new i;const u=z(e.params??{}),p=l.geometry(u);let d=null;const m=me(e);"shaderGraph"===m&&(d=await he(e,"surface",a,r,s));null==d&&"shader"===m&&null!=e.shader&&(d=await de(e,t,s));null==d&&(d="material"===m&&null!=e.material?ye(await t.getMaterial(e.material)):function(){const e=k(new h("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:E({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}());return fe(d,e),new n.Mesh(p,d)}(e.output,t,r,u,I));break;case"mesh":D=new a(await async function(e,t,a,r,s){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new i;const o=await t.getMesh(e.assetId),l=await t.getAsset(e.assetId),c=me(e);if("shaderGraph"===c||"shader"===c||"material"===c){let i;"shaderGraph"===c?i=await he(e,"surface",a,r,s):"shader"===c&&null!=e.shader?i=await de(e,t,s):"material"===c&&null!=e.material&&(i=ye(await t.getMaterial(e.material))),fe(i,e),o.traverse(e=>{e instanceof n.Mesh&&null!=i&&(e.material=i)})}else{const e=[];if(null!=l.materialAssignments)for(const a of l.materialAssignments)o.traverse(r=>{r instanceof n.Mesh&&r.material instanceof n.Material&&r.material.color instanceof n.Color&&(r.material.name!=a.name&&null!=a.name||"#"+r.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>r.material=e)))});await Promise.all(e)}const u=[];if(o.traverse(e=>{e instanceof n.Mesh&&u.push(e)}),1===u.length){const e=u[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return o}(e.output,t,r,u,I));break;case"trail":{const s="shaderGraph"===me(e.output)?await he(e.output,"trail",r,u,I,{trailBillboard:e.output.billboard??!1}):null;D=new a({type:"trail",taper:e.output.taper,headGeometry:null,material:s instanceof n.ShaderMaterial?s:void 0,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1});break}default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const F=new ge;F.parent=v,F.setRate(G),F._space=e.output.space;const H=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=ee[e.type]).map(async e=>{const t=ee[e.type],a=await z(e.params??{});return le(t,e.params??{},a,P)}));H.push(D,new X),F.addInitializers(H);const U=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=$[e.type]).map(async e=>{const t=$[e.type];for(const[a,r]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&r.type!==O.Curve&&(r.type=O.Curve);const a=await z(e.params??{},r,u);return oe(t,e.params??{},a,P)}).sort((e,t)=>e instanceof ae?1:0));U.push(new we);for(const e of U)e instanceof ae&&(e.physics=x);F.addBehaviours(U);for(const a of e.children){const e=await ue(a,t,r,u,v,x,I,P),s=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=F.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&F.childEmitters.splice(e,1),s.release(t)},t}),n=F.eventDispatcher,i=new Map;F.bindEmitterEvent=!0,n.addEventListener("PARTICLE_DEAD",e=>{const t=i.get(e.id);if(null!=t){const e=F.childEmitters.findIndex(e=>e.id===t.id);null!=e&&(t.stopEmit(),F.childEmitters.splice(e,1))}});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}n.addEventListener(o,e=>{const t=s.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),F.childEmitters.push(t),i.set(e.id,t),t.parentParticle=e,t.system=F.system,t.emit()})}return F}const pe=(new n.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function de(e,t,a){const r=a.get(e.shader);if(null==r)return console.error("No shader exists with name "+e.shader),new n.Material;const s=new r.type,i=await D(e.shaderParams??{},r.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0,void 0,s);return Object.assign(s,i),s.build()}async function he(e,t,a,r,s,n={}){const i=e.shaderGraph;if("asset"!==i?.source||null==i.assetId)return console.warn(`Missing shader graph asset reference for ${e.type} VFX output`),null;const o=await a.getAsset(i.assetId),l=o?.shaderGraph;if(null==l)return console.warn(`Missing shader graph asset "${i.assetId}" for ${e.type} VFX output`),null;if(l.target!==t)return console.warn(`Shader graph "${o.name}" targets "${l.target}" but ${e.type} VFX output expects "${t}"`),null;try{const t=await F(e.shaderGraphParams??{},l,a,r,void 0,s.shaders),o=ce(l,{parameters:t,trailBillboard:n.trailBillboard});return o.userData.customShaderName=`shaderGraph:${i.assetId}`,fe(o,e),o}catch(e){return console.log("Shader graph VFX runtime error: "+e,e),null}}function me(e){return null!=e.materialSource?e.materialSource:"asset"===e.shaderGraph?.source?"shaderGraph":"shader"in e&&null!=e.shader?"shader":"mesh"!==e.type&&"shape"!==e.type||null==e.material?"default":"material"}function fe(e,t){null!=e&&("bloom"in t&&!0===t.bloom&&(e.userData.hasBloom=!0),"sprite"===t.type?(e.blending=Z[t.blendingMode]??n.NormalBlending,!0===t.lockY&&e instanceof n.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.LOCK_Y_AXIS="")):"decal"===t.type&&(e.blending=Z[t.blendingMode]??n.NormalBlending,e.transparent=!0,e.side=n.BackSide,e.depthTest=!1,e instanceof n.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE="")))}function ye(e){const t=k(new h("instanceColor")).rgb;let a,r=k(new o("particleData")).x;if(e instanceof n.MeshStandardMaterial||e instanceof n.MeshLambertMaterial||e instanceof n.MeshBasicMaterial){let s=t.multiply(I(e.color));null!=e.map&&(s=s.multiply(B(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(r=r.multiply(B(e.alphaMap).sample(j.uv).r)),e instanceof n.MeshStandardMaterial?a=new c({color:P({color:s,emissive:I(e.emissive),emissiveIntensity:v(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(r),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof n.MeshLambertMaterial?a=new c({color:E({color:s}).rgb.rgba(r),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof n.MeshBasicMaterial&&(a=new c({color:s.rgb.rgba(r),emissive:s.rgb,transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class we extends t{initialize(e){e.body instanceof n.Object3D&&e.body.traverse(e=>{if(e instanceof n.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[H]||null!=t.uniforms[U]||t.uniforms[J])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof i&&e.target.traverse(t=>{if(t instanceof n.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[H]&&(a.uniforms[H].value=this.energy),null!=a.uniforms[U]&&(a.uniforms[U].value=e.age),null!=a.uniforms[J]&&(a.uniforms[J].value=e.velocity))}})}}class ge extends r{constructor(){super(...arguments),this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}update(e){if(!this.isEmitting&&0===this.particles.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle?t.position.copy(t.parentParticle.position):t.setPosition(this.position),t.update(e)}clone(){const e=new ge;return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
|
|
1
|
+
import e,{Behaviour as t,Body as a,Emitter as r,Rate as s}from"@hology/nebula";import*as i from"three";import{Object3D as n}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as p,UniformFloatNode as u,UniformVec3Node as h,Vec3ExpressionNode as d,Vec4Node as m,attributeFloat as f,attributeVec3 as y,attributeVec4 as g,attributes as w,clamp as b,float as v,glslFunction as E,lambertMaterial as A,log as M,pow as x,rgb as P,rgba as S,smoothstep as I,standardMaterial as T,textureSampler2d as C,uniformFloat as R,uniforms as B,varying as k,varyingAttributes as j,varyingVec3 as D,varyingVec4 as G}from"three-shader-graph";import{prepareClassParameters as V,prepareShaderGraphParameters as F,prepareShapeParameters as z}from"../../scene/materializer.js";import{SerializedParamType as L}from"../../scene/model.js";import{ShapeLibrary as O}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as W,linearEyeDepth as Q}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as H,particleTimeUniformName as U,particleUniforms as q,particleVelcoityUniformName as J}from"../../shader-nodes/particle.js";import{sampleFlipbook as N}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as X}from"./initializsers.js";import{DelayRate as _,OnceRate as K}from"./rates.js";import{StretchedSprite as Y}from"./stretched-sprite.js";import{ThreeBlendingMode as Z}from"./vfx-asset.js";import{VfxBehaviourLibrary as $,VfxInitializserLibrary as ee}from"./vfx-defs.js";import{MultiRenderer as te}from"./vfx-renderers.js";import{WorldCollisionBehaviour as ae}from"./vfx-collision-behaviour.js";import{getSpritePosition as re,SpriteNodeShaderMaterial as se}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ie}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as ne}from"../../shader/builtin/decal-standard-shader.js";import{createBoundBehaviour as oe,createBoundInitializer as le}from"./vfx-binding-runtime.js";import{buildShaderGraphMaterial as ce}from"../../shader/graph/index.js";export async function materializeVfx(t,a,r,s,o,l,c,p,u){let h=a;for(;null!=h.parent;)h=h.parent;const d=new n;d.name="particle system local",a.add(d);const m=new n;m.name="particle system world";const f=new te(m,d,i,s),y=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await pe(e,r,c,p,y,o,l,u,a);return t.setParentRecursive(y),t.emit()}))).forEach(e=>y.addEmitter(e)),y.addRenderer(f).emit({onEnd:()=>{}}),{container:m,system:y,dispose:()=>{m.removeFromParent(),d.removeFromParent(),f.dispose()}}}async function pe(e,t,r,p,v,x,P,T,D){const V=function(e){let t;switch(e.rate.type){case"continuous":t=new _(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new K(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new s(0,1/0)}return t}(e);let F;switch(e.output.type){case"decal":F=new a(await async function(e,t,a,r,s){if("shaderGraph"===me(e)){const t=await de(e,"decal",a,r,s);if(null!=t){const a=new i.Mesh(new i.BoxGeometry(1,1,1),t);return null!=e.renderOrder&&(a.renderOrder=e.renderOrder),a}}const n=!1!==e.unlit?new ie:new ne;n.color=new i.Color(e.color),n instanceof ie?n.intensity=e.intensity??1:n.emissiveIntensity=e.intensity??1;if(e.colorMap){const a=await t.getTexture(e.colorMap);n.colorMap=a}if(e.alphaMap){const a=await t.getTexture(e.alphaMap);n.alphaMap=a}const o=n.build();o.blending=Z[e.blendingMode]??i.NormalBlending,o.transparent=!0,o.side=i.BackSide,o.depthTest=!1,null!=o&&!0===e.bloom&&(o.userData.hasBloom=!0);o.defines.IS_PARTICLE="";const l=new i.BoxGeometry(1,1,1),c=new i.Mesh(l,o);null!=e.renderOrder&&(c.renderOrder=e.renderOrder);return c}(e.output,t,r,p,P));break;case"sprite":F=new a(await async function(e,t,a,r,s){let n=null;const o=me(e);"shaderGraph"===o&&(n=await de(e,"sprite",a,r,s));null==n&&"shader"===o&&null!=e.shader&&(n=await he(e,t,s));null==n&&(n=await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):ue,r=C(a);let s=r.sample(j.uv);e.flipbook?.enabled&&(s=N(r,w.uv,e.flipbook.columns,e.flipbook.rows,q.time,e.flipbook.fps,e.flipbook.mode));const n=new u("rotation",0),o=new h("color").rgb,l=R("opacity",1),c=Q.subtract(W).divide(Q);let p=l;switch(e.opacityChannel??"red"){case"none":break;case"red":p=p.multiply(s.r);break;case"alpha":p=p.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=b(c,0,1e3);p=p.multiply(I(0,.2*e.softness,t))}const d=re(n),m=S(o.multiply(s.rgb).multiplyScalar(e.intensity??1),p);var f=new se({color:m,emissive:m.rgb.multiplyScalar(p),transparent:!0,position:d,alphaTest:1e-4,uniforms:{color:{value:new i.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=Z[e.blendingMode]??i.NormalBlending,f}(e,t));fe(n,e);const l=new i.Mesh(new i.PlaneGeometry(1,1),n);return l.name="sprite",l}(e.output,t,r,p,P));break;case"stretchedSprite":F=new a(await async function(e,t){"shaderGraph"===me(e)&&console.warn("Shader graph materials are not supported for stretched sprite VFX outputs yet. Falling back to the default stretched sprite material.");const a=null!=e.texture?await t.getTexture(e.texture):ue,r=C(a).sample(j.uv),s=G(new l("color")),n=s.rgb.multiply(r.rgb);let o=s.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(r.r);break;case"alpha":o=o.multiply(r.a)}if("number"==typeof e.softness&&e.softness>0){const t=Q.subtract(W).divide(M(Q)),a=b(t,0,1e3);o=o.multiply(I(0,.2*e.softness,a))}const c=E(m,{position:w.position,offset:y("offset"),modelViewMatrix:B.modelViewMatrix,velocity:g("velocity"),size:y("size"),rotation:f("rotation")},"\n float lengthFactor = velocity.w;\n float avgSize = (size.x + size.y) * 0.5;\n\n vec4 mvPosition = modelViewMatrix * vec4( offset , 1.0 );\n vec3 viewVelocity = normalMatrix * velocity.xyz;\n float vlength = length(viewVelocity); \n mvPosition.xyz += position.y * normalize(cross(mvPosition.xyz, viewVelocity)) * avgSize; \n mvPosition.xyz -= (position.x + 0.5) * viewVelocity * (1.0 + lengthFactor / vlength) * avgSize;\n return projectionMatrix * mvPosition;\n ");var p=new se({color:S(n.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:c,uniforms:{color:{value:new i.Color(e.color)}}});null!=p&&!0===e.bloom&&(p.userData.hasBloom=!0);p.blending=Z[e.blendingMode]??i.NormalBlending;const u=new Y(new i.PlaneGeometry(1,1),p);return u.scaleFactor=e.scale,u}(e.output,t));break;case"shape":F=new a(await async function(e,t,a,r,s){if(null==e.shape)return console.log("Shape is null"),new n;const l=O[e.shape];if(null==l)return console.error(`No shape with type ${e.shape}`),new n;const p=z(e.params??{}),u=l.geometry(p);let h=null;const m=me(e);"shaderGraph"===m&&(h=await de(e,"surface",a,r,s));null==h&&"shader"===m&&null!=e.shader&&(h=await he(e,t,s));null==h&&(h="material"===m&&null!=e.material?ye(await t.getMaterial(e.material)):function(){const e=k(new d("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:A({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}());return fe(h,e),new i.Mesh(u,h)}(e.output,t,r,p,P));break;case"mesh":F=new a(await async function(e,t,a,r,s){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new n;const o=await t.getMesh(e.assetId),l=await t.getAsset(e.assetId),c=me(e);if("shaderGraph"===c||"shader"===c||"material"===c){let n;"shaderGraph"===c?n=await de(e,"surface",a,r,s):"shader"===c&&null!=e.shader?n=await he(e,t,s):"material"===c&&null!=e.material&&(n=ye(await t.getMaterial(e.material))),fe(n,e),o.traverse(e=>{e instanceof i.Mesh&&null!=n&&(e.material=n)})}else{const e=[];if(null!=l.materialAssignments)for(const a of l.materialAssignments)o.traverse(r=>{r instanceof i.Mesh&&r.material instanceof i.Material&&r.material.color instanceof i.Color&&(r.material.name!=a.name&&null!=a.name||"#"+r.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>r.material=e)))});await Promise.all(e)}const p=[];if(o.traverse(e=>{e instanceof i.Mesh&&p.push(e)}),1===p.length){const e=p[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return o}(e.output,t,r,p,P));break;case"trail":{const s="shaderGraph"===me(e.output)?await de(e.output,"trail",r,p,P,{trailBillboard:e.output.billboard??!1}):null;F=new a({type:"trail",taper:e.output.taper,headGeometry:null,material:s instanceof i.ShaderMaterial?s:void 0,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1});break}default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const H=new we(D);H.parent=v,H.setRate(V),H._space=e.output.space;const U=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=ee[e.type]).map(async e=>{const t=ee[e.type],a=await z(e.params??{});return le(t,e.params??{},a,T)}));U.push(F,new X),H.addInitializers(U);const J=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=$[e.type]).map(async e=>{const t=$[e.type];for(const[a,r]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&r.type!==L.Curve&&(r.type=L.Curve);const a=await z(e.params??{},r,p);return oe(t,e.params??{},a,T)}).sort((e,t)=>e instanceof ae?1:0));J.push(new ge);for(const e of J)e instanceof ae&&(e.physics=x);H.addBehaviours(J);for(const a of e.children??[]){const e=await pe(a,t,r,p,v,x,P,T,D),s=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=H.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&H.childEmitters.splice(e,1),null!=t.parentParticle&&(n.delete(t.parentParticle.id),t.parentParticle=null),s.release(t)},t}),i=H.eventDispatcher,n=new Map;H.bindEmitterEvent=!0,i.addEventListener("PARTICLE_DEAD",e=>{const t=n.get(e.id);null!=t&&(H.detachChildEmitterFromParticle(t,e),n.delete(e.id))});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}i.addEventListener(o,e=>{const t=s.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),H.childEmitters.push(t),n.set(e.id,t),t.parentParticle=e,t.system=H.system,t.emit()})}return H}const ue=(new i.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function he(e,t,a){const r=a.get(e.shader);if(null==r)return console.error("No shader exists with name "+e.shader),new i.Material;const s=new r.type,n=await V(e.shaderParams??{},r.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0,void 0,s);return Object.assign(s,n),s.build()}async function de(e,t,a,r,s,i={}){const n=e.shaderGraph;if("asset"!==n?.source||null==n.assetId)return console.warn(`Missing shader graph asset reference for ${e.type} VFX output`),null;const o=await a.getAsset(n.assetId),l=o?.shaderGraph;if(null==l)return console.warn(`Missing shader graph asset "${n.assetId}" for ${e.type} VFX output`),null;if(l.target!==t)return console.warn(`Shader graph "${o.name}" targets "${l.target}" but ${e.type} VFX output expects "${t}"`),null;try{const t=await F(e.shaderGraphParams??{},l,a,r,void 0,s.shaders),o=ce(l,{parameters:t,trailBillboard:i.trailBillboard});return o.userData.customShaderName=`shaderGraph:${n.assetId}`,fe(o,e),o}catch(e){return console.log("Shader graph VFX runtime error: "+e,e),null}}function me(e){return null!=e.materialSource?e.materialSource:"asset"===e.shaderGraph?.source?"shaderGraph":"shader"in e&&null!=e.shader?"shader":"mesh"!==e.type&&"shape"!==e.type||null==e.material?"default":"material"}function fe(e,t){null!=e&&("bloom"in t&&!0===t.bloom&&(e.userData.hasBloom=!0),"sprite"===t.type?(e.blending=Z[t.blendingMode]??i.NormalBlending,!0===t.lockY&&e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.LOCK_Y_AXIS="")):"decal"===t.type&&(e.blending=Z[t.blendingMode]??i.NormalBlending,e.transparent=!0,e.side=i.BackSide,e.depthTest=!1,e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE="")))}function ye(e){const t=k(new d("instanceColor")).rgb;let a,r=k(new o("particleData")).x;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial){let s=t.multiply(P(e.color));null!=e.map&&(s=s.multiply(C(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(r=r.multiply(C(e.alphaMap).sample(j.uv).r)),e instanceof i.MeshStandardMaterial?a=new c({color:T({color:s,emissive:P(e.emissive),emissiveIntensity:v(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshLambertMaterial?a=new c({color:A({color:s}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshBasicMaterial&&(a=new c({color:s.rgb.rgba(r),emissive:s.rgb,transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class ge extends t{initialize(e){e.body instanceof i.Object3D&&e.body.traverse(e=>{if(e instanceof i.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[H]||null!=t.uniforms[U]||t.uniforms[J])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof n&&e.target.traverse(t=>{if(t instanceof i.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[H]&&(a.uniforms[H].value=this.energy),null!=a.uniforms[U]&&(a.uniforms[U].value=e.age),null!=a.uniforms[J]&&(a.uniforms[J].value=e.velocity))}})}}class we extends r{constructor(e){super(),this.transformRoot=e,this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}clearParticlesRecursive(){let e=this.childEmitters.length;for(;e--;){const t=this.childEmitters[e];t.stopEmit(),t.clearParticlesRecursive(),t.onExpired()}this.childEmitters.length=0;let t=this.particles.length;for(;t--;){const e=this.particles[t];this.system?.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),null!=this.system?this.system.pool.expire(e.reset()):e.reset()}this.particles.length=0}detachChildEmitterFromParticle(e,t){this.copyPositionToChildSpace(e,t.position),e.parentParticle=null,e.stopEmit()}update(e){if(!this.isEmitting&&0===this.particles.length&&0===this.childEmitters.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.isEmitting&&this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||0!==this.childEmitters.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle&&this.copyPositionToChildSpace(t,t.parentParticle.position),t.update(e)}copyPositionToChildSpace(e,t){const a=this._space??"world",r=e._space??"world";a!==r&&null!=this.transformRoot?(be.copy(t),"local"===a&&"world"===r?be.applyMatrix4(this.transformRoot.matrixWorld):"world"===a&&"local"===r&&(ve.copy(this.transformRoot.matrixWorld).invert(),be.applyMatrix4(ve)),e.position.copy(be)):e.position.copy(t)}clone(){const e=new we(this.transformRoot);return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}const be=new i.Vector3,ve=new i.Matrix4;export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { Mesh } from 'three';
|
|
2
|
+
import type { SceneObject } from '../materializer.js';
|
|
2
3
|
import { LandscapeMesh } from './landscape.js';
|
|
4
|
+
export interface LandscapeSectionExpansion {
|
|
5
|
+
west?: number;
|
|
6
|
+
east?: number;
|
|
7
|
+
north?: number;
|
|
8
|
+
south?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function extendLandscapeSections(source: SceneObject, expansion: LandscapeSectionExpansion): boolean;
|
|
3
11
|
export declare function smoothNormalsCrossMeshes(meshes: LandscapeMesh[]): void;
|
|
4
12
|
export declare class SectionGrid {
|
|
5
13
|
private grid;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Vector3 as
|
|
1
|
+
import{Vector3 as t}from"three";export function extendLandscapeSections(t,r){if(null==t.landscape?.options)return!1;const s=function(t){return{west:e(t.west),east:e(t.east),north:e(t.north),south:e(t.south)}}(r),i=s.west+s.east,c=s.north+s.south;if(0===i&&0===c)return!1;const u=t.landscape.options;u.sections.x=Math.max(0,Math.floor(u.sections.x))+i,u.sections.y=Math.max(0,Math.floor(u.sections.y))+c;const a=n(u.sectionSize,0);t.position??(t.position=[0,0,0]),t.position[0]=n(t.position[0],0)+(s.east-s.west)*a/2,t.position[1]=n(t.position[1],0),t.position[2]=n(t.position[2],0)+(s.south-s.north)*a/2;for(const e of t.landscape.heightMaps??[])e.x+=s.west,e.y+=s.north;return o(t.vertexMaterials,s),o(t.landscape.holes,s),!0}function e(t){const e="number"==typeof t?t:Number(t);return Number.isFinite(e)?Math.max(0,Math.floor(e)):0}function n(t,e){const n="number"==typeof t?t:Number(t);return Number.isFinite(n)?n:e}function o(t,e){for(const n of t??[]){const t=r(n.m,e);null!=t&&(n.m=t)}}function r(t,e){if(null==t)return;const n=/^(-?\d+),(-?\d+)$/.exec(t);if(null==n)return;return`${Number(n[1])+e.west},${Number(n[2])+e.north}`}export function smoothNormalsCrossMeshes(e){const n=new SectionGrid(e);performance.now();const o=new t,r=new t,s=new t,i=new t;for(const t of e){const e=t.geometry.getAttribute("position"),c=t.geometry.getAttribute("normal");for(const u of m(e.count)){const{otherMesh:a,j:f}=l(u,e.count,t,n);if(null==a)continue;o.fromBufferAttribute(e,u),o.applyMatrix4(t.matrixWorld);const d=a.geometry.getAttribute("position"),h=a.geometry.getAttribute("normal");a.updateMatrixWorld(),r.fromBufferAttribute(d,f),r.applyMatrix4(a.matrixWorld),s.fromBufferAttribute(c,u),i.fromBufferAttribute(h,f);const m=s.add(i).divideScalar(2);c.setXYZ(u,m.x,m.y,m.z),h.setXYZ(f,m.x,m.y,m.z),c.needsUpdate=!0,h.needsUpdate=!0;const x=(e.getY(u)+d.getY(f))/2;e.setY(u,x),d.setY(f,x)}}performance.now()}export class SectionGrid{constructor(t){this.grid=new Map;for(const e of t){const{x:t,y:n}=e;this.grid.has(t)||this.grid.set(t,new Map),this.grid.get(t).set(n,e)}}find(t,e){return this.grid.get(t)?.get(e)}}const s={meshPredicate:(t,e)=>t.find(e.x,e.y-1),vertexFunc:(t,e)=>t+e*(e-1)},i={meshPredicate:(t,e)=>t.find(e.x-1,e.y-1),vertexFunc:(t,e)=>e*e-1},c={meshPredicate:(t,e)=>t.find(e.x+1,e.y-1),vertexFunc:(t,e)=>e*e-e},u={meshPredicate:(t,e)=>t.find(e.x,e.y+1),vertexFunc:(t,e)=>t-e*(e-1)},a={meshPredicate:(t,e)=>t.find(e.x-1,e.y+1),vertexFunc:(t,e)=>e-1},f={meshPredicate:(t,e)=>t.find(e.x+1,e.y+1),vertexFunc:(t,e)=>0},d={meshPredicate:(t,e)=>t.find(e.x-1,e.y),vertexFunc:(t,e)=>t+e-1},h={meshPredicate:(t,e)=>t.find(e.x+1,e.y),vertexFunc:(t,e)=>t-e+1};function l(t,e,n,o){const r=Math.sqrt(e),l=(t+1)%r===0,m=t%r===0;let x;if(t<r?(x=s,m&&(x=i),l&&(x=c)):t>=e-r?(x=u,m?x=a:l&&(x=f)):m?x=d:l&&(x=h),null==x)return{otherMesh:null,j:null};return{otherMesh:x.meshPredicate(o,n),j:x.vertexFunc(t,r)}}function*m(t){const e=Math.sqrt(t);for(let n=0;n<e;n++)yield n,yield n+t-e;for(let t=1,n=e-1;t<n;t++)yield t*e,yield t*e+e-1}export function onEdge(t,e){const n=Math.sqrt(e);return t<n||t%n===0||t>=e-n||(t+1)%n===0}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__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 i from"three";import{BoxGeometry as n,Color as o,Euler as l,Fog as c,FogExp2 as h,Group as u,Material as p,Matrix4 as d,Mesh as m,MeshLambertMaterial as f,MeshPhongMaterial as g,MeshStandardMaterial as y,Object3D as w,PointLight as v,Quaternion as M,Scene as b,Texture as S,Vector2 as A,Vector3 as x,Vector4 as I}from"three";import{attributes as j,batchingUniformFloat as P,batchingUniformVec2 as D,batchingUniformVec3 as C,batchingUniformVec4 as T,bool as V,BooleanExpression as E,BooleanNode as O,colorToNormal as k,float as N,FloatNode as z,ifDefApply as F,mix as B,NodeShaderMaterial as _,rgb as U,rgba as $,RgbNode as G,select as W,standardMaterial as L,Texture2dLookupNode as R,textureSampler2d as q,textureSampler2dArray as J,UniformBoolNode as H,UniformFloatNode as X,UniformSampler2dArraySlice as Y,UniformVec2Node as Z,UniformVec3Node as K,UniformVec4Node as Q,varying as ee,varyingAttributes as te,varyingTransformed as ae,vec2 as se,Vec2Node as re,vec3 as ie,Vec3Node as ne,vec4 as oe,Vec4Node as le}from"three-shader-graph";import{Service as ce}from"typedi";import{VfxActor as he}from"../effects/vfx/vfx-actor.js";import{VisualEffect as ue}from"../effects/vfx/vfx-param.js";import{Prefab as pe,PrefabOf as de}from"./objects/prefab.js";import{BaseActor as me}from"../gameplay/actors/actor.js";import fe from"../gameplay/actors/builtin/index.js";import{ActorComponent as ge}from"../gameplay/actors/component.js";import{PhysicsBodyType as ye}from"../gameplay/services/physics/physics-system.js";import{ThreeBlendingMode as we}from"../effects/vfx/vfx-asset.js";import{withInjectionContext as ve}from"../gameplay/inject.js";import{RenderingView as Me}from"../rendering.js";import{curveSampler as be,oneMinus as Se,particleUniforms as Ae,Sampler2DNode as xe}from"../shader-nodes/index.js";import{LambertShader as Ie}from"../shader/builtin/lambert-shader.js";import{LandscapeCompositeShader as je}from"../shader/builtin/landscape-composite-shader";import{LandscapeShader as Pe}from"../shader/builtin/landscape-shader.js";import{StandardShader as De}from"../shader/builtin/standard-shader.js";import{UnlitShader as Ce}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as Te,shaderParameterUniformName as Ve}from"../shader/parameter.js";import{ArrayMap as Ee,DefaultMap as Oe,groupBy as ke}from"../utils/collections.js";import{iterateMaterials as Ne}from"../utils/materials.js";import{filterChildrenShallow as ze,filterSceneShallow as Fe,findFirstVisibleMesh as Be,findFirstVisibleObject as _e,traverseAsync as Ue}from"../utils/three/traverse.js";import{AssetMeshInstance as $e,AssetResourceLoader as Ge}from"./asset-resource-loader.js";import{AssetsProvider as We}from"./assets-provider.js";import{isCollisionMesh as Le}from"./collision/collision-shape-import.js";import{BoxCollisionShape as Re,PhysicalShapeMesh as qe}from"./collision/collision-shape.js";import{LandscapeManager as Je}from"./landscape/landscape-manager.js";import{initLandscape as He}from"./landscape/landscape.js";import{SectionGrid as Xe,smoothNormalsCrossMeshes as Ye}from"./landscape/utils.js";import{createGrassFoliageMaterial as Ze}from"./materials/grass-foliage.js";import{createGrassMaterial as Ke}from"./materials/grass.js";import{getMaterialAttribute as Qe}from"./materials/utils/material-painting.js";import{SurfaceScatterManager as et}from"./scatter/surface-scatter-manager.js";import{createWaterMaterial as tt}from"./materials/water.js";import{SerializedParamType as at}from"./model.js";import{applyRuntimeParamTypeInference as st,convertConfiguredParamsToRuntimeTypes as rt,convertConfiguredParamValueToRuntimeType as it,inferRuntimeSerializedParamTypeHint as nt}from"./custom-param-runtime-types.js";import{ShapeLibrary as ot,ShapeLibraryKeys as lt}from"./objects/shapes.js";import{ambientLightName as ct,createSky as ht,defaultSkyMaterial as ut}from"./sky.js";import{Curve2 as pt}from"../utils/curve.js";import{DecalUnlitShader as dt}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as mt}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as ft,defaultValueColorLayer as gt,defaultValueMaskLayer as yt,MaskLayer as wt}from"../shader/color-layer.js";import{LayeredShader as vt}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as Mt}from"../shader/color-layer";import{FogVolume as bt}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as St}from"../utils/three/unscaled-sprite.js";import{ToonShader as At}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as xt}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as It}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as jt}from"../shader-nodes/pom.js";import{traverseVisibleEvery as Pt}from"../utils/three/traverse";import{RectAreaLightHelper as Dt}from"three/examples/jsm/Addons.js";import{Sequence as Ct}from"../effects/sequence/sequence-data.js";import{applyUvTiling as Tt}from"./../shader/uv-nodes.js";import{buildShaderGraphMaterial as Vt,shaderGraphMaterialSideToThree as Et}from"../shader/graph/index.js";export{st as applyRuntimeParamTypeInference,rt as convertConfiguredParamsToRuntimeTypes,it as convertConfiguredParamValueToRuntimeType,nt as inferRuntimeSerializedParamTypeHint};const Ot={},kt=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),Nt=/^((?!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,n,o,l,c,h=[]){this.scene=e,this.dataProvider=t,this.assetsService=a,this.assetManagerService=s,this.renderingView=n,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.componentTypes=h,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.idToSceneObject=new Map,this.inEditor=!0,this.updated$=new r,this.removed$=new r,this.error$=new r,this.editorActorParamSnapshot=new Map,this.assets=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.pmremGeneratorResults=new WeakMap,this.prefabInstanceChain=[],this.prefabInstanceExposedActorMap=new Map,this.geometryCache=new Map,this.collisionShapeCache=new Map,this.assetManagerService.materialProvider=async e=>materialFromAsset(this.assets.get(e)??await this.assetsService.getAsset(e),this.renderingView,this.assetsService,this.assetManagerService,this.shaders),this.originalFog=null,t.onCreate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onUpdate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onRemove(e=>{this.remove(e),this.handleSurfaceScatterSceneMutation(e)}),this.createAssetSubscription=a.onCreate.subscribe(e=>{this.assets.set(e.id,e)}),this.updateSubscription=a.onUpdate.subscribe(async t=>{if(this.assets.set(t.id,t),"material"==t.type)e.traverse(e=>{if(e instanceof i.Mesh)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterial(e,e.material[a],t,a);else this.refreshMaterial(e,e.material,t)});else if("mesh"==t.type){this.findByAssetId(t.id).forEach(async e=>{this.remove(e.userData.src);const t=await this.materializeAndInitActor(e.userData.src);this.updated$.next({object:t,source:e.userData.src})});for(const e of this.assets.values())if("prefab"==e.type){if(!e.prefab.objects.some(e=>ya(e,e=>e.assetId==t.id,this.assets)))continue;this.findByAssetId(e.id).forEach(e=>{this.remove(e.userData.src),this.materializeAndInitActor(e.userData.src)})}this.landscapeManagers.forEach(e=>{const a=e.source?.grass?.layers?.some(e=>e.meshes.some(e=>e.assetId===t.id));a&&e.queueRefreshScatter(this.renderingView?.camera.position??new x,!0)}),null!=this.surfaceScatterManager&&(this.surfaceScatterManager.usesSourceAsset(t.id)||this.surfaceScatterManager.usesScatterAsset(t.id))&&this.surfaceScatterManager.queueRefresh(!0)}else if("prefab"===t.type)this.findByAssetId(t.id).forEach(e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}),(this.surfaceScatterManager?.usesPrefabAsset(t.id)||this.sceneReferencesPrefabAsset(t.id)&&await this.prefabAssetContainsSurfaceScatter(t))&&await this.refreshSurfaceScatterPresence(!0);else if("vfx"===t.type)for(const e of this.dataProvider.getObjects())await qt(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 qt(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 i.ShaderMaterial)for(const[e,s]of Object.entries(t.uniforms))s.value instanceof i.Texture&&s.value.userData.assetId===a.id&&(t.uniforms[e].value=r);else for(const[e,s]of Object.entries(t))s instanceof i.Texture&&s.userData.assetId===a.id&&(t[e]=r);else console.error("Can not refresh material textures. Texture not found",a)}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===at.Material&&s.value===a.id){t=!0;break}if(s.type===at.Array&&"element"in s&&s.element===at.Material&&s.value.includes(a.id)){t=!0;break}}if(!t)return}const i=await materialFromAsset(this.assets.get(r),this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1),n=i.userData;i.userData=t.userData,i.userData.hasBloom=n.hasBloom,i.userData.reflective=n.reflective,i.userData.outlineParameters=n.outlineParameters,null!=s?aa(e.material[s],i)||(e.material[s]=i):aa(e.material,i)||(e.material=i,e===this.sky&&this.applySkySettings(e.material))}vfxAssetUsesShaderGraph(e,t){return null!=e.vfx&&e.vfx.emitters.some(e=>this.emitterUsesShaderGraph(e,t))}emitterUsesShaderGraph(e,t){const a=e.output;return"shaderGraph"===a.materialSource&&"asset"===a.shaderGraph?.source&&a.shaderGraph.assetId===t||!!e.children&&e.children.some(e=>this.emitterUsesShaderGraph(e,t))}getTopLevelActors(){return Array.from(this.materializedActors.entries()).filter(([e,t])=>!e.includes("/")).map(([,e])=>e)}get actorInstances(){return Array.from(this.materializedActors.values())}async initTextures(){const e=[];if(await Promise.all(this.dataProvider.getObjects().filter(e=>"shape_mesh"===e.type||"asset_mesh"===e.type).filter(e=>null!=e.materialAssignments).flatMap(e=>e.materialAssignments).map(async t=>{const a=this.assets.get(t.materialId);if(null!=a)for(const t of Object.values(a.material.shaderParams??{}))if(t.type===at.Texture&&"string"==typeof t.value){const a=this.assets.get(t.value),s=await this.assetManagerService.getTexture(a);null!=s&&e.push(s)}})),0!==e.length&&this.renderingView){console.log(`Initializing ${e.length} textures`),console.time("Init textures");for(const t of e)this.renderingView.renderer.initTexture(t);console.timeEnd("Init textures")}}async prefetchAssets(){const e=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)}))),this.initTextures()}async init(){await this.preInit(),Bt.clear(),_t.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.refreshSurfaceScatterPresence(!0)}async initVfx(){console.time("Init VFX");const e=new Set,t=[],a=new b;for(const s of this.actorInstances){const r=fa(s);for(const s of r){const r=s.asset;if(e.has(r.id))continue;e.add(r.id),r.vfx.emitters;const i=await s.create(a);a.add(i.object),a.add(i.particleSystemContainer),i.play(),i.onUpdate(.5),i.stop(),i.pause(),t.push(i)}}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=await this.assetsService.getAsset(a.assetId),r=e.split("/"),i=r.slice(0,-1),n=i.join("/"),o=(r[r.length-1],new Map);for(const[e,t]of this.materializedActors)if(o.set(e,t),0===n.length)e.includes("/")||o.set(e,t);else if(e.startsWith(n+"/")){const a=e.slice(n.length+1);a.includes("/")||o.set(a,t)}const l={...s?.actor?.params??{},...a.actor?.params??{}},c=[...a.actor?.innerParams??[]];for(let t=i.length-1;t>=0;t--){const a=i.slice(0,t+1).join("/"),s=this.idToSceneObject.get(a);if("prefab"===s?.type&&null!=s.prefab){const i=await this.assetsService.getAsset(s.assetId);if(null!=i){let n=!1,o=a+"/"+i.prefab?.mainActorId;for(;null!=o;){if(o===e){n=!0;break}o=this.prefabInstanceExposedActorMap.get(o)}if(n&&null!=s.prefab.params&&Object.assign(l,Xt(s.prefab.params)),null!=s.prefab.innerParams)for(const e of s.prefab.innerParams){const a=r.slice(t+1);e.path.length>=a.length&&e.path.slice(0,a.length).every((e,t)=>e===a[t])&&c.push({path:e.path.slice(a.length),params:e.params})}}}}for(const e of c)await this.applyActorComponentParams(t,e.path.slice(),e.params,o);await this.attachEditorComponents(t,a,o);const h=await prepareClassParameters(l,t.constructor,this.assetsService,this.assetManagerService,o,this.renderingView,this.shaders,this.actorProvider,e=>{const t=n.length>0?n+"/"+e:e;return this.prefabInstanceExposedActorMap.get(t)??null},t);Object.assign(t,h);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 i=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,i);Object.assign(i,e)}for(const e of r.innerParams??[])await this.applyActorComponentParams(i,e.path.slice(),e.params,a)}}addVfxChildActors(e,t=e){}async applyActorComponentParams(e,t,a,s){const r=t.length,i=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[i]&&await this.applyActorComponentParams(e[i],t,a,s)}canObjectBeInstanced(e){return e.physics?.type!==ye.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=>{!Le(e)&&e.isMesh&&s.push(e)});const r=1==s.length&&0==s[0].children.length,i=!Nt,n=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||n&&i)&&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)}),this.assetsService.getAssets().then(e=>{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(),Bt.clear(),_t.clear();const e=[],t=new Ee,a=new Ee,s=new Ee;let r=0,n=0,c=0;const h=new Map,u=new Oe(()=>new Map);for(const i of this.dataProvider.getObjects())await qt(i,async(i,l,p)=>{if(!this.shouldBeMaterialized(i))return;const d="asset_mesh"==i.type&&this.canObjectBeInstanced(i)&&await this.canAssetBeInstanced(i),f="shape_mesh"===i.type&&"landscape"!==i.shape&&i.physics?.type!==ye.dynamic;if(d||f){if(l&&l.children?.length>0){const e=l.children.findIndex(e=>e.id===i.id);e>=0&&l.children.splice(e,1)}if(f){let e=i.shape+JSON.stringify(i.shapeParams??{})+i.castShadow+i.receiveShadow;const t=i.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===at.Color&&null!=e.value&&(r=new o(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:{...i,parentTransform:p},color:r}),c++}else{const e=this.assets.get(i.assetId);let s=h.get(i.assetId);if(null==s){const e=await this.createFromAsset(i,{assignMaterials:!1});if(null==e)return;if(s=h.get(i.assetId),null==s){s={useBatchedMesh:null!=Be(e)&&Pt(e,e=>!(e instanceof m)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},h.set(i.assetId,s)}}const o=Zt(i.materialAssignments,e.materialAssignments);if(s.useBatchedMesh)await Ue(s.assetMesh,async e=>{if(!(e instanceof m))return;const t=Array.isArray(e.material)?e.material[0]:e.material,s=await this.resolveMaterialForAssignments(t,o);if(null!=s){u.get(i.id).set(e.uuid,s),ga(e.geometry,s);let t=oa(s);t+=ia(e),a.push(t,{...i,parentTransform:p,meshUUID:e.uuid}),r++}else console.warn("Can not materialize mesh because missing material",i)});else{const e=i.assetId+JSON.stringify(i.materialAssignments??[]);t.push(e,{...i,parentTransform:p}),n++}}}else null==l&&e.push({...i,parentTransform:p})});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 ${n} objects.\n Shapes: ${s.size} batch groups containing in total ${c} objects. \n ${e.length} objects can not be batched. \n `);for(const e of h.values())this.prepareCollisionShapesForInstanced(e.assetMesh);console.time("materialize batches");for(const[e,t]of a.entries()){if(0==t.length)continue;let e;h.get(t[0].assetId).assetMesh;e=this.createBatchedMesh(t,u,h);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 $e;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=h.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 $e;r.add(t),r.userData.src=e[0],a instanceof $e&&(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=_e(a,e=>!Le(e)&&null!=e.geometry),r=s.material.clone();null!=e[0].color&&null!=r.color&&(r.color=new o(16777215));const n=s.geometry;let c,h;!(Nt||r instanceof _||null==n.index)?(c=new i.BatchedMesh(e.length,n.getAttribute("position").count,n.index.count,r),c.perObjectFrustumCulled=!0,h=c.addGeometry(n)):c=new i.InstancedMesh(n,r,e.length),c.castShadow=a.castShadow??!0,c.receiveShadow=s.receiveShadow??!0;for(let t=0;t<e.length;t++){const a=e[t],s=(new i.Matrix4).compose((new x).fromArray(a.object.position),(new M).setFromEuler((new l).fromArray(a.object.rotation)),(new x).fromArray(a.object.scale)),r=(new d).copy(a.object.parentTransform).multiply(s);let n;n=c instanceof i.BatchedMesh?c.addInstance(h):t,c.setMatrixAt(n,r),a.color}for(let t=0;t<e.length;t++){const s=e[t],r=new $e;r.userData.src=e[0],a instanceof qe&&(r.collisionShapes=[a.collisionShape]),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r),r.add(c),null==c.userData.hasCollision&&(c.userData.hasCollision=[]),c.userData.hasCollision[t]=!!s.object.collisionDetection}}await Promise.all(e.map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.initVfx(),await this.refreshSurfaceScatterPresence(!0)}prepareCollisionShapesForInstanced(e){e instanceof $e&&e.collisionShapes.forEach(e=>{e instanceof a&&e.mesh instanceof m&&(e.mesh=e.mesh.geometry)})}testCanBatch(e,t){return!Nt&&(!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 Ee;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,n=0,l=0;const c=new Map;for(const[e,t]of s.entries()){const s=t[0].assetId,i=a.get(s);if(null==i){console.warn("Missing batching info for asset id "+s);continue}const o=_e(i.assetMesh,t=>t instanceof m&&t.uuid===e);if(null==o){console.warn("Missing mesh in batched asset");continue}c.set(e,o);const h=o.geometry.getAttribute("position");null==h&&console.warn("Missing position attribute for batched mesh"),r+=o.geometry.index.count*t.length,n+=h.count*t.length,l+=t.length}const h=["color","map","roughness","roughnessMap","metalness","metalnessMap","opacity","alphaMap","aoMap","aoMapIntensity","normalMap","normalScale","emissive","emissiveIntensity","emissiveMap"];let u=new Map;const p=[];let d=new i.MeshStandardMaterial({color:"white"});const f=t.get(e[0].id).get(e[0].meshUUID);if(null==f)throw"missing source material";if(f instanceof y&&!(f instanceof i.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 h){let r=e[t];r instanceof i.CompressedArrayTexture&&null!=r.userData.index&&(r=r.userData.index);const n=s.get(t);void 0===n||ma(r,n)?s.set(t,r):a.add(t)}}for(const e of a){let t;const a=f[e];if("number"==typeof a){let a=p.find(e=>e.params.length<4);if(null==a){const t="vp"+p.length;a={name:t,params:[e],node:T(t)},p.push(a)}else a.params.push(e);t=pa(a.node,a.params.length-1)}else if(a instanceof I)t=T(e);else if(a instanceof x||a instanceof o)t=C(e);else if(a instanceof A)t=D(e);else if(a instanceof i.CompressedArrayTexture)t=P(e+"_i");else if(a instanceof S)continue;u.set(e,t)}let r=te.uv;f instanceof It&&null!=f.heightMap&&(r=jt(r,q(f.heightMap),N(f.heightScale)));let n=la(u.get("opacity"),z)??N(f.opacity??1);if(null!=f.alphaMap){let e;if(f.alphaMap instanceof i.CompressedArrayTexture){const t=J(f.alphaMap),a=la(u.get("alphaMap"),z)??N(f.alphaMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.alphaMap).sample(r);n=n.multiply(e.r)}let l=$(la(u.get("color"),ne)??f.color,n);if(null!=f.map){let e;if(f.map instanceof i.CompressedArrayTexture){const t=J(f.map),a=la(u.get("map"),z)??N(f.map.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.map).sample(Tt(r,f.map));l=l.multiply(e),n=n.multiply(e.a)}f.vertexColors&&(l=l.multiply(oe(ee(j.color.rgb),1)));let c=$(la(u.get("emissive"),ne)??f.emissive,n);if(null!=f.emissiveMap){let e;if(f.emissiveMap instanceof i.CompressedArrayTexture){const t=J(f.emissiveMap),a=la(u.get("emissiveMap"),z)??N(f.emissiveMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.emissiveMap).sample(Tt(r,f.emissiveMap));c=c.multiply(e)}const m=la(u.get("emissiveIntensity"),z)??N(f.emissiveIntensity??1),g=la(u.get("normalScale"),re)??se(f.normalScale??new A(1,1));let y=ae.normal;if(null!=f.normalMap){let e;if(f.normalMap instanceof i.CompressedArrayTexture){const t=J(f.normalMap),a=la(u.get("normalMap"),z)??N(f.normalMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.normalMap).sample(Tt(r,f.normalMap));y=k(e.rgb,g.x)}let w=la(u.get("roughness"),z)??N(f.roughness??1);if(null!=f.roughnessMap){let e;if(f.roughnessMap instanceof i.CompressedArrayTexture){const t=J(f.roughnessMap),a=la(u.get("roughnessMap"),z)??N(f.roughnessMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.roughnessMap).sample(Tt(r,f.roughnessMap));w=w.multiply(e.g)}let v=la(u.get("metalness"),z)??N(f.metalness??0);if(null!=f.metalnessMap){let e;if(f.metalnessMap instanceof i.CompressedArrayTexture){const t=J(f.metalnessMap),a=la(u.get("metalnessMap"),z)??N(f.metalnessMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.metalnessMap).sample(Tt(r,f.metalnessMap));v=v.multiply(e.b)}let M=N(1);if(null!=f.aoMap){let e;if(f.aoMap instanceof i.CompressedArrayTexture){const t=J(f.aoMap),a=la(u.get("aoMap"),z)??N(f.aoMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.aoMap).sample(Tt(r,f.aoMap));M=M.multiply(e.r)}const b=la(u.get("aoMapIntensity"),z)??N(f.aoMapIntensity??0);let V=y;!0!==f.userData.disableAO&&(V=F("DOUBLE_SIDED",V,e=>W(new E("gl_FrontFacing"),e,e.multiplyScalar(-1))));const O=new _({color:L({color:l,roughness:w,metalness:v,ambientOcclusion:M,ambientOcclusionIntensity:b,emissive:c,emissiveIntensity:m,normal:V}),normal:y,roughness:w,emissive:c.rgb,transparent:f.transparent,alphaTest:f.alphaTest,envMap:f.envMap,opacity:n});null!=f.envMap&&(O.uniforms.envMapIntensity={value:f.envMapIntensity},O.uniforms.envMapRotation={value:ua(f.envMapRotation,f.envMap)}),O.envMap=f.envMap,O.side=f.side,d=O}else{d=f;for(const a of e){const e=t.get(a.id).get(a.meshUUID);if(e!=d){console.error(`Different materials in group for object ${a.id} and mesh uuid ${a.meshUUID}`,{objectMaterial:e,sourceMaterial:f});break}}}const g=new xt(l,n,r,d);for(const e of p)g.initUniform(e.name,4);for(const[e,t]of u.entries()){if(p.some(t=>t.params.includes(e)))continue;let a=1;t instanceof le||t instanceof ne?a=4:t instanceof re&&(a=2),g.initUniform(e,a,0)}for(const[e,r]of s.entries()){const s=r[0].assetId,n=c.get(e);if(null==n){console.error(`Missing single asset mesh for mesh uuid ${e} and asset id ${s}`);continue}if(null==n.geometry){console.error("Missing geometry on mesh mesh");continue}const l=g.addGeometry(n.geometry),h=a.get(s);if(null==h){console.warn("Missing batching info when configuring for asset id "+s);continue}const d=Be(h.assetMesh)?.uuid===e,m=h.assetMesh instanceof $e&&d?h.assetMesh.collisionShapes:void 0,f=this.configureBatchedInstancedMesh(r,g,n,l,m);for(let e=0;e<f.length;e++){const a=r[e],s=f[e],n=t.get(a.id).get(a.meshUUID);for(const e of p){let t=da.set(0,0,0,0);for(let a=0;a<e.params.length;a++){const s=n[e.params[a]];"number"==typeof s&&t.setComponent(a,s)}g.setUniformAt(e.name,s,t)}for(let e of u.keys()){if(p.some(t=>t.params.includes(e)))continue;let t=n[e];if(t instanceof o&&(t=new x(t.r,t.g,t.b)),t instanceof i.CompressedArrayTexture)t=t.userData.index??0,e+="_i";else if(t instanceof S||null==t)continue;g.setUniformAt(e,s,t)}}}return g}async createInstancedMesh(e,t){const a=_e(t,e=>!Le(e)&&null!=e.geometry),s=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(t,Zt(e[0].materialAssignments,s.materialAssignments)),a.updateMatrix();const r=a.geometry.clone(),n=a.material;let o;if(o=new i.InstancedMesh(r,n,e.length),this.configureBatchedInstancedMesh(e,o,a),a.material instanceof p&&o.castShadow&&o.receiveShadow&&Array.isArray(n))for(const e of n);return o}configureBatchedInstancedMesh(e,t,a,s,r){const n=[];a.updateWorldMatrix(!0,!0);for(let o=0;o<e.length;o++){let c=o;t instanceof i.BatchedMesh&&(c=t.addInstance(s)),n.push(c);const h=(new i.Matrix4).compose((new x).fromArray(e[o].position),(new M).setFromEuler((new l).fromArray(e[o].rotation)),(new x).fromArray(e[o].scale)),u=(new d).copy(e[o].parentTransform).multiply(h).multiply(a.matrixWorld);t.setMatrixAt(c,u),null==t.userData.hasCollision&&(t.userData.hasCollision=[]),t.userData.hasCollision[c]=!!e[o].collisionDetection,null!=r&&(null==t.userData.collisionShapes&&(t.userData.collisionShapes=[]),t.userData.collisionShapes[c]=r)}return n}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 Fe(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)try{return materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders)}catch(e){console.error("Failed to apply material",e)}},this._originalMaterials)}async resolveMaterialForAssignments(e,t){let a=e,s=null,r=null;for(const e of t??[]){if(!ta(a,e,s,r))continue;const t=this.assets.get(e.materialId);if(null==t){console.warn("Missing material with id "+e.materialId);continue}const i=await materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0);null!=i&&a.id!==i.id&&(s=s??ea(a),r=r??a.name,a=i)}return a}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(fe));Fe(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,Fe(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 Bt.entries())t.userData.customShaderName&&Bt.delete(e);this.landscapeManagers.forEach(t=>t.updateShaders(e)),Fe(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=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);if("world_env"===e.type&&null!=this.worldEnvObj)return void this.updateWorldEnv(e);const t=this.sceneObjectMap.get(e.id);if(t){let s=!1;if(t.traverseAncestors(e=>{"_hology_transform_group"===e.name&&(s=!0)}),!s){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);Zt(e.materialAssignments,a.materialAssignments).forEach(e=>this.applyMaterial(t,e))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);if(s||(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 o(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 o(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 o(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 Dt&&e.update()})}}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(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 h?"density":"linear")!==e.fog.type;this.scene.fog=Rt(e.fog),t&&(a=this.scene).traverse(e=>{if(e instanceof m){const t=e.material;t instanceof _&&(a.fog instanceof c?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof h&&(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 bt){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)||s||(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 qe&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}if("shape_mesh"===e.type&&"landscape"!==e.shape)Ft(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;Ft(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;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:ze(t,t=>t.children?.some(t=>t.id===e.id),()=>!0))[0];return null==t?this.scene:null!=t?Fe(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 o(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=ke(e.vertexMaterials,e=>e.m);t.traverse(e=>{if(e instanceof m){if(null==e.geometry)return;if(sa(Qe(e,0,!1)),a>0){sa(Qe(e,0,!1))}}});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=Qe(s,0,!0);sa(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=Qe(s,4,!0);sa(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),e.needsUpdate=!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,a=!1,s){const r=this.getNestedActorId(e.id,s);if(this.idToSceneObject.set(r,e),!this.shouldBeMaterialized(e))return;let i,n;switch(e.type){case"asset_mesh":i=await this.createFromAsset(e);break;case"shape_mesh":i=await this.createFromShape(e);break;case"light":i=await this.createLight(e);break;case"particles":i=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=Rt(e.fog),this.fixFogColor(),i=new u;break;case"sky":this.sky=ht(),this.updateSky(e),i=this.sky;break;case"world_env":this.updateWorldEnv(e),i=new u,this.worldEnvObj=i;break;case"actor":({object:i,actor:n}=await this.createFromActor(e,s));break;case"group":i=new u;break;case"prefab":i=await this.createFromPrefab(e,s,t);break;case"vfx":i=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!=i){if(e.name&&e.name.length>0&&(i.name=e.name),this.applyTransform(e,i),a?i.userData._src=e:i.userData.src=e,null!=n&&(i.userData.actor=n),this.inEditor,this.inEditor,this.objectMap.set(i.uuid,e),this.sceneObjectMap.set(e.id,i),e.physics?.type!==ye.dynamic||null==t||this.inEditor?null==t?this.scene.add(i):null==t||"actor"!==e.type||this.inEditor?t?.add(i):(t.add(i),this.scene?.attach(i),console.log(i)):(t.add(i),i.getWorldPosition(i.position),i.getWorldQuaternion(i.quaternion),i.getWorldScale(i.scale),this.scene?.attach(i)),null!=e.children&&await Promise.all(e.children?.map(e=>this.materialize(e,i,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==ye.dynamic||Lt(i),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,i;console.warn("RenderingView not found in materializer")}}async handleSurfaceScatterSceneMutation(e){const t=this.surfaceScatterManager?.referencesSceneObject(e.id)??!1,a=await this.sceneObjectContainsSurfaceScatter(e);(t||a)&&await this.refreshSurfaceScatterPresence(!0)}async refreshSurfaceScatterPresence(e=!1){return await this.sceneContainsSurfaceScatter()?(null==this.surfaceScatterManager&&(this.surfaceScatterManager=new et(this.scene,this.dataProvider,this.renderingView,this.assetManagerService,this.assetsService)),this.surfaceScatterManager.queueRefresh(e),!0):(this.disposeSurfaceScatterManager(),!1)}disposeSurfaceScatterManager(){null!=this.surfaceScatterManager&&(this.surfaceScatterManager.clear(),this.surfaceScatterManager.stop(),this.surfaceScatterManager=void 0)}async sceneContainsSurfaceScatter(){return this.sceneObjectsContainSurfaceScatter(this.dataProvider.getObjects())}async sceneObjectsContainSurfaceScatter(e,t=[]){for(const a of e??[])if(await this.sceneObjectContainsSurfaceScatter(a,t))return!0;return!1}async sceneObjectContainsSurfaceScatter(e,t=[]){if("asset_mesh"===e.type&&(e.surfaceScatter?.meshes?.length??0)>0)return!0;if(null!=e.children&&await this.sceneObjectsContainSurfaceScatter(e.children,t))return!0;if("prefab"===e.type&&null!=e.assetId){if(t.includes(e.assetId))return!1;const a=this.assets.get(e.assetId)??await this.assetsService.getAsset(e.assetId),s=a?.prefab?.objects;if(null!=s)return this.sceneObjectsContainSurfaceScatter(s,[...t,e.assetId])}return!1}sceneReferencesPrefabAsset(e){const t=(a=[])=>{for(const s of a??[]){if("prefab"===s.type&&s.assetId===e)return!0;if(t(s.children))return!0}return!1};return t(this.dataProvider.getObjects())}async prefabAssetContainsSurfaceScatter(e){return"prefab"===e.type&&null!=e.prefab?.objects&&this.sceneObjectsContainSurfaceScatter(e.prefab.objects,[e.id])}applyTransform(e,t){null!=e.position&&t.position.fromArray(e.position),null!=e.scale&&t.scale.fromArray(e.scale),null!=e.rotation&&t.rotation.fromArray(e.rotation)}updateWorldEnv(e){this.renderingView.aoPass.enabled=e.worldEnv.ao.enabled,this.renderingView.aoPass.blendIntensity=e.worldEnv.ao.blendIntensity,this.renderingView.aoPass.updateGtaoMaterial(e.worldEnv.ao);const t=e.worldEnv.toneMapping;null!=t&&(this.renderingView.baseToneMapping=t.mapping??0,this.renderingView.baseToneMappingExposure=t.exposure??1,this.renderingView.renderer.toneMapping=this.renderingView.baseToneMapping,this.renderingView.renderer.toneMappingExposure=this.renderingView.baseToneMappingExposure);const a=e.worldEnv.environment;null!=a&&null!=a.textureId?this.assetManagerService.getTexture(this.assets.get(a.textureId)).then(e=>{null==this.pmremGenerator&&(this.pmremGenerator=new i.PMREMGenerator(this.renderingView.renderer),this.pmremGenerator.compileEquirectangularShader()),this.pmremGeneratorResults.has(e)||this.pmremGeneratorResults.set(e,this.pmremGenerator.fromEquirectangular(e).texture);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!==ut?(this.sky.material=ut,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=i.BackSide,(e instanceof y||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(e.fog=!1),e.depthTest=!1}async createComponent(e,t,a,s){const r=new Ot[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,t){const a=this.actorTypes.find(t=>t.name===e.actor?.type)?.type??fe[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 x).fromArray(e.position),(new l).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(he,(new x).fromArray(e.position),(new l).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 y({name:"Default",color:new o("#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 u;const a=He(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new Je(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 Xe(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(()=>Ye(r),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&<.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=ot[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,ot[e].collision(s));return new qe(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(Zt(e.materialAssignments,a.materialAssignments).map(e=>this.applyMaterial(s,e)))}catch(t){console.error("Failed to apply material"+t,e)}const r=e.receiveShadow??!!a.receiveShadow,i=e.castShadow??!!a.castShadow;return s.receiveShadow=r,Ft(s,i,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 i=new u;null!=s&&this.applyTransform(s,i),null!=a&&a.add(i),await Promise.all(e.prefab.objects.filter(e=>"global_fog"!==e.type&&"world_env"!==e.type).map(e=>this.materialize(e,i,!0,structuredClone(t))));const n=t.sceneObjectChain.join("/"),o=Array.from(this.materializedActors.entries()).filter(([e,a])=>e.startsWith(n)&&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(n)).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:i,actors:c,mainActor:l}}async createParticleSystem(e){await this.assetsService.getAsset(e.assetId);return new w}async createLight(e){if("point"===e.light.type){const t=new v(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 i.TextureLoader).load("assets/light-bulb-icon.webp"),a=new i.SpriteMaterial({map:e,alphaTest:.5}),s=new St(a);s.scale.multiplyScalar(.6),t.add(s)}return t}if("spot"===e.light.type){const t=new i.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 w,t.target.position.set(0,-1,0),t.add(t.target),this.inEditor){const e=(new i.TextureLoader).load("assets/light-bulb-icon.webp"),a=new i.SpriteMaterial({map:e,alphaTest:.5}),s=new St(a);s.scale.multiplyScalar(.6),t.add(s),t.add(new i.SpotLightHelper(t))}return t}if("rectArea"===e.light.type){const t=new i.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 i.TextureLoader).load("assets/light-bulb-icon.webp"),a=new i.SpriteMaterial({map:e,alphaTest:.5}),s=new St(a);s.scale.multiplyScalar(.6),t.add(s);const r=new Dt(t);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional,e),new u):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient,e),new u):void 0}applyDirectionalAmbientLight(e,t,a){const s=this.scene.children.find(e=>e.name===ct);null!=s?(s.intensity=t.intensity,s.color.set(t.color),s.groundColor.set(t.color),s.userData.src=a,s.userData.volumetricIntensity=t.volumetricIntensity):console.warn("Couldn't find ambient light")}applyDirectionalLight(e,t){for(const a of this.renderingView.csm.lights)a.intensity=e.intensity,a.color.set(e.color),a.castShadow=e.castShadow,a.userData.src=t,a.userData.volumetricIntensity=e.volumetricIntensity;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.createAssetSubscription.unsubscribe(),this.materializedActors.forEach(e=>e.disposed.next(!0)),this.materializedActors.clear()}};zt=e([ce(),t("design:paramtypes",[b,Object,We,Ge,Me,Array,Array,Object,Array])],zt);export{zt as SceneMaterializer};function Ft(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const Bt=new Map,_t=new Map,Ut=new f({color:16711935}),$t=new Map;export async function materialFromAsset(e,t,a,s,r,i=!0){if(null==e||null==e.material)return console.error("Asset or asset material is null",e),Ut;const n=JSON.stringify(e.material)+t?._id,o=i&&!("shaderGraph"===e.material.type&&"asset"===e.material.shaderGraph?.source);if(o&&Bt.has(n))return Bt.get(n);if(o&&_t.has(n))return await _t.get(n);const l=_materialFromAsset(n,e,t,a,s,r,o);return o?_t.set(n,l).get(n):l}export async function _materialFromAsset(e,t,a,r,n,l,c=!0){const h={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 o(t.material.params?.color),transparent:null!=t.material.params?.opacity&&t.material.params?.opacity<1},u={};if(null!=t.material.params?.map){const e=t.material.params.map,a=await r.getAsset(e);null!=a&&(h.map=await n.getTexture(a))}let p,d,m;switch(t.material.type){case"phong":p=new g({...h,...u});break;case"water":p=tt(h,a);break;case"grassFoliage":p=Ze({color:h.color,map:h.map},a);break;case"grass":p=Ke({...h,colorTwo:new o(t.material.params.colorTwo),colorThree:new o(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),p=Ut;break}"surface"===e.target&&null!=e.materialOptions?.side&&(d=Et(e.materialOptions.side)),"decal"===e.target?m=!1:null!=e.materialOptions?.transparent&&(m=e.materialOptions.transparent);try{const s=await prepareShaderGraphParameters(t.material?.shaderParams??{},e,r,n,a,l),i=t.shaderGraphPreviewNodeId,o=t.trailBillboard;p=Vt(e,{parameters:s,previewNodeId:i,trailBillboard:o}),p.userData.customShaderName="asset"===t.material.shaderGraph?.source?`shaderGraph:${t.material.shaderGraph.assetId}`:`shaderGraph:${t.id}`}catch(e){console.log("Shader graph runtime error: "+e,e),p=Ut}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:kt?Ie:De,lambert:Ie,unlit:Ce,toon:At,layered:vt,landscape:Pe,"landscape-composite":je,"decal-unlit":dt,"decal-standard":mt,sprite:s}[t.material.type]??l.find(e=>e.name==t.material.shader)?.type;if(e){try{let s=new e;const i=await prepareClassParameters(t.material?.shaderParams??{},e,r,n,null,a,l,void 0,void 0,s);Object.assign(s,i),p=s.build()}catch(e){console.log("Shader runtime error: "+e,e),$t.has(t.material.shader)||$t.set(t.material.shader,Ut.clone()),p=$t.get(t.material.shader)}p.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),p=Ut;break;default:throw new Error("Unsupported material type "+t.material.type)}return a?.csm.setupMaterial(p),c&&null!=a&&Bt.set(e,p),p.side=d??t.material.side??p.side??i.FrontSide,p.transparent=(m??t.material.transparent??h.transparent??!1)||p.transparent,p.alphaTest=t.material.alphaTest??p.alphaTest??0,null!=t.material.blending&&(p.blending=we[t.material.blending]??i.NormalBlending),t.material.bloom&&(p.userData.hasBloom=!0),t.material.reflective&&(p.userData.reflective=!0),!0===t.material.outlines&&(p.userData.outlineParameters={},null!=t.material.outlineParams&&(null!=t.material.outlineParams.color&&(p.userData.outlineParameters.color=new o(t.material.outlineParams.color).toArray()),null!=t.material.outlineParams.thickness&&(p.userData.outlineParameters.thickness=t.material.outlineParams.thickness))),p.userData.assetId=t.id,c&&_t.delete(e),p}export function prepareCustomParamsFromShaderGraph(e,t={}){return Object.fromEntries((e.parameters??[]).map(e=>{const a=function(e){switch(e){case"float":return at.FloatNode;case"boolean":return at.BooleanNode;case"texture":return at.Sampler2DNode;case"vec2":return at.Vec2Node;case"vec3":return at.Vec3Node;case"vec4":return at.Vec4Node;case"color":return at.RgbNode}}(e.type),s=t[e.name],r=s?.override??null!=s,i=void 0!==e.defaultValue?e.defaultValue:customParameterDefaultValueByType.get(a),n=!1===r?Yt(i):s?.value??Yt(i);return[e.name,{type:a,value:n,override:r}]}))}export async function prepareShaderGraphParameters(e,t,a,s,r,i){const n={},o=prepareCustomParamsFromShaderGraph(t,e);for(const[e,t]of Object.entries(o)){const o=await Wt(e,t,a,s,null,r,i);null!=o&&(n[e]=o)}return n}export async function prepareClassParameters(e,t,a,s,r,i,n,o,l,c){const h={},{params:u,skipped:p}=rt(e,{parameterType:t,parameterTarget:c,extractPropertyParameters:Te,toSerializedParamType:toSerializedParamType});for(const e of p)console.warn(`Skipping stored parameter "${e.key}" because it could not be converted from ${at[e.sourceType]} to ${at[e.targetType]}`);for(const[e,t]of Object.entries(u)){if(!1===t.override)continue;const c=await Wt(e,t,a,s,r,i,n,o,void 0,void 0,l);null!=c&&(h[e]=c)}return h}export async function prepareShapeParameters(e,t,a){const s={};for(const[r,i]of Object.entries(e)){const e=await Wt(r,i,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const Gt=new Map;async function Wt(e,t,a,s,r,i,n,c,h=t.value,u=t.type,p){if(null==t||null==h||""===h)return null;switch(u){case at.Array:if(Array.isArray(h)&&"element"in t)return await Promise.all(h.map(o=>Wt(e,t,a,s,r,i,n,c,o,t.element,p)));break;case at.Number:case at.FloatNode:let d;if("string"==typeof h?d=parseFloat(h):"number"==typeof h&&(d=h),u===at.FloatNode){if("object"==typeof h&&"a"in h&&"b"in h){const e=h;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=Gt.get(e);return null==t&&(t=be(pt.decode(e)),Gt.set(e,t)),t}(e.easing),r=s.sample(Se(Ae.energy));return B(N(t),N(a),r)}return new X(Ve(e),d,void 0,!1)}return d;case at.Texture:let m=await s.getTexture(await a.getAsset(h));return"envmap"===e.toLowerCase()&&null!=i&&(m=i.getEnvTexture(m)),m;case at.Sampler2DNode:const f=await a.getAsset(h);if(null!=f.texture?.textureArrayFileKey){const{texture:e,layerIndex:t}=await s.getTextureArray(f);if(e&&null!=t)return new Y(null,e,N(t))}const g=await s.getTexture(f);return g?q(g):null;case at.Boolean:return h;case at.BooleanNode:return new H(Ve(e),h,void 0,!1);case at.Vector2:case at.Vec2Node:if("object"==typeof h){const t=h instanceof Array?(new A).fromArray(h):new A(h.x,h.y);return u===at.Vec2Node?new Z(Ve(e),t,void 0,!1):t}return null;case at.Vector3:case at.Vec3Node:if("object"==typeof h){const t=h instanceof Array?(new x).fromArray(h):new x(h.x,h.y,h.z);return u===at.Vec3Node?new K(Ve(e),t,void 0,!1):t}return null;case at.Vector4:case at.Vec4Node:if("object"==typeof h){const t=h instanceof Array?(new I).fromArray(h):new I(h.x,h.y,h.z,h.w);return u===at.Vec4Node?new Q(Ve(e),t,void 0,!1):t}return null;case at.Color:case at.RgbNode:const y=new o(h);return u===at.RgbNode?new K(Ve(e),new x(y.r,y.g,y.b),void 0,!1).rgb:y;case at.String:return h;case at.BaseActor:const w=h;if(null==r&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==w)return null;if("object"==typeof w&&null!=w.type&&null!=w.id){if("actor"===w.type)return r?.get(w.id)??null;if("prefab"===w.type){const e=p?p(w.id):null;if(null!=e)return r?.get(e)??null;const t=[];for(const[e,a]of r?.entries()??[])e.startsWith(w.id+"/")&&t.push(a);return 1===t.length?t[0]:null}}if("string"==typeof w){const e=r?.get(w);if(null!=e)return e;const t=p?p(w):null;if(null!=t)return r?.get(t)??null;const a=[];for(const[e,t]of r?.entries()??[])e.startsWith(w+"/")&&a.push(t);return 1===a.length?a[0]:null}return null;case at.Euler:const v=h;return(new l).fromArray(v);case at.Object3D:{const e=await a.getAsset(h);return(await s.getMesh(e,{applyMaterials:!0})).scene}case at.Material:{if(null==h)return null;const e=await a.getAsset(h);return null==e?(console.warn("Material asset not found for material parameter",h),null):null==e.material?(console.warn("Using a non-material asset for material parameter"),null):await materialFromAsset(e,i,a,s,n)}case at.AudioBuffer:return await s.getAudio(await a.getAsset(h));case at.VisualEffect:const M=await a.getAsset(h);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in M)return new ue(c,M);console.error("Using a non-vfx asset for visual effect parameter");break;case at.Prefab:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new pe(e)}case at.PrefabActor:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new de(new pe(e))}case at.Sequence:{const e=await a.getAsset(h);if("sequence"===e.type&&"sequence"in e)return new Ct(e.sequence);console.error("Using a non-sequence asset for sequence parameter");break}case at.Curve:return pt.decode(h);case at.ColorLayer:case at.MaskLayer:if(Mt(h)){const e=await ft.decode(h,async e=>await s.getTexture(await a.getAsset(e))),t=await prepareClassParameters(h.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",h),null;case at.AnimationClip:{const e="string"==typeof h?h:"object"==typeof h&&null!=h?h.assetId:null;if(null==e)return console.warn("Invalid animation clip asset id value",h),null;return await s.getAnimationClip(await a.getAsset(e))}}return null}function Lt(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 Rt(e){return"linear"===e.type?new c(new o(e.color),e.near??100,e.far??1e3):"density"===e.type?new h(e.color,e.density):void console.warn("Invalid fog type",e)}new y({color:4229780});async function qt(e,t,a,s){null==s&&(s=(new d).identity());const r=s.clone().multiply(Jt(e,new i.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await qt(e.children[a],t,e,r);await t(e,a,s)}function Jt(e,t){return null==e.position||null==e.rotation||null==e.scale?t.identity():t.compose((new x).fromArray(e.position),(new M).setFromEuler((new l).fromArray(e.rotation)),(new x).fromArray(e.scale))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?at.Number:t instanceof z||"function"==typeof e.prototype.isFloat?at.FloatNode:t instanceof S||e===S||e.isTexture?at.Texture:t instanceof xe||e===xe||e===R||"function"==typeof e.prototype?.isSampler2D||!0===e.prototype?.isSampler2D?at.Sampler2DNode:t instanceof Boolean||e===Boolean?at.Boolean:t instanceof O?at.BooleanNode:t instanceof o||e==o?at.Color:t instanceof G||"function"==typeof e.prototype.isRgb?at.RgbNode:t instanceof A||e==A?at.Vector2:t instanceof re||"function"==typeof e.prototype.isVec2?at.Vec2Node:t instanceof x||e==x?at.Vector3:t instanceof ne||"function"==typeof e.prototype.isVec3?at.Vec3Node:t instanceof I||e==I?at.Vector4:t instanceof le||"function"==typeof e.prototype.isVec4?at.Vec4Node:t instanceof String||e===String?at.String:t instanceof me||e==me||e.prototype instanceof me||e.prototype==me?at.BaseActor:t instanceof l||e==l?at.Euler:t instanceof w||e==w?at.Object3D:t instanceof p||e==p?at.Material:t instanceof AudioBuffer||e==AudioBuffer?at.AudioBuffer:t instanceof ue||e==ue?at.VisualEffect:t instanceof pe||e==pe?at.Prefab:t instanceof de||e==de?at.PrefabActor:t instanceof pt||e==pt?at.Curve:t instanceof ft||e==ft?at.ColorLayer:t instanceof wt||e==wt?at.MaskLayer:t instanceof i.AnimationClip||e==i.AnimationClip?at.AnimationClip:t instanceof Ct||e==Ct||"SequenceData"===e.name||e.prototype&&"tracks"in e.prototype?at.Sequence: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=>{const s=e.options.array?at.Array:toSerializedParamType(e.type),r=e.options.array?toSerializedParamType(e.type):void 0,i=t[e.name];let n=i?.override;void 0===n&&null!=i&&!0===e.options.optional&&(n=!0),void 0===n&&!0===e.options.optional&&(n=!1);const o=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}return customParameterDefaultValueByType.get(toSerializedParamType(e.type))}(e,a),l=!1!==n||e.options.array?i?.value??(e.options.array?[]:Yt(o)):Yt(o);return[e.name,{type:s,...r?{element:r}:{},value:l,override:n}]}))}function Ht(e){return null!=e&&(!1!==e.override&&(!0===e.override||function(e){return null!=e&&(e.type===at.Array?Array.isArray(e.value)?e.value.length>0:null!=e.value:null!=e.value&&""!==e.value)}(e)))}function Xt(e){return null==e?{}:Object.fromEntries(Object.entries(e).filter(([,e])=>Ht(e)))}export function prepareCustomParamsFromType(e,t,a=null){const s=Te(e);if(0===s.length)return{};let r;null!=a?ve(a,()=>{r=a.get(e)}):r=new e;const i={};for(const e of s){const t=r[e.name];if(null!=t&&!0!==e.options.array){const a=serializeCustomParameter(e.type,t);null!=a&&(i[e.name]=a)}}return prepareCustomParams(s,t,i)}function Yt(e){return null==e?e:Array.isArray(e)?e.map(e=>Yt(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 A:return t instanceof A?t.toArray():void a();case x:return t instanceof x?t.toArray():void a();case I:return t instanceof I?t.toArray():void a();case o:return t instanceof o?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new o(t).getHexString():void a();case String:return t;case l:return t instanceof l?t.toArray():void a();case pe:return t instanceof pe?t.asset?.id??null:void a()}if(t&&"object"==typeof t&&"tracks"in t&&"duration"in t)return t}function Zt(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=>Kt(e.materialId)),(t??[]).filter(e=>Kt(e.materialId)),e=>e.color+e.name)}function Kt(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[at.RgbNode,"#000000"],[at.Color,"#000000"],[at.Vector4,[0,0,0,0]],[at.Vec4Node,[0,0,0,0]],[at.Vector3,[0,0,0]],[at.Vec3Node,[0,0,0]],[at.Vector2,[0,0]],[at.Vec2Node,[0,0]],[at.Euler,[0,0,0,"XYZ"]],[at.Array,[]],[at.ColorLayer,gt],[at.MaskLayer,yt]]);let Qt=new o;new o;function ea(e){return null==e?.color?null:(Qt.set(e.color),"#"+Qt.getHexString())}function ta(e,t,a,s){const r=ea(e);return null!=r&&(r===t.color&&(e.name===t.name||null==t.name)||a===t.color&&s===t.name)}export function applyMaterial(e,t,a,s){const r=[];return e.traverse(async e=>{if(e instanceof m||e.isMesh||e instanceof i.SkinnedMesh||e.isSkinnedMesh)for(const t of Ne(e.material))t.hasOwnProperty("color")&&r.push(e)}),Promise.all(r.map(async e=>{if(e.material instanceof Array)for(let r=0;r<e.material.length;r++){const i=e.material[r];if(null==i.color||!(i.color instanceof o))continue;const n=ea(i),l=i.name;if(ta(i,t,e.userData["originalColor_"+r],e.userData["originalMaterialName_"+r])){const i=await a(t.materialId),o=e.material[r];null!=i&&o.id!=i.id&&(e.material[r]=i,e.userData["originalColor_"+r]=e.userData["originalColor_"+r]??n,e.userData["originalMaterialName_"+r]=e.userData["originalMaterialName_"+r]??l,null!=s&&s.set(e.id+"#"+r,o))}}else if("color"in e.material){const r=e.material,i=ea(r),n=r.name;if(ta(r,t,e.userData.originalColor,e.userData.originalMaterialName)){const r=await a(t.materialId),o=e.material;null!=r&&(e.material=r,e.userData.originalColor=e.userData.originalColor??i,e.userData.originalMaterialName=e.userData.originalMaterialName??n,null!=s&&(s.has(e.id)||s.set(e.id,o)))}}}))}function aa(e,t){if(e instanceof i.ShaderMaterial&&t instanceof i.ShaderMaterial){return e.fragmentShader+e.vertexShader==t.fragmentShader+t.vertexShader&&function(e,t){if(e instanceof i.ShaderMaterial&&t instanceof i.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}}const ra=new WeakMap;function ia(e){let t=ra.get(e);return null==t&&(t=function(e){const t=Be(e);if(null==t)return"";return Object.keys(t.geometry.attributes).sort().join(",")}(e),ra.set(e,t)),t}const na=new WeakMap;function oa(e){let t=na.get(e);return null==t&&(t=function(e){let t=e.type;e instanceof i.MeshStandardMaterial&&!(e instanceof i.MeshPhysicalMaterial)||(t+=e.id+"");(e instanceof i.MeshBasicMaterial||e instanceof i.MeshLambertMaterial||e instanceof y||e instanceof g)&&(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 y&&(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 i.MeshPhysicalMaterial&&(null!=e.sheenColorMap&&(t+="sc"+e.sheenColorMap?.id),null!=e.sheenRoughnessMap&&(t+="sr"+e.sheenRoughnessMap?.id));(e instanceof f||e instanceof g)&&null!=e.specularMap&&(t+="s"+e.specularMap?.id);e instanceof i.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 It&&null!=e.heightMap&&(t+="h"+e.heightMap?.id);if(e instanceof i.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),na.set(e,t)),t}function la(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 ca=new d,ha=new l;function ua(e,t){return ha.copy(e),ha.x*=-1,ha.y*=-1,ha.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(ha.y*=-1,ha.z*=-1),(new i.Matrix3).setFromMatrix4(ca.makeRotationFromEuler(ha))}function pa(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 da=new I;function ma(e,t){return e===t||null==e==(null==t)&&("number"==typeof e&&"number"==typeof t?e===t||isNaN(e)&&isNaN(t):e instanceof i.Color&&t instanceof i.Color?e.r===t.r&&e.g===t.g&&e.b===t.b:e instanceof A&&t instanceof A?e.x===t.x&&e.y===t.y:e instanceof x&&t instanceof x?e.x===t.x&&e.y===t.y&&e.z===t.z:e instanceof I&&t instanceof I&&(e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w))}function fa(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof ue?t.push(s):s instanceof ge&&t.push(...fa(s));return t}function ga(e,t){if(!(t instanceof i.ShaderMaterial)){if(e.deleteAttribute("uv1"),e.hasAttribute("color")){const t=e.getAttribute("color");let a=!0;for(let e=0;e<t.count;e++)for(let s=0;s<3;s++){if(1!=t.getComponent(e,s)){a=!1;break}}a&&e.deleteAttribute("color")}if(e.hasAttribute("uv2")){null!=t.lightMap&&null!=t.aoMap||e.deleteAttribute("uv2")}}}function ya(e,t,a){if(t(e))return e;for(const s of e.children??[]){const e=ya(s,t,a);if(null!=e)return e}if(null!=a&&"prefab"===e.type){const s=a.get(e.assetId);if(null!=s){const e=s.prefab.objects.find(e=>ya(e,t,a));if(null!=e)return e}}return null}/*
|
|
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 i from"three";import{BoxGeometry as n,Color as o,Euler as l,Fog as c,FogExp2 as h,Group as u,Material as p,Matrix4 as d,Mesh as m,MeshLambertMaterial as f,MeshPhongMaterial as g,MeshStandardMaterial as y,Object3D as w,PointLight as v,Quaternion as M,Scene as b,Texture as S,Vector2 as A,Vector3 as x,Vector4 as I}from"three";import{attributes as j,batchingUniformFloat as P,batchingUniformVec2 as D,batchingUniformVec3 as C,batchingUniformVec4 as T,bool as V,BooleanExpression as E,BooleanNode as O,colorToNormal as k,float as N,FloatNode as z,ifDefApply as F,mix as B,NodeShaderMaterial as _,rgb as U,rgba as $,RgbNode as G,select as W,standardMaterial as L,Texture2dLookupNode as R,textureSampler2d as q,textureSampler2dArray as J,UniformBoolNode as H,UniformFloatNode as X,UniformSampler2dArraySlice as Y,UniformVec2Node as Z,UniformVec3Node as K,UniformVec4Node as Q,varying as ee,varyingAttributes as te,varyingTransformed as ae,vec2 as se,Vec2Node as re,vec3 as ie,Vec3Node as ne,vec4 as oe,Vec4Node as le}from"three-shader-graph";import{Service as ce}from"typedi";import{VfxActor as he}from"../effects/vfx/vfx-actor.js";import{VisualEffect as ue}from"../effects/vfx/vfx-param.js";import{Prefab as pe,PrefabOf as de}from"./objects/prefab.js";import{BaseActor as me}from"../gameplay/actors/actor.js";import fe from"../gameplay/actors/builtin/index.js";import{ActorComponent as ge}from"../gameplay/actors/component.js";import{PhysicsBodyType as ye}from"../gameplay/services/physics/physics-system.js";import{ThreeBlendingMode as we}from"../effects/vfx/vfx-asset.js";import{withInjectionContext as ve}from"../gameplay/inject.js";import{RenderingView as Me}from"../rendering.js";import{curveSampler as be,oneMinus as Se,particleUniforms as Ae,Sampler2DNode as xe}from"../shader-nodes/index.js";import{LambertShader as Ie}from"../shader/builtin/lambert-shader.js";import{LandscapeCompositeShader as je}from"../shader/builtin/landscape-composite-shader";import{LandscapeShader as Pe}from"../shader/builtin/landscape-shader.js";import{StandardShader as De}from"../shader/builtin/standard-shader.js";import{UnlitShader as Ce}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as Te,shaderParameterUniformName as Ve}from"../shader/parameter.js";import{ArrayMap as Ee,DefaultMap as Oe,groupBy as ke}from"../utils/collections.js";import{iterateMaterials as Ne}from"../utils/materials.js";import{filterChildrenShallow as ze,filterSceneShallow as Fe,findFirstVisibleMesh as Be,findFirstVisibleObject as _e,traverseAsync as Ue}from"../utils/three/traverse.js";import{AssetMeshInstance as $e,AssetResourceLoader as Ge}from"./asset-resource-loader.js";import{AssetsProvider as We}from"./assets-provider.js";import{isCollisionMesh as Le}from"./collision/collision-shape-import.js";import{BoxCollisionShape as Re,PhysicalShapeMesh as qe}from"./collision/collision-shape.js";import{LandscapeManager as Je}from"./landscape/landscape-manager.js";import{initLandscape as He}from"./landscape/landscape.js";import{SectionGrid as Xe,smoothNormalsCrossMeshes as Ye}from"./landscape/utils.js";import{createGrassFoliageMaterial as Ze}from"./materials/grass-foliage.js";import{createGrassMaterial as Ke}from"./materials/grass.js";import{getMaterialAttribute as Qe}from"./materials/utils/material-painting.js";import{SurfaceScatterManager as et}from"./scatter/surface-scatter-manager.js";import{createWaterMaterial as tt}from"./materials/water.js";import{SerializedParamType as at}from"./model.js";import{applyRuntimeParamTypeInference as st,convertConfiguredParamsToRuntimeTypes as rt,convertConfiguredParamValueToRuntimeType as it,inferRuntimeSerializedParamTypeHint as nt}from"./custom-param-runtime-types.js";import{ShapeLibrary as ot,ShapeLibraryKeys as lt}from"./objects/shapes.js";import{ambientLightName as ct,createSky as ht,defaultSkyMaterial as ut}from"./sky.js";import{Curve2 as pt}from"../utils/curve.js";import{DecalUnlitShader as dt}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as mt}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as ft,defaultValueColorLayer as gt,defaultValueMaskLayer as yt,MaskLayer as wt}from"../shader/color-layer.js";import{LayeredShader as vt}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as Mt}from"../shader/color-layer";import{FogVolume as bt}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as St}from"../utils/three/unscaled-sprite.js";import{ToonShader as At}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as xt}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as It}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as jt}from"../shader-nodes/pom.js";import{traverseVisibleEvery as Pt}from"../utils/three/traverse";import{RectAreaLightHelper as Dt}from"three/examples/jsm/Addons.js";import{Sequence as Ct}from"../effects/sequence/sequence-data.js";import{applyUvTiling as Tt}from"./../shader/uv-nodes.js";import{buildShaderGraphMaterial as Vt,shaderGraphMaterialSideToThree as Et}from"../shader/graph/index.js";export{st as applyRuntimeParamTypeInference,rt as convertConfiguredParamsToRuntimeTypes,it as convertConfiguredParamValueToRuntimeType,nt as inferRuntimeSerializedParamTypeHint};const Ot={},kt=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),Nt=/^((?!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,n,o,l,c,h=[]){this.scene=e,this.dataProvider=t,this.assetsService=a,this.assetManagerService=s,this.renderingView=n,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.componentTypes=h,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.idToSceneObject=new Map,this.inEditor=!0,this.updated$=new r,this.removed$=new r,this.error$=new r,this.editorActorParamSnapshot=new Map,this.assets=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.pmremGeneratorResults=new WeakMap,this.prefabInstanceChain=[],this.prefabInstanceExposedActorMap=new Map,this.geometryCache=new Map,this.collisionShapeCache=new Map,this.assetManagerService.materialProvider=async e=>materialFromAsset(this.assets.get(e)??await this.assetsService.getAsset(e),this.renderingView,this.assetsService,this.assetManagerService,this.shaders),this.originalFog=null,t.onCreate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onUpdate(e=>{this.update(e),this.handleSurfaceScatterSceneMutation(e)}),t.onRemove(e=>{this.remove(e),this.handleSurfaceScatterSceneMutation(e)}),this.createAssetSubscription=a.onCreate.subscribe(e=>{this.assets.set(e.id,e)}),this.updateSubscription=a.onUpdate.subscribe(async t=>{if(this.assets.set(t.id,t),"material"==t.type)e.traverse(e=>{if(e instanceof i.Mesh)if(Array.isArray(e.material))for(let a=0;a<e.material.length;a++)this.refreshMaterial(e,e.material[a],t,a);else this.refreshMaterial(e,e.material,t)});else if("mesh"==t.type){this.findByAssetId(t.id).forEach(async e=>{this.remove(e.userData.src);const t=await this.materializeAndInitActor(e.userData.src);this.updated$.next({object:t,source:e.userData.src})});for(const e of this.assets.values())if("prefab"==e.type){if(!e.prefab.objects.some(e=>ya(e,e=>e.assetId==t.id,this.assets)))continue;this.findByAssetId(e.id).forEach(e=>{this.remove(e.userData.src),this.materializeAndInitActor(e.userData.src)})}this.landscapeManagers.forEach(e=>{const a=e.source?.grass?.layers?.some(e=>e.meshes.some(e=>e.assetId===t.id));a&&e.queueRefreshScatter(this.renderingView?.camera.position??new x,!0)}),null!=this.surfaceScatterManager&&(this.surfaceScatterManager.usesSourceAsset(t.id)||this.surfaceScatterManager.usesScatterAsset(t.id))&&this.surfaceScatterManager.queueRefresh(!0)}else if("prefab"===t.type)this.findByAssetId(t.id).forEach(e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}),(this.surfaceScatterManager?.usesPrefabAsset(t.id)||this.sceneReferencesPrefabAsset(t.id)&&await this.prefabAssetContainsSurfaceScatter(t))&&await this.refreshSurfaceScatterPresence(!0);else if("vfx"===t.type)for(const e of this.dataProvider.getObjects())await qt(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 qt(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 i.ShaderMaterial)for(const[e,s]of Object.entries(t.uniforms))s.value instanceof i.Texture&&s.value.userData.assetId===a.id&&(t.uniforms[e].value=r);else for(const[e,s]of Object.entries(t))s instanceof i.Texture&&s.userData.assetId===a.id&&(t[e]=r);else console.error("Can not refresh material textures. Texture not found",a)}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===at.Material&&s.value===a.id){t=!0;break}if(s.type===at.Array&&"element"in s&&s.element===at.Material&&s.value.includes(a.id)){t=!0;break}}if(!t)return}const i=await materialFromAsset(this.assets.get(r),this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1),n=i.userData;i.userData=t.userData,i.userData.hasBloom=n.hasBloom,i.userData.reflective=n.reflective,i.userData.outlineParameters=n.outlineParameters,null!=s?aa(e.material[s],i)||(e.material[s]=i):aa(e.material,i)||(e.material=i,e===this.sky&&this.applySkySettings(e.material))}vfxAssetUsesShaderGraph(e,t){return null!=e.vfx&&e.vfx.emitters.some(e=>this.emitterUsesShaderGraph(e,t))}emitterUsesShaderGraph(e,t){const a=e.output;return"shaderGraph"===a.materialSource&&"asset"===a.shaderGraph?.source&&a.shaderGraph.assetId===t||!!e.children&&e.children.some(e=>this.emitterUsesShaderGraph(e,t))}getTopLevelActors(){return Array.from(this.materializedActors.entries()).filter(([e,t])=>!e.includes("/")).map(([,e])=>e)}get actorInstances(){return Array.from(this.materializedActors.values())}async initTextures(){const e=[];if(await Promise.all(this.dataProvider.getObjects().filter(e=>"shape_mesh"===e.type||"asset_mesh"===e.type).filter(e=>null!=e.materialAssignments).flatMap(e=>e.materialAssignments).map(async t=>{const a=this.assets.get(t.materialId);if(null!=a)for(const t of Object.values(a.material.shaderParams??{}))if(t.type===at.Texture&&"string"==typeof t.value){const a=this.assets.get(t.value),s=await this.assetManagerService.getTexture(a);null!=s&&e.push(s)}})),0!==e.length&&this.renderingView){console.log(`Initializing ${e.length} textures`),console.time("Init textures");for(const t of e)this.renderingView.renderer.initTexture(t);console.timeEnd("Init textures")}}async prefetchAssets(){const e=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)}))),this.initTextures()}async init(){await this.preInit(),Bt.clear(),_t.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.refreshSurfaceScatterPresence(!0)}async initVfx(){console.time("Init VFX");const e=new Set,t=[],a=new b;for(const s of this.actorInstances){const r=fa(s);for(const s of r){const r=s.asset;if(e.has(r.id))continue;e.add(r.id),r.vfx.emitters;const i=await s.create(a);a.add(i.object),a.add(i.particleSystemContainer),i.play(),i.onUpdate(.5),i.stop(),i.pause(),t.push(i)}}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=await this.assetsService.getAsset(a.assetId),r=e.split("/"),i=r.slice(0,-1),n=i.join("/"),o=(r[r.length-1],new Map);for(const[e,t]of this.materializedActors)if(o.set(e,t),0===n.length)e.includes("/")||o.set(e,t);else if(e.startsWith(n+"/")){const a=e.slice(n.length+1);a.includes("/")||o.set(a,t)}const l={...s?.actor?.params??{},...a.actor?.params??{}},c=[...a.actor?.innerParams??[]];for(let t=i.length-1;t>=0;t--){const a=i.slice(0,t+1).join("/"),s=this.idToSceneObject.get(a);if("prefab"===s?.type&&null!=s.prefab){const i=await this.assetsService.getAsset(s.assetId);if(null!=i){let n=!1,o=a+"/"+i.prefab?.mainActorId;for(;null!=o;){if(o===e){n=!0;break}o=this.prefabInstanceExposedActorMap.get(o)}if(n&&null!=s.prefab.params&&Object.assign(l,Xt(s.prefab.params)),null!=s.prefab.innerParams)for(const e of s.prefab.innerParams){const a=r.slice(t+1);e.path.length>=a.length&&e.path.slice(0,a.length).every((e,t)=>e===a[t])&&c.push({path:e.path.slice(a.length),params:e.params})}}}}for(const e of c)await this.applyActorComponentParams(t,e.path.slice(),e.params,o);await this.attachEditorComponents(t,a,o);const h=await prepareClassParameters(l,t.constructor,this.assetsService,this.assetManagerService,o,this.renderingView,this.shaders,this.actorProvider,e=>{const t=n.length>0?n+"/"+e:e;return this.prefabInstanceExposedActorMap.get(t)??null},t);Object.assign(t,h);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 i=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,i);Object.assign(i,e)}for(const e of r.innerParams??[])await this.applyActorComponentParams(i,e.path.slice(),e.params,a)}}addVfxChildActors(e,t=e){}async applyActorComponentParams(e,t,a,s){const r=t.length,i=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[i]&&await this.applyActorComponentParams(e[i],t,a,s)}canObjectBeInstanced(e){return e.physics?.type!==ye.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=>{!Le(e)&&e.isMesh&&s.push(e)});const r=1==s.length&&0==s[0].children.length,i=!Nt,n=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||n&&i)&&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)}),this.assetsService.getAssets().then(e=>{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(),Bt.clear(),_t.clear();const e=[],t=new Ee,a=new Ee,s=new Ee;let r=0,n=0,c=0;const h=new Map,u=new Oe(()=>new Map);for(const i of this.dataProvider.getObjects())await qt(i,async(i,l,p)=>{if(!this.shouldBeMaterialized(i))return;const d="asset_mesh"==i.type&&this.canObjectBeInstanced(i)&&await this.canAssetBeInstanced(i),f="shape_mesh"===i.type&&"landscape"!==i.shape&&i.physics?.type!==ye.dynamic;if(d||f){if(l&&l.children?.length>0){const e=l.children.findIndex(e=>e.id===i.id);e>=0&&l.children.splice(e,1)}if(f){let e=i.shape+JSON.stringify(i.shapeParams??{})+i.castShadow+i.receiveShadow;const t=i.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===at.Color&&null!=e.value&&(r=new o(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:{...i,parentTransform:p},color:r}),c++}else{const e=this.assets.get(i.assetId);let s=h.get(i.assetId);if(null==s){const e=await this.createFromAsset(i,{assignMaterials:!1});if(null==e)return;if(s=h.get(i.assetId),null==s){s={useBatchedMesh:null!=Be(e)&&Pt(e,e=>!(e instanceof m)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},h.set(i.assetId,s)}}const o=Zt(i.materialAssignments,e.materialAssignments);if(s.useBatchedMesh)await Ue(s.assetMesh,async e=>{if(!(e instanceof m))return;const t=Array.isArray(e.material)?e.material[0]:e.material,s=await this.resolveMaterialForAssignments(t,o);if(null!=s){u.get(i.id).set(e.uuid,s),ga(e.geometry,s);let t=oa(s);t+=ia(e),a.push(t,{...i,parentTransform:p,meshUUID:e.uuid}),r++}else console.warn("Can not materialize mesh because missing material",i)});else{const e=i.assetId+JSON.stringify(i.materialAssignments??[]);t.push(e,{...i,parentTransform:p}),n++}}}else null==l&&e.push({...i,parentTransform:p})});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 ${n} objects.\n Shapes: ${s.size} batch groups containing in total ${c} objects. \n ${e.length} objects can not be batched. \n `);for(const e of h.values())this.prepareCollisionShapesForInstanced(e.assetMesh);console.time("materialize batches");for(const[e,t]of a.entries()){if(0==t.length)continue;let e;h.get(t[0].assetId).assetMesh;e=this.createBatchedMesh(t,u,h);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 $e;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=h.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 $e;r.add(t),r.userData.src=e[0],a instanceof $e&&(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=_e(a,e=>!Le(e)&&null!=e.geometry),r=s.material.clone();null!=e[0].color&&null!=r.color&&(r.color=new o(16777215));const n=s.geometry;let c,h;!(Nt||r instanceof _||null==n.index)?(c=new i.BatchedMesh(e.length,n.getAttribute("position").count,n.index.count,r),c.perObjectFrustumCulled=!0,h=c.addGeometry(n)):c=new i.InstancedMesh(n,r,e.length),c.castShadow=a.castShadow??!0,c.receiveShadow=s.receiveShadow??!0;for(let t=0;t<e.length;t++){const a=e[t],s=(new i.Matrix4).compose((new x).fromArray(a.object.position),(new M).setFromEuler((new l).fromArray(a.object.rotation)),(new x).fromArray(a.object.scale)),r=(new d).copy(a.object.parentTransform).multiply(s);let n;n=c instanceof i.BatchedMesh?c.addInstance(h):t,c.setMatrixAt(n,r),a.color}for(let t=0;t<e.length;t++){const s=e[t],r=new $e;r.userData.src=e[0],a instanceof qe&&(r.collisionShapes=[a.collisionShape]),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r),r.add(c),null==c.userData.hasCollision&&(c.userData.hasCollision=[]),c.userData.hasCollision[t]=!!s.object.collisionDetection}}await Promise.all(e.map(e=>this.materialize(e))),await this.initActorsPostInit(),await this.initVfx(),await this.refreshSurfaceScatterPresence(!0)}prepareCollisionShapesForInstanced(e){e instanceof $e&&e.collisionShapes.forEach(e=>{e instanceof a&&e.mesh instanceof m&&(e.mesh=e.mesh.geometry)})}testCanBatch(e,t){return!Nt&&(!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 Ee;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,n=0,l=0;const c=new Map;for(const[e,t]of s.entries()){const s=t[0].assetId,i=a.get(s);if(null==i){console.warn("Missing batching info for asset id "+s);continue}const o=_e(i.assetMesh,t=>t instanceof m&&t.uuid===e);if(null==o){console.warn("Missing mesh in batched asset");continue}c.set(e,o);const h=o.geometry.getAttribute("position");null==h&&console.warn("Missing position attribute for batched mesh"),r+=o.geometry.index.count*t.length,n+=h.count*t.length,l+=t.length}const h=["color","map","roughness","roughnessMap","metalness","metalnessMap","opacity","alphaMap","aoMap","aoMapIntensity","normalMap","normalScale","emissive","emissiveIntensity","emissiveMap"];let u=new Map;const p=[];let d=new i.MeshStandardMaterial({color:"white"});const f=t.get(e[0].id).get(e[0].meshUUID);if(null==f)throw"missing source material";if(f instanceof y&&!(f instanceof i.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 h){let r=e[t];r instanceof i.CompressedArrayTexture&&null!=r.userData.index&&(r=r.userData.index);const n=s.get(t);void 0===n||ma(r,n)?s.set(t,r):a.add(t)}}for(const e of a){let t;const a=f[e];if("number"==typeof a){let a=p.find(e=>e.params.length<4);if(null==a){const t="vp"+p.length;a={name:t,params:[e],node:T(t)},p.push(a)}else a.params.push(e);t=pa(a.node,a.params.length-1)}else if(a instanceof I)t=T(e);else if(a instanceof x||a instanceof o)t=C(e);else if(a instanceof A)t=D(e);else if(a instanceof i.CompressedArrayTexture)t=P(e+"_i");else if(a instanceof S)continue;u.set(e,t)}let r=te.uv;f instanceof It&&null!=f.heightMap&&(r=jt(r,q(f.heightMap),N(f.heightScale)));let n=la(u.get("opacity"),z)??N(f.opacity??1);if(null!=f.alphaMap){let e;if(f.alphaMap instanceof i.CompressedArrayTexture){const t=J(f.alphaMap),a=la(u.get("alphaMap"),z)??N(f.alphaMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.alphaMap).sample(r);n=n.multiply(e.r)}let l=$(la(u.get("color"),ne)??f.color,n);if(null!=f.map){let e;if(f.map instanceof i.CompressedArrayTexture){const t=J(f.map),a=la(u.get("map"),z)??N(f.map.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.map).sample(Tt(r,f.map));l=l.multiply(e),n=n.multiply(e.a)}f.vertexColors&&(l=l.multiply(oe(ee(j.color.rgb),1)));let c=$(la(u.get("emissive"),ne)??f.emissive,n);if(null!=f.emissiveMap){let e;if(f.emissiveMap instanceof i.CompressedArrayTexture){const t=J(f.emissiveMap),a=la(u.get("emissiveMap"),z)??N(f.emissiveMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.emissiveMap).sample(Tt(r,f.emissiveMap));c=c.multiply(e)}const m=la(u.get("emissiveIntensity"),z)??N(f.emissiveIntensity??1),g=la(u.get("normalScale"),re)??se(f.normalScale??new A(1,1));let y=ae.normal;if(null!=f.normalMap){let e;if(f.normalMap instanceof i.CompressedArrayTexture){const t=J(f.normalMap),a=la(u.get("normalMap"),z)??N(f.normalMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.normalMap).sample(Tt(r,f.normalMap));y=k(e.rgb,g.x)}let w=la(u.get("roughness"),z)??N(f.roughness??1);if(null!=f.roughnessMap){let e;if(f.roughnessMap instanceof i.CompressedArrayTexture){const t=J(f.roughnessMap),a=la(u.get("roughnessMap"),z)??N(f.roughnessMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.roughnessMap).sample(Tt(r,f.roughnessMap));w=w.multiply(e.g)}let v=la(u.get("metalness"),z)??N(f.metalness??0);if(null!=f.metalnessMap){let e;if(f.metalnessMap instanceof i.CompressedArrayTexture){const t=J(f.metalnessMap),a=la(u.get("metalnessMap"),z)??N(f.metalnessMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.metalnessMap).sample(Tt(r,f.metalnessMap));v=v.multiply(e.b)}let M=N(1);if(null!=f.aoMap){let e;if(f.aoMap instanceof i.CompressedArrayTexture){const t=J(f.aoMap),a=la(u.get("aoMap"),z)??N(f.aoMap.userData.index??0);e=t.sample(ie(r.x,r.y,a))}else e=q(f.aoMap).sample(Tt(r,f.aoMap));M=M.multiply(e.r)}const b=la(u.get("aoMapIntensity"),z)??N(f.aoMapIntensity??0);let V=y;!0!==f.userData.disableAO&&(V=F("DOUBLE_SIDED",V,e=>W(new E("gl_FrontFacing"),e,e.multiplyScalar(-1))));const O=new _({color:L({color:l,roughness:w,metalness:v,ambientOcclusion:M,ambientOcclusionIntensity:b,emissive:c,emissiveIntensity:m,normal:V}),normal:y,roughness:w,emissive:c.rgb,transparent:f.transparent,alphaTest:f.alphaTest,envMap:f.envMap,opacity:n});null!=f.envMap&&(O.uniforms.envMapIntensity={value:f.envMapIntensity},O.uniforms.envMapRotation={value:ua(f.envMapRotation,f.envMap)}),O.envMap=f.envMap,O.side=f.side,d=O}else{d=f;for(const a of e){const e=t.get(a.id).get(a.meshUUID);if(e!=d){console.error(`Different materials in group for object ${a.id} and mesh uuid ${a.meshUUID}`,{objectMaterial:e,sourceMaterial:f});break}}}const g=new xt(l,n,r,d);for(const e of p)g.initUniform(e.name,4);for(const[e,t]of u.entries()){if(p.some(t=>t.params.includes(e)))continue;let a=1;t instanceof le||t instanceof ne?a=4:t instanceof re&&(a=2),g.initUniform(e,a,0)}for(const[e,r]of s.entries()){const s=r[0].assetId,n=c.get(e);if(null==n){console.error(`Missing single asset mesh for mesh uuid ${e} and asset id ${s}`);continue}if(null==n.geometry){console.error("Missing geometry on mesh mesh");continue}const l=g.addGeometry(n.geometry),h=a.get(s);if(null==h){console.warn("Missing batching info when configuring for asset id "+s);continue}const d=Be(h.assetMesh)?.uuid===e,m=h.assetMesh instanceof $e&&d?h.assetMesh.collisionShapes:void 0,f=this.configureBatchedInstancedMesh(r,g,n,l,m);for(let e=0;e<f.length;e++){const a=r[e],s=f[e],n=t.get(a.id).get(a.meshUUID);for(const e of p){let t=da.set(0,0,0,0);for(let a=0;a<e.params.length;a++){const s=n[e.params[a]];"number"==typeof s&&t.setComponent(a,s)}g.setUniformAt(e.name,s,t)}for(let e of u.keys()){if(p.some(t=>t.params.includes(e)))continue;let t=n[e];if(t instanceof o&&(t=new x(t.r,t.g,t.b)),t instanceof i.CompressedArrayTexture)t=t.userData.index??0,e+="_i";else if(t instanceof S||null==t)continue;g.setUniformAt(e,s,t)}}}return g}async createInstancedMesh(e,t){const a=_e(t,e=>!Le(e)&&null!=e.geometry),s=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(t,Zt(e[0].materialAssignments,s.materialAssignments)),a.updateMatrix();const r=a.geometry.clone(),n=a.material;let o;if(o=new i.InstancedMesh(r,n,e.length),this.configureBatchedInstancedMesh(e,o,a),a.material instanceof p&&o.castShadow&&o.receiveShadow&&Array.isArray(n))for(const e of n);return o}configureBatchedInstancedMesh(e,t,a,s,r){const n=[];a.updateWorldMatrix(!0,!0);for(let o=0;o<e.length;o++){let c=o;t instanceof i.BatchedMesh&&(c=t.addInstance(s)),n.push(c);const h=(new i.Matrix4).compose((new x).fromArray(e[o].position),(new M).setFromEuler((new l).fromArray(e[o].rotation)),(new x).fromArray(e[o].scale)),u=(new d).copy(e[o].parentTransform).multiply(h).multiply(a.matrixWorld);t.setMatrixAt(c,u),null==t.userData.hasCollision&&(t.userData.hasCollision=[]),t.userData.hasCollision[c]=!!e[o].collisionDetection,null!=r&&(null==t.userData.collisionShapes&&(t.userData.collisionShapes=[]),t.userData.collisionShapes[c]=r)}return n}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 Fe(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)try{return materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders)}catch(e){console.error("Failed to apply material",e)}},this._originalMaterials)}async resolveMaterialForAssignments(e,t){let a=e,s=null,r=null;for(const e of t??[]){if(!ta(a,e,s,r))continue;const t=this.assets.get(e.materialId);if(null==t){console.warn("Missing material with id "+e.materialId);continue}const i=await materialFromAsset(t,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0);null!=i&&a.id!==i.id&&(s=s??ea(a),r=r??a.name,a=i)}return a}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(fe));Fe(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,Fe(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 Bt.entries())t.userData.customShaderName&&Bt.delete(e);this.landscapeManagers.forEach(t=>t.updateShaders(e)),Fe(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=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);if("world_env"===e.type&&null!=this.worldEnvObj)return void this.updateWorldEnv(e);const t=this.sceneObjectMap.get(e.id);if(t){let i=!1;if(t.traverseAncestors(e=>{"_hology_transform_group"===e.name&&(i=!0)}),!i){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);Zt(e.materialAssignments,a.materialAssignments).forEach(e=>this.applyMaterial(t,e))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);if(i||(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 o(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 o(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 o(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 Dt&&e.update()})}}else if("landscape"===e.shape){const a=this.landscapeManagers.find(t=>t.source.id===e.id),i=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&&i){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 h?"density":"linear")!==e.fog.type;this.scene.fog=Rt(e.fog),t&&(a=this.scene).traverse(e=>{if(e instanceof m){const t=e.material;t instanceof _&&(a.fog instanceof c?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof h&&(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 bt){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)||i||(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 qe&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}if("shape_mesh"===e.type&&"landscape"!==e.shape)Ft(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;Ft(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:ze(t,t=>t.children?.some(t=>t.id===e.id),()=>!0))[0];return null==t?this.scene:null!=t?Fe(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 o(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=ke(e.vertexMaterials,e=>e.m);t.traverse(e=>{if(e instanceof m){if(null==e.geometry)return;if(sa(Qe(e,0,!1)),a>0){sa(Qe(e,0,!1))}}});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=Qe(s,0,!0);sa(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=Qe(s,4,!0);sa(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),e.needsUpdate=!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,a=!1,s){const r=this.getNestedActorId(e.id,s);if(this.idToSceneObject.set(r,e),!this.shouldBeMaterialized(e))return;let i,n;switch(e.type){case"asset_mesh":i=await this.createFromAsset(e);break;case"shape_mesh":i=await this.createFromShape(e);break;case"light":i=await this.createLight(e);break;case"particles":i=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=Rt(e.fog),this.fixFogColor(),i=new u;break;case"sky":this.sky=ht(),this.updateSky(e),i=this.sky;break;case"world_env":this.updateWorldEnv(e),i=new u,this.worldEnvObj=i;break;case"actor":({object:i,actor:n}=await this.createFromActor(e,s));break;case"group":i=new u;break;case"prefab":i=await this.createFromPrefab(e,s,t);break;case"vfx":i=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!=i){if(e.name&&e.name.length>0&&(i.name=e.name),this.applyTransform(e,i),a?i.userData._src=e:i.userData.src=e,null!=n&&(i.userData.actor=n),this.inEditor,this.inEditor,this.objectMap.set(i.uuid,e),this.sceneObjectMap.set(e.id,i),e.physics?.type!==ye.dynamic||null==t||this.inEditor?null==t?this.scene.add(i):null==t||"actor"!==e.type||this.inEditor?t?.add(i):(t.add(i),this.scene?.attach(i),console.log(i)):(t.add(i),i.getWorldPosition(i.position),i.getWorldQuaternion(i.quaternion),i.getWorldScale(i.scale),this.scene?.attach(i)),null!=e.children&&await Promise.all(e.children?.map(e=>this.materialize(e,i,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==ye.dynamic||Lt(i),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,i;console.warn("RenderingView not found in materializer")}}async handleSurfaceScatterSceneMutation(e){const t=this.surfaceScatterManager?.referencesSceneObject(e.id)??!1,a=await this.sceneObjectContainsSurfaceScatter(e);(t||a)&&await this.refreshSurfaceScatterPresence(!0)}async refreshSurfaceScatterPresence(e=!1){return await this.sceneContainsSurfaceScatter()?(null==this.surfaceScatterManager&&(this.surfaceScatterManager=new et(this.scene,this.dataProvider,this.renderingView,this.assetManagerService,this.assetsService)),this.surfaceScatterManager.queueRefresh(e),!0):(this.disposeSurfaceScatterManager(),!1)}disposeSurfaceScatterManager(){null!=this.surfaceScatterManager&&(this.surfaceScatterManager.clear(),this.surfaceScatterManager.stop(),this.surfaceScatterManager=void 0)}async sceneContainsSurfaceScatter(){return this.sceneObjectsContainSurfaceScatter(this.dataProvider.getObjects())}async sceneObjectsContainSurfaceScatter(e,t=[]){for(const a of e??[])if(await this.sceneObjectContainsSurfaceScatter(a,t))return!0;return!1}async sceneObjectContainsSurfaceScatter(e,t=[]){if("asset_mesh"===e.type&&(e.surfaceScatter?.meshes?.length??0)>0)return!0;if(null!=e.children&&await this.sceneObjectsContainSurfaceScatter(e.children,t))return!0;if("prefab"===e.type&&null!=e.assetId){if(t.includes(e.assetId))return!1;const a=this.assets.get(e.assetId)??await this.assetsService.getAsset(e.assetId),s=a?.prefab?.objects;if(null!=s)return this.sceneObjectsContainSurfaceScatter(s,[...t,e.assetId])}return!1}sceneReferencesPrefabAsset(e){const t=(a=[])=>{for(const s of a??[]){if("prefab"===s.type&&s.assetId===e)return!0;if(t(s.children))return!0}return!1};return t(this.dataProvider.getObjects())}async prefabAssetContainsSurfaceScatter(e){return"prefab"===e.type&&null!=e.prefab?.objects&&this.sceneObjectsContainSurfaceScatter(e.prefab.objects,[e.id])}applyTransform(e,t){null!=e.position&&t.position.fromArray(e.position),null!=e.scale&&t.scale.fromArray(e.scale),null!=e.rotation&&t.rotation.fromArray(e.rotation)}updateWorldEnv(e){this.renderingView.aoPass.enabled=e.worldEnv.ao.enabled,this.renderingView.aoPass.blendIntensity=e.worldEnv.ao.blendIntensity,this.renderingView.aoPass.updateGtaoMaterial(e.worldEnv.ao);const t=e.worldEnv.toneMapping;null!=t&&(this.renderingView.baseToneMapping=t.mapping??0,this.renderingView.baseToneMappingExposure=t.exposure??1,this.renderingView.renderer.toneMapping=this.renderingView.baseToneMapping,this.renderingView.renderer.toneMappingExposure=this.renderingView.baseToneMappingExposure);const a=e.worldEnv.environment;null!=a&&null!=a.textureId?this.assetManagerService.getTexture(this.assets.get(a.textureId)).then(e=>{null==this.pmremGenerator&&(this.pmremGenerator=new i.PMREMGenerator(this.renderingView.renderer),this.pmremGenerator.compileEquirectangularShader()),this.pmremGeneratorResults.has(e)||this.pmremGeneratorResults.set(e,this.pmremGenerator.fromEquirectangular(e).texture);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!==ut?(this.sky.material=ut,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=i.BackSide,(e instanceof y||e instanceof i.MeshBasicMaterial||e instanceof i.ShaderMaterial)&&(e.fog=!1),e.depthTest=!1}async createComponent(e,t,a,s){const r=new Ot[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,t){const a=this.actorTypes.find(t=>t.name===e.actor?.type)?.type??fe[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 x).fromArray(e.position),(new l).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(he,(new x).fromArray(e.position),(new l).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 y({name:"Default",color:new o("#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 u;const a=He(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new Je(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 Xe(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(()=>Ye(r),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&<.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=ot[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,ot[e].collision(s));return new qe(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(Zt(e.materialAssignments,a.materialAssignments).map(e=>this.applyMaterial(s,e)))}catch(t){console.error("Failed to apply material"+t,e)}const r=e.receiveShadow??!!a.receiveShadow,i=e.castShadow??!!a.castShadow;return s.receiveShadow=r,Ft(s,i,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 i=new u;null!=s&&this.applyTransform(s,i),null!=a&&a.add(i),await Promise.all(e.prefab.objects.filter(e=>"global_fog"!==e.type&&"world_env"!==e.type).map(e=>this.materialize(e,i,!0,structuredClone(t))));const n=t.sceneObjectChain.join("/"),o=Array.from(this.materializedActors.entries()).filter(([e,a])=>e.startsWith(n)&&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(n)).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:i,actors:c,mainActor:l}}async createParticleSystem(e){await this.assetsService.getAsset(e.assetId);return new w}async createLight(e){if("point"===e.light.type){const t=new v(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 i.TextureLoader).load("assets/light-bulb-icon.webp"),a=new i.SpriteMaterial({map:e,alphaTest:.5}),s=new St(a);s.scale.multiplyScalar(.6),t.add(s)}return t}if("spot"===e.light.type){const t=new i.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 w,t.target.position.set(0,-1,0),t.add(t.target),this.inEditor){const e=(new i.TextureLoader).load("assets/light-bulb-icon.webp"),a=new i.SpriteMaterial({map:e,alphaTest:.5}),s=new St(a);s.scale.multiplyScalar(.6),t.add(s),t.add(new i.SpotLightHelper(t))}return t}if("rectArea"===e.light.type){const t=new i.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 i.TextureLoader).load("assets/light-bulb-icon.webp"),a=new i.SpriteMaterial({map:e,alphaTest:.5}),s=new St(a);s.scale.multiplyScalar(.6),t.add(s);const r=new Dt(t);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional,e),new u):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient,e),new u):void 0}applyDirectionalAmbientLight(e,t,a){const s=this.scene.children.find(e=>e.name===ct);null!=s?(s.intensity=t.intensity,s.color.set(t.color),s.groundColor.set(t.color),s.userData.src=a,s.userData.volumetricIntensity=t.volumetricIntensity):console.warn("Couldn't find ambient light")}applyDirectionalLight(e,t){for(const a of this.renderingView.csm.lights)a.intensity=e.intensity,a.color.set(e.color),a.castShadow=e.castShadow,a.userData.src=t,a.userData.volumetricIntensity=e.volumetricIntensity;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.createAssetSubscription.unsubscribe(),this.materializedActors.forEach(e=>e.disposed.next(!0)),this.materializedActors.clear()}};zt=e([ce(),t("design:paramtypes",[b,Object,We,Ge,Me,Array,Array,Object,Array])],zt);export{zt as SceneMaterializer};function Ft(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const Bt=new Map,_t=new Map,Ut=new f({color:16711935}),$t=new Map;export async function materialFromAsset(e,t,a,s,r,i=!0){if(null==e||null==e.material)return console.error("Asset or asset material is null",e),Ut;const n=JSON.stringify(e.material)+t?._id,o=i&&!("shaderGraph"===e.material.type&&"asset"===e.material.shaderGraph?.source);if(o&&Bt.has(n))return Bt.get(n);if(o&&_t.has(n))return await _t.get(n);const l=_materialFromAsset(n,e,t,a,s,r,o);return o?_t.set(n,l).get(n):l}export async function _materialFromAsset(e,t,a,r,n,l,c=!0){const h={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 o(t.material.params?.color),transparent:null!=t.material.params?.opacity&&t.material.params?.opacity<1},u={};if(null!=t.material.params?.map){const e=t.material.params.map,a=await r.getAsset(e);null!=a&&(h.map=await n.getTexture(a))}let p,d,m;switch(t.material.type){case"phong":p=new g({...h,...u});break;case"water":p=tt(h,a);break;case"grassFoliage":p=Ze({color:h.color,map:h.map},a);break;case"grass":p=Ke({...h,colorTwo:new o(t.material.params.colorTwo),colorThree:new o(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),p=Ut;break}"surface"===e.target&&null!=e.materialOptions?.side&&(d=Et(e.materialOptions.side)),"decal"===e.target?m=!1:null!=e.materialOptions?.transparent&&(m=e.materialOptions.transparent);try{const s=await prepareShaderGraphParameters(t.material?.shaderParams??{},e,r,n,a,l),i=t.shaderGraphPreviewNodeId,o=t.trailBillboard;p=Vt(e,{parameters:s,previewNodeId:i,trailBillboard:o}),p.userData.customShaderName="asset"===t.material.shaderGraph?.source?`shaderGraph:${t.material.shaderGraph.assetId}`:`shaderGraph:${t.id}`}catch(e){console.log("Shader graph runtime error: "+e,e),p=Ut}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:kt?Ie:De,lambert:Ie,unlit:Ce,toon:At,layered:vt,landscape:Pe,"landscape-composite":je,"decal-unlit":dt,"decal-standard":mt,sprite:s}[t.material.type]??l.find(e=>e.name==t.material.shader)?.type;if(e){try{let s=new e;const i=await prepareClassParameters(t.material?.shaderParams??{},e,r,n,null,a,l,void 0,void 0,s);Object.assign(s,i),p=s.build()}catch(e){console.log("Shader runtime error: "+e,e),$t.has(t.material.shader)||$t.set(t.material.shader,Ut.clone()),p=$t.get(t.material.shader)}p.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),p=Ut;break;default:throw new Error("Unsupported material type "+t.material.type)}return a?.csm.setupMaterial(p),c&&null!=a&&Bt.set(e,p),p.side=d??t.material.side??p.side??i.FrontSide,p.transparent=(m??t.material.transparent??h.transparent??!1)||p.transparent,p.alphaTest=t.material.alphaTest??p.alphaTest??0,null!=t.material.blending&&(p.blending=we[t.material.blending]??i.NormalBlending),t.material.bloom&&(p.userData.hasBloom=!0),t.material.reflective&&(p.userData.reflective=!0),!0===t.material.outlines&&(p.userData.outlineParameters={},null!=t.material.outlineParams&&(null!=t.material.outlineParams.color&&(p.userData.outlineParameters.color=new o(t.material.outlineParams.color).toArray()),null!=t.material.outlineParams.thickness&&(p.userData.outlineParameters.thickness=t.material.outlineParams.thickness))),p.userData.assetId=t.id,c&&_t.delete(e),p}export function prepareCustomParamsFromShaderGraph(e,t={}){return Object.fromEntries((e.parameters??[]).map(e=>{const a=function(e){switch(e){case"float":return at.FloatNode;case"boolean":return at.BooleanNode;case"texture":return at.Sampler2DNode;case"vec2":return at.Vec2Node;case"vec3":return at.Vec3Node;case"vec4":return at.Vec4Node;case"color":return at.RgbNode}}(e.type),s=t[e.name],r=s?.override??null!=s,i=void 0!==e.defaultValue?e.defaultValue:customParameterDefaultValueByType.get(a),n=!1===r?Yt(i):s?.value??Yt(i);return[e.name,{type:a,value:n,override:r}]}))}export async function prepareShaderGraphParameters(e,t,a,s,r,i){const n={},o=prepareCustomParamsFromShaderGraph(t,e);for(const[e,t]of Object.entries(o)){const o=await Wt(e,t,a,s,null,r,i);null!=o&&(n[e]=o)}return n}export async function prepareClassParameters(e,t,a,s,r,i,n,o,l,c){const h={},{params:u,skipped:p}=rt(e,{parameterType:t,parameterTarget:c,extractPropertyParameters:Te,toSerializedParamType:toSerializedParamType});for(const e of p)console.warn(`Skipping stored parameter "${e.key}" because it could not be converted from ${at[e.sourceType]} to ${at[e.targetType]}`);for(const[e,t]of Object.entries(u)){if(!1===t.override)continue;const c=await Wt(e,t,a,s,r,i,n,o,void 0,void 0,l);null!=c&&(h[e]=c)}return h}export async function prepareShapeParameters(e,t,a){const s={};for(const[r,i]of Object.entries(e)){const e=await Wt(r,i,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const Gt=new Map;async function Wt(e,t,a,s,r,i,n,c,h=t.value,u=t.type,p){if(null==t||null==h||""===h)return null;switch(u){case at.Array:if(Array.isArray(h)&&"element"in t)return await Promise.all(h.map(o=>Wt(e,t,a,s,r,i,n,c,o,t.element,p)));break;case at.Number:case at.FloatNode:let d;if("string"==typeof h?d=parseFloat(h):"number"==typeof h&&(d=h),u===at.FloatNode){if("object"==typeof h&&"a"in h&&"b"in h){const e=h;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=Gt.get(e);return null==t&&(t=be(pt.decode(e)),Gt.set(e,t)),t}(e.easing),r=s.sample(Se(Ae.energy));return B(N(t),N(a),r)}return new X(Ve(e),d,void 0,!1)}return d;case at.Texture:let m=await s.getTexture(await a.getAsset(h));return"envmap"===e.toLowerCase()&&null!=i&&(m=i.getEnvTexture(m)),m;case at.Sampler2DNode:const f=await a.getAsset(h);if(null!=f.texture?.textureArrayFileKey){const{texture:e,layerIndex:t}=await s.getTextureArray(f);if(e&&null!=t)return new Y(null,e,N(t))}const g=await s.getTexture(f);return g?q(g):null;case at.Boolean:return h;case at.BooleanNode:return new H(Ve(e),h,void 0,!1);case at.Vector2:case at.Vec2Node:if("object"==typeof h){const t=h instanceof Array?(new A).fromArray(h):new A(h.x,h.y);return u===at.Vec2Node?new Z(Ve(e),t,void 0,!1):t}return null;case at.Vector3:case at.Vec3Node:if("object"==typeof h){const t=h instanceof Array?(new x).fromArray(h):new x(h.x,h.y,h.z);return u===at.Vec3Node?new K(Ve(e),t,void 0,!1):t}return null;case at.Vector4:case at.Vec4Node:if("object"==typeof h){const t=h instanceof Array?(new I).fromArray(h):new I(h.x,h.y,h.z,h.w);return u===at.Vec4Node?new Q(Ve(e),t,void 0,!1):t}return null;case at.Color:case at.RgbNode:const y=new o(h);return u===at.RgbNode?new K(Ve(e),new x(y.r,y.g,y.b),void 0,!1).rgb:y;case at.String:return h;case at.BaseActor:const w=h;if(null==r&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==w)return null;if("object"==typeof w&&null!=w.type&&null!=w.id){if("actor"===w.type)return r?.get(w.id)??null;if("prefab"===w.type){const e=p?p(w.id):null;if(null!=e)return r?.get(e)??null;const t=[];for(const[e,a]of r?.entries()??[])e.startsWith(w.id+"/")&&t.push(a);return 1===t.length?t[0]:null}}if("string"==typeof w){const e=r?.get(w);if(null!=e)return e;const t=p?p(w):null;if(null!=t)return r?.get(t)??null;const a=[];for(const[e,t]of r?.entries()??[])e.startsWith(w+"/")&&a.push(t);return 1===a.length?a[0]:null}return null;case at.Euler:const v=h;return(new l).fromArray(v);case at.Object3D:{const e=await a.getAsset(h);return(await s.getMesh(e,{applyMaterials:!0})).scene}case at.Material:{if(null==h)return null;const e=await a.getAsset(h);return null==e?(console.warn("Material asset not found for material parameter",h),null):null==e.material?(console.warn("Using a non-material asset for material parameter"),null):await materialFromAsset(e,i,a,s,n)}case at.AudioBuffer:return await s.getAudio(await a.getAsset(h));case at.VisualEffect:const M=await a.getAsset(h);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in M)return new ue(c,M);console.error("Using a non-vfx asset for visual effect parameter");break;case at.Prefab:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new pe(e)}case at.PrefabActor:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new de(new pe(e))}case at.Sequence:{const e=await a.getAsset(h);if("sequence"===e.type&&"sequence"in e)return new Ct(e.sequence);console.error("Using a non-sequence asset for sequence parameter");break}case at.Curve:return pt.decode(h);case at.ColorLayer:case at.MaskLayer:if(Mt(h)){const e=await ft.decode(h,async e=>await s.getTexture(await a.getAsset(e))),t=await prepareClassParameters(h.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",h),null;case at.AnimationClip:{const e="string"==typeof h?h:"object"==typeof h&&null!=h?h.assetId:null;if(null==e)return console.warn("Invalid animation clip asset id value",h),null;return await s.getAnimationClip(await a.getAsset(e))}}return null}function Lt(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 Rt(e){return"linear"===e.type?new c(new o(e.color),e.near??100,e.far??1e3):"density"===e.type?new h(e.color,e.density):void console.warn("Invalid fog type",e)}new y({color:4229780});async function qt(e,t,a,s){null==s&&(s=(new d).identity());const r=s.clone().multiply(Jt(e,new i.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await qt(e.children[a],t,e,r);await t(e,a,s)}function Jt(e,t){return null==e.position||null==e.rotation||null==e.scale?t.identity():t.compose((new x).fromArray(e.position),(new M).setFromEuler((new l).fromArray(e.rotation)),(new x).fromArray(e.scale))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?at.Number:t instanceof z||"function"==typeof e.prototype.isFloat?at.FloatNode:t instanceof S||e===S||e.isTexture?at.Texture:t instanceof xe||e===xe||e===R||"function"==typeof e.prototype?.isSampler2D||!0===e.prototype?.isSampler2D?at.Sampler2DNode:t instanceof Boolean||e===Boolean?at.Boolean:t instanceof O?at.BooleanNode:t instanceof o||e==o?at.Color:t instanceof G||"function"==typeof e.prototype.isRgb?at.RgbNode:t instanceof A||e==A?at.Vector2:t instanceof re||"function"==typeof e.prototype.isVec2?at.Vec2Node:t instanceof x||e==x?at.Vector3:t instanceof ne||"function"==typeof e.prototype.isVec3?at.Vec3Node:t instanceof I||e==I?at.Vector4:t instanceof le||"function"==typeof e.prototype.isVec4?at.Vec4Node:t instanceof String||e===String?at.String:t instanceof me||e==me||e.prototype instanceof me||e.prototype==me?at.BaseActor:t instanceof l||e==l?at.Euler:t instanceof w||e==w?at.Object3D:t instanceof p||e==p?at.Material:t instanceof AudioBuffer||e==AudioBuffer?at.AudioBuffer:t instanceof ue||e==ue?at.VisualEffect:t instanceof pe||e==pe?at.Prefab:t instanceof de||e==de?at.PrefabActor:t instanceof pt||e==pt?at.Curve:t instanceof ft||e==ft?at.ColorLayer:t instanceof wt||e==wt?at.MaskLayer:t instanceof i.AnimationClip||e==i.AnimationClip?at.AnimationClip:t instanceof Ct||e==Ct||"SequenceData"===e.name||e.prototype&&"tracks"in e.prototype?at.Sequence: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=>{const s=e.options.array?at.Array:toSerializedParamType(e.type),r=e.options.array?toSerializedParamType(e.type):void 0,i=t[e.name];let n=i?.override;void 0===n&&null!=i&&!0===e.options.optional&&(n=!0),void 0===n&&!0===e.options.optional&&(n=!1);const o=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}return customParameterDefaultValueByType.get(toSerializedParamType(e.type))}(e,a),l=!1!==n||e.options.array?i?.value??(e.options.array?[]:Yt(o)):Yt(o);return[e.name,{type:s,...r?{element:r}:{},value:l,override:n}]}))}function Ht(e){return null!=e&&(!1!==e.override&&(!0===e.override||function(e){return null!=e&&(e.type===at.Array?Array.isArray(e.value)?e.value.length>0:null!=e.value:null!=e.value&&""!==e.value)}(e)))}function Xt(e){return null==e?{}:Object.fromEntries(Object.entries(e).filter(([,e])=>Ht(e)))}export function prepareCustomParamsFromType(e,t,a=null){const s=Te(e);if(0===s.length)return{};let r;null!=a?ve(a,()=>{r=a.get(e)}):r=new e;const i={};for(const e of s){const t=r[e.name];if(null!=t&&!0!==e.options.array){const a=serializeCustomParameter(e.type,t);null!=a&&(i[e.name]=a)}}return prepareCustomParams(s,t,i)}function Yt(e){return null==e?e:Array.isArray(e)?e.map(e=>Yt(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 A:return t instanceof A?t.toArray():void a();case x:return t instanceof x?t.toArray():void a();case I:return t instanceof I?t.toArray():void a();case o:return t instanceof o?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new o(t).getHexString():void a();case String:return t;case l:return t instanceof l?t.toArray():void a();case pe:return t instanceof pe?t.asset?.id??null:void a()}if(t&&"object"==typeof t&&"tracks"in t&&"duration"in t)return t}function Zt(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=>Kt(e.materialId)),(t??[]).filter(e=>Kt(e.materialId)),e=>e.color+e.name)}function Kt(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[at.RgbNode,"#000000"],[at.Color,"#000000"],[at.Vector4,[0,0,0,0]],[at.Vec4Node,[0,0,0,0]],[at.Vector3,[0,0,0]],[at.Vec3Node,[0,0,0]],[at.Vector2,[0,0]],[at.Vec2Node,[0,0]],[at.Euler,[0,0,0,"XYZ"]],[at.Array,[]],[at.ColorLayer,gt],[at.MaskLayer,yt]]);let Qt=new o;new o;function ea(e){return null==e?.color?null:(Qt.set(e.color),"#"+Qt.getHexString())}function ta(e,t,a,s){const r=ea(e);return null!=r&&(r===t.color&&(e.name===t.name||null==t.name)||a===t.color&&s===t.name)}export function applyMaterial(e,t,a,s){const r=[];return e.traverse(async e=>{if(e instanceof m||e.isMesh||e instanceof i.SkinnedMesh||e.isSkinnedMesh)for(const t of Ne(e.material))t.hasOwnProperty("color")&&r.push(e)}),Promise.all(r.map(async e=>{if(e.material instanceof Array)for(let r=0;r<e.material.length;r++){const i=e.material[r];if(null==i.color||!(i.color instanceof o))continue;const n=ea(i),l=i.name;if(ta(i,t,e.userData["originalColor_"+r],e.userData["originalMaterialName_"+r])){const i=await a(t.materialId),o=e.material[r];null!=i&&o.id!=i.id&&(e.material[r]=i,e.userData["originalColor_"+r]=e.userData["originalColor_"+r]??n,e.userData["originalMaterialName_"+r]=e.userData["originalMaterialName_"+r]??l,null!=s&&s.set(e.id+"#"+r,o))}}else if("color"in e.material){const r=e.material,i=ea(r),n=r.name;if(ta(r,t,e.userData.originalColor,e.userData.originalMaterialName)){const r=await a(t.materialId),o=e.material;null!=r&&(e.material=r,e.userData.originalColor=e.userData.originalColor??i,e.userData.originalMaterialName=e.userData.originalMaterialName??n,null!=s&&(s.has(e.id)||s.set(e.id,o)))}}}))}function aa(e,t){if(e instanceof i.ShaderMaterial&&t instanceof i.ShaderMaterial){return e.fragmentShader+e.vertexShader==t.fragmentShader+t.vertexShader&&function(e,t){if(e instanceof i.ShaderMaterial&&t instanceof i.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}}const ra=new WeakMap;function ia(e){let t=ra.get(e);return null==t&&(t=function(e){const t=Be(e);if(null==t)return"";return Object.keys(t.geometry.attributes).sort().join(",")}(e),ra.set(e,t)),t}const na=new WeakMap;function oa(e){let t=na.get(e);return null==t&&(t=function(e){let t=e.type;e instanceof i.MeshStandardMaterial&&!(e instanceof i.MeshPhysicalMaterial)||(t+=e.id+"");(e instanceof i.MeshBasicMaterial||e instanceof i.MeshLambertMaterial||e instanceof y||e instanceof g)&&(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 y&&(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 i.MeshPhysicalMaterial&&(null!=e.sheenColorMap&&(t+="sc"+e.sheenColorMap?.id),null!=e.sheenRoughnessMap&&(t+="sr"+e.sheenRoughnessMap?.id));(e instanceof f||e instanceof g)&&null!=e.specularMap&&(t+="s"+e.specularMap?.id);e instanceof i.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 It&&null!=e.heightMap&&(t+="h"+e.heightMap?.id);if(e instanceof i.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),na.set(e,t)),t}function la(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 ca=new d,ha=new l;function ua(e,t){return ha.copy(e),ha.x*=-1,ha.y*=-1,ha.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(ha.y*=-1,ha.z*=-1),(new i.Matrix3).setFromMatrix4(ca.makeRotationFromEuler(ha))}function pa(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 da=new I;function ma(e,t){return e===t||null==e==(null==t)&&("number"==typeof e&&"number"==typeof t?e===t||isNaN(e)&&isNaN(t):e instanceof i.Color&&t instanceof i.Color?e.r===t.r&&e.g===t.g&&e.b===t.b:e instanceof A&&t instanceof A?e.x===t.x&&e.y===t.y:e instanceof x&&t instanceof x?e.x===t.x&&e.y===t.y&&e.z===t.z:e instanceof I&&t instanceof I&&(e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w))}function fa(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof ue?t.push(s):s instanceof ge&&t.push(...fa(s));return t}function ga(e,t){if(!(t instanceof i.ShaderMaterial)){if(e.deleteAttribute("uv1"),e.hasAttribute("color")){const t=e.getAttribute("color");let a=!0;for(let e=0;e<t.count;e++)for(let s=0;s<3;s++){if(1!=t.getComponent(e,s)){a=!1;break}}a&&e.deleteAttribute("color")}if(e.hasAttribute("uv2")){null!=t.lightMap&&null!=t.aoMap||e.deleteAttribute("uv2")}}}function ya(e,t,a){if(t(e))return e;for(const s of e.children??[]){const e=ya(s,t,a);if(null!=e)return e}if(null!=a&&"prefab"===e.type){const s=a.get(e.assetId);if(null!=s){const e=s.prefab.objects.find(e=>ya(e,t,a));if(null!=e)return e}}return null}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -49,7 +49,9 @@ export declare class ShaderGraphCompiler {
|
|
|
49
49
|
private compileNodeInternal;
|
|
50
50
|
private compileParameterNode;
|
|
51
51
|
private compileBinaryMath;
|
|
52
|
+
private expectBinaryMathValue;
|
|
52
53
|
private compileUnaryMath;
|
|
54
|
+
private compileAtan2;
|
|
53
55
|
private compileBinaryFunction;
|
|
54
56
|
private compilePaintedLayerMix;
|
|
55
57
|
private defaultUV;
|