@hology/core 0.0.185 → 0.0.187
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-materializer.d.ts +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/render.d.ts +1 -1
- package/dist/rendering/fog/fog-volume-actor.d.ts +4 -0
- package/dist/rendering/fog/fog-volume-actor.js +1 -1
- package/dist/rendering/fog/fog-volume-object.d.ts +13 -0
- package/dist/rendering/fog/volumetric-fog-pass.js +1 -1
- package/dist/rendering/outline-effect.js +1 -1
- package/dist/rendering.d.ts +8 -0
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/materializer.d.ts +11 -2
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +1 -1
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/lambert-shader.d.ts +1 -3
- package/dist/shader/builtin/lambert-shader.js +1 -1
- package/dist/shader/builtin/standard-shader.d.ts +1 -0
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/toon-shader.d.ts +1 -0
- package/dist/shader/builtin/toon-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.d.ts +1 -4
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/sprite-shader.d.ts +8 -0
- package/dist/shader/sprite-shader.js +1 -1
- package/dist/shader-nodes/decal.js +1 -1
- package/dist/shader-nodes/pom.d.ts +15 -1
- package/dist/shader-nodes/pom.js +1 -1
- package/dist/utils/three/transform-controls.d.ts +2 -2
- package/dist/utils/three/traverse.d.ts +1 -1
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{ConvexPolyhedronCollisionShape as a}from"@hology/core";import{Subject as s}from"rxjs";import*as r from"three";import{BoxGeometry as i,Color as n,Euler as o,Fog as l,FogExp2 as c,Group as h,Material as p,Matrix4 as d,Mesh as m,MeshLambertMaterial as u,MeshPhongMaterial as f,MeshStandardMaterial as g,Object3D as y,PointLight as w,Quaternion as M,Scene as b,Texture as v,Vector2 as A,Vector3 as S,Vector4 as x}from"three";import{batchingUniformFloat as I,batchingUniformVec2 as j,batchingUniformVec3 as P,batchingUniformVec4 as D,bool as C,BooleanExpression as E,BooleanNode as T,colorToNormal as V,float as O,FloatNode as k,ifDefApply as z,mix as F,NodeShaderMaterial as B,rgb as N,rgba as _,RgbNode as U,select as $,standardMaterial as W,Texture2dLookupNode as L,textureSampler2d as R,textureSampler2dArray as G,varyingAttributes as H,varyingTransformed as J,vec2 as X,Vec2Node as q,vec3 as Y,Vec3Node as Z,vec4 as K,Vec4Node as Q}from"three-shader-graph";import{Service as ee}from"typedi";import{VfxActor as te}from"../effects/vfx/vfx-actor.js";import{VisualEffect as ae}from"../effects/vfx/vfx-param.js";import{Prefab as se,PrefabOf as re}from"./objects/prefab.js";import{BaseActor as ie}from"../gameplay/actors/actor.js";import ne from"../gameplay/actors/builtin/index.js";import{ActorComponent as oe,PhysicsBodyType as le,ThreeBlendingMode as ce,withInjectionContext as he}from"../gameplay/index.js";import{RenderingView as pe}from"../rendering.js";import{curveSampler as de,oneMinus as me,particleUniforms as ue,Sampler2DNode as fe}from"../shader-nodes/index.js";import{LambertShader as ge}from"../shader/builtin/lambert-shader.js";import{LandscapeCompositeShader as ye}from"../shader/builtin/landscape-composite-shader";import{LandscapeShader as we}from"../shader/builtin/landscape-shader.js";import{StandardShader as Me}from"../shader/builtin/standard-shader.js";import{UnlitShader as be}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as ve}from"../shader/parameter.js";import{ArrayMap as Ae,DefaultMap as Se,groupBy as xe}from"../utils/collections.js";import{iterateMaterials as Ie}from"../utils/materials.js";import{filterChildrenShallow as je,filterSceneShallow as Pe,findFirstVisibleMesh as De,findFirstVisibleObject as Ce,traverseAsync as Ee}from"../utils/three/traverse.js";import{AssetMeshInstance as Te,AssetResourceLoader as Ve}from"./asset-resource-loader.js";import{AssetsProvider as Oe}from"./assets-provider.js";import{isCollisionMesh as ke}from"./collision/collision-shape-import.js";import{BoxCollisionShape as ze,PhysicalShapeMesh as Fe}from"./collision/collision-shape.js";import{LandscapeManager as Be}from"./landscape/landscape-manager.js";import{initLandscape as Ne}from"./landscape/landscape.js";import{SectionGrid as _e,smoothNormalsCrossMeshes as Ue}from"./landscape/utils.js";import{createGrassFoliageMaterial as $e}from"./materials/grass-foliage.js";import{createGrassMaterial as We}from"./materials/grass.js";import{getMaterialAttribute as Le}from"./materials/utils/material-painting.js";import{createWaterMaterial as Re}from"./materials/water.js";import{SerializedParamType as Ge}from"./model.js";import{ShapeLibrary as He,ShapeLibraryKeys as Je}from"./objects/shapes.js";import{ambientLightName as Xe,createSky as qe,defaultSkyMaterial as Ye}from"./sky.js";import{Curve2 as Ze}from"../utils/curve.js";import{DecalUnlitShader as Ke}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as Qe}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as et,defaultValueColorLayer as tt,defaultValueMaskLayer as at,MaskLayer as st}from"../shader/color-layer.js";import{LayeredShader as rt}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as it}from"../shader/color-layer";import{FogVolume as nt}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as ot}from"../utils/three/unscaled-sprite.js";import{ToonShader as lt}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as ct}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as ht}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as pt}from"../shader-nodes/pom.js";import{traverseVisibleEvery as dt}from"../utils/three/traverse";const mt={},ut=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),ft=/^((?!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 gt(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}let gt=class{constructor(e,t,a,i,n,o,l,c,h=[]){this.scene=e,this.dataProvider=t,this.assetsService=a,this.assetManagerService=i,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 s,this.removed$=new s,this.error$=new s,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.originalFog=null,t.onCreate(e=>this.update(e)),t.onUpdate(e=>this.update(e)),t.onRemove(e=>this.remove(e)),this.createAssetSubscription=a.onCreate.subscribe(e=>{this.assets.set(e.id,e)}),this.updateSubscription=a.onUpdate.subscribe(async t=>{this.assets.set(t.id,t),"material"==t.type?e.traverse(e=>{if(e instanceof r.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)}):"mesh"==t.type?(this.findByAssetId(t.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 S,!0)})):"prefab"===t.type?this.findByAssetId(t.id).forEach(e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}):"vfx"===t.type&&this.dataProvider.getObjects().forEach(e=>{jt(e,(e,a)=>{"vfx"===e.type&&e.assetId===t.id&&(this.remove(e),this.materializeAndInitActor(e))})})})}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)for(const s of Object.values(e.material.shaderParams)){if(s.type===Ge.Material&&s.value===a.id){t=!0;break}if(s.type===Ge.Array&&"element"in s&&s.element===Ge.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?Ot(e.material[s],i)||(e.material[s]=i):Ot(e.material,i)||(e.material=i,e===this.sky&&this.applySkySettings(e.material))}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===Ge.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(),wt.clear(),Mt.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit()}async initVfx(){console.time("Init VFX");const e=new Set,t=[],a=new b;for(const s of this.actorInstances){const r=Ht(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,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});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);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);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!==le.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=>{!ke(e)&&e.isMesh&&s.push(e)});const r=1==s.length&&0==s[0].children.length,i=!ft,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(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(),wt.clear(),Mt.clear();const e=[],t=new Ae,a=new Ae,s=new Ae;let i=0,l=0,c=0;const h=new Map,p=new Se(()=>new Map);for(const r of this.dataProvider.getObjects())await jt(r,async(r,o,d)=>{if(!this.shouldBeMaterialized(r))return;const u="asset_mesh"==r.type&&this.canObjectBeInstanced(r)&&await this.canAssetBeInstanced(r),f="shape_mesh"===r.type&&"landscape"!==r.shape&&r.physics?.type!==le.dynamic;if(u||f){if(o&&o.children?.length>0){const e=o.children.findIndex(e=>e.id===r.id);e>=0&&o.children.splice(e,1)}if(f){let e=r.shape+JSON.stringify(r.shapeParams??{})+r.castShadow+r.receiveShadow;const t=r.materialAssignments?.at(0)?.materialId,a=null!=t?this.assets.get(t):null;let i=null;if(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===Ge.Color&&null!=e.value&&(i=new n(e.value))}}}else e+=t;s.push(e,{object:{...r,parentTransform:d},color:i}),c++}else{const e=this.assets.get(r.assetId);let s=h.get(r.assetId);if(null==s){const e=await this.createFromAsset(r,{assignMaterials:!1});if(null==e)return;if(s=h.get(r.assetId),null==s){s={useBatchedMesh:null!=De(e)&&dt(e,e=>!(e instanceof m)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},h.set(r.assetId,s)}}const n=Dt(r.materialAssignments,e.materialAssignments);if(s.useBatchedMesh)await Ee(s.assetMesh,async e=>{if(!(e instanceof m))return;const t=Array.isArray(e.material)?e.material[0]:e.material,s=n.find(e=>null!=t.color&&Vt(e.color,t.color)&&(null==e.name||t.name===e.name))?.materialId;let o=t;if(null!=s){const e=this.assets.get(s);o=await materialFromAsset(e,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0)}if(null!=o){p.get(r.id).set(e.uuid,o),Jt(e.geometry,o);let t=Nt(o);t+=Ft(e),a.push(t,{...r,parentTransform:d,meshUUID:e.uuid}),i++}else console.warn("Can not materialize mesh because missing material",r)});else{const e=r.assetId+JSON.stringify(r.materialAssignments??[]);t.push(e,{...r,parentTransform:d}),l++}}}else null==o&&e.push({...r,parentTransform:d})});console.log(`Scene init stats: \n Batched Assets: ${a.size} groups containing in total ${i} objects.\n Instanced Assets: ${t.size} groups containing in total ${l} 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;const a=h.get(t[0].assetId).assetMesh;e=this.createBatchedMesh(t,p,h);const s=this.assets.get(t[0].assetId);e.castShadow=t[0].castShadow??s.castShadow??!0,e.receiveShadow=t[0].receiveShadow??s.receiveShadow??!0;const r=new Te;r.add(e),r.userData.src=t[0],a instanceof Te&&(r.collisionShapes=a.collisionShapes),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r)}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 Te;r.add(t),r.userData.src=e[0],a instanceof Te&&(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=Ce(a,e=>!ke(e)&&null!=e.geometry),i=s.material.clone();null!=e[0].color&&null!=i.color&&(i.color=new n(16777215));const l=s.geometry;let c,h;!(ft||i instanceof B||null==l.index)?(c=new r.BatchedMesh(e.length,l.getAttribute("position").count,l.index.count,i),c.perObjectFrustumCulled=!0,h=c.addGeometry(l)):c=new r.InstancedMesh(l,i,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 r.Matrix4).compose((new S).fromArray(a.object.position),(new M).setFromEuler((new o).fromArray(a.object.rotation)),(new S).fromArray(a.object.scale)),i=(new d).copy(a.object.parentTransform).multiply(s);let n;n=c instanceof r.BatchedMesh?c.addInstance(h):t,c.setMatrixAt(n,i),null!=a.color&&c.setColorAt(n,a.color)}for(let t=0;t<e.length;t++){const s=e[t],r=new Te;r.userData.src=e[0],a instanceof Fe&&(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()}prepareCollisionShapesForInstanced(e){e instanceof Te&&e.collisionShapes.forEach(e=>{e instanceof a&&e.mesh instanceof m&&(e.mesh=e.mesh.geometry)})}testCanBatch(e,t){return!ft&&t.groups.length<2&&(!Array.isArray(e)||1==e.length)&&this.testCanBatchMaterial(e)}testCanBatchMaterial(e){const t=Array.isArray(e)?e[0]:e;return null!=t&&(!(t instanceof g)||null==t.bumpMap&&null==t.lightMap&&null==t.displacementMap)}createBatchedMesh(e,t,a){const s=new Ae;for(const t of e)null!=t.meshUUID?s.push(t.meshUUID??t.assetId,t):console.warn("Missing mesh uuid for batching");let i=0,o=0,l=0;const c=new Map;for(const[e,t]of s.entries()){const s=t[0].assetId,r=a.get(s);if(null==r){console.warn("Missing batching info for asset id "+s);continue}const n=Ce(r.assetMesh,t=>t instanceof m&&t.uuid===e);if(null==n){console.warn("Missing mesh in batched asset");continue}c.set(e,n);const h=n.geometry.getAttribute("position");null==h&&console.warn("Missing position attribute for batched mesh"),i+=n.geometry.index.count*t.length,o+=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 p=new Map;const d=[];let u=new r.MeshStandardMaterial({color:"white"});const f=t.get(e[0].id).get(e[0].meshUUID);if(null==f)throw"missing source material";if(f instanceof g){const a=new Set,s=new Map;for(const i of e){const e=t.get(i.id).get(i.meshUUID);if(null==e)throw"missing mat";for(const t of h){let i=e[t];i instanceof r.CompressedArrayTexture&&null!=i.userData.index&&(i=i.userData.index);const n=s.get(t);void 0===n||Gt(i,n)?s.set(t,i):a.add(t)}}for(const e of a){let t;const a=f[e];if("number"==typeof a){let a=d.find(e=>e.params.length<4);if(null==a){const t="vp"+d.length;a={name:t,params:[e],node:D(t)},d.push(a)}else a.params.push(e);t=Lt(a.node,a.params.length-1)}else if(a instanceof x)t=D(e);else if(a instanceof S||a instanceof n)t=P(e);else if(a instanceof A)t=j(e);else if(a instanceof r.CompressedArrayTexture)t=I(e+"_i");else if(a instanceof v)continue;p.set(e,t)}let i=H.uv;f instanceof ht&&null!=f.heightMap&&(i=pt(i,R(f.heightMap),O(f.heightScale)));let o=_t(p.get("opacity"),k)??O(f.opacity??1);if(null!=f.alphaMap){let e;if(f.alphaMap instanceof r.CompressedArrayTexture){const t=G(f.alphaMap),a=_t(p.get("alphaMap"),k)??O(f.alphaMap.userData.index??0);e=t.sample(Y(i.x,i.y,a))}else e=R(f.alphaMap).sample(i);o=o.multiply(e.r)}let l=_(_t(p.get("color"),Z)??f.color,o);if(null!=f.map){let e;if(f.map instanceof r.CompressedArrayTexture){const t=G(f.map),a=_t(p.get("map"),k)??O(f.map.userData.index??0);e=t.sample(Y(i.x,i.y,a))}else e=R(f.map).sample(i);l=l.multiply(e)}let c=_(_t(p.get("emissive"),Z)??f.emissive,o);if(null!=f.emissiveMap){let e;if(f.emissiveMap instanceof r.CompressedArrayTexture){const t=G(f.emissiveMap),a=_t(p.get("emissiveMap"),k)??O(f.emissiveMap.userData.index??0);e=t.sample(Y(i.x,i.y,a))}else e=R(f.emissiveMap).sample(i);c=c.multiply(e)}const m=_t(p.get("emissiveIntensity"),k)??O(f.emissiveIntensity??1),g=_t(p.get("normalScale"),q)??X(f.normalScale??new A(1,1));let y=J.normal;if(null!=f.normalMap){let e;if(f.normalMap instanceof r.CompressedArrayTexture){const t=G(f.normalMap),a=_t(p.get("normalMap"),k)??O(f.normalMap.userData.index??0);e=t.sample(Y(i.x,i.y,a))}else e=R(f.normalMap).sample(i);y=V(e.rgb,g.x)}let w=_t(p.get("roughness"),k)??O(f.roughness??1);if(null!=f.roughnessMap){let e;if(f.roughnessMap instanceof r.CompressedArrayTexture){const t=G(f.roughnessMap),a=_t(p.get("roughnessMap"),k)??O(f.roughnessMap.userData.index??0);e=t.sample(Y(i.x,i.y,a))}else e=R(f.roughnessMap).sample(i);w=w.multiply(e.g)}let M=_t(p.get("metalness"),k)??O(f.metalness??0);if(null!=f.metalnessMap){let e;if(f.metalnessMap instanceof r.CompressedArrayTexture){const t=G(f.metalnessMap),a=_t(p.get("metalnessMap"),k)??O(f.metalnessMap.userData.index??0);e=t.sample(Y(i.x,i.y,a))}else e=R(f.metalnessMap).sample(i);M=M.multiply(e.b)}let b=O(1);if(null!=f.aoMap){let e;if(f.aoMap instanceof r.CompressedArrayTexture){const t=G(f.aoMap),a=_t(p.get("aoMap"),k)??O(f.aoMap.userData.index??0);e=t.sample(Y(i.x,i.y,a))}else e=R(f.aoMap).sample(i);b=b.multiply(e.r)}const C=_t(p.get("aoMapIntensity"),k)??O(f.aoMapIntensity??0);let T=y;!0!==f.userData.disableAO&&(T=z("DOUBLE_SIDED",T,e=>$(new E("gl_FrontFacing"),e,e.multiplyScalar(-1))));const F=new B({color:W({color:l,roughness:w,metalness:M,ambientOcclusion:b,ambientOcclusionIntensity:C,emissive:c,emissiveIntensity:m,normal:T}),normal:y,roughness:w,emissive:c.rgb,transparent:f.transparent,alphaTest:f.alphaTest,envMap:f.envMap});null!=f.envMap&&(F.uniforms.envMapIntensity={value:f.envMapIntensity},F.uniforms.envMapRotation={value:Wt(f.envMapRotation,f.envMap)}),F.envMap=f.envMap,F.side=f.side,u=F}else{u=f;for(const a of e){const e=t.get(a.id).get(a.meshUUID);if(e!=u){console.error(`Different materials in group for object ${a.id} and mesh uuid ${a.meshUUID}`,{objectMaterial:e,sourceMaterial:f});break}}}const y=new ct(l,o,i,u);for(const e of d)y.initUniform(e.name,4);for(const[e,t]of p.entries()){if(d.some(t=>t.params.includes(e)))continue;let a=1;t instanceof Q||t instanceof Z?a=4:t instanceof q&&(a=2),y.initUniform(e,a,0)}for(const[e,i]of s.entries()){const s=i[0].assetId,o=c.get(e);if(null==o){console.error(`Missing single asset mesh for mesh uuid ${e} and asset id ${s}`);continue}if(null==o.geometry){console.error("Missing geometry on mesh mesh");continue}const l=y.addGeometry(o.geometry),h=a.get(s);if(null==h){console.warn("Missing batching info when configuring for asset id "+s);continue}const m=De(h.assetMesh)?.uuid===e,u=h.assetMesh instanceof Te&&m?h.assetMesh.collisionShapes:void 0,f=this.configureBatchedInstancedMesh(i,y,o,l,u);for(let e=0;e<f.length;e++){const a=i[e],s=f[e],o=t.get(a.id).get(a.meshUUID);for(const t of d){let a=Rt.set(0,0,0,0);for(let e=0;e<t.params.length;e++){const s=o[t.params[e]];"number"==typeof s&&a.setComponent(e,s)}y.setUniformAt(t.name,e,a)}for(let e of p.keys()){if(d.some(t=>t.params.includes(e)))continue;let t=o[e];if(t instanceof n&&(t=new S(t.r,t.g,t.b)),t instanceof r.CompressedArrayTexture)t=t.userData.index??0,e+="_i";else if(t instanceof v||null==t)continue;y.setUniformAt(e,s,t)}}}return y}async createInstancedMesh(e,t){const a=Ce(t,e=>!ke(e)&&null!=e.geometry),s=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(t,Dt(e[0].materialAssignments,s.materialAssignments)),a.updateMatrix();const i=a.geometry.clone(),n=a.material;let o;if(o=new r.InstancedMesh(i,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,i){const n=[];a.updateMatrixWorld();for(let l=0;l<e.length;l++){let c=l;t instanceof r.BatchedMesh&&(c=t.addInstance(s)),n.push(c);const h=(new r.Matrix4).compose((new S).fromArray(e[l].position),(new M).setFromEuler((new o).fromArray(e[l].rotation)),(new S).fromArray(e[l].scale)),p=(new d).copy(e[l].parentTransform).multiply(h).multiply(a.matrixWorld);t.setMatrixAt(c,p),null==t.userData.hasCollision&&(t.userData.hasCollision=[]),t.userData.hasCollision[c]=!!e[l].collisionDetection,null!=i&&(null==t.userData.collisionShapes&&(t.userData.collisionShapes=[]),t.userData.collisionShapes[c]=i)}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 Pe(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)}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(ne));Pe(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,Pe(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 wt.entries())t.userData.customShaderName&&wt.delete(e);this.landscapeManagers.forEach(t=>t.updateShaders(e)),Pe(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){const a=this.assets.get(e.assetId);Dt(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 n(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 n(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"directional"===e.light.type?this.applyDirectionalLight(e.light.directional,e):"ambient"===e.light.type&&this.applyDirectionalAmbientLight(t,e.light.ambient,e);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 c?"density":"linear")!==e.fog.type;this.scene.fog=It(e.fog),t&&(a=this.scene).traverse(e=>{if(e instanceof m){const t=e.material;t instanceof B&&(a.fog instanceof l?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof c&&(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 nt){const a=await prepareClassParameters(e.actor.params,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,[],this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null);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 Fe&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}("asset_mesh"===e.type||"shape_mesh"===e.type&&"landscape"!==e.shape)&&yt(t,e.castShadow,e.receiveShadow),e.name&&e.name.length>0&&(t.name=e.name),this.updated$.next({object:t,source:e})}else{const t=await this.materializeAndInitActor(e);this.updated$.next({object:t,source:e})}var a;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:je(t,t=>t.children?.some(t=>t.id===e.id),()=>!0))[0];return null==t?this.scene:null!=t?Pe(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 n(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=xe(e.vertexMaterials,e=>e.m);t.traverse(e=>{if(e instanceof m){if(null==e.geometry)return;if(kt(Le(e,0,!1)),a>0){kt(Le(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=Le(s,0,!0);kt(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=Le(s,4,!0);kt(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=It(e.fog),this.fixFogColor(),i=new h;break;case"sky":this.sky=qe(),this.updateSky(e),i=this.sky;break;case"world_env":this.updateWorldEnv(e),i=new h,this.worldEnvObj=i;break;case"actor":({object:i,actor:n}=await this.createFromActor(e,s));break;case"group":i=new h;break;case"prefab":i=await this.createFromPrefab(e,s,t);break;case"vfx":i=await this.createFromVfx(e,s);break;default:if(this.inEditor)throw new Error("unknown type "+e.type);console.warn(`Failed to materialize object. Unknown type '${e.type}'. This might be because the hology/core library is not compatible with the editor version.`)}if(null!=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!==le.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==le.dynamic||xt(i),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,i;console.warn("RenderingView not found in materializer")}}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.renderer.toneMapping=t.mapping??0,this.renderingView.renderer.toneMappingExposure=t.exposure??1);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 r.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.renderer.toneMapping=0,this.renderingView.renderer.toneMappingExposure=1}async updateSky(e){if(null==e?.sky?.materialId)return void(this.sky.material=Ye);const t=await this.assetsService.getAsset(e.sky.materialId),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=r.BackSide,(e instanceof g||e instanceof r.MeshBasicMaterial||e instanceof r.ShaderMaterial)&&(e.fog=!1),e.depthTest=!1}async createComponent(e,t,a,s){const r=new mt[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??ne[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 S).fromArray(e.position),(new o).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(te,(new S).fromArray(e.position),(new o).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 g({name:"Default",color:new n("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});const r=await this.createMeshByShape(e.shape,s,e.shapeParams);r.castShadow=e.castShadow??!0,r.receiveShadow=e.castShadow??!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 h;const a=Ne(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new Be(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 _e(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(()=>Ue(r),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&Je.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=He[e].geometry(s);t.computeTangents(),this.geometryCache.set(r,t)}this.collisionShapeCache.has(r)||this.collisionShapeCache.set(r,He[e].collision(s));return new Fe(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=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(Dt(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,yt(s,i,r),e.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}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 h;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 y}async createLight(e){if("point"===e.light.type){const t=new w(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 r.TextureLoader).load("assets/light-bulb-icon.webp"),a=new r.SpriteMaterial({map:e,alphaTest:.5}),s=new ot(a);s.scale.multiplyScalar(.6),t.add(s)}return t}if("spot"===e.light.type){const t=new r.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 y,t.target.position.set(0,-1,0),t.add(t.target),this.inEditor){const e=(new r.TextureLoader).load("assets/light-bulb-icon.webp"),a=new r.SpriteMaterial({map:e,alphaTest:.5}),s=new ot(a);s.scale.multiplyScalar(.6),t.add(s),t.add(new r.SpotLightHelper(t))}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional,e),new h):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient,e),new h):void 0}applyDirectionalAmbientLight(e,t,a){const s=this.scene.children.find(e=>e.name===Xe);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()}};gt=e([ee(),t("design:paramtypes",[b,Object,Oe,Ve,pe,Array,Array,Object,Array])],gt);export{gt as SceneMaterializer};function yt(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const wt=new Map,Mt=new Map,bt=new u({color:16711935}),vt=new Map;export async function materialFromAsset(e,t,a,s,r,i=!0){const n=JSON.stringify(e.material)+t?._id;return i&&wt.has(n)?wt.get(n):i&&Mt.has(n)?await Mt.get(n):Mt.set(n,_materialFromAsset(n,e,t,a,s,r,i)).get(n)}export async function _materialFromAsset(e,t,a,s,i,o,l=!0){const c={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 n(t.material.params?.color),transparent:null!=t.material.params?.opacity&&t.material.params?.opacity<1},h={};if(null!=t.material.params?.map){const e=t.material.params.map,a=await s.getAsset(e);null!=a&&(c.map=await i.getTexture(a))}let p;switch(t.material.type){case"phong":p=new f({...c,...h});break;case"water":p=Re(c,a);break;case"grassFoliage":p=$e({color:c.color,map:c.map},a);break;case"grass":p=We({...c,colorTwo:new n(t.material.params.colorTwo),colorThree:new n(t.material.params.colorThree)},a);break;case"standard":case"unlit":case"toon":case"layered":case"lambert":case"shader":case"landscape":case"landscape-composite":case"decal-unlit":case"decal-standard":const e={standard:ut?ge:Me,lambert:ge,unlit:be,toon:lt,layered:rt,landscape:we,"landscape-composite":ye,"decal-unlit":Ke,"decal-standard":Qe}[t.material.type]??o.find(e=>e.name==t.material.shader)?.type;if(e){try{let r=new e;const n=await prepareClassParameters(t.material?.shaderParams??{},e,s,i,null,a,o);Object.assign(r,n),p=r.build()}catch(e){console.log("Shader runtime error: "+e),vt.has(t.material.shader)||vt.set(t.material.shader,bt.clone()),p=vt.get(t.material.shader)}p.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),p=bt;break;default:throw new Error("Unsupported material type"+t.material.type)}return a?.csm.setupMaterial(p),null!=a&&wt.set(e,p),p.side=t.material.side??p.side??r.FrontSide,p.transparent=(t.material.transparent??c.transparent??!1)||p.transparent,p.alphaTest=t.material.alphaTest??p.alphaTest??0,null!=t.material.blending&&(p.blending=ce[t.material.blending]??r.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 n(t.material.outlineParams.color).toArray()),null!=t.material.outlineParams.thickness&&(p.userData.outlineParameters.thickness=t.material.outlineParams.thickness))),p.userData.assetId=t.id,Mt.delete(e),p}export async function prepareClassParameters(e,t,a,s,r,i,n,o,l){const c={};for(const[t,h]of Object.entries(e)){if(!1===h.override)continue;const e=await St(t,h,a,s,r,i,n,o,void 0,void 0,l);null!=e&&(c[t]=e)}return c}export async function prepareShapeParameters(e,t,a){const s={};for(const[r,i]of Object.entries(e)){const e=await St(r,i,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const At=new Map;async function St(e,t,a,s,r,i,l,c,h=t.value,p=t.type,d){if(null==t||null==h||""===h)return null;switch(p){case Ge.Array:if(Array.isArray(h)&&"element"in t)return await Promise.all(h.map(n=>St(e,t,a,s,r,i,l,c,n,t.element,d)));break;case Ge.Number:case Ge.FloatNode:let p;if("string"==typeof h?p=parseFloat(h):"number"==typeof h&&(p=h),t.type===Ge.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=At.get(e);return null==t&&(t=de(Ze.decode(e)),At.set(e,t)),t}(e.easing),r=s.sample(me(ue.energy));return F(O(t),O(a),r)}return O(p)}return p;case Ge.Texture:let m=await s.getTexture(await a.getAsset(h));return"envmap"===e.toLowerCase()&&null!=i&&(m=i.getEnvTexture(m)),m;case Ge.Sampler2DNode:return R(await s.getTexture(await a.getAsset(h)));case Ge.Boolean:return h;case Ge.BooleanNode:return C(h);case Ge.Vector2:case Ge.Vec2Node:if("object"==typeof h){const e=h instanceof Array?(new A).fromArray(h):new A(h.x,h.y);return t.type===Ge.Vec2Node?X(e):e}return null;case Ge.Vector3:case Ge.Vec3Node:if("object"==typeof h){const e=h instanceof Array?(new S).fromArray(h):new S(h.x,h.y,h.z);return t.type===Ge.Vec3Node?Y(e):e}return null;case Ge.Color:case Ge.RgbNode:const u=new n(h);return t.type===Ge.RgbNode?N(u):u;case Ge.String:return h;case Ge.BaseActor:const f=h;if(null==r&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==f)return null;if("object"==typeof f&&null!=f.type&&null!=f.id){if("actor"===f.type)return r?.get(f.id)??null;if("prefab"===f.type){const e=d?d(f.id):null;if(null!=e)return r?.get(e)??null;const t=[];for(const[e,a]of r?.entries()??[])e.startsWith(f.id+"/")&&t.push(a);return 1===t.length?t[0]:null}}if("string"==typeof f){const e=r?.get(f);if(null!=e)return e;const t=d?d(f):null;if(null!=t)return r?.get(t)??null;const a=[];for(const[e,t]of r?.entries()??[])e.startsWith(f+"/")&&a.push(t);return 1===a.length?a[0]:null}return null;case Ge.Euler:const g=h;return(new o).fromArray(g);case Ge.Object3D:return(await s.getMesh(await a.getAsset(h))).scene;case Ge.Material:return await materialFromAsset(await a.getAsset(h),i,a,s,l);case Ge.AudioBuffer:return await s.getAudio(await a.getAsset(h));case Ge.VisualEffect:const y=await a.getAsset(h);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in y)return new ae(c,y);console.error("Using a non-vfx asset for visual effect parameter");break;case Ge.Prefab:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new se(e)}case Ge.PrefabActor:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new re(new se(e))}case Ge.Curve:return Ze.decode(h);case Ge.ColorLayer:case Ge.MaskLayer:if(it(h)){const e=await et.decode(h,async e=>await s.getTexture(await a.getAsset(e))),t=await prepareClassParameters(h.params,null,a,s);return Object.assign(e,t),e}return console.warn("Expecting color layer but got",h),null;case Ge.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 xt(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 It(e){return"linear"===e.type?new l(new n(e.color),e.near??100,e.far??1e3):"density"===e.type?new c(e.color,e.density):void console.warn("Invalid fog type",e)}new g({color:4229780});async function jt(e,t,a,s){null==s&&(s=(new d).identity());const i=s.clone().multiply(Pt(e,new r.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await jt(e.children[a],t,e,i);await t(e,a,s)}function Pt(e,t){return null==e.position||null==e.rotation||null==e.scale?t.identity():t.compose((new S).fromArray(e.position),(new M).setFromEuler((new o).fromArray(e.rotation)),(new S).fromArray(e.scale))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?Ge.Number:t instanceof k||"function"==typeof e.prototype.isFloat?Ge.FloatNode:t instanceof v||e===v||e.isTexture?Ge.Texture:t instanceof fe||e===L?Ge.Sampler2DNode:t instanceof Boolean||e===Boolean?Ge.Boolean:t instanceof T?Ge.BooleanNode:t instanceof n||e==n?Ge.Color:t instanceof U||"function"==typeof e.prototype.isRgb?Ge.RgbNode:t instanceof A||e==A?Ge.Vector2:t instanceof q||"function"==typeof e.prototype.isVec2?Ge.Vec2Node:t instanceof S||e==S?Ge.Vector3:t instanceof Z||"function"==typeof e.prototype.isVec3?Ge.Vec3Node:t instanceof String||e===String?Ge.String:t instanceof ie||e==ie||e.prototype instanceof ie||e.prototype==ie?Ge.BaseActor:t instanceof o||e==o?Ge.Euler:t instanceof y||e==y?Ge.Object3D:t instanceof p||e==p?Ge.Material:t instanceof AudioBuffer||e==AudioBuffer?Ge.AudioBuffer:t instanceof ae||e==ae?Ge.VisualEffect:t instanceof se||e==se?Ge.Prefab:t instanceof re||e==re?Ge.PrefabActor:t instanceof Ze||e==Ze?Ge.Curve:t instanceof et||e==et?Ge.ColorLayer:t instanceof st||e==st?Ge.MaskLayer:t instanceof r.AnimationClip||e==r.AnimationClip?Ge.AnimationClip: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?Ge.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&&(n=!0);const o=a[e.name]??customParameterDefaultValueByType.get(toSerializedParamType(e.type)),l=!1!==n||e.options.array?i?.value??(e.options.array?[]:o):o;return[e.name,{type:s,...r?{element:r}:{},value:l,override:n}]}))}export function prepareCustomParamsFromType(e,t,a=null){const s=ve(e);if(0===s.length)return{};let r;null!=a?he(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)}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 S:return t instanceof S?t.toArray():void a();case x:return t instanceof x?t.toArray():void a();case n:return t instanceof n?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new n(t).getHexString():void a();case String:return t;case o:return t instanceof o?t.toArray():void a();case se:return t instanceof se?t.asset?.id??null:void a()}}function Dt(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=>Ct(e.materialId)),(t??[]).filter(e=>Ct(e.materialId)),e=>e.color+e.name)}function Ct(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[Ge.RgbNode,"#000000"],[Ge.Color,"#000000"],[Ge.Vector4,[0,0,0,0]],[Ge.Vec4Node,[0,0,0,0]],[Ge.Vector3,[0,0,0]],[Ge.Vec3Node,[0,0,0]],[Ge.Vector2,[0,0]],[Ge.Vec2Node,[0,0]],[Ge.Euler,[0,0,0,"XYZ"]],[Ge.Array,[]],[Ge.ColorLayer,tt],[Ge.MaskLayer,at]]);let Et=new n,Tt=new n;function Vt(e,t){return Et.set(e),Tt.set(t),Et.getHexString()==Tt.getHexString()}export function applyMaterial(e,t,a,s){const i=[];return e.traverse(async e=>{if(e instanceof m||e.isMesh||e instanceof r.SkinnedMesh||e.isSkinnedMesh)for(const t of Ie(e.material))t.hasOwnProperty("color")&&i.push(e)}),Promise.all(i.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 n))continue;const o="#"+i.color.getHexString(),l=i.name;if(o===t.color&&(i.name===t.name||null==t.name)||e.userData["originalColor_"+r]===t.color&&e.userData["originalMaterialName_"+r]===t.name){const i=await a(t.materialId),n=e.material[r];null!=i&&n.id!=i.id&&(e.material[r]=i,e.userData["originalColor_"+r]=e.userData["originalColor_"+r]??o,e.userData["originalMaterialName_"+r]=e.userData["originalMaterialName_"+r]??l,null!=s&&s.set(e.id+"#"+r,n))}}else if("color"in e.material){const r="#"+e.material.color.getHexString(),i=e.material.name;if(r===t.color&&(e.material.name===t.name||null==t.name)||e.userData.originalColor===t.color&&e.userData.originalName===t.name){const n=await a(t.materialId),o=e.material;null!=n&&(e.material=n,e.userData.originalColor=e.userData.originalColor??r,e.userData.originalMaterialName=e.userData.originalMaterialName??i,null!=s&&(s.has(e.id)||s.set(e.id,o)))}}}))}function Ot(e,t){if(e instanceof r.ShaderMaterial&&t instanceof r.ShaderMaterial){return e.fragmentShader+e.vertexShader==t.fragmentShader+t.vertexShader&&function(e,t){if(e instanceof r.ShaderMaterial&&t instanceof r.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 kt(e){if(null!=e){for(let t=0;t<e.array.length;t++)e.setX(t,0);e.needsUpdate=!0}}const zt=new WeakMap;function Ft(e){let t=zt.get(e);return null==t&&(t=function(e){const t=De(e);if(null==t)return"";return Object.keys(t.geometry.attributes).sort().join(",")}(e),zt.set(e,t)),t}const Bt=new WeakMap;function Nt(e){let t=Bt.get(e);return null==t&&(t=function(e){let t=e.type;e instanceof r.MeshStandardMaterial||(t+=e.id+"");(e instanceof r.MeshBasicMaterial||e instanceof r.MeshLambertMaterial||e instanceof g||e instanceof f)&&(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 g&&(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 u||e instanceof f)&&null!=e.specularMap&&(t+="s"+e.specularMap?.id);e instanceof r.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 ht&&null!=e.heightMap&&(t+="h"+e.heightMap?.id);if(e instanceof r.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.depthWrite?"dw":"",t+=e.depthTest?"dt":"",t+=e.alphaTest?"at":"",t}(e),Bt.set(e,t)),t}function _t(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 Ut=new d,$t=new o;function Wt(e,t){return $t.copy(e),$t.x*=-1,$t.y*=-1,$t.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&($t.y*=-1,$t.z*=-1),(new r.Matrix3).setFromMatrix4(Ut.makeRotationFromEuler($t))}function Lt(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 Rt=new x;function Gt(e,t){return e===t||null==e==(null==t)&&("number"==typeof e&&"number"==typeof t?e===t||isNaN(e)&&isNaN(t):e instanceof r.Color&&t instanceof r.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 S&&t instanceof S?e.x===t.x&&e.y===t.y&&e.z===t.z:e instanceof x&&t instanceof x&&(e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w))}function Ht(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof ae?t.push(s):s instanceof oe&&t.push(...Ht(s));return t}function Jt(e,t){if(!(t instanceof r.ShaderMaterial)&&(e.deleteAttribute("uv1"),e.deleteAttribute("tangent"),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")}}/*
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{ConvexPolyhedronCollisionShape as a}from"@hology/core";import{Subject as s}from"rxjs";import*as r from"three";import{BoxGeometry as i,Color as n,Euler as o,Fog as l,FogExp2 as c,Group as h,Material as p,Matrix4 as u,Mesh as d,MeshLambertMaterial as m,MeshPhongMaterial as f,MeshStandardMaterial as g,Object3D as y,PointLight as w,Quaternion as M,Scene as b,Texture as v,Vector2 as A,Vector3 as S,Vector4 as x}from"three";import{attributes as I,batchingUniformFloat as j,batchingUniformVec2 as D,batchingUniformVec3 as P,batchingUniformVec4 as C,bool as E,BooleanExpression as T,BooleanNode as k,colorToNormal as V,float as O,FloatNode as z,ifDefApply as F,mix as B,NodeShaderMaterial as N,rgb as _,rgba as U,RgbNode as $,select as W,standardMaterial as L,Texture2dLookupNode as R,textureSampler2d as G,textureSampler2dArray as H,varying as J,varyingAttributes as X,varyingTransformed as q,vec2 as Y,Vec2Node as Z,vec3 as K,Vec3Node as Q,vec4 as ee,Vec4Node as te}from"three-shader-graph";import{Service as ae}from"typedi";import{VfxActor as se}from"../effects/vfx/vfx-actor.js";import{VisualEffect as re}from"../effects/vfx/vfx-param.js";import{Prefab as ie,PrefabOf as ne}from"./objects/prefab.js";import{BaseActor as oe}from"../gameplay/actors/actor.js";import le from"../gameplay/actors/builtin/index.js";import{ActorComponent as ce,PhysicsBodyType as he,ThreeBlendingMode as pe,withInjectionContext as ue}from"../gameplay/index.js";import{RenderingView as de}from"../rendering.js";import{curveSampler as me,oneMinus as fe,particleUniforms as ge,Sampler2DNode as ye}from"../shader-nodes/index.js";import{LambertShader as we}from"../shader/builtin/lambert-shader.js";import{LandscapeCompositeShader as Me}from"../shader/builtin/landscape-composite-shader";import{LandscapeShader as be}from"../shader/builtin/landscape-shader.js";import{StandardShader as ve}from"../shader/builtin/standard-shader.js";import{UnlitShader as Ae}from"../shader/builtin/unlit-shader.js";import{extractShaderParameters as Se}from"../shader/parameter.js";import{ArrayMap as xe,DefaultMap as Ie,groupBy as je}from"../utils/collections.js";import{iterateMaterials as De}from"../utils/materials.js";import{filterChildrenShallow as Pe,filterSceneShallow as Ce,findFirstVisibleMesh as Ee,findFirstVisibleObject as Te,traverseAsync as ke}from"../utils/three/traverse.js";import{AssetMeshInstance as Ve,AssetResourceLoader as Oe}from"./asset-resource-loader.js";import{AssetsProvider as ze}from"./assets-provider.js";import{isCollisionMesh as Fe}from"./collision/collision-shape-import.js";import{BoxCollisionShape as Be,PhysicalShapeMesh as Ne}from"./collision/collision-shape.js";import{LandscapeManager as _e}from"./landscape/landscape-manager.js";import{initLandscape as Ue}from"./landscape/landscape.js";import{SectionGrid as $e,smoothNormalsCrossMeshes as We}from"./landscape/utils.js";import{createGrassFoliageMaterial as Le}from"./materials/grass-foliage.js";import{createGrassMaterial as Re}from"./materials/grass.js";import{getMaterialAttribute as Ge}from"./materials/utils/material-painting.js";import{createWaterMaterial as He}from"./materials/water.js";import{SerializedParamType as Je}from"./model.js";import{ShapeLibrary as Xe,ShapeLibraryKeys as qe}from"./objects/shapes.js";import{ambientLightName as Ye,createSky as Ze,defaultSkyMaterial as Ke}from"./sky.js";import{Curve2 as Qe}from"../utils/curve.js";import{DecalUnlitShader as et}from"../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as tt}from"../shader/builtin/decal-standard-shader.js";import{ColorLayer as at,defaultValueColorLayer as st,defaultValueMaskLayer as rt,MaskLayer as it}from"../shader/color-layer.js";import{LayeredShader as nt}from"../shader/builtin/layered-shader";import{isColorLayerSerialized as ot}from"../shader/color-layer";import{FogVolume as lt}from"../rendering/fog/fog-volume-actor.js";import{UnscaledSprite as ct}from"../utils/three/unscaled-sprite.js";import{ToonShader as ht}from"../shader/builtin/toon-shader.js";import{BatchedMesh2 as pt}from"./batched-mesh-2.js";import{ParallaxStandardMaterial as ut}from"../shader/builtin/standard-shader";import{parallaxOcclusionMapping as dt}from"../shader-nodes/pom.js";import{traverseVisibleEvery as mt}from"../utils/three/traverse";import{RectAreaLightHelper as ft}from"three/examples/jsm/Addons.js";const gt={},yt=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),wt=/^((?!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 Mt(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}let Mt=class{constructor(e,t,a,i,n,o,l,c,h=[]){this.scene=e,this.dataProvider=t,this.assetsService=a,this.assetManagerService=i,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 s,this.removed$=new s,this.error$=new s,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.originalFog=null,t.onCreate(e=>this.update(e)),t.onUpdate(e=>this.update(e)),t.onRemove(e=>this.remove(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 r.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(e=>{this.remove(e.userData.src),this.materializeAndInitActor(e.userData.src)});for(const e of this.assets.values())if("prefab"==e.type){if(!e.prefab.objects.some(e=>Zt(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 S,!0)})}else"prefab"===t.type?this.findByAssetId(t.id).forEach(e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}):"vfx"===t.type?this.dataProvider.getObjects().forEach(e=>{Ct(e,(e,a)=>{"vfx"===e.type&&e.assetId===t.id&&(this.remove(e),this.materializeAndInitActor(e))})}):"texture"===t.type&&this.scene.traverse(e=>{if(e instanceof d)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)})})}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 i=await this.assetManagerService.getTexture(a);if(null!=i)if(t instanceof r.ShaderMaterial)for(const[e,s]of Object.entries(t.uniforms))s.value instanceof r.Texture&&s.value.userData.assetId===a.id&&(t.uniforms[e].value=i);else for(const[e,s]of Object.entries(t))s instanceof r.Texture&&s.userData.assetId===a.id&&(t[e]=i);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)for(const s of Object.values(e.material.shaderParams)){if(s.type===Je.Material&&s.value===a.id){t=!0;break}if(s.type===Je.Array&&"element"in s&&s.element===Je.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?Ft(e.material[s],i)||(e.material[s]=i):Ft(e.material,i)||(e.material=i,e===this.sky&&this.applySkySettings(e.material))}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===Je.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(),vt.clear(),At.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map(e=>this.materialize(e))),await this.initActorsPostInit()}async initVfx(){console.time("Init VFX");const e=new Set,t=[],a=new b;for(const s of this.actorInstances){const r=qt(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,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});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);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);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!==he.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=>{!Fe(e)&&e.isMesh&&s.push(e)});const r=1==s.length&&0==s[0].children.length,i=!wt,n=s.every(e=>!Array.isArray(e.material)||1===e.material.length),o=s.some(e=>e instanceof d&&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(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(),vt.clear(),At.clear();const e=[],t=new xe,a=new xe,s=new xe;let i=0,l=0,c=0;const h=new Map,p=new Ie(()=>new Map);for(const r of this.dataProvider.getObjects())await Ct(r,async(r,o,u)=>{if(!this.shouldBeMaterialized(r))return;const m="asset_mesh"==r.type&&this.canObjectBeInstanced(r)&&await this.canAssetBeInstanced(r),f="shape_mesh"===r.type&&"landscape"!==r.shape&&r.physics?.type!==he.dynamic;if(m||f){if(o&&o.children?.length>0){const e=o.children.findIndex(e=>e.id===r.id);e>=0&&o.children.splice(e,1)}if(f){let e=r.shape+JSON.stringify(r.shapeParams??{})+r.castShadow+r.receiveShadow;const t=r.materialAssignments?.at(0)?.materialId,a=null!=t?this.assets.get(t):null;let i=null;if(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===Je.Color&&null!=e.value&&(i=new n(e.value))}}}else e+=t;s.push(e,{object:{...r,parentTransform:u},color:i}),c++}else{const e=this.assets.get(r.assetId);let s=h.get(r.assetId);if(null==s){const e=await this.createFromAsset(r,{assignMaterials:!1});if(null==e)return;if(s=h.get(r.assetId),null==s){s={useBatchedMesh:null!=Ee(e)&&mt(e,e=>!(e instanceof d)||this.testCanBatch(e.material,e.geometry)),assetMesh:e},h.set(r.assetId,s)}}const n=Tt(r.materialAssignments,e.materialAssignments);if(s.useBatchedMesh)await ke(s.assetMesh,async e=>{if(!(e instanceof d))return;const t=Array.isArray(e.material)?e.material[0]:e.material,s=n.find(e=>null!=t.color&&zt(e.color,t.color)&&(null==e.name||t.name===e.name))?.materialId;let o=t;if(null!=s){const e=this.assets.get(s);o=await materialFromAsset(e,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!0)}if(null!=o){p.get(r.id).set(e.uuid,o),Yt(e.geometry,o);let t=$t(o);t+=_t(e),a.push(t,{...r,parentTransform:u,meshUUID:e.uuid}),i++}else console.warn("Can not materialize mesh because missing material",r)});else{const e=r.assetId+JSON.stringify(r.materialAssignments??[]);t.push(e,{...r,parentTransform:u}),l++}}}else null==o&&e.push({...r,parentTransform:u})});console.log(`Scene init stats: \n Batched Assets: ${a.size} groups containing in total ${i} objects.\n Instanced Assets: ${t.size} groups containing in total ${l} 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;const a=h.get(t[0].assetId).assetMesh;e=this.createBatchedMesh(t,p,h);const s=this.assets.get(t[0].assetId);e.castShadow=t[0].castShadow??s.castShadow??!0,e.receiveShadow=t[0].receiveShadow??s.receiveShadow??!0;const r=new Ve;r.add(e),r.userData.src=t[0],a instanceof Ve&&(r.collisionShapes=a.collisionShapes),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r)}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 Ve;r.add(t),r.userData.src=e[0],a instanceof Ve&&(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=Te(a,e=>!Fe(e)&&null!=e.geometry),i=s.material.clone();null!=e[0].color&&null!=i.color&&(i.color=new n(16777215));const l=s.geometry;let c,h;!(wt||i instanceof N||null==l.index)?(c=new r.BatchedMesh(e.length,l.getAttribute("position").count,l.index.count,i),c.perObjectFrustumCulled=!0,h=c.addGeometry(l)):c=new r.InstancedMesh(l,i,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 r.Matrix4).compose((new S).fromArray(a.object.position),(new M).setFromEuler((new o).fromArray(a.object.rotation)),(new S).fromArray(a.object.scale)),i=(new u).copy(a.object.parentTransform).multiply(s);let n;n=c instanceof r.BatchedMesh?c.addInstance(h):t,c.setMatrixAt(n,i),null!=a.color&&c.setColorAt(n,a.color)}for(let t=0;t<e.length;t++){const s=e[t],r=new Ve;r.userData.src=e[0],a instanceof Ne&&(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()}prepareCollisionShapesForInstanced(e){e instanceof Ve&&e.collisionShapes.forEach(e=>{e instanceof a&&e.mesh instanceof d&&(e.mesh=e.mesh.geometry)})}testCanBatch(e,t){return!wt&&t.groups.length<2&&(!Array.isArray(e)||1==e.length)&&this.testCanBatchMaterial(e)}testCanBatchMaterial(e){const t=Array.isArray(e)?e[0]:e;return null!=t&&(!(t instanceof g)||null==t.bumpMap&&null==t.lightMap&&null==t.displacementMap)}createBatchedMesh(e,t,a){const s=new xe;for(const t of e)null!=t.meshUUID?s.push(t.meshUUID??t.assetId,t):console.warn("Missing mesh uuid for batching");let i=0,o=0,l=0;const c=new Map;for(const[e,t]of s.entries()){const s=t[0].assetId,r=a.get(s);if(null==r){console.warn("Missing batching info for asset id "+s);continue}const n=Te(r.assetMesh,t=>t instanceof d&&t.uuid===e);if(null==n){console.warn("Missing mesh in batched asset");continue}c.set(e,n);const h=n.geometry.getAttribute("position");null==h&&console.warn("Missing position attribute for batched mesh"),i+=n.geometry.index.count*t.length,o+=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 p=new Map;const u=[];let m=new r.MeshStandardMaterial({color:"white"});const f=t.get(e[0].id).get(e[0].meshUUID);if(null==f)throw"missing source material";if(f instanceof g){const a=new Set,s=new Map;for(const i of e){const e=t.get(i.id).get(i.meshUUID);if(null==e)throw"missing mat";for(const t of h){let i=e[t];i instanceof r.CompressedArrayTexture&&null!=i.userData.index&&(i=i.userData.index);const n=s.get(t);void 0===n||Xt(i,n)?s.set(t,i):a.add(t)}}for(const e of a){let t;const a=f[e];if("number"==typeof a){let a=u.find(e=>e.params.length<4);if(null==a){const t="vp"+u.length;a={name:t,params:[e],node:C(t)},u.push(a)}else a.params.push(e);t=Ht(a.node,a.params.length-1)}else if(a instanceof x)t=C(e);else if(a instanceof S||a instanceof n)t=P(e);else if(a instanceof A)t=D(e);else if(a instanceof r.CompressedArrayTexture)t=j(e+"_i");else if(a instanceof v)continue;p.set(e,t)}let i=X.uv;f instanceof ut&&null!=f.heightMap&&(i=dt(i,G(f.heightMap),O(f.heightScale)));let o=Wt(p.get("opacity"),z)??O(f.opacity??1);if(null!=f.alphaMap){let e;if(f.alphaMap instanceof r.CompressedArrayTexture){const t=H(f.alphaMap),a=Wt(p.get("alphaMap"),z)??O(f.alphaMap.userData.index??0);e=t.sample(K(i.x,i.y,a))}else e=G(f.alphaMap).sample(i);o=o.multiply(e.r)}let l=U(Wt(p.get("color"),Q)??f.color,o);if(null!=f.map){let e;if(f.map instanceof r.CompressedArrayTexture){const t=H(f.map),a=Wt(p.get("map"),z)??O(f.map.userData.index??0);e=t.sample(K(i.x,i.y,a))}else e=G(f.map).sample(i);l=l.multiply(e)}f.vertexColors&&(l=l.multiply(ee(J(I.color.rgb),1)));let c=U(Wt(p.get("emissive"),Q)??f.emissive,o);if(null!=f.emissiveMap){let e;if(f.emissiveMap instanceof r.CompressedArrayTexture){const t=H(f.emissiveMap),a=Wt(p.get("emissiveMap"),z)??O(f.emissiveMap.userData.index??0);e=t.sample(K(i.x,i.y,a))}else e=G(f.emissiveMap).sample(i);c=c.multiply(e)}const d=Wt(p.get("emissiveIntensity"),z)??O(f.emissiveIntensity??1),g=Wt(p.get("normalScale"),Z)??Y(f.normalScale??new A(1,1));let y=q.normal;if(null!=f.normalMap){let e;if(f.normalMap instanceof r.CompressedArrayTexture){const t=H(f.normalMap),a=Wt(p.get("normalMap"),z)??O(f.normalMap.userData.index??0);e=t.sample(K(i.x,i.y,a))}else e=G(f.normalMap).sample(i);y=V(e.rgb,g.x)}let w=Wt(p.get("roughness"),z)??O(f.roughness??1);if(null!=f.roughnessMap){let e;if(f.roughnessMap instanceof r.CompressedArrayTexture){const t=H(f.roughnessMap),a=Wt(p.get("roughnessMap"),z)??O(f.roughnessMap.userData.index??0);e=t.sample(K(i.x,i.y,a))}else e=G(f.roughnessMap).sample(i);w=w.multiply(e.g)}let M=Wt(p.get("metalness"),z)??O(f.metalness??0);if(null!=f.metalnessMap){let e;if(f.metalnessMap instanceof r.CompressedArrayTexture){const t=H(f.metalnessMap),a=Wt(p.get("metalnessMap"),z)??O(f.metalnessMap.userData.index??0);e=t.sample(K(i.x,i.y,a))}else e=G(f.metalnessMap).sample(i);M=M.multiply(e.b)}let b=O(1);if(null!=f.aoMap){let e;if(f.aoMap instanceof r.CompressedArrayTexture){const t=H(f.aoMap),a=Wt(p.get("aoMap"),z)??O(f.aoMap.userData.index??0);e=t.sample(K(i.x,i.y,a))}else e=G(f.aoMap).sample(i);b=b.multiply(e.r)}const E=Wt(p.get("aoMapIntensity"),z)??O(f.aoMapIntensity??0);let k=y;!0!==f.userData.disableAO&&(k=F("DOUBLE_SIDED",k,e=>W(new T("gl_FrontFacing"),e,e.multiplyScalar(-1))));const B=new N({color:L({color:l,roughness:w,metalness:M,ambientOcclusion:b,ambientOcclusionIntensity:E,emissive:c,emissiveIntensity:d,normal:k}),normal:y,roughness:w,emissive:c.rgb,transparent:f.transparent,alphaTest:f.alphaTest,envMap:f.envMap});null!=f.envMap&&(B.uniforms.envMapIntensity={value:f.envMapIntensity},B.uniforms.envMapRotation={value:Gt(f.envMapRotation,f.envMap)}),B.envMap=f.envMap,B.side=f.side,m=B}else{m=f;for(const a of e){const e=t.get(a.id).get(a.meshUUID);if(e!=m){console.error(`Different materials in group for object ${a.id} and mesh uuid ${a.meshUUID}`,{objectMaterial:e,sourceMaterial:f});break}}}const y=new pt(l,o,i,m);for(const e of u)y.initUniform(e.name,4);for(const[e,t]of p.entries()){if(u.some(t=>t.params.includes(e)))continue;let a=1;t instanceof te||t instanceof Q?a=4:t instanceof Z&&(a=2),y.initUniform(e,a,0)}for(const[e,i]of s.entries()){const s=i[0].assetId,o=c.get(e);if(null==o){console.error(`Missing single asset mesh for mesh uuid ${e} and asset id ${s}`);continue}if(null==o.geometry){console.error("Missing geometry on mesh mesh");continue}const l=y.addGeometry(o.geometry),h=a.get(s);if(null==h){console.warn("Missing batching info when configuring for asset id "+s);continue}const d=Ee(h.assetMesh)?.uuid===e,m=h.assetMesh instanceof Ve&&d?h.assetMesh.collisionShapes:void 0,f=this.configureBatchedInstancedMesh(i,y,o,l,m);for(let e=0;e<f.length;e++){const a=i[e],s=f[e],o=t.get(a.id).get(a.meshUUID);for(const t of u){let a=Jt.set(0,0,0,0);for(let e=0;e<t.params.length;e++){const s=o[t.params[e]];"number"==typeof s&&a.setComponent(e,s)}y.setUniformAt(t.name,e,a)}for(let e of p.keys()){if(u.some(t=>t.params.includes(e)))continue;let t=o[e];if(t instanceof n&&(t=new S(t.r,t.g,t.b)),t instanceof r.CompressedArrayTexture)t=t.userData.index??0,e+="_i";else if(t instanceof v||null==t)continue;y.setUniformAt(e,s,t)}}}return y}async createInstancedMesh(e,t){const a=Te(t,e=>!Fe(e)&&null!=e.geometry),s=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(t,Tt(e[0].materialAssignments,s.materialAssignments)),a.updateMatrix();const i=a.geometry.clone(),n=a.material;let o;if(o=new r.InstancedMesh(i,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,i){const n=[];a.updateMatrixWorld();for(let l=0;l<e.length;l++){let c=l;t instanceof r.BatchedMesh&&(c=t.addInstance(s)),n.push(c);const h=(new r.Matrix4).compose((new S).fromArray(e[l].position),(new M).setFromEuler((new o).fromArray(e[l].rotation)),(new S).fromArray(e[l].scale)),p=(new u).copy(e[l].parentTransform).multiply(h).multiply(a.matrixWorld);t.setMatrixAt(c,p),null==t.userData.hasCollision&&(t.userData.hasCollision=[]),t.userData.hasCollision[c]=!!e[l].collisionDetection,null!=i&&(null==t.userData.collisionShapes&&(t.userData.collisionShapes=[]),t.userData.collisionShapes[c]=i)}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 Ce(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)}unapplyMaterials(e){e.traverse(async e=>{if(e instanceof d)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(le));Ce(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,Ce(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 vt.entries())t.userData.customShaderName&&vt.delete(e);this.landscapeManagers.forEach(t=>t.updateShaders(e)),Ce(this.scene,e=>!0).forEach(e=>{e.traverse(async e=>{if(e instanceof d)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 d&&(e.material.wireframe=!0)}):t.traverse(e=>{e instanceof d&&(e.material.wireframe=!1)})}if("asset_mesh"===e.type){const a=this.assets.get(e.assetId);Tt(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 n(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 n(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 n(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 ft&&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 c?"density":"linear")!==e.fog.type;this.scene.fog=Pt(e.fog),t&&(a=this.scene).traverse(e=>{if(e instanceof d){const t=e.material;t instanceof N&&(a.fog instanceof l?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof c&&(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 lt){const a=await prepareClassParameters(e.actor.params,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,[],this.actorProvider,e=>this.prefabInstanceExposedActorMap.get(e)??null);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 Ne&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}("asset_mesh"===e.type||"shape_mesh"===e.type&&"landscape"!==e.shape)&&bt(t,e.castShadow,e.receiveShadow),e.name&&e.name.length>0&&(t.name=e.name),this.updated$.next({object:t,source:e})}else{const t=await this.materializeAndInitActor(e);this.updated$.next({object:t,source:e})}var a;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:Pe(t,t=>t.children?.some(t=>t.id===e.id),()=>!0))[0];return null==t?this.scene:null!=t?Ce(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 n(this.scene.fog.color))}findMeshWithGeometry(e){let t;return e.traverse(e=>{e instanceof d&&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=je(e.vertexMaterials,e=>e.m);t.traverse(e=>{if(e instanceof d){if(null==e.geometry)return;if(Bt(Ge(e,0,!1)),a>0){Bt(Ge(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=Ge(s,0,!0);Bt(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=Ge(s,4,!0);Bt(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=Pt(e.fog),this.fixFogColor(),i=new h;break;case"sky":this.sky=Ze(),this.updateSky(e),i=this.sky;break;case"world_env":this.updateWorldEnv(e),i=new h,this.worldEnvObj=i;break;case"actor":({object:i,actor:n}=await this.createFromActor(e,s));break;case"group":i=new h;break;case"prefab":i=await this.createFromPrefab(e,s,t);break;case"vfx":i=await this.createFromVfx(e,s);break;default:if(this.inEditor)throw new Error("unknown type "+e.type);console.warn(`Failed to materialize object. Unknown type '${e.type}'. This might be because the hology/core library is not compatible with the editor version.`)}if(null!=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!==he.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==he.dynamic||Dt(i),null!=this.renderingView)return this.renderingView.renderer.shadowMap.needsUpdate=!0,i;console.warn("RenderingView not found in materializer")}}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.renderer.toneMapping=t.mapping??0,this.renderingView.renderer.toneMappingExposure=t.exposure??1);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 r.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.renderer.toneMapping=0,this.renderingView.renderer.toneMappingExposure=1}async updateSky(e){null!=this.sky&&(null==e?.sky?.materialId&&this.sky.material!==Ke?(this.sky.material=Ke,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),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=r.BackSide,(e instanceof g||e instanceof r.MeshBasicMaterial||e instanceof r.ShaderMaterial)&&(e.fog=!1),e.depthTest=!1}async createComponent(e,t,a,s){const r=new gt[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??le[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 S).fromArray(e.position),(new o).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(se,(new S).fromArray(e.position),(new o).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 d&&this._originalMaterials.set(e.id,e.material)});else{let s=new g({name:"Default",color:new n("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});const r=await this.createMeshByShape(e.shape,s,e.shapeParams);r.castShadow=e.castShadow??!0,r.receiveShadow=e.castShadow??!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 h;const a=Ue(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new _e(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 $e(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(()=>We(r),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&qe.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);if(!this.geometryCache.has(r)){const t=Xe[e].geometry(s);t.computeTangents(),this.geometryCache.set(r,t)}this.collisionShapeCache.has(r)||this.collisionShapeCache.set(r,Xe[e].collision(s));return new Ne(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=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(Tt(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,bt(s,i,r),e.collisionDetection||(s.collisionShapes=[]),null!=e.physics&&!0!==this.inEditor&&(s.physics=e.physics),this.applyVertexMaterials(e,s),s.traverse(e=>{e instanceof d&&"computeBoundsTree"in e.geometry&&null==e.geometry.boundsTree&&e.geometry.computeBoundsTree()}),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 h;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 y}async createLight(e){if("point"===e.light.type){const t=new w(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 r.TextureLoader).load("assets/light-bulb-icon.webp"),a=new r.SpriteMaterial({map:e,alphaTest:.5}),s=new ct(a);s.scale.multiplyScalar(.6),t.add(s)}return t}if("spot"===e.light.type){const t=new r.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 y,t.target.position.set(0,-1,0),t.add(t.target),this.inEditor){const e=(new r.TextureLoader).load("assets/light-bulb-icon.webp"),a=new r.SpriteMaterial({map:e,alphaTest:.5}),s=new ct(a);s.scale.multiplyScalar(.6),t.add(s),t.add(new r.SpotLightHelper(t))}return t}if("rectArea"===e.light.type){const t=new r.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 r.TextureLoader).load("assets/light-bulb-icon.webp"),a=new r.SpriteMaterial({map:e,alphaTest:.5}),s=new ct(a);s.scale.multiplyScalar(.6),t.add(s);const i=new ft(t);t.add(i)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional,e),new h):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient,e),new h):void 0}applyDirectionalAmbientLight(e,t,a){const s=this.scene.children.find(e=>e.name===Ye);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()}};Mt=e([ae(),t("design:paramtypes",[b,Object,ze,Oe,de,Array,Array,Object,Array])],Mt);export{Mt as SceneMaterializer};function bt(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse(e=>{e.castShadow=t,e.receiveShadow=a})}const vt=new Map,At=new Map,St=new m({color:16711935}),xt=new Map;export async function materialFromAsset(e,t,a,s,r,i=!0){const n=JSON.stringify(e.material)+t?._id;return i&&vt.has(n)?vt.get(n):i&&At.has(n)?await At.get(n):At.set(n,_materialFromAsset(n,e,t,a,s,r,i)).get(n)}export async function _materialFromAsset(e,t,a,s,i,o,l=!0){const c={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 n(t.material.params?.color),transparent:null!=t.material.params?.opacity&&t.material.params?.opacity<1},h={};if(null!=t.material.params?.map){const e=t.material.params.map,a=await s.getAsset(e);null!=a&&(c.map=await i.getTexture(a))}let p;switch(t.material.type){case"phong":p=new f({...c,...h});break;case"water":p=He(c,a);break;case"grassFoliage":p=Le({color:c.color,map:c.map},a);break;case"grass":p=Re({...c,colorTwo:new n(t.material.params.colorTwo),colorThree:new n(t.material.params.colorThree)},a);break;case"standard":case"unlit":case"toon":case"layered":case"lambert":case"shader":case"landscape":case"landscape-composite":case"decal-unlit":case"decal-standard":const e={standard:yt?we:ve,lambert:we,unlit:Ae,toon:ht,layered:nt,landscape:be,"landscape-composite":Me,"decal-unlit":et,"decal-standard":tt}[t.material.type]??o.find(e=>e.name==t.material.shader)?.type;if(e){try{let r=new e;const n=await prepareClassParameters(t.material?.shaderParams??{},e,s,i,null,a,o);Object.assign(r,n),p=r.build()}catch(e){console.log("Shader runtime error: "+e),xt.has(t.material.shader)||xt.set(t.material.shader,St.clone()),p=xt.get(t.material.shader)}p.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),p=St;break;default:throw new Error("Unsupported material type"+t.material.type)}return a?.csm.setupMaterial(p),null!=a&&vt.set(e,p),p.side=t.material.side??p.side??r.FrontSide,p.transparent=(t.material.transparent??c.transparent??!1)||p.transparent,p.alphaTest=t.material.alphaTest??p.alphaTest??0,null!=t.material.blending&&(p.blending=pe[t.material.blending]??r.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 n(t.material.outlineParams.color).toArray()),null!=t.material.outlineParams.thickness&&(p.userData.outlineParameters.thickness=t.material.outlineParams.thickness))),p.userData.assetId=t.id,At.delete(e),p}export async function prepareClassParameters(e,t,a,s,r,i,n,o,l){const c={};for(const[t,h]of Object.entries(e)){if(!1===h.override)continue;const e=await jt(t,h,a,s,r,i,n,o,void 0,void 0,l);null!=e&&(c[t]=e)}return c}export async function prepareShapeParameters(e,t,a){const s={};for(const[r,i]of Object.entries(e)){const e=await jt(r,i,t,a,null,void 0,void 0,void 0,void 0,void 0);null!=e&&(s[r]=e)}return s}const It=new Map;async function jt(e,t,a,s,r,i,l,c,h=t.value,p=t.type,u){if(null==t||null==h||""===h)return null;switch(p){case Je.Array:if(Array.isArray(h)&&"element"in t)return await Promise.all(h.map(n=>jt(e,t,a,s,r,i,l,c,n,t.element,u)));break;case Je.Number:case Je.FloatNode:let p;if("string"==typeof h?p=parseFloat(h):"number"==typeof h&&(p=h),t.type===Je.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=It.get(e);return null==t&&(t=me(Qe.decode(e)),It.set(e,t)),t}(e.easing),r=s.sample(fe(ge.energy));return B(O(t),O(a),r)}return O(p)}return p;case Je.Texture:let d=await s.getTexture(await a.getAsset(h));return"envmap"===e.toLowerCase()&&null!=i&&(d=i.getEnvTexture(d)),d;case Je.Sampler2DNode:return G(await s.getTexture(await a.getAsset(h)));case Je.Boolean:return h;case Je.BooleanNode:return E(h);case Je.Vector2:case Je.Vec2Node:if("object"==typeof h){const e=h instanceof Array?(new A).fromArray(h):new A(h.x,h.y);return t.type===Je.Vec2Node?Y(e):e}return null;case Je.Vector3:case Je.Vec3Node:if("object"==typeof h){const e=h instanceof Array?(new S).fromArray(h):new S(h.x,h.y,h.z);return t.type===Je.Vec3Node?K(e):e}return null;case Je.Color:case Je.RgbNode:const m=new n(h);return t.type===Je.RgbNode?_(m):m;case Je.String:return h;case Je.BaseActor:const f=h;if(null==r&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==f)return null;if("object"==typeof f&&null!=f.type&&null!=f.id){if("actor"===f.type)return r?.get(f.id)??null;if("prefab"===f.type){const e=u?u(f.id):null;if(null!=e)return r?.get(e)??null;const t=[];for(const[e,a]of r?.entries()??[])e.startsWith(f.id+"/")&&t.push(a);return 1===t.length?t[0]:null}}if("string"==typeof f){const e=r?.get(f);if(null!=e)return e;const t=u?u(f):null;if(null!=t)return r?.get(t)??null;const a=[];for(const[e,t]of r?.entries()??[])e.startsWith(f+"/")&&a.push(t);return 1===a.length?a[0]:null}return null;case Je.Euler:const g=h;return(new o).fromArray(g);case Je.Object3D:return(await s.getMesh(await a.getAsset(h))).scene;case Je.Material:return await materialFromAsset(await a.getAsset(h),i,a,s,l);case Je.AudioBuffer:return await s.getAudio(await a.getAsset(h));case Je.VisualEffect:const y=await a.getAsset(h);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in y)return new re(c,y);console.error("Using a non-vfx asset for visual effect parameter");break;case Je.Prefab:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new ie(e)}case Je.PrefabActor:{const e=await a.getAsset(h);return null==e?(console.error("Using a non-prefab asset for prefab parameter",h),null):new ne(new ie(e))}case Je.Curve:return Qe.decode(h);case Je.ColorLayer:case Je.MaskLayer:if(ot(h)){const e=await at.decode(h,async e=>await s.getTexture(await a.getAsset(e))),t=await prepareClassParameters(h.params,null,a,s);return Object.assign(e,t),e}return console.warn("Expecting color layer but got",h),null;case Je.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 Dt(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 Pt(e){return"linear"===e.type?new l(new n(e.color),e.near??100,e.far??1e3):"density"===e.type?new c(e.color,e.density):void console.warn("Invalid fog type",e)}new g({color:4229780});async function Ct(e,t,a,s){null==s&&(s=(new u).identity());const i=s.clone().multiply(Et(e,new r.Matrix4));if(null!=e.children&&e.children.length>0)for(let a=e.children.length-1;a>=0;a--)await Ct(e.children[a],t,e,i);await t(e,a,s)}function Et(e,t){return null==e.position||null==e.rotation||null==e.scale?t.identity():t.compose((new S).fromArray(e.position),(new M).setFromEuler((new o).fromArray(e.rotation)),(new S).fromArray(e.scale))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?Je.Number:t instanceof z||"function"==typeof e.prototype.isFloat?Je.FloatNode:t instanceof v||e===v||e.isTexture?Je.Texture:t instanceof ye||e===R?Je.Sampler2DNode:t instanceof Boolean||e===Boolean?Je.Boolean:t instanceof k?Je.BooleanNode:t instanceof n||e==n?Je.Color:t instanceof $||"function"==typeof e.prototype.isRgb?Je.RgbNode:t instanceof A||e==A?Je.Vector2:t instanceof Z||"function"==typeof e.prototype.isVec2?Je.Vec2Node:t instanceof S||e==S?Je.Vector3:t instanceof Q||"function"==typeof e.prototype.isVec3?Je.Vec3Node:t instanceof String||e===String?Je.String:t instanceof oe||e==oe||e.prototype instanceof oe||e.prototype==oe?Je.BaseActor:t instanceof o||e==o?Je.Euler:t instanceof y||e==y?Je.Object3D:t instanceof p||e==p?Je.Material:t instanceof AudioBuffer||e==AudioBuffer?Je.AudioBuffer:t instanceof re||e==re?Je.VisualEffect:t instanceof ie||e==ie?Je.Prefab:t instanceof ne||e==ne?Je.PrefabActor:t instanceof Qe||e==Qe?Je.Curve:t instanceof at||e==at?Je.ColorLayer:t instanceof it||e==it?Je.MaskLayer:t instanceof r.AnimationClip||e==r.AnimationClip?Je.AnimationClip: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?Je.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);const o=a[e.name]??customParameterDefaultValueByType.get(toSerializedParamType(e.type)),l=!1!==n||e.options.array?i?.value??(e.options.array?[]:o):o;return[e.name,{type:s,...r?{element:r}:{},value:l,override:n}]}))}export function prepareCustomParamsFromType(e,t,a=null){const s=Se(e);if(0===s.length)return{};let r;null!=a?ue(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)}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 S:return t instanceof S?t.toArray():void a();case x:return t instanceof x?t.toArray():void a();case n:return t instanceof n?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new n(t).getHexString():void a();case String:return t;case o:return t instanceof o?t.toArray():void a();case ie:return t instanceof ie?t.asset?.id??null:void a()}}function Tt(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([[Je.RgbNode,"#000000"],[Je.Color,"#000000"],[Je.Vector4,[0,0,0,0]],[Je.Vec4Node,[0,0,0,0]],[Je.Vector3,[0,0,0]],[Je.Vec3Node,[0,0,0]],[Je.Vector2,[0,0]],[Je.Vec2Node,[0,0]],[Je.Euler,[0,0,0,"XYZ"]],[Je.Array,[]],[Je.ColorLayer,st],[Je.MaskLayer,rt]]);let Vt=new n,Ot=new n;function zt(e,t){return Vt.set(e),Ot.set(t),Vt.getHexString()==Ot.getHexString()}export function applyMaterial(e,t,a,s){const i=[];return e.traverse(async e=>{if(e instanceof d||e.isMesh||e instanceof r.SkinnedMesh||e.isSkinnedMesh)for(const t of De(e.material))t.hasOwnProperty("color")&&i.push(e)}),Promise.all(i.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 n))continue;const o="#"+i.color.getHexString(),l=i.name;if(o===t.color&&(i.name===t.name||null==t.name)||e.userData["originalColor_"+r]===t.color&&e.userData["originalMaterialName_"+r]===t.name){const i=await a(t.materialId),n=e.material[r];null!=i&&n.id!=i.id&&(e.material[r]=i,e.userData["originalColor_"+r]=e.userData["originalColor_"+r]??o,e.userData["originalMaterialName_"+r]=e.userData["originalMaterialName_"+r]??l,null!=s&&s.set(e.id+"#"+r,n))}}else if("color"in e.material){const r="#"+e.material.color.getHexString(),i=e.material.name;if(r===t.color&&(e.material.name===t.name||null==t.name)||e.userData.originalColor===t.color&&e.userData.originalName===t.name){const n=await a(t.materialId),o=e.material;null!=n&&(e.material=n,e.userData.originalColor=e.userData.originalColor??r,e.userData.originalMaterialName=e.userData.originalMaterialName??i,null!=s&&(s.has(e.id)||s.set(e.id,o)))}}}))}function Ft(e,t){if(e instanceof r.ShaderMaterial&&t instanceof r.ShaderMaterial){return e.fragmentShader+e.vertexShader==t.fragmentShader+t.vertexShader&&function(e,t){if(e instanceof r.ShaderMaterial&&t instanceof r.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 Bt(e){if(null!=e){for(let t=0;t<e.array.length;t++)e.setX(t,0);e.needsUpdate=!0}}const Nt=new WeakMap;function _t(e){let t=Nt.get(e);return null==t&&(t=function(e){const t=Ee(e);if(null==t)return"";return Object.keys(t.geometry.attributes).sort().join(",")}(e),Nt.set(e,t)),t}const Ut=new WeakMap;function $t(e){let t=Ut.get(e);return null==t&&(t=function(e){let t=e.type;e instanceof r.MeshStandardMaterial||(t+=e.id+"");(e instanceof r.MeshBasicMaterial||e instanceof r.MeshLambertMaterial||e instanceof g||e instanceof f)&&(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 g&&(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 m||e instanceof f)&&null!=e.specularMap&&(t+="s"+e.specularMap?.id);e instanceof r.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 ut&&null!=e.heightMap&&(t+="h"+e.heightMap?.id);if(e instanceof r.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),Ut.set(e,t)),t}function Wt(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 Lt=new u,Rt=new o;function Gt(e,t){return Rt.copy(e),Rt.x*=-1,Rt.y*=-1,Rt.z*=-1,t.isCubeTexture&&!1===t.isRenderTargetTexture&&(Rt.y*=-1,Rt.z*=-1),(new r.Matrix3).setFromMatrix4(Lt.makeRotationFromEuler(Rt))}function Ht(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 Jt=new x;function Xt(e,t){return e===t||null==e==(null==t)&&("number"==typeof e&&"number"==typeof t?e===t||isNaN(e)&&isNaN(t):e instanceof r.Color&&t instanceof r.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 S&&t instanceof S?e.x===t.x&&e.y===t.y&&e.z===t.z:e instanceof x&&t instanceof x&&(e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w))}function qt(e){const t=[];for(const[a,s]of Object.entries(e))s instanceof re?t.push(s):s instanceof ce&&t.push(...qt(s));return t}function Yt(e,t){if(!(t instanceof r.ShaderMaterial)){if(e.deleteAttribute("uv1"),function(e){if(e instanceof ut)return!0;if(e instanceof r.ShaderMaterial)return e.vertexShader.includes("tangent");return!1}(t)||e.deleteAttribute("tangent"),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 Zt(e,t,a){if(t(e))return e;for(const s of e.children??[]){const e=Zt(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=>Zt(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
|
*/
|
package/dist/scene/model.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { AttachedComponent, SceneObject } from './materializer.js';
|
|
|
4
4
|
import { LibraryShapeType } from './objects/shapes.js';
|
|
5
5
|
export type AssetType = 'mesh' | 'material' | 'shape' | 'particles' | 'light' | 'texture' | 'actor' | 'audio' | 'prefab' | 'vfx' | 'animationclip';
|
|
6
6
|
export type ShapeType = LibraryShapeType | 'landscape';
|
|
7
|
-
export type LightType = 'point' | 'spot' | 'directional' | 'ambient';
|
|
7
|
+
export type LightType = 'point' | 'spot' | 'directional' | 'ambient' | 'rectArea';
|
|
8
8
|
/**
|
|
9
9
|
* The detail is used to determine what objects to place in a scene.
|
|
10
10
|
* When loading a scene, you can decide what to include.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{randomUUID as e}from"../../utils/uuid.js";import{pathJoin as t}from"../../utils/files.js";import{combineLatest as a,EMPTY as i,filter as r,firstValueFrom as s,from as n,map as h,mergeAll as o,mergeMap as l,Observable as c,of as u,startWith as p,Subject as d,switchMap as w,tap as f}from"rxjs";import{sleepDelay as m}from"../../utils/async.js";const y={},v={},j={},b={};null==y.read&&window.require&&(Object.assign(y,window.require("fs")),Object.assign(v,y.promises),Object.assign(j,window.require("path")),Object.assign(b,window.require("chokidar")));const g=null!=y.existsSync;function F(){if(g){const e="--path=",t=window.process.argv.find(t=>t.startsWith(e));return t?t.substring(e.length):""}return""}const
|
|
1
|
+
import{randomUUID as e}from"../../utils/uuid.js";import{pathJoin as t}from"../../utils/files.js";import{combineLatest as a,EMPTY as i,filter as r,firstValueFrom as s,from as n,map as h,mergeAll as o,mergeMap as l,Observable as c,of as u,startWith as p,Subject as d,switchMap as w,tap as f}from"rxjs";import{sleepDelay as m}from"../../utils/async.js";const y={},v={},j={},b={};null==y.read&&window.require&&(Object.assign(y,window.require("fs")),Object.assign(v,y.promises),Object.assign(j,window.require("path")),Object.assign(b,window.require("chokidar")));const g=null!=y.existsSync;function F(){if(g){const e="--path=",t=window.process.argv.find(t=>t.startsWith(e));return t?t.substring(e.length):""}return""}const P=/^[A-Z]:/;function x(...e){return 0===e.length?"":P.test(e[0])||g?j.join(...e):t(...e)}export class ObjectStorage{get pathResources(){return x(this.path+"-resources")}constructor(e,t){this.name=e,this.filePathFn=t,this.basePathUpdates=new d,this.basePath=this.basePathUpdates.pipe(h(e=>x(F(),e)),f(e=>{this.path=x(e,this.name),O(this.path),this.determineIfMetaFileShouldBeCreated()})),this.loaded=s(this.basePath),this.shouldCreateIndex=!0,this.watchers=[]}setBasePath(e){this.basePathUpdates.next(e)}async determineIfMetaFileShouldBeCreated(){try{(await v.readFile(x(F(),"vite.config.ts"))).toString().includes("hologyBuild")&&(this.shouldCreateIndex=!1)}catch(e){console.warn("Failed to read vite config to determine if meta files should be created")}}async createFolder(e,t=""){S(),await v.mkdir(j.join(this.path,t,e),{recursive:!0})}async deleteFolderForceDangerous(e){await v.rm(j.join(this.path,e),{recursive:!0,force:!0})}async moveFolder(e,t){if(S(),""==e)return void console.warn("Can not move a folder in root");const a=j.resolve(j.join(this.path,t),j.basename(e));if(await C(a)){if(a!==j.resolve(this.path,e))throw new Error("Can not move to directory as a file already exists with the same name")}else{if(function(e,t){const a=j.resolve(e),i=j.resolve(t),r=j.normalize(a)+j.sep;return(j.normalize(i)+j.sep).startsWith(r)}(j.join(this.path,e),j.join(this.path,t)))throw new Error("Can not move a folder into a folder it contains");await v.rename(j.join(this.path,e),a)}}async renameFolder(e,t){await v.rename(j.join(this.path,e),j.resolve(j.dirname(j.join(this.path,e)),t))}async moveToFolder(e,t){if(S(),e.path===t)return;const a=this.privateObjectPath({...e,path:t});await v.rename(this.privateObjectPath(e),a)}getAbsolutePath(e=""){return j.join(this.path,e)}getResourceAbsolutePath(e=""){return j.join(this.pathResources,e)}watchFolders(){const e=v.readdir(this.path,{recursive:!0,withFileTypes:!0});return a([n(e),this.watchDir(this.path).pipe(r(e=>!e.filename.endsWith(".json")),p(null))]).pipe(w(([e,t])=>null!=t?n(v.readdir(this.path,{recursive:!0,withFileTypes:!0})):u(e)),h(e=>Array.from(new Set(e.filter(e=>e.isDirectory()).map(e=>j.relative(this.path,j.join(e.parentPath,e.name)).replace(/^\.$/,"")).values()))))}watch(){S();n(this.loaded).pipe(w(()=>a([this.watchDir(this.pathResources),n(this.getAll())]).pipe(r(([e])=>null!=e),l(([e,t])=>{if("change"===e.event){const a=j.basename(e.filename),i=t.filter(e=>e.fileKey===a);if(i.length>0)return n(i).pipe(l(e=>{const t=this.privateObjectRelativePath(e);return n(this.readFileIfExists(t)).pipe(h(a=>({event:"change",object:a,path:e.path,filename:t})))}))}return i}))));return n(this.loaded).pipe(w(()=>this.watchDir(this.path)),l(e=>{const t={event:e.event,path:j.dirname(e.filename).replace(/^\.$/,""),filename:j.basename(e.filename)};return e.filename.endsWith(".json")?"unlink"!==e.event?n(this.readFileIfExists(e.filename)).pipe(h(e=>({object:e,...t}))):u({object:null,...t}):"change"===e.event?n(this.reloadSubdirectory(e.filename)).pipe(o(),h(e=>({object:e,...t}))):i}))}async reloadSubdirectory(e){return(await this.getAll(e)).filter(t=>t.path.startsWith(e))}async readFileIfExists(e){const t=x(this.path,e);try{const a=await v.readFile(t);return{...JSON.parse(a.toString()),path:j.dirname(e).replace(/^\.$/,""),filename:j.basename(e)}}catch{return console.error("Could not find file at "+t),null}}async getAll(e){if(g){await this.loaded,await O(this.path);const t=(await v.readdir(j.join(this.path,e??""),{recursive:!0,withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(".json")&&!/^[\._]/.test(e.name)),a=100,i=[];for(let e=0;e<t.length;e+=a){const r=t.slice(e,e+a),s=await Promise.all(r.map(e=>v.readFile(x(e.parentPath,e.name)).then(t=>({...JSON.parse(t.toString()),path:j.relative(this.path,e.parentPath).replace(/^\.$/,""),filename:j.basename(e.parentPath)}))));i.push(...s)}return i}const t=await this.loadIndex();return Promise.all(Object.keys(t).map(e=>this.get(e)))}async get(e){const t=await this.loadIndex(),a=t[e]??Object.values(t).find(t=>t.name===e);if(null==a)return;const i=this.privateObjectPath(a);if(!g)return(await fetch(i)).json();return await I(i)?JSON.parse((await v.readFile(i)).toString()):null}async save(e){return S(),await this.loaded,await v.writeFile(this.privateObjectPath(e),this.serialize(e)),await this.updateIndex(),e}async rename(e,t){const a={...e,name:t},i=this.privateObjectPath(e),r=this.privateObjectPath(a);try{await v.rename(i,r)}catch(e){console.error(e),console.warn("Rename failed, retrying",{currentPath:i,newPath:r}),await m(400),await v.rename(i,r)}return await this.save(a),await this.updateIndex(),a}async delete(e){await v.unlink(this.privateObjectPath(e)),this.updateIndex()}async create(t){S(),await this.loaded,t.id=e();const a=this.privateObjectPath(t);if(await C(a))throw Error(`Can not create because a file already exists at ${a}`);return await v.writeFile(a,this.serialize(t)),await this.updateIndex(),t}prepareCreate(t){return S(),t.id=e(),t}serialize(e){const t={...e};return delete t.path,delete t.filename,JSON.stringify(t,null,2)}async updateIndex(){S();const e=await this.getAll(),t={};for(const a of e)t[a.id]={id:a.id,name:a.name??a.id,path:a.path};if(this.cachedIndex=t,g){if(!this.shouldCreateIndex)return;await v.writeFile(this.indexFilePath,JSON.stringify(t,null,2))}}get indexFilePath(){return x(this.path,"_meta.json")}async loadIndex(){return null==this.cachedIndex&&(g?await this.updateIndex():this.cachedIndex=await(await fetch(this.indexFilePath)).json()),this.cachedIndex}async ensureResourceDir(){await O(x(this.path+"-resources"))}async saveFile(e,t){return S(),await O(x(this.path+"-resources")),v.copyFile(t.path,x(this.path+"-resources",e.fileKey))}async saveExtraFile(e,t){return S(),await O(x(this.path+"-resources")),v.copyFile(e,x(this.path+"-resources",t))}getAssetPath(e){return window&&"function"==typeof window.require?window.require("path").join(this.path+"-resources",e.fileKey):x(this.path+"-resources",e.fileKey)}async replaceFile(e,t){if(await I(t))return v.copyFile(t,x(this.path+"-resources",e.fileKey));console.error("Failed to replace file using path "+t)}async deleteFile(e){if(null==e)return;S();const t=x(this.path+"-resources",e);return await I(t)?v.unlink(t):void 0}privateObjectPath(e){return x(this.path,this.privateObjectRelativePath(e))}privateObjectRelativePath(e){return this.filePathFn?x(e.path??"",this.filePathFn(e)):x(e.path??"",tokenizeName(e.name??e.id)+".json")}watchDir(e){return new c(t=>{const a=b.watch(e,{cwd:e});return a.on("all",(e,a,i)=>{t.next({event:e,filename:a})}),a.on("unlinkDir",e=>{}),a.on("error",()=>{}),this.watchers.push(a),()=>{a.close()}})}}export function tokenizeName(e){return e.trim().replace(/\s/g,"_").replace(/[^a-z0-9_\-\.]/gi,"")}async function O(e){g&&(await I(e)||await v.mkdir(e,{recursive:!0}))}function I(e){return!!g&&new Promise(function(t,a){y.exists(e,function(e){t(e)})})}function S(){if(!g)throw new Error("Must have direct access to filesystem")}async function C(e){try{await v.access(e,v.constants.F_OK)}catch(e){return!1}return!0}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -14,10 +14,8 @@ export declare class LambertShader extends Shader {
|
|
|
14
14
|
aoMapIntensity?: number;
|
|
15
15
|
normalMap?: Texture;
|
|
16
16
|
normalScale?: Vector2;
|
|
17
|
-
specularMap?: Texture;
|
|
18
17
|
envMap?: Texture;
|
|
19
|
-
|
|
20
|
-
refractionRatio?: number;
|
|
18
|
+
vertexColor?: boolean;
|
|
21
19
|
build(): Material;
|
|
22
20
|
}
|
|
23
21
|
//# sourceMappingURL=lambert-shader.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{Color as
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{Color as o,Texture as a,Vector2 as i,MeshLambertMaterial as r}from"three";import{Shader as p}from"../shader.js";import{Parameter as s}from"../parameter.js";import{removeObjectUndefined as n}from"../../utils/collections.js";export class LambertShader extends p{constructor(){super(...arguments),this.color=new o("#FFFFFF"),this.opacity=1,this.normalScale=new i(1,1),this.vertexColor=!1}build(){return new r(n({color:this.color,opacity:this.opacity,emissive:this.emissive,emissiveIntensity:this.emissiveIntensity,emissiveMap:this.emissiveMap,map:this.map,lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:this.aoMap,aoMapIntensity:this.aoMapIntensity,normalMap:this.normalMap,normalScale:this.normalScale,alphaMap:this.alphaMap,envMap:this.envMap,vertexColors:this.vertexColor}))}}e([s(),t("design:type",o)],LambertShader.prototype,"color",void 0),e([s({label:"Color Map"}),t("design:type",a)],LambertShader.prototype,"map",void 0),e([s({range:[0,1]}),t("design:type",Number)],LambertShader.prototype,"opacity",void 0),e([s(),t("design:type",a)],LambertShader.prototype,"alphaMap",void 0),e([s(),t("design:type",o)],LambertShader.prototype,"emissive",void 0),e([s({range:[0,1]}),t("design:type",Number)],LambertShader.prototype,"emissiveIntensity",void 0),e([s(),t("design:type",a)],LambertShader.prototype,"emissiveMap",void 0),e([s(),t("design:type",a)],LambertShader.prototype,"lightMap",void 0),e([s(),t("design:type",Number)],LambertShader.prototype,"lightMapIntensity",void 0),e([s(),t("design:type",a)],LambertShader.prototype,"aoMap",void 0),e([s(),t("design:type",Number)],LambertShader.prototype,"aoMapIntensity",void 0),e([s(),t("design:type",a)],LambertShader.prototype,"normalMap",void 0),e([s(),t("design:type",i)],LambertShader.prototype,"normalScale",void 0),e([s(),t("design:type",a)],LambertShader.prototype,"envMap",void 0),e([s(),t("design:type",Boolean)],LambertShader.prototype,"vertexColor",void 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 a}from"tslib";import{Color as t,MeshStandardMaterial as n,Texture as r,Vector2 as i}from"three";import{Shader as s}from"../shader.js";import{Parameter as o}from"../parameter.js";import{removeObjectUndefined as p}from"../../utils/collections.js";const l=new r;export class StandardShader extends s{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.opacity=1,this.roughness=1,this.metalness=0,this.normalScale=new i(1,1),this.heightMap=l}build(){const e=(null!=this.map||null!=this.normalMap)&&null!=this.heightMap&&this.heightMap!=l&&0!==this.heightScale;return new(e?ParallaxStandardMaterial:n)(p({color:this.color,opacity:this.opacity,roughness:this.roughness,metalness:this.metalness,map:this.map,lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:this.aoMap,aoMapIntensity:this.aoMapIntensity,emissive:this.emissive,emissiveIntensity:this.emissiveIntensity,emissiveMap:this.emissiveMap,bumpMap:this.bumpMap,bumpScale:this.bumpScale,normalMap:this.normalMap,normalScale:this.normalScale,displacementMap:this.displacementMap,displacementScale:this.displacementScale,displacementBias:this.displacementBias,roughnessMap:this.roughnessMap,metalnessMap:this.metalnessMap,alphaMap:this.alphaMap,envMap:this.envMap,envMapIntensity:this.envMapIntensity,refractionRatio:this.refractionRatio,...e?{heightMap:this.heightMap,heightScale:this.heightScale}:{}}))}}e([o(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([o({label:"Color Map"}),a("design:type",r)],StandardShader.prototype,"map",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"alphaMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"roughnessMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"metalnessMap",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"lightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"aoMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([o(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([o({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"emissiveMap",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"bumpMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"bumpScale",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"normalMap",void 0),e([o(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"displacementMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"displacementScale",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"displacementBias",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"refractionRatio",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"heightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0);export var ParallaxType;!function(e){e[e.none=0]="none",e[e.offset=1]="offset",e[e.pom=2]="pom"}(ParallaxType||(ParallaxType={}));export class ParallaxStandardMaterial extends n{constructor(e={}){super(e),e.heightMap&&(this.heightMap=e.heightMap),this.heightScale=e.heightScale??.05,this.parallaxType=e.parallaxType??ParallaxType.pom,this.minLayers=e.minLayers??10,this.maxLayers=e.maxLayers??32}onBeforeCompile(e){e.uniforms.heightMap={value:this.heightMap},e.uniforms.heightScale={value:this.heightScale},e.uniforms.minLayers={value:this.minLayers},e.uniforms.maxLayers={value:this.maxLayers},e.uniforms.parallaxType={value:this.parallaxType},e.vertexTangents=!0,e.vertexShader=e.vertexShader.replace("#include <uv_pars_vertex>","\n #include <uv_pars_vertex>\n varying vec3 vViewDirTS;\n varying mat3 vTBN;\n "),e.vertexShader=e.vertexShader.replace("#include <begin_vertex>","\n #include <begin_vertex>\n vec3 N = normalize(normalMatrix * normal);\n vec3 T = normalize(normalMatrix * tangent.xyz);\n vec3 B = cross(N, T) * tangent.w;\n vTBN = mat3(T, B, N);\n\n vec3 viewDir = cameraPosition - (modelMatrix * vec4(transformed, 1.0)).xyz;\n vViewDirTS = normalize(vTBN * viewDir);\n "),e.fragmentShader=e.fragmentShader.replace("#include <uv_pars_fragment>","\n #include <uv_pars_fragment>\n uniform sampler2D heightMap;\n uniform float heightScale;\n uniform int minLayers;\n uniform int maxLayers;\n uniform int parallaxType;\n\n varying vec3 vViewDirTS;\n varying mat3 vTBN;\n\n vec2 parallaxOffset(vec2 uv, vec3 viewDirTS) {\n float h = texture(heightMap, uv).r;\n return uv - (viewDirTS.xy / viewDirTS.z) * (h * heightScale);\n }\n\n vec2 parallaxOcclusion2(vec2 uv, vec3 viewDirTS) {\n vec3 viewDir = normalize(vViewPosition);\n vec3 vv = -viewDir * vTBN;\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n // Probably should use actual normal but it might not matter\n vec3 nNormal = vec3(0.0, 0.0, 1.0);\n float nNumSamples = mix(float(maxLayers), float(minLayers), dot(viewDir, nNormal));\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 50; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture2D(heightMap, uv + vCurrOffset).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n }\n "),e.fragmentShader=e.fragmentShader.replace("#include <map_fragment>","\n vec2 uvPOM = vMapUv ;\n if (parallaxType == 1) {\n uvPOM = parallaxOffset(vMapUv , vViewDirTS);\n } else if (parallaxType == 2) {\n uvPOM = parallaxOcclusion2(vMapUv , vViewDirTS);\n }\n\n\n vec4 texelColor = texture2D(map, uvPOM);\n //texelColor = mapTexelToLinear(texelColor);\n diffuseColor *= texelColor;\n "),e.fragmentShader=e.fragmentShader.replace("#include <normal_fragment_maps>","\n #ifdef USE_NORMALMAP\n vec3 mapN = texture2D(normalMap, uvPOM).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n normal = normalize( tbn * mapN );\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <roughnessmap_fragment>","\n float roughnessFactor = roughness;\n #ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, uvPOM );\n // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n roughnessFactor *= texelRoughness.g;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <metalnesssmap_fragment>","\n float metalnessFactor = metalness;\n #ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, uvPOM );\n // reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n metalnessFactor *= texelMetalness.b;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <aomap_fragment>","\n #ifdef USE_AOMAP\n\n // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n float ambientOcclusion = ( texture2D( aoMap, uvPOM ).r - 1.0 ) * aoMapIntensity + 1.0;\n\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\n #endif\n\n #endif\n "),this.userData.shader=e}clone(){const e=super.clone();return e.heightMap=this.heightMap,e.heightScale=this.heightScale,e.parallaxType=this.parallaxType,e.minLayers=this.minLayers,e.maxLayers=this.maxLayers,e}}/*
|
|
1
|
+
import{__decorate as e,__metadata as a}from"tslib";import{Color as t,MeshStandardMaterial as n,Texture as r,Vector2 as i}from"three";import{Shader as p}from"../shader.js";import{Parameter as s}from"../parameter.js";import{removeObjectUndefined as d}from"../../utils/collections.js";const o=new r;export class StandardShader extends p{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.opacity=1,this.roughness=1,this.metalness=0,this.normalScale=new i(1,1),this.heightMap=o,this.vertexColor=!1}build(){const e=(null!=this.map||null!=this.normalMap)&&null!=this.heightMap&&this.heightMap!=o&&0!==this.heightScale;return new(e?ParallaxStandardMaterial:n)(d({color:this.color,vertexColors:this.vertexColor,opacity:this.opacity,roughness:this.roughness,metalness:this.metalness,map:this.map,lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:this.aoMap,aoMapIntensity:this.aoMapIntensity,emissive:this.emissive,emissiveIntensity:this.emissiveIntensity,emissiveMap:this.emissiveMap,bumpMap:this.bumpMap,bumpScale:this.bumpScale,normalMap:this.normalMap,normalScale:this.normalScale,displacementMap:this.displacementMap,displacementScale:this.displacementScale,displacementBias:this.displacementBias,roughnessMap:this.roughnessMap,metalnessMap:this.metalnessMap,alphaMap:this.alphaMap,envMap:this.envMap,envMapIntensity:this.envMapIntensity,refractionRatio:this.refractionRatio,...e?{heightMap:this.heightMap,heightScale:this.heightScale}:{}}))}}e([s(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([s({label:"Color Map"}),a("design:type",r)],StandardShader.prototype,"map",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"alphaMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"roughnessMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"metalnessMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"lightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"aoMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([s(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([s({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"emissiveMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"bumpMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"bumpScale",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"normalMap",void 0),e([s(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"displacementMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"displacementScale",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"displacementBias",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"refractionRatio",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"heightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0),e([s(),a("design:type",Boolean)],StandardShader.prototype,"vertexColor",void 0);export var ParallaxType;!function(e){e[e.none=0]="none",e[e.offset=1]="offset",e[e.pom=2]="pom"}(ParallaxType||(ParallaxType={}));export class ParallaxStandardMaterial extends n{constructor(e={}){super(e),e.heightMap&&(this.heightMap=e.heightMap),this.heightScale=e.heightScale??.05,this.parallaxType=e.parallaxType??ParallaxType.pom,this.minLayers=e.minLayers??10,this.maxLayers=e.maxLayers??32}onBeforeCompile(e){e.uniforms.heightMap={value:this.heightMap},e.uniforms.heightScale={value:this.heightScale},e.uniforms.minLayers={value:this.minLayers},e.uniforms.maxLayers={value:this.maxLayers},e.uniforms.parallaxType={value:this.parallaxType},e.vertexTangents=!0,e.vertexShader=e.vertexShader.replace("#include <uv_pars_vertex>","\n #include <uv_pars_vertex>\n "),e.vertexShader=e.vertexShader.replace("#include <begin_vertex>","\n #include <begin_vertex>\n "),e.fragmentShader=e.fragmentShader.replace("#include <uv_pars_fragment>","\n #include <uv_pars_fragment>\n uniform sampler2D heightMap;\n uniform float heightScale;\n uniform int minLayers;\n uniform int maxLayers;\n uniform int parallaxType;\n\n vec2 parallaxOffset(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 viewDirTS = -viewDir * tbn;\n\n float h = texture(heightMap, uv).r;\n return uv - (viewDirTS.xy / viewDirTS.z) * (h * heightScale);\n }\n\n vec2 parallaxOcclusion2(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 vv = -viewDir * tbn;\n\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n float factor = pow(1.0 - abs(vv.z), 2.0);\n float nNumSamples = mix(float(minLayers), float(maxLayers), factor);\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 128; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture2D(heightMap, uv + vCurrOffset).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n }\n "),e.fragmentShader=e.fragmentShader.replace("#include <map_fragment>","\n vec3 pomViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n vec2 uvPOM = vMapUv ;\n if (parallaxType == 1) {\n uvPOM = parallaxOffset(vMapUv, pomViewDir, vNormal);\n } else if (parallaxType == 2) {\n uvPOM = parallaxOcclusion2(vMapUv, pomViewDir, vNormal);\n }\n\n vec4 texelColor = texture2D(map, uvPOM);\n diffuseColor *= texelColor;\n "),e.fragmentShader=e.fragmentShader.replace("#include <normal_fragment_maps>","\n #ifdef USE_NORMALMAP\n // RE-COMPUTE TBN for normal mapping consistency\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uvPOM);\n vec2 duv2 = dFdy(uvPOM);\n vec3 dp2perp = cross(dp2, vNormal);\n vec3 dp1perp = cross(vNormal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 localTBN = mat3(T * invmax, B * invmax, vNormal);\n\n vec3 mapN = texture2D(normalMap, uvPOM).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n normal = normalize( localTBN * mapN );\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <roughnessmap_fragment>","\n float roughnessFactor = roughness;\n #ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, uvPOM );\n // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n roughnessFactor *= texelRoughness.g;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <metalnesssmap_fragment>","\n float metalnessFactor = metalness;\n #ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, uvPOM );\n // reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n metalnessFactor *= texelMetalness.b;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <aomap_fragment>","\n #ifdef USE_AOMAP\n\n // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n float ambientOcclusion = ( texture2D( aoMap, uvPOM ).r - 1.0 ) * aoMapIntensity + 1.0;\n\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\n #endif\n\n #endif\n "),this.userData.shader=e}clone(){const e=super.clone();return e.heightMap=this.heightMap,e.heightScale=this.heightScale,e.parallaxType=this.parallaxType,e.minLayers=this.minLayers,e.maxLayers=this.maxLayers,e}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{Color as o,DataTexture as i,MeshToonMaterial as p,RedFormat as s,Texture as r,Vector2 as n}from"three";import{removeObjectUndefined as a}from"../../utils/collections.js";import{Parameter as h}from"../parameter.js";import{Shader as d}from"../shader.js";export class ToonShader extends d{constructor(){super(...arguments),this.color=new o("#FFFFFF"),this.opacity=1,this.intensity=1,this.lightSteps=[],this.normalScale=new n(1,1),this.vertexColor=!1}build(){let e;if(null!=this.lightSteps&&this.lightSteps.length>0){const t=new Uint8Array(this.lightSteps.length);for(let e=0;e<=t.length;e++)t[e]=255*this.lightSteps[e];e=new i(t,t.length,1,s),e.needsUpdate=!0}return new p(a({color:this.color.multiplyScalar(this.intensity),opacity:this.opacity,map:this.map,gradientMap:e,lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,normalMap:this.normalMap,normalScale:this.normalScale,emissive:this.emissive,emissiveIntensity:this.emissiveIntensity,emissiveMap:this.emissiveMap,aoMap:this.aoMap,aoMapIntensity:this.aoMapIntensity,alphaMap:this.alphaMap,vertexColors:this.vertexColor}))}}e([h(),t("design:type",o)],ToonShader.prototype,"color",void 0),e([h({range:[0,1]}),t("design:type",Number)],ToonShader.prototype,"opacity",void 0),e([h({range:[0,10]}),t("design:type",Number)],ToonShader.prototype,"intensity",void 0),e([h(),t("design:type",r)],ToonShader.prototype,"map",void 0),e([h({type:Number,array:!0,range:[0,1]}),t("design:type",Array)],ToonShader.prototype,"lightSteps",void 0),e([h(),t("design:type",r)],ToonShader.prototype,"lightMap",void 0),e([h(),t("design:type",Number)],ToonShader.prototype,"lightMapIntensity",void 0),e([h(),t("design:type",r)],ToonShader.prototype,"normalMap",void 0),e([h(),t("design:type",n)],ToonShader.prototype,"normalScale",void 0),e([h(),t("design:type",r)],ToonShader.prototype,"aoMap",void 0),e([h(),t("design:type",Number)],ToonShader.prototype,"aoMapIntensity",void 0),e([h(),t("design:type",r)],ToonShader.prototype,"alphaMap",void 0),e([h(),t("design:type",o)],ToonShader.prototype,"emissive",void 0),e([h({range:[0,10]}),t("design:type",Number)],ToonShader.prototype,"emissiveIntensity",void 0),e([h(),t("design:type",r)],ToonShader.prototype,"emissiveMap",void 0),e([h(),t("design:type",Boolean)],ToonShader.prototype,"vertexColor",void 0);/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -9,12 +9,9 @@ export declare class UnlitShader extends Shader {
|
|
|
9
9
|
lightMapIntensity?: number;
|
|
10
10
|
aoMap?: Texture;
|
|
11
11
|
aoMapIntensity?: number;
|
|
12
|
-
specularMap?: Texture;
|
|
13
12
|
alphaMap?: Texture;
|
|
14
13
|
envMap?: Texture;
|
|
15
|
-
|
|
16
|
-
reflectivity?: number;
|
|
17
|
-
refractionRatio?: number;
|
|
14
|
+
vertexColor?: boolean;
|
|
18
15
|
build(): Material;
|
|
19
16
|
}
|
|
20
17
|
//# sourceMappingURL=unlit-shader.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import{
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import{Color as i,MeshBasicMaterial as o,Texture as p}from"three";import{Shader as r}from"../shader.js";import{Parameter as a}from"../parameter.js";import{removeObjectUndefined as n}from"../../utils/collections.js";export class UnlitShader extends r{constructor(){super(...arguments),this.color=new i("#FFFFFF"),this.opacity=1,this.intensity=1,this.vertexColor=!1}build(){return new o(n({color:this.color.multiplyScalar(this.intensity),emissive:this.color.multiplyScalar(this.intensity),opacity:this.opacity,map:this.map,lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:this.aoMap,aoMapIntensity:this.aoMapIntensity,alphaMap:this.alphaMap,envMap:this.envMap,vertexColors:this.vertexColor}))}}t([a(),e("design:type",i)],UnlitShader.prototype,"color",void 0),t([a({range:[0,1]}),e("design:type",Number)],UnlitShader.prototype,"opacity",void 0),t([a({range:[0,10]}),e("design:type",Number)],UnlitShader.prototype,"intensity",void 0),t([a(),e("design:type",p)],UnlitShader.prototype,"map",void 0),t([a(),e("design:type",p)],UnlitShader.prototype,"lightMap",void 0),t([a(),e("design:type",Number)],UnlitShader.prototype,"lightMapIntensity",void 0),t([a(),e("design:type",p)],UnlitShader.prototype,"aoMap",void 0),t([a(),e("design:type",Number)],UnlitShader.prototype,"aoMapIntensity",void 0),t([a(),e("design:type",p)],UnlitShader.prototype,"alphaMap",void 0),t([a(),e("design:type",p)],UnlitShader.prototype,"envMap",void 0),t([a(),e("design:type",Boolean)],UnlitShader.prototype,"vertexColor",void 0);/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -7,6 +7,14 @@ export declare abstract class SpriteNodeShader {
|
|
|
7
7
|
build(): Material;
|
|
8
8
|
abstract output(): NodeShaderOutput;
|
|
9
9
|
}
|
|
10
|
+
export declare class SpriteShader extends SpriteNodeShader {
|
|
11
|
+
color: THREE.Color;
|
|
12
|
+
opacity: number;
|
|
13
|
+
intensity: number;
|
|
14
|
+
map?: THREE.Texture;
|
|
15
|
+
alphaMap?: THREE.Texture;
|
|
16
|
+
output(): NodeShaderOutput;
|
|
17
|
+
}
|
|
10
18
|
export declare function getSpritePosition(rotation: FloatNode): Vec4Node;
|
|
11
19
|
export declare class SpriteNodeShaderMaterial extends NodeShaderMaterial {
|
|
12
20
|
get color(): THREE.ColorRepresentation;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{Vec4Node as
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{Parameter as i}from"./shader.js";import{Vec4Node as r,glslFunction as n,transformed as a,uniforms as s,UniformFloatNode as l,rgba as p,textureSampler2d as c,varyingAttributes as d,float as m}from"three-shader-graph";import*as h from"three";export class SpriteNodeShader{build(){const t=this.output(),e=getSpritePosition(new l("rotation",0));return new SpriteNodeShaderMaterial({color:t.color,discard:t.discard,transparent:t.transparent??!0,position:e,uniforms:{color:{value:new h.Color(0)}}})}}export class SpriteShader extends SpriteNodeShader{constructor(){super(...arguments),this.color=new h.Color("#FFFFFF"),this.opacity=1,this.intensity=1}output(){let t=m(this.opacity);this.alphaMap&&(t=t.multiply(c(this.alphaMap).sample(d.uv).r));let e=p(this.color,t);return this.map&&(e=e.multiply(c(this.map).sample(d.uv))),null!=this.intensity&&1!==this.intensity&&(e=p(e.rgb.multiplyScalar(this.intensity),e.a)),{color:e}}}t([i(),e("design:type",h.Color)],SpriteShader.prototype,"color",void 0),t([i({range:[0,1]}),e("design:type",Number)],SpriteShader.prototype,"opacity",void 0),t([i({range:[0,10]}),e("design:type",Number)],SpriteShader.prototype,"intensity",void 0),t([i(),e("design:type",h.Texture)],SpriteShader.prototype,"map",void 0),t([i(),e("design:type",h.Texture)],SpriteShader.prototype,"alphaMap",void 0);export function getSpritePosition(t){return n(r,{position:a.position,cameraPosition:s.cameraPosition,viewMatrix:s.viewMatrix,modelViewMatrix:s.modelViewMatrix,rotation:t},"\n // Scale from your model matrix\n vec2 scale;\n scale.x = length(vec3(modelMatrix[0].x, modelMatrix[0].y, modelMatrix[0].z));\n scale.y = length(vec3(modelMatrix[1].x, modelMatrix[1].y, modelMatrix[1].z));\n\n vec3 right, up;\n vec3 objectPos = (modelMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;\n\n #ifdef LOCK_Y_AXIS\n vec3 cameraPos = cameraPosition;\n vec3 lookDir = normalize(vec3(cameraPos.x - objectPos.x, 0.0, cameraPos.z - objectPos.z));\n right = normalize(vec3(lookDir.z, 0.0, -lookDir.x));\n up = vec3(0.0, 1.0, 0.0);\n #else\n right = vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);\n up = vec3(viewMatrix[0][1], viewMatrix[1][1], viewMatrix[2][1]);\n #endif\n\n // then your shared code:\n vec2 center = vec2(0.5, 0.5);\n vec2 alignedPosition = (position.xy - (center - vec2(0.5))) * scale;\n\n vec2 rotatedPosition;\n rotatedPosition.x = cos(rotation) * alignedPosition.x - sin(rotation) * alignedPosition.y;\n rotatedPosition.y = sin(rotation) * alignedPosition.x + cos(rotation) * alignedPosition.y;\n\n vec3 billboardPos = objectPos + right * rotatedPosition.x + up * rotatedPosition.y;\n\n return projectionMatrix * viewMatrix * vec4(billboardPos, 1.0);\n ")}export class SpriteNodeShaderMaterial extends o{get color(){return this.uniforms.color.value}set color(t){this.uniforms.color.value=new h.Color(t)}get rotation(){return this.uniforms.rotation.value}set rotation(t){this.uniforms.rotation.value=t}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{abs as t,
|
|
1
|
+
import{abs as t,batchingMatrix as r,ifDefApply as o,inverse as e,min as l,smoothstep as a,uniforms as c,varying as p,vec4 as x}from"three-shader-graph";import{depthNormal as d,depthWorldPosition as i}from"./depth.js";const m=o("USE_BATCHING",c.instanceMatrix,t=>r.multiply(t)),s=p(e(c.modelMatrix.multiply(m))),y=s.multiplyVec(x(i,1)).xyz;export const decalNormal=s.multiplyVec(x(d,0)).xyz;export const decalDiscard=t(y.x).gt(.5).or(t(y.y).gt(.5)).or(t(y.z).gt(.5));export const decalUV=y.xz.addScalar(.5);export const decalAlpha=l(a(.5,.49,t(y.x)),l(a(.5,.49,t(y.y)),a(.5,.49,t(y.z))));/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|