@hology/core 0.0.185 → 0.0.186
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{BehaviorSubject as o,distinctUntilChanged as n,filter as r,map as a,Subject as l,takeUntil as c}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as y,BufferGeometry as u,Group as p,LineSegments as g,Matrix4 as m,Object3D as f,Quaternion as w,Raycaster as B,Scene as x,Vector3 as b}from"three";import{Service as v}from"typedi";import{AssetMeshInstance as C}from"../../../scene/asset-resource-loader.js";import{BoxCollisionShape as A,CapsuleCollisionShape as S,CollisionShapeSource as R,ConeCollisionShape as D,ConvexPolyhedronCollisionShape as z,CylinderCollisionShape as T,PhysicalShapeMesh as E,PlaneCollisionShape as M,SphereCollisionShape as P,TrimeshCollisionShape as V}from"../../../index.js";import{LandscapeGroup as _}from"../../../scene/landscape/landscape.js";import{ViewController as F}from"../render.js";import{World as I}from"../world.js";import*as k from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as W}from"../../../utils/three/traverse.js";import{AbstractPhysicsSystem as N}from"./abstract-physics-system.js";import{ActorComponent as j,Component as L}from"../../../gameplay/actors/component.js";import{inject as O}from"../../../gameplay/inject.js";export{Component,ActorComponent,attach,Attach}from"../../actors/component.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.hitNormal=new b}}export class ShapeCastResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.normal=new b}reset(){this.actor=void 0,this.hasHit=!1,this.distance=0,this.hitPoint.set(0,0,0),this.normal.set(0,0,0)}}ShapeCastResult.shared=new ShapeCastResult;export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));const G=new b,K=new b,U=new w,q=new w,H=(new w,[]);let Q=class extends N{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.collisionEvents=new l,this.beforeStep=new l,this.afterStep=new l,this.shouldRenderDebug=!1,this.viewController=O(F),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this._raycaster=new B,this._reusableResult=new RayTestResult,this._raytestDiff=new b,this._raytestDirection=new b,this.controlledActors=new Set,this.ready=this.setup()}getBallShape(t){let e=this.shapeCacheBall.get(t);return null==e&&(e=new i.Ball(t),this.shapeCacheBall.set(t,e)),e}getBoxShape(t,e,s){const o=t+1e6*e+1e12*s;let n=this.shapeCacheBox.get(o);return null==n&&(n=new i.Cuboid(t,e,s),this.shapeCacheBox.set(o,n)),n}hasBoxIntersection(t){const e=t.getCenter(G),i=t.getSize(K),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,U,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,U,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,n]of this.bodyActors)if(n instanceof i||null==i)for(let i=0,r=e.numColliders();i<r;i++){e.collider(i).intersectsShape(s,t,U)&&o.push(n)}return o}createDebugMesh(){return new g(new u,new d.LineBasicMaterial({color:255}))}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene?.add(this.debugMesh));const t=this.world.debugRender().vertices,e=this.debugMesh.geometry,i=e.getAttribute("position");null==i||(i.array.length,t.length);{const i=new y(t,3);i.setUsage(d.DynamicDrawUsage),e.setAttribute("position",i)}e.setDrawRange(0,t.length/3)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await rt(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach(t=>{if(t.isFixed())return;const e=this.staticMeshes.get(t)??this.bodyActors.get(t)?.object;null!=e&&e.parent instanceof x&&(ct(e.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&dt(e.quaternion,t.rotation()),e.matrixWorldNeedsUpdate=!0)}),this.afterStep.next(t)})}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})})}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(st,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult);const o=this._raytestDiff,n=this._raytestDirection;if(o.subVectors(e,t),n.copy(o).normalize(),0===n.length())return console.warn("Ray test called with to and from being equal"),i;at(mt.origin,t),at(mt.dir,n);const r=o.length(),a=this.world.castRayAndGetNormal(mt,r,!1,void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0,s?.excludeTriggers?t=>!t.isSensor():void 0);if(i.hasHit=null!=a,i.hasHit){const e=mt.pointAt(a.timeOfImpact);i._internal=a,ct(i.hitNormal,a.normal),ct(i.hitPoint,e),i.distance=yt.subVectors(i.hitPoint,t).length();const s=this.world.bodies.getAll().find(t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,t=>t===a.collider));i.actor=null!=s?this.bodyActors.get(s):null}if(this.showDebug){let e;H.length>0?(e=H.pop(),e.setDirection(n),e.position.copy(t),e.setLength(r,.2,.1),e.setColor(s?.debugColor??255)):e=new h(n,t,r,s?.debugColor??255),this.scene?.add(e),setTimeout(()=>{this.scene?.remove(e),H.push(e)},s?.debugLifetime??200)}return i}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return J.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())ht(t,t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof E&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof C){const e=!1!==t.userData?.src?.collisionDetection;if(t.children[0]&&(t.children[0].instanceMatrix&&e||t.children[0].isBatchedMesh))this.createForInstancedMesh(t.children[0],t.collisionShapes);else if(e){const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}}else t instanceof _?this.addLandscapeGroup(t):(t instanceof p||t instanceof x)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new m;if(t instanceof d.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map;for(let o=0;o<e.length;o++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[o])continue;let e=t.userData.collisionShapes?.[o];if(null==e&&t.parent instanceof C&&(e=t.parent.collisionShapes),null==e)continue;let n=s.get(e);null==n&&(n=this.instancedShapeReset(e),s.set(e,n));const r=new f;r.matrix.identity(),t.getMatrixAt(o,i),r.applyMatrix4(i);this.createStaticBody(r,n)}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new f;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);this.createStaticBody(o,s)}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>t.source===R.rendered?t.withOffset(wt):t)}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,o=null){const n=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=n.collider(0);e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,o,pt);const a=e.computedMovement();return ct(ut,a),ut}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world);return this.colliders.set(i.handle,s),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const s=(()=>{switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyDesc.dynamic();case PhysicsBodyType.static:return i.RigidBodyDesc.fixed();case PhysicsBodyType.kinematic:return i.RigidBodyDesc.kinematicPositionBased();case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyDesc.kinematicVelocityBased();default:return i.RigidBodyDesc.dynamic()}})();e.position&&s.setTranslation(e.position.x,e.position.y,e.position.z),e.rotation&&s.setRotation({x:e.rotation.x,y:e.rotation.y,z:e.rotation.z,w:e.rotation.w}),"boolean"==typeof e.canSleep&&s.setCanSleep(e.canSleep),"boolean"==typeof e.ccdEnabled&&s.setCcdEnabled(e.ccdEnabled),"number"==typeof e.gravityScale&&s.setGravityScale(e.gravityScale),"number"==typeof e.mass&&s.setAdditionalMass(e.mass),void 0!==e.userData&&(s.userData=e.userData);const o=this.world.createRigidBody(s);return new PhysicsBody(o,this.world)}getCharacterComputedMovement(t,e,i,o=null){const n=t.collider;e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,o,pt);const r=e.computedMovement();return ct(ut,r),ut}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition(X),s=e.getWorldQuaternion(Y);t.setNextKinematicTranslation(ot(i)),t.setNextKinematicRotation(nt(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.setAngvel(tt,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.setLinvel(tt,!0)}getLinearVelocity(t,e=new b){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new b){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(ot(e),!1)}getPosition(t,e=new b){const i=this.actorBodies.get(t.id);i&&ct(e,i.translation())}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(nt(e),!1)}getRotation(t,e=new w){const i=this.actorBodies.get(t.id);i&&dt(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}addLandscapeGroup(t){const e=t.userData.src,s=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));var o=n.getWorldPosition(new b);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===n.name&&0!==t.w[0])){const t=n.geometry.clone(),s=n.scale,r=n.geometry.getAttribute("hole"),a=new Float32Array(t.getAttribute("position").array);for(let t=0;t<a.length;t+=3)a[t]*=s.x,a[t+1]*=s.y,a[t+2]*=s.z;const l=t.index;for(let t=0;t<l.count;t+=3){const e=r.getX(l.getX(t)),i=r.getX(l.getY(t)),s=r.getX(l.getZ(t));(e>.5||i>.5||s>.5)&&(l.setX(t,0),l.setY(t,0),l.setZ(t,0))}const c=i.ColliderDesc.trimesh(a,new Uint32Array(t.getIndex().array));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(i.RigidBodyDesc.fixed()),e=new i.Vector3(0,0,0);at(e,o),t.setTranslation(e,!1),this.world.createCollider(c,t),this.staticBodies.set(n,t)}continue}const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=s.find(t=>t.x===n.x&&t.y==n.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=i.ColliderDesc.heightfield(c,c,new Float32Array(d),new i.Vector3(r,r,r));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(i.RigidBodyDesc.fixed()),e=new i.Vector3(0,0,0);at(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(n,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e)}addActor(t,e,s={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const o=t.object;let n;switch(s.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:n=i.RigidBodyDesc.dynamic(),n.mass=s.mass??1;break;case PhysicsBodyType.kinematic:n=i.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:n=i.RigidBodyDesc.kinematicVelocityBased();break;default:n=s.isTrigger?i.RigidBodyDesc.kinematicVelocityBased():i.RigidBodyDesc.fixed()}const r=this.world.createRigidBody(n);r.enableCcd(1==s.continousCollisionDetection);for(const t of e)this.addShape(r,t,o);return ht(r,t=>{null!=s.isTrigger&&(t.setSensor(s.isTrigger),t.setActiveCollisionTypes(i.ActiveCollisionTypes.ALL),t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)),null!=s.friction&&t.setFriction(s.friction),null!=s.density&&t.setDensity(s.density),null!=s.mass&&t.setMass(s.mass),null!=s.restitution&&t.setRestitution(s.restitution)}),Z(r,o),!0===s.ignoreForNavMesh&&(r.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,r),this.bodyActors.set(r,t),new PhysicsBody(r,this.world)}applyTorque(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.addTorque(tt,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.applyTorqueImpulse(tt,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.addForce(tt,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.applyImpulse(tt,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);at(tt,e),null==i?s?.addForce(tt,!0):(at(et,i),s?.addForceAtPoint(tt,et,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);at(tt,e),null==i?s.applyImpulse(tt,!0):(at(et,i),s.applyImpulseAtPoint(tt,et,!0))}applyRadiusImpulse(t,e,s){this.world.bodies.forEach(o=>{if(o.collider(0)?.isSensor())return;if(o.bodyType()!==i.RigidBodyType.Dynamic)return;const n=it;ct(n,o.translation());const r=n.clone().sub(t);if(r.length()>e)return;const a=r.clone().normalize().multiplyScalar(s);tt.x=a.x,tt.y=a.y,tt.z=a.z,o.applyImpulse(tt,!0)})}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.staticBodies.delete(t),this.world.removeRigidBody(i))}removeSceneObject(t){if(t instanceof _){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(({started:t})=>t===i),a(({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t)?.parent()),a2:this.bodyActors.get(this.world.getCollider(e)?.parent()),started:i})),r(({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s)),a(({a2:t})=>t))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>!t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onHasContactChanged(t){const e=new Set,i=new o(!1);return this.onBeginContact(t).subscribe(t=>{e.add(t),i.next(e.size>0)}),this.onEndContact(t).subscribe(t=>{e.delete(t),i.next(e.size>0)}),i.pipe(n())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e&&Z(e,t.object)}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t}sphereCast(t,e,i,s,o=ShapeCastResult.shared,n){o.reset();const r=this.getBallShape(e);this.shapeCacheBall.get;const a={x:t.x,y:t.y,z:t.z},l={x:i.x,y:i.y,z:i.z},c=n?.excludeActor?this.actorBodies.get(n.excludeActor.id):null,d=this.world.castShape(a,{x:0,y:0,z:0,w:1},l,r,.01,s,!0,null,n?.collisionFilter??void 0,null,c,n?.excludeTriggers?t=>!t.isSensor():void 0);if(null!=d){ct(o.hitPoint,d.witness1),o.normal.set(d.normal1.x,d.normal1.y,d.normal1.z),o.distance=d.time_of_impact,o.hasHit=!0;const t=d.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(o.actor=e)}}return o}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const n=this.actorBodies.get(t.id);if(n&&n.numColliders()>0){for(let t=0;t<n.numColliders();t++){const r=n.collider(t);let a=r.shape,l=r.translation(),c=r.rotation(),d=e,h=i;const y=this.world.castShape(l,c,d,a,.01,h,!0,null,o,null,n,void 0);if(null!=y){y.collider;const t=r;return ct(s.hitPoint,y.witness1),Bt(t.rotation(),y.normal1,s.normal,q),s.distance=y.time_of_impact,s.actor=this.bodyActors.get(y.collider.parent()),s.hasHit=!0,s}}return s}return console.warn("Actor is not added to the physics system"),s}stop(){this.world?.bodies.forEach(t=>this.world.removeRigidBody(t)),this.world?.free(),this.fixedupdateSub?.unsubscribe(),this.collisionSub?.unsubscribe(),H.length=0}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed();o.setSleeping(!0);const n=this.world.createRigidBody(o);for(const i of e){if(null==i){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(n,i,t);null!=s?.friction&&o.setFriction(s.friction),null!=s?.density&&o.setDensity(s.density),null!=s?.mass&&o.setMass(s.mass/e.length),null!=s?.restitution&&o.setRestitution(s.restitution)}return Z(n,t),n.userData=t.uuid,n.sleep(),n}addShape(t=void 0,e,i){const s=i?.getWorldScale(gt)??$,o=this.createShape(e,s);this.applyShapeSettings(o,e);const n=e.offset.clone().multiply(s);at(o.translation,n);const r=(new w).setFromEuler(e.rotation);e instanceof z&&e.mesh instanceof d.Mesh&&r.multiply(e.mesh.getWorldQuaternion(Y)),lt(o.rotation,r);return this.world.createCollider(o,t)}applyShapeSettings(t,e){null!=e.collisionGroup&&t.setCollisionGroups(e.collisionGroup),t.friction=e.friction??.1,null!=e.restitution&&(t.restitution=e.restitution),null!=e.density&&(t.density=e.density,t.massPropsMode=i.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=i.MassPropsMode.Mass)}createShape(t,e){if(t instanceof A)return i.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof S){return i.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof V){const s=null!=t.geometry.getIndex()?t.geometry:k.mergeVertices(t.geometry),o=extractFloat32Array(s.getAttribute("position"));for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;return i.ColliderDesc.trimesh(o,new Uint32Array(s.getIndex().array))}if(t instanceof z){let s;t.mesh instanceof d.Mesh?s=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?s=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const o=extractFloat32Array(s.getAttribute("position"));if(t.mesh instanceof d.Mesh){const e=W(t.mesh);for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z}for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;const n=o;n.length;return i.ColliderDesc.convexHull(n)}if(t instanceof P){const s=2*e.x-e.y-e.z;return Math.abs(s)>.01?this.createShape(new z(new d.SphereGeometry(t.radius).scale(e.x,e.y,e.z)),new b(1,1,1)):i.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z))}return t instanceof T?i.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof D?i.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof M?i.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.001):(console.error("Unsupported shape",t),i.ColliderDesc.cuboid(1,1,1))}createCharacterCollision(){return new i.CharacterCollision}};Q=t([v(),e("design:paramtypes",[])],Q);export{Q as PhysicsSystem};const X=new b,Y=new d.Quaternion;function Z(t,e){const i=e.getWorldPosition(X),s=e.getWorldQuaternion(Y);t.setTranslation(ot(i),!1),t.setRotation(nt(s),!1)}const J=new b,$=new b(1,1,1),tt=new i.Vector3(0,0,0),et=new i.Vector3(0,0,0),it=new b,st=new d.Vector2;function ot(t){return at(tt,t),tt}function nt(t){return lt(q,t),q}const rt=async()=>{let t=await import("@dimforge/rapier3d-compat");return await t.init(),t};function at(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function lt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function ct(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function dt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function ht(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const yt=new b,ut=new b,pt=t=>!t.isSensor(),gt=new b;const mt=new i.Ray(new i.Vector3(0,0,0),new i.Vector3(0,1,0));let ft=class extends j{constructor(){super(...arguments),this._active=!0,this.physics=O(Q),this.world=O(I)}set active(t){this._active=t,t?(this.world.scene.remove(this.actor.object),this.physics.setEnabled(this.actor,t)):(this.world.scene.add(this.actor.object),this.physics.setEnabled(this.actor,t))}get active(){return this._active}};ft=t([L()],ft);export function extractFloat32Array(t){const e=t.itemSize,i=t.count,s=new Float32Array(i*e);for(let o=0;o<i;o++)for(let i=0;i<e;i++)s[o*e+i]=t.getComponent(o,i);return s}const wt=new b;function Bt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e){this.collider=t,this.world=e,this.disposed=new l,this.onBeginOverlapActor=new l,this.onEndOverlapActor=new l}dispose(){this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t)}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e){this.body=t,this.world=e}dispose(){this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t)}isEnabled(){return this.body.isEnabled()}getPosition(t){const e=this.body.translation();return t.set(e.x,e.y,e.z),t}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0)}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0)}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyType.Dynamic;case PhysicsBodyType.static:return i.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return i.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static)}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}/*
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{BehaviorSubject as o,distinctUntilChanged as n,filter as r,map as a,Subject as l,takeUntil as c}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as y,BufferGeometry as u,Group as p,LineSegments as g,Matrix4 as m,Object3D as f,Quaternion as w,Raycaster as B,Scene as x,Vector3 as b}from"three";import{Service as v}from"typedi";import{AssetMeshInstance as C}from"../../../scene/asset-resource-loader.js";import{BoxCollisionShape as A,CapsuleCollisionShape as S,CollisionShapeSource as R,ConeCollisionShape as D,ConvexPolyhedronCollisionShape as z,CylinderCollisionShape as T,PhysicalShapeMesh as E,PlaneCollisionShape as M,SphereCollisionShape as P,TrimeshCollisionShape as V}from"../../../index.js";import{LandscapeGroup as _}from"../../../scene/landscape/landscape.js";import{ViewController as F}from"../render.js";import{World as I}from"../world.js";import*as k from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as W}from"../../../utils/three/traverse.js";import{AbstractPhysicsSystem as N}from"./abstract-physics-system.js";import{ActorComponent as j,Component as L}from"../../../gameplay/actors/component.js";import{inject as O}from"../../../gameplay/inject.js";export{Component,ActorComponent,attach,Attach}from"../../actors/component.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.hitNormal=new b}}export class ShapeCastResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.normal=new b}reset(){this.actor=void 0,this.hasHit=!1,this.distance=0,this.hitPoint.set(0,0,0),this.normal.set(0,0,0)}}ShapeCastResult.shared=new ShapeCastResult;export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));const G=new b,K=new b,U=new w,q=new w,H=(new w,[]);let Q=class extends N{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.collisionEvents=new l,this.beforeStep=new l,this.afterStep=new l,this.shouldRenderDebug=!1,this.viewController=O(F),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this._raycaster=new B,this._reusableResult=new RayTestResult,this._raytestDiff=new b,this._raytestDirection=new b,this.controlledActors=new Set,this.ready=this.setup()}getBallShape(t){let e=this.shapeCacheBall.get(t);return null==e&&(e=new i.Ball(t),this.shapeCacheBall.set(t,e)),e}getBoxShape(t,e,s){const o=t+1e6*e+1e12*s;let n=this.shapeCacheBox.get(o);return null==n&&(n=new i.Cuboid(t,e,s),this.shapeCacheBox.set(o,n)),n}hasBoxIntersection(t){const e=t.getCenter(G),i=t.getSize(K),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,U,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,U,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,n]of this.bodyActors)if(n instanceof i||null==i)for(let i=0,r=e.numColliders();i<r;i++){e.collider(i).intersectsShape(s,t,U)&&o.push(n)}return o}createDebugMesh(){return new g(new u,new d.LineBasicMaterial({color:255}))}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene?.add(this.debugMesh));const t=this.world.debugRender().vertices,e=this.debugMesh.geometry,i=e.getAttribute("position");null==i||(i.array.length,t.length);{const i=new y(t,3);i.setUsage(d.DynamicDrawUsage),e.setAttribute("position",i)}e.setDrawRange(0,t.length/3)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await rt(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach(t=>{if(t.isFixed())return;const e=this.staticMeshes.get(t)??this.bodyActors.get(t)?.object;null!=e&&e.parent instanceof x&&(ct(e.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&dt(e.quaternion,t.rotation()),e.matrixWorldNeedsUpdate=!0)}),this.afterStep.next(t)})}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})})}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(st,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult);const o=this._raytestDiff,n=this._raytestDirection;if(o.subVectors(e,t),n.copy(o).normalize(),0===n.length())return console.warn("Ray test called with to and from being equal"),i;at(mt.origin,t),at(mt.dir,n);const r=o.length(),a=this.world.castRayAndGetNormal(mt,r,!1,void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0,s?.excludeTriggers?t=>!t.isSensor():void 0);if(i.hasHit=null!=a,i.hasHit){const e=mt.pointAt(a.timeOfImpact);i._internal=a,ct(i.hitNormal,a.normal),ct(i.hitPoint,e),i.distance=yt.subVectors(i.hitPoint,t).length();const s=this.world.bodies.getAll().find(t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,t=>t===a.collider));i.actor=null!=s?this.bodyActors.get(s):null}if(this.showDebug){let e;H.length>0?(e=H.pop(),e.setDirection(n),e.position.copy(t),e.setLength(r,.2,.1),e.setColor(s?.debugColor??255)):e=new h(n,t,r,s?.debugColor??255),this.scene?.add(e),setTimeout(()=>{this.scene?.remove(e),H.push(e)},s?.debugLifetime??200)}return i}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return J.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())ht(t,t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof E&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof C){const e=!1!==t.userData?.src?.collisionDetection;if(t.children[0]&&(t.children[0].instanceMatrix&&e||t.children[0].isBatchedMesh))this.createForInstancedMesh(t.children[0],t.collisionShapes);else if(e){const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}}else t instanceof _?this.addLandscapeGroup(t):(t instanceof p||t instanceof x)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new m;if(t instanceof d.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map;for(let o=0;o<e.length;o++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[o])continue;let e=t.userData.collisionShapes?.[o];if(null==e&&t.parent instanceof C&&(e=t.parent.collisionShapes),null==e)continue;let n=s.get(e);null==n&&(n=this.instancedShapeReset(e),s.set(e,n));const r=new f;r.matrix.identity(),t.getMatrixAt(o,i),r.applyMatrix4(i);this.createStaticBody(r,n)}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new f;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);this.createStaticBody(o,s)}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>t.source===R.rendered?t.withOffset(wt):t)}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,o=null){const n=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=n.collider(0);e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,o,pt);const a=e.computedMovement();return ct(ut,a),ut}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world);return this.colliders.set(i.handle,s),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const s=(()=>{switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyDesc.dynamic();case PhysicsBodyType.static:return i.RigidBodyDesc.fixed();case PhysicsBodyType.kinematic:return i.RigidBodyDesc.kinematicPositionBased();case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyDesc.kinematicVelocityBased();default:return i.RigidBodyDesc.dynamic()}})();e.position&&s.setTranslation(e.position.x,e.position.y,e.position.z),e.rotation&&s.setRotation({x:e.rotation.x,y:e.rotation.y,z:e.rotation.z,w:e.rotation.w}),"boolean"==typeof e.canSleep&&s.setCanSleep(e.canSleep),"boolean"==typeof e.ccdEnabled&&s.setCcdEnabled(e.ccdEnabled),"number"==typeof e.gravityScale&&s.setGravityScale(e.gravityScale),"number"==typeof e.mass&&s.setAdditionalMass(e.mass),void 0!==e.userData&&(s.userData=e.userData);const o=this.world.createRigidBody(s);return new PhysicsBody(o,this.world)}getCharacterComputedMovement(t,e,i,o=null){const n=t.collider;e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,o,pt);const r=e.computedMovement();return ct(ut,r),ut}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition(X),s=e.getWorldQuaternion(Y);t.setNextKinematicTranslation(ot(i)),t.setNextKinematicRotation(nt(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.setAngvel(tt,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.setLinvel(tt,!0)}getLinearVelocity(t,e=new b){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new b){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(ot(e),!1)}getPosition(t,e=new b){const i=this.actorBodies.get(t.id);i&&ct(e,i.translation())}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(nt(e),!1)}getRotation(t,e=new w){const i=this.actorBodies.get(t.id);i&&dt(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}addLandscapeGroup(t){const e=t.userData.src,s=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));var o=n.getWorldPosition(new b);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===n.name&&0!==t.w[0])){const t=n.geometry.clone(),s=n.scale,r=n.geometry.getAttribute("hole"),a=new Float32Array(t.getAttribute("position").array);for(let t=0;t<a.length;t+=3)a[t]*=s.x,a[t+1]*=s.y,a[t+2]*=s.z;const l=t.index;for(let t=0;t<l.count;t+=3){const e=r.getX(l.getX(t)),i=r.getX(l.getY(t)),s=r.getX(l.getZ(t));(e>.5||i>.5||s>.5)&&(l.setX(t,0),l.setY(t,0),l.setZ(t,0))}const c=i.ColliderDesc.trimesh(a,new Uint32Array(t.getIndex().array));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(i.RigidBodyDesc.fixed()),e=new i.Vector3(0,0,0);at(e,o),t.setTranslation(e,!1),this.world.createCollider(c,t),this.staticBodies.set(n,t)}continue}const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=s.find(t=>t.x===n.x&&t.y==n.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=i.ColliderDesc.heightfield(c,c,new Float32Array(d),new i.Vector3(r,r,r));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(i.RigidBodyDesc.fixed()),e=new i.Vector3(0,0,0);at(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(n,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e)}addActor(t,e,s={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const o=t.object;let n;switch(s.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:n=i.RigidBodyDesc.dynamic(),n.mass=s.mass??1;break;case PhysicsBodyType.kinematic:n=i.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:n=i.RigidBodyDesc.kinematicVelocityBased();break;default:n=s.isTrigger?i.RigidBodyDesc.kinematicVelocityBased():i.RigidBodyDesc.fixed()}const r=this.world.createRigidBody(n);r.enableCcd(1==s.continousCollisionDetection);for(const t of e)this.addShape(r,t,o);return ht(r,t=>{null!=s.isTrigger&&(t.setSensor(s.isTrigger),t.setActiveCollisionTypes(i.ActiveCollisionTypes.ALL),t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)),null!=s.friction&&t.setFriction(s.friction),null!=s.density&&t.setDensity(s.density),null!=s.mass&&t.setMass(s.mass),null!=s.restitution&&t.setRestitution(s.restitution)}),Z(r,o),!0===s.ignoreForNavMesh&&(r.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,r),this.bodyActors.set(r,t),new PhysicsBody(r,this.world)}applyTorque(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.addTorque(tt,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.applyTorqueImpulse(tt,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.addForce(tt,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);tt.x=e.x,tt.y=e.y,tt.z=e.z,i?.applyImpulse(tt,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);at(tt,e),null==i?s?.addForce(tt,!0):(at(et,i),s?.addForceAtPoint(tt,et,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);at(tt,e),null==i?s.applyImpulse(tt,!0):(at(et,i),s.applyImpulseAtPoint(tt,et,!0))}applyRadiusImpulse(t,e,s){this.world.bodies.forEach(o=>{if(o.collider(0)?.isSensor())return;if(o.bodyType()!==i.RigidBodyType.Dynamic)return;const n=it;ct(n,o.translation());const r=n.clone().sub(t);if(r.length()>e)return;const a=r.clone().normalize().multiplyScalar(s);tt.x=a.x,tt.y=a.y,tt.z=a.z,o.applyImpulse(tt,!0)})}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.staticBodies.delete(t),this.world.removeRigidBody(i))}removeSceneObject(t){if(t instanceof _){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(({started:t})=>t===i),a(({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t)?.parent()),a2:this.bodyActors.get(this.world.getCollider(e)?.parent()),started:i})),r(({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s)),a(({a2:t})=>t))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>!t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onHasContactChanged(t){const e=new Set,i=new o(!1);return this.onBeginContact(t).subscribe(t=>{e.add(t),i.next(e.size>0)}),this.onEndContact(t).subscribe(t=>{e.delete(t),i.next(e.size>0)}),i.pipe(n())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e&&Z(e,t.object)}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t}sphereCast(t,e,i,s,o=ShapeCastResult.shared,n){o.reset();const r=this.getBallShape(e);this.shapeCacheBall.get;const a={x:t.x,y:t.y,z:t.z},l={x:i.x,y:i.y,z:i.z},c=n?.excludeActor?this.actorBodies.get(n.excludeActor.id):null,d=this.world.castShape(a,{x:0,y:0,z:0,w:1},l,r,.01,s,!0,null,n?.collisionFilter??void 0,null,c,n?.excludeTriggers?t=>!t.isSensor():void 0);if(null!=d){ct(o.hitPoint,d.witness1),o.normal.set(d.normal1.x,d.normal1.y,d.normal1.z),o.distance=d.time_of_impact,o.hasHit=!0;const t=d.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(o.actor=e)}}return o}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const n=this.actorBodies.get(t.id);if(n&&n.numColliders()>0){for(let t=0;t<n.numColliders();t++){const r=n.collider(t);let a=r.shape,l=r.translation(),c=r.rotation(),d=e,h=i;const y=this.world.castShape(l,c,d,a,.01,h,!0,null,o,null,n,void 0);if(null!=y){y.collider;const t=r;return ct(s.hitPoint,y.witness1),Bt(t.rotation(),y.normal1,s.normal,q),s.distance=y.time_of_impact,s.actor=this.bodyActors.get(y.collider.parent()),s.hasHit=!0,s}}return s}return console.warn("Actor is not added to the physics system"),s}stop(){this.world?.bodies.forEach(t=>this.world.removeRigidBody(t)),this.world?.free(),this.fixedupdateSub?.unsubscribe(),this.collisionSub?.unsubscribe(),H.length=0}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed();o.setSleeping(!0);const n=this.world.createRigidBody(o);for(const i of e){if(null==i){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(n,i,t);null!=s?.friction&&o.setFriction(s.friction),null!=s?.density&&o.setDensity(s.density),null!=s?.mass&&o.setMass(s.mass/e.length),null!=s?.restitution&&o.setRestitution(s.restitution)}return Z(n,t),n.userData=t.uuid,n.sleep(),n}addShape(t=void 0,e,i){const s=i?.getWorldScale(gt)??$,o=this.createShape(e,s);this.applyShapeSettings(o,e);const n=e.offset.clone().multiply(s);at(o.translation,n);const r=(new w).setFromEuler(e.rotation);e instanceof z&&e.mesh instanceof d.Mesh&&r.multiply(e.mesh.getWorldQuaternion(Y)),lt(o.rotation,r);return this.world.createCollider(o,t)}applyShapeSettings(t,e){null!=e.collisionGroup&&t.setCollisionGroups(e.collisionGroup),t.friction=e.friction??.1,null!=e.restitution&&(t.restitution=e.restitution),null!=e.density&&(t.density=e.density,t.massPropsMode=i.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=i.MassPropsMode.Mass)}createShape(t,e){if(t instanceof A)return this.rapier.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof S){return this.rapier.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof V){const i=null!=t.geometry.getIndex()?t.geometry:k.mergeVertices(t.geometry),s=extractFloat32Array(i.getAttribute("position"));for(let t=0;t<s.length;t+=3)s[t]*=e.x,s[t+1]*=e.y,s[t+2]*=e.z;return this.rapier.ColliderDesc.trimesh(s,new Uint32Array(i.getIndex().array))}if(t instanceof z){let i;t.mesh instanceof d.Mesh?i=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?i=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const s=extractFloat32Array(i.getAttribute("position"));if(t.mesh instanceof d.Mesh){const e=W(t.mesh);for(let t=0;t<s.length;t+=3)s[t]*=e.x,s[t+1]*=e.y,s[t+2]*=e.z}for(let t=0;t<s.length;t+=3)s[t]*=e.x,s[t+1]*=e.y,s[t+2]*=e.z;const o=s;o.length;return this.rapier.ColliderDesc.convexHull(o)}if(t instanceof P){const i=2*e.x-e.y-e.z;return Math.abs(i)>.01?this.createShape(new z(new d.SphereGeometry(t.radius).scale(e.x,e.y,e.z)),new b(1,1,1)):this.rapier.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z))}return t instanceof T?this.rapier.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof D?this.rapier.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof M?this.rapier.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.001):(console.error("Unsupported shape",t),this.rapier.ColliderDesc.cuboid(1,1,1))}createCharacterCollision(){return new this.rapier.CharacterCollision}};Q=t([v(),e("design:paramtypes",[])],Q);export{Q as PhysicsSystem};const X=new b,Y=new d.Quaternion;function Z(t,e){const i=e.getWorldPosition(X),s=e.getWorldQuaternion(Y);t.setTranslation(ot(i),!1),t.setRotation(nt(s),!1)}const J=new b,$=new b(1,1,1),tt=new i.Vector3(0,0,0),et=new i.Vector3(0,0,0),it=new b,st=new d.Vector2;function ot(t){return at(tt,t),tt}function nt(t){return lt(q,t),q}const rt=async()=>{let t=await import("@dimforge/rapier3d-compat");return await t.init(),t};function at(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function lt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function ct(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function dt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function ht(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const yt=new b,ut=new b,pt=t=>!t.isSensor(),gt=new b;const mt=new i.Ray(new i.Vector3(0,0,0),new i.Vector3(0,1,0));let ft=class extends j{constructor(){super(...arguments),this._active=!0,this.physics=O(Q),this.world=O(I)}set active(t){this._active=t,t?(this.world.scene.remove(this.actor.object),this.physics.setEnabled(this.actor,t)):(this.world.scene.add(this.actor.object),this.physics.setEnabled(this.actor,t))}get active(){return this._active}};ft=t([L()],ft);export function extractFloat32Array(t){const e=t.itemSize,i=t.count,s=new Float32Array(i*e);for(let o=0;o<i;o++)for(let i=0;i<e;i++)s[o*e+i]=t.getComponent(o,i);return s}const wt=new b;function Bt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e){this.collider=t,this.world=e,this.disposed=new l,this.onBeginOverlapActor=new l,this.onEndOverlapActor=new l}dispose(){this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t)}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e){this.body=t,this.world=e}dispose(){this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t)}isEnabled(){return this.body.isEnabled()}getPosition(t){const e=this.body.translation();return t.set(e.x,e.y,e.z),t}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0)}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0)}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyType.Dynamic;case PhysicsBodyType.static:return i.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return i.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static)}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{ConvexPolyhedronCollisionShape as a}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 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)){if(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")}if(e.hasAttribute("uv2")){null!=t.lightMap&&null!=t.aoMap||e.deleteAttribute("uv2")}}}/*
|
|
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
|
*/
|