@hology/core 0.0.233 → 0.0.235

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.
Files changed (150) hide show
  1. package/dist/csm.d.ts +2 -2
  2. package/dist/data/surface-definition.js +1 -1
  3. package/dist/effects/sequence/sequence-action.d.ts +4 -4
  4. package/dist/effects/sequence/sequence-animation-retiming.d.ts +1 -1
  5. package/dist/effects/sequence/sequence-data.d.ts +3 -2
  6. package/dist/effects/sequence/sequence-definitions.d.ts +2 -2
  7. package/dist/effects/sequence/sequence-event.d.ts +1 -1
  8. package/dist/effects/sequence/sequence-locator.d.ts +1 -1
  9. package/dist/effects/sequence/sequence-ops.d.ts +1 -1
  10. package/dist/effects/sequence/sequence-player.d.ts +8 -7
  11. package/dist/effects/sequence/sequence-transform.d.ts +1 -1
  12. package/dist/effects/sequence/sequence-value-lane.d.ts +2 -2
  13. package/dist/effects/vfx/behaviours.d.ts +2 -1
  14. package/dist/effects/vfx/initializsers.d.ts +2 -1
  15. package/dist/effects/vfx/rates.d.ts +1 -1
  16. package/dist/effects/vfx/trail-renderer.d.ts +1 -1
  17. package/dist/effects/vfx/vfx-asset.d.ts +4 -3
  18. package/dist/effects/vfx/vfx-binding-runtime.d.ts +2 -2
  19. package/dist/effects/vfx/vfx-collision-behaviour.d.ts +3 -2
  20. package/dist/effects/vfx/vfx-defs.d.ts +5 -3
  21. package/dist/effects/vfx/vfx-input-runtime.d.ts +1 -1
  22. package/dist/effects/vfx/vfx-materializer.d.ts +7 -7
  23. package/dist/effects/vfx/vfx-param.d.ts +3 -3
  24. package/dist/effects/vfx/vfx-renderers.d.ts +4 -3
  25. package/dist/effects/vfx/vfx-renderers.js +1 -1
  26. package/dist/effects/vfx/vfx-service.d.ts +1 -1
  27. package/dist/effects/vfx/vfx-service.js +1 -1
  28. package/dist/game-component/game-component.d.ts +1 -1
  29. package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
  30. package/dist/gameplay/actors/builtin/components/editor-sprite-component.d.ts +1 -1
  31. package/dist/gameplay/actors/builtin/components/editor-sprite-component.js +1 -1
  32. package/dist/gameplay/actors/builtin/components/volume-editor-component.d.ts +1 -1
  33. package/dist/gameplay/actors/builtin/components/volume-editor-component.js +1 -1
  34. package/dist/gameplay/actors/builtin/navmesh-actor.d.ts +1 -1
  35. package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
  36. package/dist/gameplay/actors/builtin/post-process-volume-actor.d.ts +1 -1
  37. package/dist/gameplay/actors/builtin/post-process-volume-actor.js +1 -1
  38. package/dist/gameplay/actors/component.d.ts +2 -2
  39. package/dist/gameplay/actors/controller/actor-controller.d.ts +1 -1
  40. package/dist/gameplay/actors/controller/actor-controller.js +1 -1
  41. package/dist/gameplay/actors/internal/component-init.d.ts +1 -1
  42. package/dist/gameplay/actors/internal/container-map.d.ts +2 -2
  43. package/dist/gameplay/ai/behavior-tree/move.d.ts +3 -3
  44. package/dist/gameplay/ai/behavior-tree/move.js +1 -1
  45. package/dist/gameplay/ai/build-tile.d.ts +2 -1
  46. package/dist/gameplay/ai/dynamic-tiled-navmesh.d.ts +4 -3
  47. package/dist/gameplay/ai/navigation.js +1 -1
  48. package/dist/gameplay/animation/anim-sm.d.ts +1 -1
  49. package/dist/gameplay/animation/retarget.d.ts +2 -1
  50. package/dist/gameplay/animation/root-motion.d.ts +2 -1
  51. package/dist/gameplay/event-graph/runtime-assets.d.ts +1 -1
  52. package/dist/gameplay/initiate.d.ts +5 -5
  53. package/dist/gameplay/inject.d.ts +1 -1
  54. package/dist/gameplay/net/browser/index.d.ts +3 -2
  55. package/dist/gameplay/net/browser/index.js +1 -1
  56. package/dist/gameplay/net/net-session.d.ts +2 -2
  57. package/dist/gameplay/services/asset-loader.js +1 -1
  58. package/dist/gameplay/services/game-time-scheduler.d.ts +1 -1
  59. package/dist/gameplay/services/physics/abstract-physics-system.d.ts +7 -7
  60. package/dist/gameplay/services/pointer-events.d.ts +2 -2
  61. package/dist/gameplay/services/pointer-events.js +1 -1
  62. package/dist/gameplay/services/world.d.ts +1 -1
  63. package/dist/gameplay/services/world.js +1 -1
  64. package/dist/index.d.ts +3 -3
  65. package/dist/index.js +1 -1
  66. package/dist/rendering/cluster-generator.d.ts +2 -1
  67. package/dist/rendering/fog/fog-volume-actor.d.ts +1 -1
  68. package/dist/rendering/fog/fog-volume-actor.js +1 -1
  69. package/dist/rendering/fog/fog-volume-object.d.ts +2 -1
  70. package/dist/rendering/fog/volumetric-fog-pass.d.ts +4 -2
  71. package/dist/rendering/fog/volumetric-fog-pass.js +1 -1
  72. package/dist/rendering/light-probes/light-volume-capture.d.ts +2 -1
  73. package/dist/rendering/motion-vector-node.d.ts +8 -0
  74. package/dist/rendering/motion-vector-node.js +4 -0
  75. package/dist/rendering/node-material-webgpu-resolver.d.ts +2 -1
  76. package/dist/rendering/post-process-effect.d.ts +1 -1
  77. package/dist/rendering/webgpu-experimental-backend.d.ts +23 -3
  78. package/dist/rendering/webgpu-experimental-backend.js +1 -1
  79. package/dist/rendering.d.ts +14 -2
  80. package/dist/rendering.js +1 -1
  81. package/dist/scene/asset-resource-loader.d.ts +5 -4
  82. package/dist/scene/assets-provider.d.ts +2 -2
  83. package/dist/scene/batched-mesh-2.d.ts +1 -1
  84. package/dist/scene/bootstrap.d.ts +8 -7
  85. package/dist/scene/collision/collision-shape-import.d.ts +3 -3
  86. package/dist/scene/collision/collision-shape.d.ts +2 -1
  87. package/dist/scene/custom-param-deserialize.d.ts +1 -1
  88. package/dist/scene/custom-param-runtime-types.d.ts +2 -1
  89. package/dist/scene/landscape/landscape-manager.d.ts +6 -6
  90. package/dist/scene/landscape/landscape-manager.js +1 -1
  91. package/dist/scene/landscape/utils.d.ts +2 -2
  92. package/dist/scene/materializer.js +1 -1
  93. package/dist/scene/materials/grass-foliage.d.ts +2 -2
  94. package/dist/scene/materials/grass.d.ts +1 -1
  95. package/dist/scene/materials/utils/material-painting.d.ts +2 -1
  96. package/dist/scene/materials/water.d.ts +1 -1
  97. package/dist/scene/model.d.ts +1 -1
  98. package/dist/scene/objects/prefab.d.ts +3 -3
  99. package/dist/scene/objects/shapes.d.ts +4 -2
  100. package/dist/scene/runtime-asset-service.d.ts +2 -2
  101. package/dist/scene/runtime-backend-service.d.ts +2 -2
  102. package/dist/scene/runtime-bundled-backend-service.d.ts +3 -3
  103. package/dist/scene/scatter/painted-scatter-manager.d.ts +1 -1
  104. package/dist/scene/scatter/surface-scatter-manager.d.ts +4 -4
  105. package/dist/scene/scene-data-service.d.ts +1 -1
  106. package/dist/scene/surface-query.d.ts +2 -2
  107. package/dist/scene/surface-query.js +1 -1
  108. package/dist/shader/builtin/decal-unlit-shader.js +1 -1
  109. package/dist/shader/builtin/index.d.ts +1 -1
  110. package/dist/shader/decal-shader.d.ts +3 -2
  111. package/dist/shader/graph/compiler.d.ts +1 -1
  112. package/dist/shader/parameter.d.ts +8 -8
  113. package/dist/shader/post-process-shader.d.ts +2 -1
  114. package/dist/shader/shader.d.ts +6 -5
  115. package/dist/shader/trail-shader.d.ts +3 -2
  116. package/dist/shader/trail-shader.js +1 -1
  117. package/dist/shader/uv-nodes.d.ts +2 -2
  118. package/dist/shader-nodes/bulge.d.ts +1 -1
  119. package/dist/shader-nodes/curve-sample.d.ts +2 -2
  120. package/dist/shader-nodes/depth.d.ts +3 -3
  121. package/dist/shader-nodes/dither.d.ts +1 -1
  122. package/dist/shader-nodes/effects.d.ts +1 -1
  123. package/dist/shader-nodes/glsl-node.d.ts +1 -1
  124. package/dist/shader-nodes/glsl-node.js +1 -1
  125. package/dist/shader-nodes/gradient-sample.d.ts +1 -1
  126. package/dist/shader-nodes/landscape.d.ts +1 -1
  127. package/dist/shader-nodes/layers.d.ts +1 -1
  128. package/dist/shader-nodes/material-flags.d.ts +1 -1
  129. package/dist/shader-nodes/material-flags.js +1 -1
  130. package/dist/shader-nodes/particle.d.ts +1 -1
  131. package/dist/shader-nodes/particle.js +1 -1
  132. package/dist/shader-nodes/pom.d.ts +2 -1
  133. package/dist/shader-nodes/pom.js +1 -1
  134. package/dist/shader-nodes/scene-sample.d.ts +2 -1
  135. package/dist/shader-nodes/shapes.d.ts +1 -1
  136. package/dist/shader-nodes/texture-sequence.d.ts +1 -1
  137. package/dist/shader-nodes/time.d.ts +1 -1
  138. package/dist/shader-nodes/voronoi.d.ts +1 -1
  139. package/dist/shader-nodes/wgsl-node.d.ts +1 -1
  140. package/dist/shader-nodes/wgsl-node.js +1 -1
  141. package/dist/test/parameter-definition.test.js +1 -1
  142. package/dist/utils/materials.d.ts +1 -1
  143. package/dist/utils/mesh.d.ts +1 -1
  144. package/dist/utils/obb-utils.d.ts +2 -1
  145. package/dist/utils/three/cleanup.d.ts +1 -1
  146. package/dist/utils/three/depth-pass.d.ts +1 -1
  147. package/dist/utils/three/traverse.d.ts +2 -1
  148. package/dist/worker/index.js +1 -1
  149. package/package.json +2 -1
  150. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{Ball as n,Capsule as s,Cone as o,ConvexPolyhedron as i,Cuboid as r,Cylinder as a,Heightfield as l,ShapeType as c,TriMesh as h}from"@dimforge/rapier3d-simd-compat";import{init as p}from"@recast-navigation/core";import{DebugDrawer as u,getPositionsAndIndices as d}from"@recast-navigation/three";import{BehaviorSubject as m,Subject as f,debounceTime as w,filter as b,firstValueFrom as g,takeUntil as y}from"rxjs";import*as x from"three";import{BufferGeometryUtils as v,ConvexHull as M}from"three/examples/jsm/Addons.js";import{Actor as B,BaseActor as S,Parameter as z,PhysicsSystem as A,ViewController as k,World as C,attach as j,inject as P}from"../../";import{sleepDelay as F}from"../../../utils/async";import{hasSharedArrayBufferSupport as I,toSharedFloat32Array as D,toSharedUint32Array as V}from"../../../utils/buffer";import{DynamicTiledNavMesh as G,MAX_NAV_MESH_WORKERS as N}from"../../ai/dynamic-tiled-navmesh";import{TriggerVolumeMesh as H}from"./components/volume-editor-component";var E;!function(e){e[e.none=0]="none",e[e.starting=1]="starting",e[e.started=2]="started"}(E||(E={}));let T=E.none,R=new m(!1);export async function safeRecastInit(){return T===E.none?(T=E.starting,p().then(()=>{R.next(!0),T=E.started})):g(R.pipe(b(e=>e)))}new x.Box3(new x.Vector3(-100,-100,-100),new x.Vector3(100,100,100));const U=Math.max(1,Math.min(N,(navigator.hardwareConcurrency??2)-1));let q=!1,O=class extends S{constructor(){super(...arguments),this.physics=P(A),this.view=P(k),this.world=P(C),this.editorVisualisation=j(H),this.debug=!0,this.refreshMs=4e3,this.tileSize=50,this.walkableClimb=.3,this.walkableSlopeAngle=45,this.walkableHeight=2,this.cellSize=.2,this.bounds=new x.Box3}async onInit(){q||(await safeRecastInit(),q=!0),setTimeout(()=>{this.init()},10),this.recreateInterval=setInterval(()=>{if("_hology_transform_group"===this.object.parent?.name)return;J.setFromCenterAndSize(this.position,this.object.scale).equals(this.bounds)||(this.disposed.next(!0),this.disposed=new f,this.init())},2e3)}onEndPlay(){clearInterval(this.recreateInterval)}applySceneParameters(e,t){return!(null==this.debugDrawer||!t.has("debug")||"boolean"!=typeof e.debug)&&(this.debugDrawer.visible=e.debug,!0)}init(){this.bounds.setFromCenterAndSize(this.position,this.object.scale);const e=this.bounds.max.x-this.bounds.min.x,t=this.bounds.max.z-this.bounds.min.z,n=Math.max(1,Math.min(e,t)),s=Math.min(400,Math.max(50,Math.ceil(n/2))),o=Math.max(this.cellSize,.01),i={tileSize:Math.max(32,Math.floor(s/o)),walkableClimb:this.walkableClimb/o,walkableSlopeAngle:this.walkableSlopeAngle,walkableRadius:2,walkableHeight:this.walkableHeight/o,detailSampleDist:1,minRegionArea:6,mergeRegionArea:400,cs:o,ch:o,maxSimplificationError:1.3,maxEdgeLen:200},r=new G({navMeshBounds:this.bounds,recastConfig:i,maxTiles:1024,workers:U,cacheId:"nav"+this.object.userData?.src?.id});this.navMesh=r.navMesh;const a=this.tileSize*i.cs*2,l=performance.now(),c=new Map,h=new u;h.userData.isDebugDrawer=!0,this.debugDrawer=h;r.navMesh;const p=this.bounds,m=()=>{const e=this.view.getCamera().getWorldPosition(new x.Vector3),t=new x.Box3((new x.Vector3).copy(e).subScalar(a),(new x.Vector3).copy(e).addScalar(a)),n=[],s=this.physics.world.bodies;if(null==s)return[];const o=new x.Box3;for(const e of s.getAll())for(let s=0,i=e.numColliders();s<i;s++){const i=e.collider(s);if(i.isSensor()||null!=i.parent().userData&&!0===i.parent().userData.ignoreForNavMesh)continue;const r=e.handle+","+s,a=c.get(r)?.mesh,l=a??X(i);if($(i,l),null!=l){o.copy(l.geometry.boundingBox),o.min.add(l.position),o.max.add(l.position);const e=o.intersectsBox(t)||!0,s=o.intersectsBox(this.bounds);c.set(r,{pos:i.translation(),mesh:l}),e&&s&&n.push(l)}}return n},f=new x.Box3,b=new Map,g=new Map;let v=!0,M=performance.now(),B=!1;const S=function(e,t){let n=!1;return(async()=>{for(;!n;)await e(),await F(t)})(),()=>{n=!0}}(async()=>{if(B)return;const e=new x.Box3,t=m();for(const n of t){const t=b.get(n);!0!==t?.equals(n.position)&&(null!=t&&e.expandByPoint(t),e.expandByObject(n),b.set(n,n.position.clone()))}e.min.subScalar(50),e.max.addScalar(50);const n=r.getTilesForBounds(e);n.length>500&&console.warn("Too many tiles to update. Consider increasing tile size");const s=n.slice(0,500);if(0!=s.length){const n=[];for(const s of t)f.setFromObject(s),f.intersectsBox(e)&&n.push(s);let[o,i]=d(n);i=function(e,t,n){const s=new x.Vector3,o=[];for(let i=0;i<t.length;i+=3){let r=!0;for(let o=0;o<3;o++){const a=3*t[i+o];if(s.fromArray(e,a),!n.containsPoint(s)){r=!1;break}}r&&o.push(t[i],t[i+1],t[i+2])}return new Uint32Array(o)}(o,i,p),I&&(o=D(o),i=V(i));const a=v;v=!1,await Promise.all(s.map(e=>(M=performance.now(),r.buildTile(o,i,e,a).then(()=>{const t=e[0]+","+e[1];g.set(t,(g.get(t)??0)+1),this.debug})))).then(()=>{this.debug,B=!1})}else B=!1},this.refreshMs??1e4);this.disposed.subscribe(()=>S()),r.onNavMeshUpdate.pipe(y(this.disposed),w(200)).subscribe(()=>{h.clear(),h.drawNavMesh(r.navMesh)}),console.log("Create navmesh with debug",this.debug),this.debug&&(this.object.rotation.set(0,0,0),this.object.updateMatrix(),this.object.updateMatrixWorld(),this.object.parent.add(h)),this.disposed.subscribe(()=>{r?.destroy(),h.removeFromParent(),h.dispose()});const z=performance.now()-l;z>1e3&&console.warn(`NavMesh update took ${z} ms. Consider changing tileSize or other parameter that may affect performance`)}};e([z(),t("design:type",Boolean)],O.prototype,"debug",void 0),e([z(),t("design:type",Number)],O.prototype,"walkableClimb",void 0),e([z({range:[0,89]}),t("design:type",Number)],O.prototype,"walkableSlopeAngle",void 0),e([z(),t("design:type",Number)],O.prototype,"walkableHeight",void 0),e([z({range:[.01,10]}),t("design:type",Number)],O.prototype,"cellSize",void 0),O=e([B()],O);export default O;const W=new Map,_=new WeakMap;function L(e){if(e.shape instanceof l)return function(e){const t=e.shape;if(t.type!==c.HeightField)throw new Error("The provided collider is not a height field.");let n=!1;const s=t,o=s.heights,i=s.nrows,r=s.ncols,a=s.scale.x,l=s.scale.z,h=s.scale.y,p=i+1,u=new x.PlaneGeometry(l,a,r,i);u.rotateX(-Math.PI/2);const d=u.attributes.position.array;let m=0;for(let e=0;e<p;e++)for(let t=0;t<p;t++)d[m+1]=o[t*p+e]*h,m+=3,0!=d[m+1]&&(n=!0);if(!n){const e=new x.PlaneGeometry(a,l,2,2);return e.rotateX(-Math.PI/2),e}return u}(e);if(e.shape instanceof n)return new x.SphereGeometry(e.shape.radius);if(e.shape instanceof r){const t=e.shape.halfExtents;return new x.BoxGeometry(2*t.x,2*t.y,2*t.z)}if(e.shape instanceof i){const t=function(e){const t=_.get(e);if(void 0!==t)return t;const n=new Uint32Array(e.buffer,e.byteOffset,e.byteLength>>>2);let s=2166136261;for(let e=0;e<n.length;e++)s=Math.imul(s^n[e],16777619)>>>0;return _.set(e,s),s}(e.shape.vertices);let n=W.get(t);return n||(n=function(e){const t=[];for(let n=0;n<e.length;n+=3)t.push(new x.Vector3(e[n],e[n+1],e[n+2]));const n=(new M).setFromPoints(t),s=[];n.faces.forEach(e=>{const t=e.edge.head().point,n=e.edge.next.head().point,o=e.edge.next.next.head().point;s.push(t.x,t.y,t.z),s.push(n.x,n.y,n.z),s.push(o.x,o.y,o.z)});const o=new x.BufferGeometry;return o.setAttribute("position",new x.Float32BufferAttribute(s,3)),o}(e.shape.vertices),W.set(t,n)),n}if(e.shape instanceof h){const t=e.shape.vertices,n=e.shape.indices;let s=new x.BufferGeometry;return s.setAttribute("position",new x.Float32BufferAttribute(t,3)),null!=n?s.setIndex(new x.Uint16BufferAttribute(n,1)):s=v.mergeVertices(s),s.computeVertexNormals(),s}if(e.shape instanceof a){const t=e.shape.halfHeight,n=e.shape.radius;return new x.CylinderGeometry(n,n,2*t)}if(e.shape instanceof o){const t=e.shape.halfHeight,n=e.shape.radius;return new x.ConeGeometry(n,2*t)}if(e.shape instanceof s){const t=e.shape.halfHeight,n=e.shape.radius;return new x.CapsuleGeometry(n,2*t)}return console.warn("Unsupported shape",e.shape.type,e),null}function X(e){const t=L(e);if(null==t)return null;const n=K,s=new x.Mesh(t,n);return s.geometry.computeBoundingBox(),s.geometry.scale(1.01,1.01,1.01),s}function $(e,t){const n=e.translation(),s=e.rotation();t.position.set(n.x,n.y,n.z),t.quaternion.set(s.x,s.y,s.z,s.w)}const J=new x.Box3,K=new x.MeshBasicMaterial({wireframe:!1,color:16711680,side:x.FrontSide});/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{Ball as n,Capsule as s,Cone as o,ConvexPolyhedron as i,Cuboid as r,Cylinder as a,Heightfield as l,ShapeType as c,TriMesh as h}from"@dimforge/rapier3d-simd-compat";import{init as p}from"@recast-navigation/core";import{DebugDrawer as u,getPositionsAndIndices as d}from"@recast-navigation/three";import{BehaviorSubject as m,Subject as f,debounceTime as w,filter as b,firstValueFrom as g,takeUntil as y}from"rxjs";import*as x from"three";import{BufferGeometryUtils as v,ConvexHull as M}from"three/examples/jsm/Addons.js";import{Actor as B,BaseActor as S,Parameter as z,PhysicsSystem as j,ViewController as A,World as k,attach as C,inject as P}from"../../index.js";import{sleepDelay as F}from"../../../utils/async.js";import{hasSharedArrayBufferSupport as I,toSharedFloat32Array as D,toSharedUint32Array as V}from"../../../utils/buffer.js";import{DynamicTiledNavMesh as G,MAX_NAV_MESH_WORKERS as N}from"../../ai/dynamic-tiled-navmesh.js";import{TriggerVolumeMesh as H}from"./components/volume-editor-component.js";var E;!function(e){e[e.none=0]="none",e[e.starting=1]="starting",e[e.started=2]="started"}(E||(E={}));let T=E.none,R=new m(!1);export async function safeRecastInit(){return T===E.none?(T=E.starting,p().then(()=>{R.next(!0),T=E.started})):g(R.pipe(b(e=>e)))}new x.Box3(new x.Vector3(-100,-100,-100),new x.Vector3(100,100,100));const U=Math.max(1,Math.min(N,(navigator.hardwareConcurrency??2)-1));let q=!1,O=class extends S{constructor(){super(...arguments),this.physics=P(j),this.view=P(A),this.world=P(k),this.editorVisualisation=C(H),this.debug=!0,this.refreshMs=4e3,this.tileSize=50,this.walkableClimb=.3,this.walkableSlopeAngle=45,this.walkableHeight=2,this.cellSize=.2,this.bounds=new x.Box3}async onInit(){q||(await safeRecastInit(),q=!0),setTimeout(()=>{this.init()},10),this.recreateInterval=setInterval(()=>{if("_hology_transform_group"===this.object.parent?.name)return;J.setFromCenterAndSize(this.position,this.object.scale).equals(this.bounds)||(this.disposed.next(!0),this.disposed=new f,this.init())},2e3)}onEndPlay(){clearInterval(this.recreateInterval)}applySceneParameters(e,t){return!(null==this.debugDrawer||!t.has("debug")||"boolean"!=typeof e.debug)&&(this.debugDrawer.visible=e.debug,!0)}init(){this.bounds.setFromCenterAndSize(this.position,this.object.scale);const e=this.bounds.max.x-this.bounds.min.x,t=this.bounds.max.z-this.bounds.min.z,n=Math.max(1,Math.min(e,t)),s=Math.min(400,Math.max(50,Math.ceil(n/2))),o=Math.max(this.cellSize,.01),i={tileSize:Math.max(32,Math.floor(s/o)),walkableClimb:this.walkableClimb/o,walkableSlopeAngle:this.walkableSlopeAngle,walkableRadius:2,walkableHeight:this.walkableHeight/o,detailSampleDist:1,minRegionArea:6,mergeRegionArea:400,cs:o,ch:o,maxSimplificationError:1.3,maxEdgeLen:200},r=new G({navMeshBounds:this.bounds,recastConfig:i,maxTiles:1024,workers:U,cacheId:"nav"+this.object.userData?.src?.id});this.navMesh=r.navMesh;const a=this.tileSize*i.cs*2,l=performance.now(),c=new Map,h=new u;h.userData.isDebugDrawer=!0,this.debugDrawer=h;r.navMesh;const p=this.bounds,m=()=>{const e=this.view.getCamera().getWorldPosition(new x.Vector3),t=new x.Box3((new x.Vector3).copy(e).subScalar(a),(new x.Vector3).copy(e).addScalar(a)),n=[],s=this.physics.world.bodies;if(null==s)return[];const o=new x.Box3;for(const e of s.getAll())for(let s=0,i=e.numColliders();s<i;s++){const i=e.collider(s);if(i.isSensor()||null!=i.parent().userData&&!0===i.parent().userData.ignoreForNavMesh)continue;const r=e.handle+","+s,a=c.get(r)?.mesh,l=a??X(i);if($(i,l),null!=l){o.copy(l.geometry.boundingBox),o.min.add(l.position),o.max.add(l.position);const e=o.intersectsBox(t)||!0,s=o.intersectsBox(this.bounds);c.set(r,{pos:i.translation(),mesh:l}),e&&s&&n.push(l)}}return n},f=new x.Box3,b=new Map,g=new Map;let v=!0,M=performance.now(),B=!1;const S=function(e,t){let n=!1;return(async()=>{for(;!n;)await e(),await F(t)})(),()=>{n=!0}}(async()=>{if(B)return;const e=new x.Box3,t=m();for(const n of t){const t=b.get(n);!0!==t?.equals(n.position)&&(null!=t&&e.expandByPoint(t),e.expandByObject(n),b.set(n,n.position.clone()))}e.min.subScalar(50),e.max.addScalar(50);const n=r.getTilesForBounds(e);n.length>500&&console.warn("Too many tiles to update. Consider increasing tile size");const s=n.slice(0,500);if(0!=s.length){const n=[];for(const s of t)f.setFromObject(s),f.intersectsBox(e)&&n.push(s);let[o,i]=d(n);i=function(e,t,n){const s=new x.Vector3,o=[];for(let i=0;i<t.length;i+=3){let r=!0;for(let o=0;o<3;o++){const a=3*t[i+o];if(s.fromArray(e,a),!n.containsPoint(s)){r=!1;break}}r&&o.push(t[i],t[i+1],t[i+2])}return new Uint32Array(o)}(o,i,p),I&&(o=D(o),i=V(i));const a=v;v=!1,await Promise.all(s.map(e=>(M=performance.now(),r.buildTile(o,i,e,a).then(()=>{const t=e[0]+","+e[1];g.set(t,(g.get(t)??0)+1),this.debug})))).then(()=>{this.debug,B=!1})}else B=!1},this.refreshMs??1e4);this.disposed.subscribe(()=>S()),r.onNavMeshUpdate.pipe(y(this.disposed),w(200)).subscribe(()=>{h.clear(),h.drawNavMesh(r.navMesh)}),console.log("Create navmesh with debug",this.debug),this.debug&&(this.object.rotation.set(0,0,0),this.object.updateMatrix(),this.object.updateMatrixWorld(),this.object.parent.add(h)),this.disposed.subscribe(()=>{r?.destroy(),h.removeFromParent(),h.dispose()});const z=performance.now()-l;z>1e3&&console.warn(`NavMesh update took ${z} ms. Consider changing tileSize or other parameter that may affect performance`)}};e([z(),t("design:type",Boolean)],O.prototype,"debug",void 0),e([z(),t("design:type",Number)],O.prototype,"walkableClimb",void 0),e([z({range:[0,89]}),t("design:type",Number)],O.prototype,"walkableSlopeAngle",void 0),e([z(),t("design:type",Number)],O.prototype,"walkableHeight",void 0),e([z({range:[.01,10]}),t("design:type",Number)],O.prototype,"cellSize",void 0),O=e([B()],O);export default O;const W=new Map,_=new WeakMap;function L(e){if(e.shape instanceof l)return function(e){const t=e.shape;if(t.type!==c.HeightField)throw new Error("The provided collider is not a height field.");let n=!1;const s=t,o=s.heights,i=s.nrows,r=s.ncols,a=s.scale.x,l=s.scale.z,h=s.scale.y,p=i+1,u=new x.PlaneGeometry(l,a,r,i);u.rotateX(-Math.PI/2);const d=u.attributes.position.array;let m=0;for(let e=0;e<p;e++)for(let t=0;t<p;t++)d[m+1]=o[t*p+e]*h,m+=3,0!=d[m+1]&&(n=!0);if(!n){const e=new x.PlaneGeometry(a,l,2,2);return e.rotateX(-Math.PI/2),e}return u}(e);if(e.shape instanceof n)return new x.SphereGeometry(e.shape.radius);if(e.shape instanceof r){const t=e.shape.halfExtents;return new x.BoxGeometry(2*t.x,2*t.y,2*t.z)}if(e.shape instanceof i){const t=function(e){const t=_.get(e);if(void 0!==t)return t;const n=new Uint32Array(e.buffer,e.byteOffset,e.byteLength>>>2);let s=2166136261;for(let e=0;e<n.length;e++)s=Math.imul(s^n[e],16777619)>>>0;return _.set(e,s),s}(e.shape.vertices);let n=W.get(t);return n||(n=function(e){const t=[];for(let n=0;n<e.length;n+=3)t.push(new x.Vector3(e[n],e[n+1],e[n+2]));const n=(new M).setFromPoints(t),s=[];n.faces.forEach(e=>{const t=e.edge.head().point,n=e.edge.next.head().point,o=e.edge.next.next.head().point;s.push(t.x,t.y,t.z),s.push(n.x,n.y,n.z),s.push(o.x,o.y,o.z)});const o=new x.BufferGeometry;return o.setAttribute("position",new x.Float32BufferAttribute(s,3)),o}(e.shape.vertices),W.set(t,n)),n}if(e.shape instanceof h){const t=e.shape.vertices,n=e.shape.indices;let s=new x.BufferGeometry;return s.setAttribute("position",new x.Float32BufferAttribute(t,3)),null!=n?s.setIndex(new x.Uint16BufferAttribute(n,1)):s=v.mergeVertices(s),s.computeVertexNormals(),s}if(e.shape instanceof a){const t=e.shape.halfHeight,n=e.shape.radius;return new x.CylinderGeometry(n,n,2*t)}if(e.shape instanceof o){const t=e.shape.halfHeight,n=e.shape.radius;return new x.ConeGeometry(n,2*t)}if(e.shape instanceof s){const t=e.shape.halfHeight,n=e.shape.radius;return new x.CapsuleGeometry(n,2*t)}return console.warn("Unsupported shape",e.shape.type,e),null}function X(e){const t=L(e);if(null==t)return null;const n=K,s=new x.Mesh(t,n);return s.geometry.computeBoundingBox(),s.geometry.scale(1.01,1.01,1.01),s}function $(e,t){const n=e.translation(),s=e.rotation();t.position.set(n.x,n.y,n.z),t.quaternion.set(s.x,s.y,s.z,s.w)}const J=new x.Box3,K=new x.MeshBasicMaterial({wireframe:!1,color:16711680,side:x.FrontSide});/*
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 { BaseActor } from "../..";
1
+ import { BaseActor } from "../../index.js";
2
2
  import { Texture } from 'three';
3
3
  import { Vector3 } from 'three';
4
4
  import * as THREE from 'three';
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as e}from"tslib";import{Actor as o,attach as i,BaseActor as p,Component as n,inject as r,Parameter as s}from"../..";import{Texture as a}from"three";import{tonemapMappings as d}from"../../../rendering/tone-mapping";import{OBB as l}from"three/examples/jsm/math/OBB.js";import{Vector3 as g}from"three";import*as u from"three";import{RenderingView as y}from"../../../rendering.js";import{TriggerVolumeMesh as h}from"./components/volume-editor-component.js";import{ActorComponent as m}from"../../actors/component.js";const b=[0,2],v=[-1,1];function f(t,e){return{optional:!0,type:g,group:t,label:e,range:b,precision:3,stepSize:.01,defaultValue:new g(1,1,1),editorInput:"colorGrade"}}function c(t,e){return{optional:!0,type:g,group:t,label:e,range:v,precision:3,stepSize:.01,defaultValue:new g(0,0,0),editorInput:"colorGrade"}}let w=class extends m{};t([s({options:d,optional:!0,group:"Tone Mapping",label:"Tone Mapping"}),e("design:type",Number)],w.prototype,"tonemapMapping",void 0),t([s({optional:!0,group:"Tone Mapping",label:"Tone Mapping Exposure",defaultValue:1}),e("design:type",Number)],w.prototype,"tonemapExposure",void 0),t([s({optional:!0}),e("design:type",a)],w.prototype,"envTexture",void 0),t([s({optional:!0,defaultValue:1}),e("design:type",Number)],w.prototype,"envIntensity",void 0),t([s({optional:!0,group:"Lens",defaultValue:0}),e("design:type",Number)],w.prototype,"vignetteIntensity",void 0),t([s({optional:!0,group:"Color Correction",defaultValue:new u.Color(16777215)}),e("design:type",u.Color)],w.prototype,"colorTint",void 0),t([s({optional:!0,group:"Color Correction",defaultValue:0}),e("design:type",Number)],w.prototype,"colorTintIntensity",void 0),t([s({optional:!0,group:"Depth of Field"}),e("design:type",Number)],w.prototype,"depthFocus",void 0),t([s({optional:!0,group:"Depth of Field"}),e("design:type",Number)],w.prototype,"depthAperture",void 0),t([s({optional:!0,group:"Depth of Field"}),e("design:type",Number)],w.prototype,"depthMaxBlur",void 0),t([s({optional:!0,range:[1e3,4e4],precision:.1,group:"White Balance",defaultValue:6500}),e("design:type",Number)],w.prototype,"temperature",void 0),t([s({optional:!0,range:[-1,1],group:"White Balance",defaultValue:0}),e("design:type",Number)],w.prototype,"temperatureTint",void 0),t([s(f("Global","Saturation")),e("design:type",g)],w.prototype,"globalSaturation",void 0),t([s(f("Global","Contrast")),e("design:type",g)],w.prototype,"globalContrast",void 0),t([s(f("Global","Gamma")),e("design:type",g)],w.prototype,"globalGamma",void 0),t([s(f("Global","Gain")),e("design:type",g)],w.prototype,"globalGain",void 0),t([s(c("Global","Offset")),e("design:type",g)],w.prototype,"globalOffset",void 0),t([s(f("Shadows","Saturation")),e("design:type",g)],w.prototype,"shadowsSaturation",void 0),t([s(f("Shadows","Contrast")),e("design:type",g)],w.prototype,"shadowsContrast",void 0),t([s(f("Shadows","Gamma")),e("design:type",g)],w.prototype,"shadowsGamma",void 0),t([s(f("Shadows","Gain")),e("design:type",g)],w.prototype,"shadowsGain",void 0),t([s(c("Shadows","Offset")),e("design:type",g)],w.prototype,"shadowsOffset",void 0),t([s({optional:!0,group:"Shadows",label:"Max",range:[0,1],precision:3,stepSize:.01,defaultValue:.09}),e("design:type",Number)],w.prototype,"shadowsMax",void 0),t([s(f("Midtones","Saturation")),e("design:type",g)],w.prototype,"midtonesSaturation",void 0),t([s(f("Midtones","Contrast")),e("design:type",g)],w.prototype,"midtonesContrast",void 0),t([s(f("Midtones","Gamma")),e("design:type",g)],w.prototype,"midtonesGamma",void 0),t([s(f("Midtones","Gain")),e("design:type",g)],w.prototype,"midtonesGain",void 0),t([s(c("Midtones","Offset")),e("design:type",g)],w.prototype,"midtonesOffset",void 0),t([s(f("Highlights","Saturation")),e("design:type",g)],w.prototype,"highlightsSaturation",void 0),t([s(f("Highlights","Contrast")),e("design:type",g)],w.prototype,"highlightsContrast",void 0),t([s(f("Highlights","Gamma")),e("design:type",g)],w.prototype,"highlightsGamma",void 0),t([s(f("Highlights","Gain")),e("design:type",g)],w.prototype,"highlightsGain",void 0),t([s(c("Highlights","Offset")),e("design:type",g)],w.prototype,"highlightsOffset",void 0),t([s({optional:!0,group:"Highlights",label:"Min",range:[0,1],precision:3,stepSize:.01,defaultValue:.5}),e("design:type",Number)],w.prototype,"highlightsMin",void 0),t([s({label:"LUT",optional:!0,group:"LUT"}),e("design:type",a)],w.prototype,"lut",void 0),t([s({label:"LUT Intensity",range:[0,1],optional:!0,group:"LUT",defaultValue:0}),e("design:type",Number)],w.prototype,"lutIntensity",void 0),w=t([n()],w);export{w as PostProcessSettings};let G=class extends p{constructor(){super(),this.settings=i(w),this.bounded=!1,this.priority=0,this.blendWeight=1,this.blendRadius=0,this.box=new l(void 0,new u.Vector3(.5,.5,.5)),this.view=r(y),this.editorView=i(h),this.disposed.subscribe(()=>{this.view.removePostProcessVolume(this)})}onInit(){this.view.addPostProcessVolume(this),this.editorView.visible=this.bounded}containsPoint(t){return!this.bounded||(this.resetBox(),this.box.containsPoint(t))}distanceToPoint(t){return this.bounded?(this.resetBox(),this.box.clampPoint(t,S),S.distanceTo(t)):0}resetBox(){const t=this.box;t.center.set(0,0,0),t.halfSize.set(.5,.5,.5),t.rotation.copy(x.rotation),t.applyMatrix4(this.object.matrixWorld)}};t([s(),e("design:type",Boolean)],G.prototype,"bounded",void 0),t([s({precision:0}),e("design:type",Number)],G.prototype,"priority",void 0),t([s({range:[0,1]}),e("design:type",Number)],G.prototype,"blendWeight",void 0),t([s(),e("design:type",Number)],G.prototype,"blendRadius",void 0),G=t([o(),e("design:paramtypes",[])],G);export{G as PostProcessVolume};const x=new l,S=new g;/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import{Actor as o,attach as i,BaseActor as p,Component as n,inject as r,Parameter as s}from"../../index.js";import{Texture as a}from"three";import{tonemapMappings as d}from"../../../rendering/tone-mapping.js";import{OBB as l}from"three/examples/jsm/math/OBB.js";import{Vector3 as g}from"three";import*as u from"three";import{RenderingView as y}from"../../../rendering.js";import{TriggerVolumeMesh as h}from"./components/volume-editor-component.js";import{ActorComponent as m}from"../../actors/component.js";const b=[0,2],v=[-1,1];function f(t,e){return{optional:!0,type:g,group:t,label:e,range:b,precision:3,stepSize:.01,defaultValue:new g(1,1,1),editorInput:"colorGrade"}}function c(t,e){return{optional:!0,type:g,group:t,label:e,range:v,precision:3,stepSize:.01,defaultValue:new g(0,0,0),editorInput:"colorGrade"}}let w=class extends m{};t([s({options:d,optional:!0,group:"Tone Mapping",label:"Tone Mapping"}),e("design:type",Number)],w.prototype,"tonemapMapping",void 0),t([s({optional:!0,group:"Tone Mapping",label:"Tone Mapping Exposure",defaultValue:1}),e("design:type",Number)],w.prototype,"tonemapExposure",void 0),t([s({optional:!0}),e("design:type",a)],w.prototype,"envTexture",void 0),t([s({optional:!0,defaultValue:1}),e("design:type",Number)],w.prototype,"envIntensity",void 0),t([s({optional:!0,group:"Lens",defaultValue:0}),e("design:type",Number)],w.prototype,"vignetteIntensity",void 0),t([s({optional:!0,group:"Color Correction",defaultValue:new u.Color(16777215)}),e("design:type",u.Color)],w.prototype,"colorTint",void 0),t([s({optional:!0,group:"Color Correction",defaultValue:0}),e("design:type",Number)],w.prototype,"colorTintIntensity",void 0),t([s({optional:!0,group:"Depth of Field"}),e("design:type",Number)],w.prototype,"depthFocus",void 0),t([s({optional:!0,group:"Depth of Field"}),e("design:type",Number)],w.prototype,"depthAperture",void 0),t([s({optional:!0,group:"Depth of Field"}),e("design:type",Number)],w.prototype,"depthMaxBlur",void 0),t([s({optional:!0,range:[1e3,4e4],precision:.1,group:"White Balance",defaultValue:6500}),e("design:type",Number)],w.prototype,"temperature",void 0),t([s({optional:!0,range:[-1,1],group:"White Balance",defaultValue:0}),e("design:type",Number)],w.prototype,"temperatureTint",void 0),t([s(f("Global","Saturation")),e("design:type",g)],w.prototype,"globalSaturation",void 0),t([s(f("Global","Contrast")),e("design:type",g)],w.prototype,"globalContrast",void 0),t([s(f("Global","Gamma")),e("design:type",g)],w.prototype,"globalGamma",void 0),t([s(f("Global","Gain")),e("design:type",g)],w.prototype,"globalGain",void 0),t([s(c("Global","Offset")),e("design:type",g)],w.prototype,"globalOffset",void 0),t([s(f("Shadows","Saturation")),e("design:type",g)],w.prototype,"shadowsSaturation",void 0),t([s(f("Shadows","Contrast")),e("design:type",g)],w.prototype,"shadowsContrast",void 0),t([s(f("Shadows","Gamma")),e("design:type",g)],w.prototype,"shadowsGamma",void 0),t([s(f("Shadows","Gain")),e("design:type",g)],w.prototype,"shadowsGain",void 0),t([s(c("Shadows","Offset")),e("design:type",g)],w.prototype,"shadowsOffset",void 0),t([s({optional:!0,group:"Shadows",label:"Max",range:[0,1],precision:3,stepSize:.01,defaultValue:.09}),e("design:type",Number)],w.prototype,"shadowsMax",void 0),t([s(f("Midtones","Saturation")),e("design:type",g)],w.prototype,"midtonesSaturation",void 0),t([s(f("Midtones","Contrast")),e("design:type",g)],w.prototype,"midtonesContrast",void 0),t([s(f("Midtones","Gamma")),e("design:type",g)],w.prototype,"midtonesGamma",void 0),t([s(f("Midtones","Gain")),e("design:type",g)],w.prototype,"midtonesGain",void 0),t([s(c("Midtones","Offset")),e("design:type",g)],w.prototype,"midtonesOffset",void 0),t([s(f("Highlights","Saturation")),e("design:type",g)],w.prototype,"highlightsSaturation",void 0),t([s(f("Highlights","Contrast")),e("design:type",g)],w.prototype,"highlightsContrast",void 0),t([s(f("Highlights","Gamma")),e("design:type",g)],w.prototype,"highlightsGamma",void 0),t([s(f("Highlights","Gain")),e("design:type",g)],w.prototype,"highlightsGain",void 0),t([s(c("Highlights","Offset")),e("design:type",g)],w.prototype,"highlightsOffset",void 0),t([s({optional:!0,group:"Highlights",label:"Min",range:[0,1],precision:3,stepSize:.01,defaultValue:.5}),e("design:type",Number)],w.prototype,"highlightsMin",void 0),t([s({label:"LUT",optional:!0,group:"LUT"}),e("design:type",a)],w.prototype,"lut",void 0),t([s({label:"LUT Intensity",range:[0,1],optional:!0,group:"LUT",defaultValue:0}),e("design:type",Number)],w.prototype,"lutIntensity",void 0),w=t([n()],w);export{w as PostProcessSettings};let G=class extends p{constructor(){super(),this.settings=i(w),this.bounded=!1,this.priority=0,this.blendWeight=1,this.blendRadius=0,this.box=new l(void 0,new u.Vector3(.5,.5,.5)),this.view=r(y),this.editorView=i(h),this.disposed.subscribe(()=>{this.view.removePostProcessVolume(this)})}onInit(){this.view.addPostProcessVolume(this),this.editorView.visible=this.bounded}containsPoint(t){return!this.bounded||(this.resetBox(),this.box.containsPoint(t))}distanceToPoint(t){return this.bounded?(this.resetBox(),this.box.clampPoint(t,S),S.distanceTo(t)):0}resetBox(){const t=this.box;t.center.set(0,0,0),t.halfSize.set(.5,.5,.5),t.rotation.copy(x.rotation),t.applyMatrix4(this.object.matrixWorld)}};t([s(),e("design:type",Boolean)],G.prototype,"bounded",void 0),t([s({precision:0}),e("design:type",Number)],G.prototype,"priority",void 0),t([s({range:[0,1]}),e("design:type",Number)],G.prototype,"blendWeight",void 0),t([s(),e("design:type",Number)],G.prototype,"blendRadius",void 0),G=t([o(),e("design:paramtypes",[])],G);export{G as PostProcessVolume};const x=new l,S=new g;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,5 @@
1
- import { Constructable } from 'typedi';
2
- import { BaseActor } from './actor.js';
1
+ import type { Constructable } from 'typedi';
2
+ import type { BaseActor } from './actor.js';
3
3
  export { getComponentClassById, getComponentClassId, getRegisteredComponentClasses, } from './type-registry.js';
4
4
  export type ActorComponentParams<T extends ActorComponent> = {
5
5
  [K in Exclude<keyof T, keyof ActorComponent> as T[K] extends (...args: any[]) => any ? never : K]: T[K];
@@ -1,4 +1,4 @@
1
- import { BaseActor } from "../actor";
1
+ import { BaseActor } from "../actor.js";
2
2
  export declare abstract class ActorController extends BaseActor {
3
3
  isLocallyControlled: boolean;
4
4
  }
@@ -1,4 +1,4 @@
1
- import{BaseActor as o}from"../actor";export class ActorController extends o{constructor(){super(...arguments),this.isLocallyControlled=!1}}export class BasePlayerController extends ActorController{constructor(){super(...arguments),this.isLocallyControlled=!1}}export class BaseAIController extends ActorController{constructor(){super(...arguments),this.isLocallyControlled=!1}}/*
1
+ import{BaseActor as o}from"../actor.js";export class ActorController extends o{constructor(){super(...arguments),this.isLocallyControlled=!1}}export class BasePlayerController extends ActorController{constructor(){super(...arguments),this.isLocallyControlled=!1}}export class BaseAIController extends ActorController{constructor(){super(...arguments),this.isLocallyControlled=!1}}/*
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 { BaseActor } from '../actor.js';
1
+ import type { BaseActor } from '../actor.js';
2
2
  import { ActorComponent } from '../component.js';
3
3
  export declare function initComponents(a: BaseActor | ActorComponent, actor: BaseActor, inEditor?: boolean): Promise<any[]>;
4
4
  export declare function initComponentsSync(a: BaseActor | ActorComponent, actor: BaseActor, inEditor?: boolean): void;
@@ -1,5 +1,5 @@
1
- import { ContainerInstance } from "typedi";
2
- import { BaseActor } from '../actor.js';
1
+ import type { ContainerInstance } from "typedi";
2
+ import type { BaseActor } from '../actor.js';
3
3
  export declare const containerRefMap: WeakMap<BaseActor, ContainerInstance>;
4
4
  export declare const activeContainerInstance: {
5
5
  value: any;
@@ -1,7 +1,7 @@
1
1
  import { Vector3 } from "three";
2
- import type { CharacterMovementLike } from "../../../gameplay/actors";
3
- import { Navigation } from "../navigation";
4
- import { LeafNode, NodeState } from "./bt";
2
+ import type { CharacterMovementLike } from "../../../gameplay/actors/index.js";
3
+ import type { Navigation } from "../navigation.js";
4
+ import { LeafNode, NodeState } from "./bt.js";
5
5
  export declare class CharacterMoveToNode extends LeafNode {
6
6
  private navigation;
7
7
  private movement;
@@ -1,4 +1,4 @@
1
- import{Vector3 as t}from"three";import{LeafNode as e,NodeState as o}from"./bt";export class CharacterMoveToNode extends e{constructor(t,e){super(),this.navigation=t,this.movement=e,this.distanceFrom=.5}tick(t){const e=this.movement.actor.object.position,i=null!=this.target?this.target():null;if(null==i)return this.movement.directionInput.vector.set(0,0),o.FAILURE;if(e.distanceTo(i)<this.distanceFrom)return this.movement.directionInput.vector.set(0,0),o.SUCCESS;const{success:r,path:s}=this.navigation.findPath(e,i);if(!r||s.length<2)return o.FAILURE;const c=s[1],a=n.subVectors(c,e);return a.y=0,a.normalize(),this.movement.rotationInput.rotation.y=Math.atan2(a.x,a.z),this.movement.directionInput.togglePositiveY(!0),o.RUNNING}}const n=new t;/*
1
+ import{Vector3 as t}from"three";import{LeafNode as e,NodeState as o}from"./bt.js";export class CharacterMoveToNode extends e{constructor(t,e){super(),this.navigation=t,this.movement=e,this.distanceFrom=.5}tick(t){const e=this.movement.actor.object.position,i=null!=this.target?this.target():null;if(null==i)return this.movement.directionInput.vector.set(0,0),o.FAILURE;if(e.distanceTo(i)<this.distanceFrom)return this.movement.directionInput.vector.set(0,0),o.SUCCESS;const{success:s,path:r}=this.navigation.findPath(e,i);if(!s||r.length<2)return o.FAILURE;const c=r[1],a=n.subVectors(c,e);return a.y=0,a.normalize(),this.movement.rotationInput.rotation.y=Math.atan2(a.x,a.z),this.movement.directionInput.togglePositiveY(!0),o.RUNNING}}const n=new t;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,5 @@
1
- import { RecastBuildContext, RecastCompactHeightfield, RecastConfig, RecastContourSet, RecastHeightfield, UnsignedCharArray, Vector3Tuple } from '@recast-navigation/core';
1
+ import type { RecastCompactHeightfield, RecastConfig, RecastContourSet, RecastHeightfield, UnsignedCharArray, Vector3Tuple } from '@recast-navigation/core';
2
+ import { RecastBuildContext } from '@recast-navigation/core';
2
3
  type BuildConfigProps = {
3
4
  recastConfig: RecastConfig;
4
5
  navMeshBounds: [min: Vector3Tuple, max: Vector3Tuple];
@@ -1,6 +1,7 @@
1
- import { NavMesh, RecastConfig, Vector3Tuple } from 'recast-navigation';
2
- import * as THREE from 'three';
3
- import { BuildTileMeshProps } from './build-tile.js';
1
+ import type { RecastConfig, Vector3Tuple } from 'recast-navigation';
2
+ import { NavMesh } from 'recast-navigation';
3
+ import type * as THREE from 'three';
4
+ import type { BuildTileMeshProps } from './build-tile.js';
4
5
  import { Subject } from 'rxjs';
5
6
  export type DynamicTiledNavMeshProps = {
6
7
  navMeshBounds: THREE.Box3;
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{NavMeshQuery as n}from"recast-navigation";import{Vector3 as s}from"three";import{inject as r,Service as o,World as i}from"../";import u,{safeRecastInit as a}from"../actors/builtin/navmesh-actor";let h=class{constructor(){this.world=r(i),a().then(()=>{const e=this.world.actors.find(e=>e instanceof u);null!=e&&(this.navMeshActor=e,this.query=null),this.world.actorAdded.subscribe(e=>{e instanceof u&&(this.navMeshActor=e,this.query=null)}),this.world.actorRemoved.subscribe(e=>{e instanceof u&&e.id===this.navMeshActor?.id&&(this.navMeshActor=null,this.query=null)})})}ensureQuery(){null==this.query&&null!=this.navMeshActor&&null!=this.navMeshActor.navMesh&&(this.query=new n(this.navMeshActor.navMesh))}findPath(e,t){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),c;const n=this.findClosestPoint(e);if(null==n)return d("Start point could not be found on NavMesh",e),c;const{success:r,error:o,path:i}=this.query.computePath(n,t);return r?{success:!0,path:i.map(e=>new s(e.x,e.y,e.z))}:(d("Failed to generate path",o),c)}findClosestPoint(e){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),null;const{success:t,point:n}=this.query.findClosestPoint(e);return t?new s(n.x,n.y,n.z):null}findRandomPoint(){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),null;const e=this.query.findRandomPoint();return{success:e.success,randomPoint:(new s).copy(e.randomPoint)}}findRandomPointAroundCircle(e,t){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),null;const n=this.query.findRandomPointAroundCircle(e,t);return{success:n.success,randomPoint:(new s).copy(n.randomPoint)}}};h=e([o(),t("design:paramtypes",[])],h);export{h as Navigation};const c={success:!1,path:[]};let l=new Set;function d(e,...t){l.has(e)||(l.add(e),setTimeout(()=>l.delete(e),2e3),console.warn(e,...t))}/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{NavMeshQuery as n}from"recast-navigation";import{Vector3 as s}from"three";import{inject as r,Service as o,World as i}from"../index.js";import u,{safeRecastInit as a}from"../actors/builtin/navmesh-actor.js";let h=class{constructor(){this.world=r(i),a().then(()=>{const e=this.world.actors.find(e=>e instanceof u);null!=e&&(this.navMeshActor=e,this.query=null),this.world.actorAdded.subscribe(e=>{e instanceof u&&(this.navMeshActor=e,this.query=null)}),this.world.actorRemoved.subscribe(e=>{e instanceof u&&e.id===this.navMeshActor?.id&&(this.navMeshActor=null,this.query=null)})})}ensureQuery(){null==this.query&&null!=this.navMeshActor&&null!=this.navMeshActor.navMesh&&(this.query=new n(this.navMeshActor.navMesh))}findPath(e,t){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),c;const n=this.findClosestPoint(e);if(null==n)return d("Start point could not be found on NavMesh",e),c;const{success:r,error:o,path:i}=this.query.computePath(n,t);return r?{success:!0,path:i.map(e=>new s(e.x,e.y,e.z))}:(d("Failed to generate path",o),c)}findClosestPoint(e){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),null;const{success:t,point:n}=this.query.findClosestPoint(e);return t?new s(n.x,n.y,n.z):null}findRandomPoint(){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),null;const e=this.query.findRandomPoint();return{success:e.success,randomPoint:(new s).copy(e.randomPoint)}}findRandomPointAroundCircle(e,t){if(this.ensureQuery(),null==this.query)return d("NavMesh has not been generated yet"),null;const n=this.query.findRandomPointAroundCircle(e,t);return{success:n.success,randomPoint:(new s).copy(n.randomPoint)}}};h=e([o(),t("design:paramtypes",[])],h);export{h as Navigation};const c={success:!1,path:[]};let l=new Set;function d(e,...t){l.has(e)||(l.add(e),setTimeout(()=>l.delete(e),2e3),console.warn(e,...t))}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import { AnimationClip } from "three";
1
+ import type { AnimationClip } from "three";
2
2
  type TransitionPredicate = (timeElapsed: number) => boolean;
3
3
  declare class Transition {
4
4
  readonly state: AnimationState;
@@ -1,4 +1,5 @@
1
- import { AnimationClip, Object3D, Quaternion } from 'three';
1
+ import type { Object3D } from 'three';
2
+ import { AnimationClip, Quaternion } from 'three';
2
3
  import type { AnimationRetargetPose, AnimationRetargeterData, AnimationRigChain, AnimationRigData, Asset, AssetId } from '../../scene/model.js';
3
4
  export declare const ANIMATION_RETARGET_GENERATOR_VERSION = 9;
4
5
  export type ExtractedAnimationRig = Omit<AnimationRigData, 'previewMeshId'>;
@@ -1,4 +1,5 @@
1
- import { AnimationClip, VectorKeyframeTrack, Bone, Object3D } from "three";
1
+ import type { VectorKeyframeTrack, Bone, Object3D } from "three";
2
+ import { AnimationClip } from "three";
2
3
  export declare class RootMotionClip extends AnimationClip {
3
4
  motionTrack: VectorKeyframeTrack;
4
5
  displacement: number;
@@ -1,4 +1,4 @@
1
- import { Euler, Vector3 } from 'three';
1
+ import type { Euler, Vector3 } from 'three';
2
2
  import { PrefabInstance } from '../../scene/objects/prefab.js';
3
3
  import { BaseActor } from '../actors/actor.js';
4
4
  import type { AssetsProvider } from '../../scene/assets-provider.js';
@@ -1,10 +1,10 @@
1
- import { Constructable, ContainerInstance } from "typedi";
2
- import { ShaderType, ActorType, ActorComponentType } from '../shader/shader.js';
1
+ import type { Constructable, ContainerInstance } from "typedi";
2
+ import type { ShaderType, ActorType, ActorComponentType } from '../shader/shader.js';
3
3
  import { World } from './services/world.js';
4
4
  import { type DynamicResolutionOptions, type ExperimentalWebGpuPostProcessingOptions, type RenderingBackend, type UpscalingOptions } from '../rendering.js';
5
- import { Observable } from 'rxjs';
6
- import { DetailTier } from "../scene/model.js";
7
- import { NetSession } from "./net/net-session.js";
5
+ import type { Observable } from 'rxjs';
6
+ import type { DetailTier } from "../scene/model.js";
7
+ import type { NetSession } from "./net/net-session.js";
8
8
  import type { ParameterType } from "../shader/parameter.js";
9
9
  type GameClass<T> = Constructable<T>;
10
10
  export type InitiateGameConfig = {
@@ -1,4 +1,4 @@
1
- import { ContainerInstance } from 'typedi';
1
+ import type { ContainerInstance } from 'typedi';
2
2
  type Constructable<T> = abstract new (...args: any[]) => T;
3
3
  export declare function inject<T>(type: Constructable<T>): T;
4
4
  export declare function withInjectionContext<T>(containerInstance: ContainerInstance, fn: (diContainer: ContainerInstance) => T): T;
@@ -1,6 +1,7 @@
1
1
  import { BehaviorSubject, Subject } from 'rxjs';
2
- import { NetReceivedMessage, NetSession, NetMode } from '../net-session';
3
- import { NetConnection } from '../net-connection';
2
+ import type { NetReceivedMessage, NetSession } from '../net-session.js';
3
+ import { NetMode } from '../net-session.js';
4
+ import type { NetConnection } from '../net-connection.js';
4
5
  export type BrowserNetSimulationOptions = {
5
6
  /**
6
7
  * Fixed one-way latency applied to outgoing messages from this session.
@@ -1,4 +1,4 @@
1
- import{BehaviorSubject as e,Subject as s}from"rxjs";import{NetMode as t}from"../net-session";const n=0,i=0,r=0,o=0;export class BrowserNetSession{get isClient(){return this.mode===t.client}get isServer(){return this.mode<t.client}get isDedicatedServer(){return this.mode===t.dedicatedServer}get clients(){return this.isServer?this.currentMembers().filter(e=>e.mode===t.client).map(e=>a(e)):[]}get server(){if(!this.isServer){const e=this.currentMembers().find(e=>e.mode<t.client);if(null!=e)return a(e)}return null}constructor(t,n,i,r={}){this.sessionId=n,this.localId=i,this.playerLeft=new s,this.playerJoined=new s,this.receivedMessageCount=new e(0),this.storageKey=`net_session_${this.sessionId}`,this.channelName=`net_session_${this.sessionId}`,this.connected=!1,this.storage=null,this.channel=null,this.heartbeatTimer=null,this.receivedMessages=[],this.knownMemberIds=new Set,this.pendingDeliveryTimers=new Set,this.reliableQueues=new Map,this.messageSequence=0,this.onStorage=e=>{if(e.key!==this.storageKey)return;const s=this.getLocalStorage();this.setMembers(s?.members??[],!0)},this.onChannelMessage=e=>{const s=e.data;if(function(e){if(null==e||"object"!=typeof e)return!1;const s=e.kind;return"join"===s||"leave"===s||"heartbeat"===s||"members-request"===s||"members"===s||"message"===s}(s)&&s.sessionId===this.sessionId&&s.sourceConnectionId!==this.localId)switch(s.kind){case"join":case"heartbeat":this.mergeMember(s.member,!0);break;case"leave":this.removeMember(s.member.connectionId,!0);break;case"members-request":this.broadcast({kind:"members",sessionId:this.sessionId,sourceConnectionId:this.localId,members:this.currentMembers()});break;case"members":this.setMembers([...this.currentMembers(),...s.members],!0);break;case"message":this.mergeMember(s.fromMember,!0),s.message.toConnectionId===this.localId&&this.enqueueReceivedMessage(s.message)}},this.onBeforeUnload=()=>{this.disconnect()},this.onUnload=()=>{this.disconnect()},this.mode=t,this.id=n,this.simulation=l(r),this.heartbeatIntervalMs=Math.max(0,r.heartbeatIntervalMs??2e3),this.memberTimeoutMs=Math.max(1,r.memberTimeoutMs??1e4),this.maxQueuedMessages=Math.max(1,r.maxQueuedMessages??1e4)}configureNetworkSimulation(e){this.simulation=l({...this.simulation,...e})}reconnect(){this.disconnect(),this.connect()}disconnect(){this.connected&&this.broadcast({kind:"leave",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.stopHeartbeat(),this.cancelPendingDeliveries(),this.connected&&(window.removeEventListener("storage",this.onStorage),window.removeEventListener("beforeunload",this.onBeforeUnload),window.removeEventListener("unload",this.onUnload),this.channel?.removeEventListener("message",this.onChannelMessage),this.channel?.close(),this.channel=null,this.connected=!1);const e=this.getLocalStorage(),s=(e?.members??this.storage?.members??[]).filter(e=>e.connectionId!==this.localId);this.writeLocalStorage({members:this.activeMembers(s)}),this.storage=null,this.knownMemberIds.clear(),this.receivedMessages=[],this.receivedMessageCount.next(0)}sendMessage(e,s,t){const n=function(e){const s=(e.id,Number(e.id));return Number.isFinite(s)?s:null}(e);if(null==n)return void console.error(`BrowserNetSession can only send to numeric connection ids. Received ${e.id}`);const i={id:this.createMessageId(),fromConnectionId:this.localId,toConnectionId:n,reliable:s,sentAt:Date.now(),buffer:c(t)};this.sendOrSimulateMessage(i,s)}hasMessage(){return this.receivedMessages.length}readMessage(){const e=this.consumeMessage();if(null!=e){const s=this.connectionForMessage(e);return null==s?(console.error(`No connection found with id ${e.fromConnectionId}`),null):{from:s,buffer:e.buffer}}return null}connect(){if(this.connected)return;if("undefined"==typeof BroadcastChannel)throw new Error("BrowserNetSession requires BroadcastChannel support");this.channel=new BroadcastChannel(this.channelName),this.channel.addEventListener("message",this.onChannelMessage),window.addEventListener("storage",this.onStorage),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("unload",this.onUnload),this.connected=!0;const e=this.getLocalStorage()??{members:[]},s=this.activeMembers([...e.members,this.createLocalMember()]);this.setMembers(s,!1),this.writeLocalStorage({members:s}),this.broadcast({kind:"join",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.broadcast({kind:"members-request",sessionId:this.sessionId,sourceConnectionId:this.localId}),this.startHeartbeat()}sendOrSimulateMessage(e,s){if(this.shouldDropMessage(s))return;if(s)return void this.enqueueReliableDelivery(e);const t=this.simulatedDelayMs();if(t<=0)return void this.deliverMessage(e);const n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),this.deliverMessage(e)},t);this.pendingDeliveryTimers.add(n)}deliverMessage(e){e.toConnectionId!==this.localId?this.broadcast({kind:"message",sessionId:this.sessionId,sourceConnectionId:this.localId,fromMember:this.createLocalMember(),message:e}):this.enqueueReceivedMessage(e)}enqueueReceivedMessage(e){this.receivedMessages.length>=this.maxQueuedMessages&&this.receivedMessages.shift(),this.receivedMessages.push(e),this.receivedMessageCount.next(this.receivedMessages.length)}consumeMessage(){const e=this.receivedMessages.shift()??null;return this.receivedMessageCount.next(this.receivedMessages.length),e}connectionForMessage(e){const s=this.server;if(s?.id===e.fromConnectionId)return s;const t=this.clients.find(s=>s.id===e.fromConnectionId);if(null!=t)return t;const n=this.currentMembers().find(s=>s.connectionId===e.fromConnectionId);return null!=n?a(n):null}enqueueReliableDelivery(e){const s=this.simulatedDelayMs(),t=this.reliableQueues.get(e.toConnectionId);if((null==t||0===t.messages.length)&&s<=0)return void this.deliverMessage(e);const n=Date.now(),i=t??{messages:[],timer:null},r=i.messages[i.messages.length-1]?.deliveryAt??n,o=Math.max(n+s,r);i.messages.push({message:e,deliveryAt:o}),this.reliableQueues.set(e.toConnectionId,i),this.scheduleReliableDelivery(e.toConnectionId,i)}scheduleReliableDelivery(e,s){if(null!=s.timer||0===s.messages.length)return;const t=Math.max(0,s.messages[0].deliveryAt-Date.now()),n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),s.timer=null,this.flushReliableDelivery(e)},t);s.timer=n,this.pendingDeliveryTimers.add(n)}flushReliableDelivery(e){const s=this.reliableQueues.get(e);if(null==s)return;const t=Date.now();for(;s.messages.length>0&&s.messages[0].deliveryAt<=t+1;)this.deliverMessage(s.messages.shift().message);s.messages.length>0?this.scheduleReliableDelivery(e,s):this.reliableQueues.delete(e)}shouldDropMessage(e){const s=e?this.simulation.reliablePacketLoss:this.simulation.packetLoss;return s>0&&Math.random()<s}simulatedDelayMs(){const e=this.simulation.jitterMs>0?(2*Math.random()-1)*this.simulation.jitterMs:0;return Math.max(0,this.simulation.latencyMs+e)}startHeartbeat(){this.heartbeatIntervalMs<=0||null!=this.heartbeatTimer||(this.heartbeatTimer=window.setInterval(()=>{const e=this.activeMembers([...this.currentMembers(),this.createLocalMember()]);this.setMembers(e,!0),this.writeLocalStorage({members:e}),this.broadcast({kind:"heartbeat",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()})},this.heartbeatIntervalMs))}stopHeartbeat(){null!=this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}cancelPendingDeliveries(){this.pendingDeliveryTimers.forEach(e=>clearTimeout(e)),this.pendingDeliveryTimers.clear(),this.reliableQueues.clear()}mergeMember(e,s){this.setMembers([...this.currentMembers(),e],s)}removeMember(e,s){this.setMembers(this.currentMembers().filter(s=>s.connectionId!==e),s)}setMembers(e,s){const t=this.storage?.members??[],n=this.activeMembers(this.connected?[...e,this.createLocalMember()]:e);if(s){const e=new Set(n.map(e=>e.connectionId));n.filter(e=>e.connectionId!==this.localId&&!this.knownMemberIds.has(e.connectionId)).forEach(e=>this.playerJoined.next(a(e))),this.knownMemberIds.forEach(s=>{if(s===this.localId||e.has(s))return;const n=t.find(e=>e.connectionId===s);null!=n&&this.playerLeft.next(a(n))})}this.storage={members:n},this.knownMemberIds.clear(),n.forEach(e=>this.knownMemberIds.add(e.connectionId))}currentMembers(){return this.activeMembers(this.storage?.members??this.getLocalStorage()?.members??[])}activeMembers(e){const s=Date.now();return function(e){const s=new Map;for(const t of e){if(!Number.isFinite(t.connectionId))continue;const e=s.get(t.connectionId);(null==e||(t.lastSeenAt??0)>=(e.lastSeenAt??0))&&s.set(t.connectionId,t)}return[...s.values()].sort((e,s)=>e.connectionId-s.connectionId)}(e).filter(e=>e.connectionId===this.localId||null!=e.lastSeenAt&&s-e.lastSeenAt<=this.memberTimeoutMs)}createLocalMember(){return{connectionId:this.localId,mode:this.mode,player:{id:this.localId.toString()},lastSeenAt:Date.now()}}createMessageId(){const e=window.crypto?.randomUUID;return"function"==typeof e?e.call(window.crypto):`${this.localId}-${Date.now()}-${this.messageSequence++}`}broadcast(e){this.channel?.postMessage(e)}getLocalStorage(){const e=localStorage.getItem(this.storageKey);if(null!=e)try{const s=JSON.parse(e);if(Array.isArray(s?.members))return{members:s.members}}catch(e){console.warn(`Failed to parse browser net session ${this.sessionId}`,e)}return null}writeLocalStorage(e){const s=this.activeMembers(e.members);0!==s.length?localStorage.setItem(this.storageKey,JSON.stringify({members:s})):localStorage.removeItem(this.storageKey)}}function a(e){return{id:e.connectionId,player:e.player}}function c(e){const s=new Uint8Array(e),t=new Uint8Array(s.byteLength);return t.set(s),t.buffer}function l(e){return{latencyMs:Math.max(0,e.latencyMs??n),jitterMs:Math.max(0,e.jitterMs??i),packetLoss:h(e.packetLoss??r),reliablePacketLoss:h(e.reliablePacketLoss??o)}}function h(e){return Math.min(1,Math.max(0,e))}/*
1
+ import{BehaviorSubject as e,Subject as s}from"rxjs";import{NetMode as t}from"../net-session.js";const n=0,i=0,r=0,o=0;export class BrowserNetSession{get isClient(){return this.mode===t.client}get isServer(){return this.mode<t.client}get isDedicatedServer(){return this.mode===t.dedicatedServer}get clients(){return this.isServer?this.currentMembers().filter(e=>e.mode===t.client).map(e=>a(e)):[]}get server(){if(!this.isServer){const e=this.currentMembers().find(e=>e.mode<t.client);if(null!=e)return a(e)}return null}constructor(t,n,i,r={}){this.sessionId=n,this.localId=i,this.playerLeft=new s,this.playerJoined=new s,this.receivedMessageCount=new e(0),this.storageKey=`net_session_${this.sessionId}`,this.channelName=`net_session_${this.sessionId}`,this.connected=!1,this.storage=null,this.channel=null,this.heartbeatTimer=null,this.receivedMessages=[],this.knownMemberIds=new Set,this.pendingDeliveryTimers=new Set,this.reliableQueues=new Map,this.messageSequence=0,this.onStorage=e=>{if(e.key!==this.storageKey)return;const s=this.getLocalStorage();this.setMembers(s?.members??[],!0)},this.onChannelMessage=e=>{const s=e.data;if(function(e){if(null==e||"object"!=typeof e)return!1;const s=e.kind;return"join"===s||"leave"===s||"heartbeat"===s||"members-request"===s||"members"===s||"message"===s}(s)&&s.sessionId===this.sessionId&&s.sourceConnectionId!==this.localId)switch(s.kind){case"join":case"heartbeat":this.mergeMember(s.member,!0);break;case"leave":this.removeMember(s.member.connectionId,!0);break;case"members-request":this.broadcast({kind:"members",sessionId:this.sessionId,sourceConnectionId:this.localId,members:this.currentMembers()});break;case"members":this.setMembers([...this.currentMembers(),...s.members],!0);break;case"message":this.mergeMember(s.fromMember,!0),s.message.toConnectionId===this.localId&&this.enqueueReceivedMessage(s.message)}},this.onBeforeUnload=()=>{this.disconnect()},this.onUnload=()=>{this.disconnect()},this.mode=t,this.id=n,this.simulation=l(r),this.heartbeatIntervalMs=Math.max(0,r.heartbeatIntervalMs??2e3),this.memberTimeoutMs=Math.max(1,r.memberTimeoutMs??1e4),this.maxQueuedMessages=Math.max(1,r.maxQueuedMessages??1e4)}configureNetworkSimulation(e){this.simulation=l({...this.simulation,...e})}reconnect(){this.disconnect(),this.connect()}disconnect(){this.connected&&this.broadcast({kind:"leave",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.stopHeartbeat(),this.cancelPendingDeliveries(),this.connected&&(window.removeEventListener("storage",this.onStorage),window.removeEventListener("beforeunload",this.onBeforeUnload),window.removeEventListener("unload",this.onUnload),this.channel?.removeEventListener("message",this.onChannelMessage),this.channel?.close(),this.channel=null,this.connected=!1);const e=this.getLocalStorage(),s=(e?.members??this.storage?.members??[]).filter(e=>e.connectionId!==this.localId);this.writeLocalStorage({members:this.activeMembers(s)}),this.storage=null,this.knownMemberIds.clear(),this.receivedMessages=[],this.receivedMessageCount.next(0)}sendMessage(e,s,t){const n=function(e){const s=(e.id,Number(e.id));return Number.isFinite(s)?s:null}(e);if(null==n)return void console.error(`BrowserNetSession can only send to numeric connection ids. Received ${e.id}`);const i={id:this.createMessageId(),fromConnectionId:this.localId,toConnectionId:n,reliable:s,sentAt:Date.now(),buffer:c(t)};this.sendOrSimulateMessage(i,s)}hasMessage(){return this.receivedMessages.length}readMessage(){const e=this.consumeMessage();if(null!=e){const s=this.connectionForMessage(e);return null==s?(console.error(`No connection found with id ${e.fromConnectionId}`),null):{from:s,buffer:e.buffer}}return null}connect(){if(this.connected)return;if("undefined"==typeof BroadcastChannel)throw new Error("BrowserNetSession requires BroadcastChannel support");this.channel=new BroadcastChannel(this.channelName),this.channel.addEventListener("message",this.onChannelMessage),window.addEventListener("storage",this.onStorage),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("unload",this.onUnload),this.connected=!0;const e=this.getLocalStorage()??{members:[]},s=this.activeMembers([...e.members,this.createLocalMember()]);this.setMembers(s,!1),this.writeLocalStorage({members:s}),this.broadcast({kind:"join",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.broadcast({kind:"members-request",sessionId:this.sessionId,sourceConnectionId:this.localId}),this.startHeartbeat()}sendOrSimulateMessage(e,s){if(this.shouldDropMessage(s))return;if(s)return void this.enqueueReliableDelivery(e);const t=this.simulatedDelayMs();if(t<=0)return void this.deliverMessage(e);const n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),this.deliverMessage(e)},t);this.pendingDeliveryTimers.add(n)}deliverMessage(e){e.toConnectionId!==this.localId?this.broadcast({kind:"message",sessionId:this.sessionId,sourceConnectionId:this.localId,fromMember:this.createLocalMember(),message:e}):this.enqueueReceivedMessage(e)}enqueueReceivedMessage(e){this.receivedMessages.length>=this.maxQueuedMessages&&this.receivedMessages.shift(),this.receivedMessages.push(e),this.receivedMessageCount.next(this.receivedMessages.length)}consumeMessage(){const e=this.receivedMessages.shift()??null;return this.receivedMessageCount.next(this.receivedMessages.length),e}connectionForMessage(e){const s=this.server;if(s?.id===e.fromConnectionId)return s;const t=this.clients.find(s=>s.id===e.fromConnectionId);if(null!=t)return t;const n=this.currentMembers().find(s=>s.connectionId===e.fromConnectionId);return null!=n?a(n):null}enqueueReliableDelivery(e){const s=this.simulatedDelayMs(),t=this.reliableQueues.get(e.toConnectionId);if((null==t||0===t.messages.length)&&s<=0)return void this.deliverMessage(e);const n=Date.now(),i=t??{messages:[],timer:null},r=i.messages[i.messages.length-1]?.deliveryAt??n,o=Math.max(n+s,r);i.messages.push({message:e,deliveryAt:o}),this.reliableQueues.set(e.toConnectionId,i),this.scheduleReliableDelivery(e.toConnectionId,i)}scheduleReliableDelivery(e,s){if(null!=s.timer||0===s.messages.length)return;const t=Math.max(0,s.messages[0].deliveryAt-Date.now()),n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),s.timer=null,this.flushReliableDelivery(e)},t);s.timer=n,this.pendingDeliveryTimers.add(n)}flushReliableDelivery(e){const s=this.reliableQueues.get(e);if(null==s)return;const t=Date.now();for(;s.messages.length>0&&s.messages[0].deliveryAt<=t+1;)this.deliverMessage(s.messages.shift().message);s.messages.length>0?this.scheduleReliableDelivery(e,s):this.reliableQueues.delete(e)}shouldDropMessage(e){const s=e?this.simulation.reliablePacketLoss:this.simulation.packetLoss;return s>0&&Math.random()<s}simulatedDelayMs(){const e=this.simulation.jitterMs>0?(2*Math.random()-1)*this.simulation.jitterMs:0;return Math.max(0,this.simulation.latencyMs+e)}startHeartbeat(){this.heartbeatIntervalMs<=0||null!=this.heartbeatTimer||(this.heartbeatTimer=window.setInterval(()=>{const e=this.activeMembers([...this.currentMembers(),this.createLocalMember()]);this.setMembers(e,!0),this.writeLocalStorage({members:e}),this.broadcast({kind:"heartbeat",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()})},this.heartbeatIntervalMs))}stopHeartbeat(){null!=this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}cancelPendingDeliveries(){this.pendingDeliveryTimers.forEach(e=>clearTimeout(e)),this.pendingDeliveryTimers.clear(),this.reliableQueues.clear()}mergeMember(e,s){this.setMembers([...this.currentMembers(),e],s)}removeMember(e,s){this.setMembers(this.currentMembers().filter(s=>s.connectionId!==e),s)}setMembers(e,s){const t=this.storage?.members??[],n=this.activeMembers(this.connected?[...e,this.createLocalMember()]:e);if(s){const e=new Set(n.map(e=>e.connectionId));n.filter(e=>e.connectionId!==this.localId&&!this.knownMemberIds.has(e.connectionId)).forEach(e=>this.playerJoined.next(a(e))),this.knownMemberIds.forEach(s=>{if(s===this.localId||e.has(s))return;const n=t.find(e=>e.connectionId===s);null!=n&&this.playerLeft.next(a(n))})}this.storage={members:n},this.knownMemberIds.clear(),n.forEach(e=>this.knownMemberIds.add(e.connectionId))}currentMembers(){return this.activeMembers(this.storage?.members??this.getLocalStorage()?.members??[])}activeMembers(e){const s=Date.now();return function(e){const s=new Map;for(const t of e){if(!Number.isFinite(t.connectionId))continue;const e=s.get(t.connectionId);(null==e||(t.lastSeenAt??0)>=(e.lastSeenAt??0))&&s.set(t.connectionId,t)}return[...s.values()].sort((e,s)=>e.connectionId-s.connectionId)}(e).filter(e=>e.connectionId===this.localId||null!=e.lastSeenAt&&s-e.lastSeenAt<=this.memberTimeoutMs)}createLocalMember(){return{connectionId:this.localId,mode:this.mode,player:{id:this.localId.toString()},lastSeenAt:Date.now()}}createMessageId(){const e=window.crypto?.randomUUID;return"function"==typeof e?e.call(window.crypto):`${this.localId}-${Date.now()}-${this.messageSequence++}`}broadcast(e){this.channel?.postMessage(e)}getLocalStorage(){const e=localStorage.getItem(this.storageKey);if(null!=e)try{const s=JSON.parse(e);if(Array.isArray(s?.members))return{members:s.members}}catch(e){console.warn(`Failed to parse browser net session ${this.sessionId}`,e)}return null}writeLocalStorage(e){const s=this.activeMembers(e.members);0!==s.length?localStorage.setItem(this.storageKey,JSON.stringify({members:s})):localStorage.removeItem(this.storageKey)}}function a(e){return{id:e.connectionId,player:e.player}}function c(e){const s=new Uint8Array(e),t=new Uint8Array(s.byteLength);return t.set(s),t.buffer}function l(e){return{latencyMs:Math.max(0,e.latencyMs??n),jitterMs:Math.max(0,e.jitterMs??i),packetLoss:h(e.packetLoss??r),reliablePacketLoss:h(e.reliablePacketLoss??o)}}function h(e){return Math.min(1,Math.max(0,e))}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,5 @@
1
- import { Observable } from "rxjs";
2
- import { NetConnection } from "./net-connection.js";
1
+ import type { Observable } from "rxjs";
2
+ import type { NetConnection } from "./net-connection.js";
3
3
  export declare enum NetMode {
4
4
  /**
5
5
  * Game is played locally so it has authority but no other clients are connected.
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as n,MTLLoader as o,OBJLoader as h,TGALoader as d}from"three-stdlib";import{KTX2Loader as c}from"three/examples/jsm/Addons.js";import{Service as l}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as g}from"../../scene/materializer";import{materialFromAsset as w,materializeDataAssetRef as f,prepareShaderGraphParameters as m}from"../../scene/materializer.js";import{Prefab as y}from"../../scene/objects/prefab.js";import{pathJoin as A}from"../../utils/files.js";import{Sequence as p}from"../../effects/sequence/sequence-data.js";import{resolveAnimationClipAssetForTarget as b}from"../animation/retarget.js";import{getDataAssetDefinitionId as v}from"@hology/core/shader/parameter";let L=class{constructor(e,t,l){this.assetResourceLoader=e,this.assetService=t,this.shaders=l,this.baseUrl="",this.urlSuffix="",this.loadingManager=new a,this.glbLoader=new n(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new h(this.loadingManager),this.mtlLoader=new o(this.loadingManager),this.tgaLoader=new d(this.loadingManager),this.ktx2Loader=new c(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager),this.animationVariantIds=new Map,this.assetResourceLoader.materialProvider=e=>this.getMaterialByAssetId(e),this.assetResourceLoader.animationRigProvider=async e=>(await this.assetService.getAsset(e))?.animationRig}resolvePath(e){return A(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getAnimationClipByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No animation clip could be found with asset id ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async getAnimationClipForTargetByAssetId(e,t){const s=await this.assetService.getAsset(e);if(null==s)throw new Error(`No animation clip could be found with asset id ${e}`);let a=s;if(null!=t&&s.anim?.rigId!==t){const r=`${e}|${t}`,i=this.animationVariantIds.get(r);null!=i?a=await this.assetService.getAsset(i):(a=b(s,await this.assetService.getAssets(),t),this.animationVariantIds.set(r,a.id))}return this.assetResourceLoader.getAnimationClip(a)}async getAnimationClipByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No animation clip could be found with asset name ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async applyMaterials(e,t){for(const s of e.materialAssignments??[])await g(t,s,async e=>this.getMaterialByAssetId(e))}async getTextureByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No texture could be found with asset name ${e}`);return this.assetResourceLoader.getTexture(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getSequenceById(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No sequence could be found with asset id ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new p(t.sequence)}async getSequenceByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No sequence could be found with asset name ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new p(t.sequence)}async getDataAssetById(e,t){const s=await f(e,this.assetService,this.assetResourceLoader,void 0,void 0,this.shaders);if(null!=t&&null!=s&&!(s.value instanceof t))throw new Error(`Invalid type. Expecting asset with id ${e} to be of type ${t.name} but got:`+s.value);return s}async getDataAssetByName(e,t){const s=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==s)throw new Error(`No data asset could be found with name ${e}`);return this.getDataAssetById(s.id,t)}async getDataAssetsByDefinition(e,t){const s=(await this.assetService.getAssets()).filter(t=>t.dataAsset?.definition===e);if(0===s.length)throw new Error(`No data assets could be found with definition ${e}`);return Promise.all(s.map(e=>this.getDataAssetById(e.id,t).then(e=>e?.value)))}async getDataAssetsByType(e){const t=v(e);return this.getDataAssetsByDefinition(t,e)}async getShaderGraphByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No shader graph could be found with asset id ${e}`);if("shaderGraph"!==t.type||null==t.shaderGraph)throw new Error(`Missing shader graph data in asset ${e}`);return t.shaderGraph}async prepareShaderGraphParameters(e,t={}){return m(t,e,this.assetService,this.assetResourceLoader,void 0,this.shaders)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return w(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}async getPrefabByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if("prefab"!==t.type)throw`Asset with name ${e} is not a prefab`;return new y(t)}async getPrefabById(e){const t=await this.getAsset(e);if("prefab"!==t.type)throw`Asset with name ${name} is not a prefab`;return new y(t)}clearCache(e){this.animationVariantIds.clear(),this.assetResourceLoader.clearCache(e)}clearCacheById(e){this.animationVariantIds.clear(),this.assetResourceLoader.clearCacheById(e)}};L=e([l(),t("design:paramtypes",[u,Function,Array])],L);export{L as AssetLoader};/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as n,MTLLoader as o,OBJLoader as h,TGALoader as d}from"three-stdlib";import{KTX2Loader as c}from"three/examples/jsm/Addons.js";import{Service as l}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as g}from"../../scene/materializer.js";import{materialFromAsset as w,materializeDataAssetRef as f,prepareShaderGraphParameters as m}from"../../scene/materializer.js";import{Prefab as y}from"../../scene/objects/prefab.js";import{pathJoin as A}from"../../utils/files.js";import{Sequence as p}from"../../effects/sequence/sequence-data.js";import{resolveAnimationClipAssetForTarget as b}from"../animation/retarget.js";import{getDataAssetDefinitionId as v}from"@hology/core/shader/parameter";let L=class{constructor(e,t,l){this.assetResourceLoader=e,this.assetService=t,this.shaders=l,this.baseUrl="",this.urlSuffix="",this.loadingManager=new a,this.glbLoader=new n(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new h(this.loadingManager),this.mtlLoader=new o(this.loadingManager),this.tgaLoader=new d(this.loadingManager),this.ktx2Loader=new c(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager),this.animationVariantIds=new Map,this.assetResourceLoader.materialProvider=e=>this.getMaterialByAssetId(e),this.assetResourceLoader.animationRigProvider=async e=>(await this.assetService.getAsset(e))?.animationRig}resolvePath(e){return A(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getAnimationClipByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No animation clip could be found with asset id ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async getAnimationClipForTargetByAssetId(e,t){const s=await this.assetService.getAsset(e);if(null==s)throw new Error(`No animation clip could be found with asset id ${e}`);let a=s;if(null!=t&&s.anim?.rigId!==t){const r=`${e}|${t}`,i=this.animationVariantIds.get(r);null!=i?a=await this.assetService.getAsset(i):(a=b(s,await this.assetService.getAssets(),t),this.animationVariantIds.set(r,a.id))}return this.assetResourceLoader.getAnimationClip(a)}async getAnimationClipByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No animation clip could be found with asset name ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async applyMaterials(e,t){for(const s of e.materialAssignments??[])await g(t,s,async e=>this.getMaterialByAssetId(e))}async getTextureByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No texture could be found with asset name ${e}`);return this.assetResourceLoader.getTexture(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getSequenceById(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No sequence could be found with asset id ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new p(t.sequence)}async getSequenceByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No sequence could be found with asset name ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new p(t.sequence)}async getDataAssetById(e,t){const s=await f(e,this.assetService,this.assetResourceLoader,void 0,void 0,this.shaders);if(null!=t&&null!=s&&!(s.value instanceof t))throw new Error(`Invalid type. Expecting asset with id ${e} to be of type ${t.name} but got:`+s.value);return s}async getDataAssetByName(e,t){const s=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==s)throw new Error(`No data asset could be found with name ${e}`);return this.getDataAssetById(s.id,t)}async getDataAssetsByDefinition(e,t){const s=(await this.assetService.getAssets()).filter(t=>t.dataAsset?.definition===e);if(0===s.length)throw new Error(`No data assets could be found with definition ${e}`);return Promise.all(s.map(e=>this.getDataAssetById(e.id,t).then(e=>e?.value)))}async getDataAssetsByType(e){const t=v(e);return this.getDataAssetsByDefinition(t,e)}async getShaderGraphByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No shader graph could be found with asset id ${e}`);if("shaderGraph"!==t.type||null==t.shaderGraph)throw new Error(`Missing shader graph data in asset ${e}`);return t.shaderGraph}async prepareShaderGraphParameters(e,t={}){return m(t,e,this.assetService,this.assetResourceLoader,void 0,this.shaders)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return w(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}async getPrefabByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if("prefab"!==t.type)throw`Asset with name ${e} is not a prefab`;return new y(t)}async getPrefabById(e){const t=await this.getAsset(e);if("prefab"!==t.type)throw`Asset with name ${name} is not a prefab`;return new y(t)}clearCache(e){this.animationVariantIds.clear(),this.assetResourceLoader.clearCache(e)}clearCacheById(e){this.animationVariantIds.clear(),this.assetResourceLoader.clearCacheById(e)}};L=e([l(),t("design:paramtypes",[u,Function,Array])],L);export{L as AssetLoader};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,5 @@
1
1
  import { Observable } from "rxjs";
2
- import { BaseActor } from "../actors/actor.js";
2
+ import type { BaseActor } from "../actors/actor.js";
3
3
  /**
4
4
  * Handles gameplay timing primitives that need to cooperate with pause/resume
5
5
  * and game-time progression without adding per-frame allocations.
@@ -1,10 +1,10 @@
1
- import { Subject, Observable } from "rxjs";
2
- import { Vector3, Object3D } from "three";
3
- import { BaseActor } from "../../actors/actor";
4
- import { AbstractType } from "../../../utils/type";
5
- import { CollisionShape } from "../../../index.js";
6
- import { PhysicsBodyType } from "./physics-system";
7
- import * as RAPIER from "@dimforge/rapier3d-simd-compat";
1
+ import type { Subject, Observable } from "rxjs";
2
+ import type { Vector3, Object3D } from "three";
3
+ import type { BaseActor } from "../../actors/actor.js";
4
+ import type { AbstractType } from "../../../utils/type.js";
5
+ import type { CollisionShape } from "../../../index.js";
6
+ import type { PhysicsBodyType } from "./physics-system.js";
7
+ import type * as RAPIER from "@dimforge/rapier3d-simd-compat";
8
8
  export type ActorPhysicsOptions = {
9
9
  isTrigger: boolean;
10
10
  mass: number;
@@ -1,7 +1,7 @@
1
- import { BaseActor } from "../actors/actor";
1
+ import { BaseActor } from "../actors/actor.js";
2
2
  import { Intersection, Object3D } from "three";
3
3
  import { Observable } from 'rxjs';
4
- import { Type } from "../../utils/type";
4
+ import { Type } from "../../utils/type.js";
5
5
  type ObjectPointerEvent = {
6
6
  object: Object3D;
7
7
  intersection: Intersection;
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as e}from"tslib";import{Raycaster as i,Vector2 as o}from"three";import{Service as n}from"typedi";import{ViewController as s}from"./render";import{World as r}from"./world";import{inject as c}from"../inject.js";import{Subject as h,tap as p,map as a,filter as d,takeUntil as l,withLatestFrom as b,mergeMap as P,merge as u,from as j}from"rxjs";let w=class{constructor(){this.view=c(s),this.world=c(r),this.enabled=!1,this.stopped=new h,this.monitoredObjects=new Map,this.useCache=!1,this.cachePointerPosition=new o,this.pointerPosition=new o,this.adjustedPosition=new o,this.raycastIntersectionResult=[],this.raycaster=new i,this.onClick=new h,this.onDoubleClick=new h,this.onPointerMove=new h,this.onPointerDown=new h,this.onPointerUp=new h,this.onPointerEnterObject3D=t=>{let e=!1;return this.onPointerMove.pipe(this.tapUsingPointerMove(),this.tapMonitorObject(t),a(()=>this.findIntersection(t)),p(t=>{null==t&&(e=!1)}),d(t=>null!=t&&!e),p(()=>{e=!0}),a(e=>({intersection:e,object:t})))},this.onPointerEnterActor=t=>this.onPointerEnterObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerEnterActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerEnterActor(t))),this.onPointerLeaveObject3D=t=>{let e=!1;return this.onPointerMove.pipe(this.tapUsingPointerMove(),this.tapMonitorObject(t),a(()=>this.findIntersection(t)),p(t=>{null!=t&&(e=!1)}),d(t=>null==t&&!e),p(()=>{e=!0}),a(e=>({intersection:e,object:t})))},this.onPointerLeaveActor=t=>this.onPointerLeaveObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerLeaveActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerLeaveActor(t))),this.onClickObject3D=t=>{const e=this.onPointerDown.pipe(a(()=>this.findIntersection(t)));return this.onPointerUp.pipe(a(()=>this.findIntersection(t))).pipe(this.tapMonitorObject(t),b(e),d(([t,e])=>null!=t&&null!=e),a(([e])=>({intersection:e,object:t})))},this.onClickActor=t=>this.onClickObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onClickActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onClickActor(t))),this.onPointerDownActor=t=>this.onPointerDownObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerDownActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerDownActor(t))),this.onPointerDownObject3D=t=>this.onPointerDown.pipe(this.tapMonitorObject(t),a(()=>this.findIntersection(t)),d(t=>null!=t),a(e=>({intersection:e,object:t}))),this.onPointerUpActor=t=>this.onPointerUpObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerUpActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerUpActor(t))),this.onPointerUpObject3D=t=>this.onPointerUp.pipe(this.tapMonitorObject(t),a(()=>this.findIntersection(t)),d(t=>null!=t),a(e=>({intersection:e,object:t}))),this.onPointerMoveActor=t=>this.onPointerMoveObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerMoveActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerMoveActor(t))),this.onPointerMoveObject3D=t=>this.onPointerMove.pipe(this.tapUsingPointerMove(),this.tapMonitorObject(t),a(()=>this.findIntersection(t)),d(t=>null!=t),a(e=>({intersection:e,object:t}))),this.usingPointerMoveEvents=!1,this.handlers={click:t=>{this.onClick.next(t)},dblclick:t=>{this.onDoubleClick.next(t)},pointermove:t=>{this.onPointerMove.next(t)},pointerup:t=>{this.onPointerUp.next(t)},pointerdown:t=>{this.onPointerDown.next(t)}},this.raycaster.firstHitOnly=!0}start(){this.enabled||(this.enabled=!0,Object.entries(this.handlers).forEach(([t,e])=>{this.view.htmlElement.addEventListener(t,i=>{("pointermove"!==t||this.usingPointerMoveEvents)&&(this.updateRaycast(i),e(i))})}),this.view.onLateUpdate().pipe(l(this.stopped)).subscribe(()=>this.useCache=!1))}stop(){this.enabled=!1,Object.entries(this.handlers).forEach(([t,e])=>{document.removeEventListener(t,e)}),this.stopped.next(!0),this.onClick.complete(),this.onDoubleClick.complete(),this.onPointerMove.complete(),this.onPointerDown.complete(),this.onPointerUp.complete()}addMonitoredObject(t){const e=this.monitoredObjects.get(t)??0;this.monitoredObjects.set(t,e+1)}removeMonitoriedObject(t){const e=this.monitoredObjects.get(t);null!=e&&(e>1?this.monitoredObjects.set(t,e-1):this.monitoredObjects.delete(t))}updateRaycast(t){this.pointerPosition.set(t.x,t.y),this.useCache&&this.cachePointerPosition.equals(this.pointerPosition)||(this.cachePointerPosition.copy(this.pointerPosition),this.useCache=!0,this.adjustedPosition.x=t.offsetX/this.view.htmlElement.offsetWidth*2-1,this.adjustedPosition.y=-t.offsetY/this.view.htmlElement.offsetHeight*2+1,this.raycaster.setFromCamera(this.adjustedPosition,this.view.getCamera()),this.raycastIntersectionResult.length=0,this.raycaster.intersectObject(this.world.scene,!0,this.raycastIntersectionResult))}tapUsingPointerMove(){return p({subscribe:()=>{this.usingPointerMoveEvents=!0},unsubscribe:()=>{}})}tapMonitorObject(t){return p({subscribe:()=>{this.addMonitoredObject(t)},unsubscribe:()=>{this.removeMonitoriedObject(t)}})}findIntersection(t){if(this.raycastIntersectionResult.length>0){let e=this.raycastIntersectionResult[0].object;for(;null!=e;){if(e.uuid===t.uuid)return this.raycastIntersectionResult[0];e=e.parent}}return null}};w=t([n(),e("design:paramtypes",[])],w);export{w as PointerEvents};/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import{Raycaster as i,Vector2 as o}from"three";import{Service as n}from"typedi";import{ViewController as s}from"./render.js";import{World as r}from"./world.js";import{inject as c}from"../inject.js";import{Subject as h,tap as p,map as a,filter as d,takeUntil as l,withLatestFrom as b,mergeMap as P,merge as u,from as j}from"rxjs";let w=class{constructor(){this.view=c(s),this.world=c(r),this.enabled=!1,this.stopped=new h,this.monitoredObjects=new Map,this.useCache=!1,this.cachePointerPosition=new o,this.pointerPosition=new o,this.adjustedPosition=new o,this.raycastIntersectionResult=[],this.raycaster=new i,this.onClick=new h,this.onDoubleClick=new h,this.onPointerMove=new h,this.onPointerDown=new h,this.onPointerUp=new h,this.onPointerEnterObject3D=t=>{let e=!1;return this.onPointerMove.pipe(this.tapUsingPointerMove(),this.tapMonitorObject(t),a(()=>this.findIntersection(t)),p(t=>{null==t&&(e=!1)}),d(t=>null!=t&&!e),p(()=>{e=!0}),a(e=>({intersection:e,object:t})))},this.onPointerEnterActor=t=>this.onPointerEnterObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerEnterActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerEnterActor(t))),this.onPointerLeaveObject3D=t=>{let e=!1;return this.onPointerMove.pipe(this.tapUsingPointerMove(),this.tapMonitorObject(t),a(()=>this.findIntersection(t)),p(t=>{null!=t&&(e=!1)}),d(t=>null==t&&!e),p(()=>{e=!0}),a(e=>({intersection:e,object:t})))},this.onPointerLeaveActor=t=>this.onPointerLeaveObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerLeaveActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerLeaveActor(t))),this.onClickObject3D=t=>{const e=this.onPointerDown.pipe(a(()=>this.findIntersection(t)));return this.onPointerUp.pipe(a(()=>this.findIntersection(t))).pipe(this.tapMonitorObject(t),b(e),d(([t,e])=>null!=t&&null!=e),a(([e])=>({intersection:e,object:t})))},this.onClickActor=t=>this.onClickObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onClickActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onClickActor(t))),this.onPointerDownActor=t=>this.onPointerDownObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerDownActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerDownActor(t))),this.onPointerDownObject3D=t=>this.onPointerDown.pipe(this.tapMonitorObject(t),a(()=>this.findIntersection(t)),d(t=>null!=t),a(e=>({intersection:e,object:t}))),this.onPointerUpActor=t=>this.onPointerUpObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerUpActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerUpActor(t))),this.onPointerUpObject3D=t=>this.onPointerUp.pipe(this.tapMonitorObject(t),a(()=>this.findIntersection(t)),d(t=>null!=t),a(e=>({intersection:e,object:t}))),this.onPointerMoveActor=t=>this.onPointerMoveObject3D(t.object).pipe(l(t.disposed),a(({intersection:e})=>({intersection:e,actor:t}))),this.onPointerMoveActorType=t=>u(j(this.world.actors),this.world.actorAdded).pipe(d(e=>e instanceof t),P(t=>this.onPointerMoveActor(t))),this.onPointerMoveObject3D=t=>this.onPointerMove.pipe(this.tapUsingPointerMove(),this.tapMonitorObject(t),a(()=>this.findIntersection(t)),d(t=>null!=t),a(e=>({intersection:e,object:t}))),this.usingPointerMoveEvents=!1,this.handlers={click:t=>{this.onClick.next(t)},dblclick:t=>{this.onDoubleClick.next(t)},pointermove:t=>{this.onPointerMove.next(t)},pointerup:t=>{this.onPointerUp.next(t)},pointerdown:t=>{this.onPointerDown.next(t)}},this.raycaster.firstHitOnly=!0}start(){this.enabled||(this.enabled=!0,Object.entries(this.handlers).forEach(([t,e])=>{this.view.htmlElement.addEventListener(t,i=>{("pointermove"!==t||this.usingPointerMoveEvents)&&(this.updateRaycast(i),e(i))})}),this.view.onLateUpdate().pipe(l(this.stopped)).subscribe(()=>this.useCache=!1))}stop(){this.enabled=!1,Object.entries(this.handlers).forEach(([t,e])=>{document.removeEventListener(t,e)}),this.stopped.next(!0),this.onClick.complete(),this.onDoubleClick.complete(),this.onPointerMove.complete(),this.onPointerDown.complete(),this.onPointerUp.complete()}addMonitoredObject(t){const e=this.monitoredObjects.get(t)??0;this.monitoredObjects.set(t,e+1)}removeMonitoriedObject(t){const e=this.monitoredObjects.get(t);null!=e&&(e>1?this.monitoredObjects.set(t,e-1):this.monitoredObjects.delete(t))}updateRaycast(t){this.pointerPosition.set(t.x,t.y),this.useCache&&this.cachePointerPosition.equals(this.pointerPosition)||(this.cachePointerPosition.copy(this.pointerPosition),this.useCache=!0,this.adjustedPosition.x=t.offsetX/this.view.htmlElement.offsetWidth*2-1,this.adjustedPosition.y=-t.offsetY/this.view.htmlElement.offsetHeight*2+1,this.raycaster.setFromCamera(this.adjustedPosition,this.view.getCamera()),this.raycastIntersectionResult.length=0,this.raycaster.intersectObject(this.world.scene,!0,this.raycastIntersectionResult))}tapUsingPointerMove(){return p({subscribe:()=>{this.usingPointerMoveEvents=!0},unsubscribe:()=>{}})}tapMonitorObject(t){return p({subscribe:()=>{this.addMonitoredObject(t)},unsubscribe:()=>{this.removeMonitoriedObject(t)}})}findIntersection(t){if(this.raycastIntersectionResult.length>0){let e=this.raycastIntersectionResult[0].object;for(;null!=e;){if(e.uuid===t.uuid)return this.raycastIntersectionResult[0];e=e.parent}}return null}};w=t([n(),e("design:paramtypes",[])],w);export{w as PointerEvents};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -5,7 +5,7 @@ import { Observable } from 'rxjs';
5
5
  import { RenderingView } from "../../rendering.js";
6
6
  import { Prefab } from "../../scene/objects/prefab.js";
7
7
  import type { SceneMaterializer } from "../../scene/materializer.js";
8
- import { PrefabInstance } from '../../scene/objects/prefab';
8
+ import { PrefabInstance } from '../../scene/objects/prefab.js';
9
9
  import { BasePlayerController } from "../actors/controller/actor-controller.js";
10
10
  import type { VisualEffect } from '../../effects/vfx/vfx-param.js';
11
11
  declare class DirectionalLightController {
@@ -1,4 +1,4 @@
1
- import{__decorate as t}from"tslib";import{Service as e}from"typedi";import{BaseActor as r}from"../actors/actor.js";import{ActorFactory as s}from"../actors/factory.js";import{Group as i,Vector3 as n}from"three";import{ActorComponent as o}from"../../gameplay/actors/component.js";import{Subject as a}from"rxjs";import{RenderingView as c}from"../../rendering.js";import{randomUUID as h}from"../../utils/uuid";import{PrefabInstance as p}from"../../scene/objects/prefab";import{PhysicsSystem as l}from"./physics/physics-system.js";import{inject as d}from"../../gameplay/inject.js";import{isComponentEnabledInEnvironment as m}from"../actors/internal/component-init.js";import{NetRole as f}from"../net/service/net-actor-role.js";import{BasePlayerController as v}from"../actors/controller/actor-controller.js";import{EventGraphInstance as y}from"../event-graph/runtime.js";import{ViewController as w}from"./render.js";import{AssetsProvider as u}from"../../scene/assets-provider.js";import{WorldEventGraphAssetRuntime as b}from"../event-graph/runtime-assets.js";import{hasExecutableEventGraphDocument as E}from"../event-graph/model.js";const A=new n;class g{constructor(t){this.view=t}get direction(){return this.view.csm.lightDirection}set intensity(t){this.view.csm.lightIntensity=t,this.view.csm.lights.forEach(t=>t.intensity=this.view.csm.lightIntensity)}get intensity(){return this.view.csm.lightIntensity}get position(){return 0==this.view.csm.lights.length?A:this.view.csm.lights[0].position}}let G=class{constructor(){this.actorFactory=d(s),this.view=d(c),this.viewController=d(w),this.physics=d(l),this.assetsProvider=d(u),this.eventGraphAssets=new b(this,this.assetsProvider),this.actors=[],this.actorAdded=new a,this.actorRemoved=new a,this.directionalLight=new g(this.view),this.sceneEventGraphs=new Map,this.sceneEventGraphSubscriptions=[]}async spawnActor(t,e,r,s){if(null==t)throw new Error("Cannot spawn actor with null type");if("prefab"in t){const i=t.prefab,n=await this.spawnPrefab(i,e,r),o=n.mainActor;if(null==o)throw new Error(`Prefab has no main actor or there was an error when spwaning it. Prefab: ${JSON.stringify(i)}`);return o.disposed.subscribe(()=>{const t=n.actors.findIndex(t=>t===o);t>=0&&n.actors.splice(t,1),this.removePrefab(n)}),null!=s?.owner&&(o.owner=s.owner),o}const i=await this.actorFactory.create(t,e,r);return null!=s?.owner&&(i.owner=s.owner),this.addActor(i,e,r),i}async spawnActorWithNetInfo(t,e,r,s,i,n){const o=await this.actorFactory.create(t,i,n,!0),a=null!=s&&0!==s?this.actors.find(t=>t.__netid===s):null;return o.__netid=e,o.netRole=r,o.owner=a,o instanceof v&&(o.isLocallyControlled=r===f.autonomousProxy),this.actorFactory.initActor(o),this.addActor(o,i,n),o}async spawnLocalPlayerController(t,e,r){const s=await this.actorFactory.create(t,e,r,!0);return s.isLocallyControlled=!0,this.actorFactory.initActor(s),this.addActor(s,e,r),s}spawnActorSync(t,e,r){if(null==t)throw new Error("Cannot spawn actor with null type");const s=this.actorFactory.createSync(t,e,r);return this.addActor(s,e,r),s}addActor(t,e,r){e&&t.object.position.copy(e),r&&t.object.rotation.copy(r),null==t.object.parent&&this.scene.add(t.object),this.actors.push(t),j(t,t=>t.onBeginPlay(),this.actorFactory.inEditor),this.actorAdded.next(t)}async preloadVisualEffects(t){await(this.materializer?.preloadVisualEffects(t))}removeActor(t){for(const[e,r]of[...this.sceneEventGraphs])r.binding.mainActor===t&&this.deactivateSceneEventGraph(e);j(t,t=>t.onEndPlay(),this.actorFactory.inEditor);const e=this.actors.indexOf(t);e>=0&&this.actors.splice(e,1),t.object.removeFromParent(),t.disposed.next(!0),this.actorRemoved.next(t),this.physics.removeActor(t)}findActorByType(t,e){return this.actors.find(r=>r instanceof t&&(null==e||r.object.name==e))}findActorsByType(t,e){return this.actors.filter(r=>r instanceof t&&(null==e||r.object.name==e))}resolveSceneActor(t){return this.materializer?.resolveSceneActor(t)}async startSceneEventGraphs(t){this.stopSceneEventGraphs(),this.sceneEventGraphSubscriptions.push(t.prefabEventGraphAdded$.subscribe(t=>{this.activateSceneEventGraph(t).catch(e=>{console.error(`Failed to start scene prefab event graph ${JSON.stringify(t.id)}`,e)})}),t.prefabEventGraphRemoved$.subscribe(t=>{this.deactivateSceneEventGraph(t.id);for(const e of t.actors)this.actors.includes(e)&&this.removeActor(e)}));for(const e of t.prefabEventGraphInstances)await this.activateSceneEventGraph(e)}stopSceneEventGraphs(){for(const t of this.sceneEventGraphSubscriptions)t.unsubscribe();this.sceneEventGraphSubscriptions.length=0;for(const t of[...this.sceneEventGraphs.keys()])this.deactivateSceneEventGraph(t)}async activateSceneEventGraph(t){if(this.sceneEventGraphs.has(t.id))return;for(const e of t.actors)this.actors.includes(e)||this.addActor(e);const e=new y(t.graph,{world:this,actorsById:t.actorsById,mainActor:t.mainActor,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});this.sceneEventGraphs.set(t.id,{binding:t,runtime:e});try{await e.beginPlay()}catch(r){throw this.sceneEventGraphs.delete(t.id),e.endPlay(),r}}deactivateSceneEventGraph(t){const e=this.sceneEventGraphs.get(t);null!=e&&(this.sceneEventGraphs.delete(t),e.runtime.endPlay())}async spawnPrefab(t,e,r){if(null==this.materializer)return console.error("Internal error: Materializer is missing on World"),null;const s=new p,n=new i;null!=e&&n.position.copy(e),null!=r&&n.rotation.copy(r),this.materializer.setScene(this.scene),this.materializer.inEditor=this.actorFactory.inEditor;const o=null!=t.asset.id?await(this.assetsProvider?.getAsset(t.asset.id))??t.asset:t.asset,{object:a,actors:c,actorsById:l,mainActor:d,instanceId:m}=await this.materializer.createFromPrefabAsset(o,{sceneObjectChain:["r-"+h()],runtimeSpawn:!0},n,void 0,!1);s.object=a,s.actors=c,s.mainActor=d,s.__materializerInstanceId=m,this.scene.attach(a),c.forEach(t=>{this.addActor(t)}),this.physics.addFromScene(a);const f=o.prefab?.eventGraph;if(!this.actorFactory.inEditor&&E(f)){s.eventGraph=new y(f,{world:this,actorsById:l,mainActor:d,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});try{await s.eventGraph.beginPlay()}catch(t){throw this.removePrefab(s),t}}return s}removePrefab(t){if(t.destroyed)return;t.destroyed=!0,t.eventGraph?.endPlay(),t.eventGraph=void 0,null!=t.__materializerInstanceId&&(this.materializer.unregisterLivePrefabInstance?.(t.__materializerInstanceId),t.__materializerInstanceId=void 0);t.actors.splice(0).forEach(t=>this.removeActor(t)),t.object?.removeFromParent(),this.physics.removeRemoved(t.object)}};G=t([e()],G);export{G as World};function j(t,e,s=!1,i=new WeakSet){if(!i.has(t))return i.add(t),e(t),t instanceof r&&t.attachedComponents.forEach(t=>{m(t,s)&&j(t,e,s,i)}),Object.entries(t).filter(([t,e])=>e instanceof o&&m(e,s)).forEach(([t,r])=>{j(r,e,s,i)})}/*
1
+ import{__decorate as t}from"tslib";import{Service as e}from"typedi";import{BaseActor as r}from"../actors/actor.js";import{ActorFactory as s}from"../actors/factory.js";import{Group as i,Vector3 as n}from"three";import{ActorComponent as o}from"../../gameplay/actors/component.js";import{Subject as a}from"rxjs";import{RenderingView as c}from"../../rendering.js";import{randomUUID as h}from"../../utils/uuid.js";import{PrefabInstance as p}from"../../scene/objects/prefab.js";import{PhysicsSystem as l}from"./physics/physics-system.js";import{inject as d}from"../../gameplay/inject.js";import{isComponentEnabledInEnvironment as m}from"../actors/internal/component-init.js";import{NetRole as f}from"../net/service/net-actor-role.js";import{BasePlayerController as v}from"../actors/controller/actor-controller.js";import{EventGraphInstance as y}from"../event-graph/runtime.js";import{ViewController as w}from"./render.js";import{AssetsProvider as u}from"../../scene/assets-provider.js";import{WorldEventGraphAssetRuntime as b}from"../event-graph/runtime-assets.js";import{hasExecutableEventGraphDocument as E}from"../event-graph/model.js";const A=new n;class g{constructor(t){this.view=t}get direction(){return this.view.csm.lightDirection}set intensity(t){this.view.csm.lightIntensity=t,this.view.csm.lights.forEach(t=>t.intensity=this.view.csm.lightIntensity)}get intensity(){return this.view.csm.lightIntensity}get position(){return 0==this.view.csm.lights.length?A:this.view.csm.lights[0].position}}let G=class{constructor(){this.actorFactory=d(s),this.view=d(c),this.viewController=d(w),this.physics=d(l),this.assetsProvider=d(u),this.eventGraphAssets=new b(this,this.assetsProvider),this.actors=[],this.actorAdded=new a,this.actorRemoved=new a,this.directionalLight=new g(this.view),this.sceneEventGraphs=new Map,this.sceneEventGraphSubscriptions=[]}async spawnActor(t,e,r,s){if(null==t)throw new Error("Cannot spawn actor with null type");if("prefab"in t){const i=t.prefab,n=await this.spawnPrefab(i,e,r),o=n.mainActor;if(null==o)throw new Error(`Prefab has no main actor or there was an error when spwaning it. Prefab: ${JSON.stringify(i)}`);return o.disposed.subscribe(()=>{const t=n.actors.findIndex(t=>t===o);t>=0&&n.actors.splice(t,1),this.removePrefab(n)}),null!=s?.owner&&(o.owner=s.owner),o}const i=await this.actorFactory.create(t,e,r);return null!=s?.owner&&(i.owner=s.owner),this.addActor(i,e,r),i}async spawnActorWithNetInfo(t,e,r,s,i,n){const o=await this.actorFactory.create(t,i,n,!0),a=null!=s&&0!==s?this.actors.find(t=>t.__netid===s):null;return o.__netid=e,o.netRole=r,o.owner=a,o instanceof v&&(o.isLocallyControlled=r===f.autonomousProxy),this.actorFactory.initActor(o),this.addActor(o,i,n),o}async spawnLocalPlayerController(t,e,r){const s=await this.actorFactory.create(t,e,r,!0);return s.isLocallyControlled=!0,this.actorFactory.initActor(s),this.addActor(s,e,r),s}spawnActorSync(t,e,r){if(null==t)throw new Error("Cannot spawn actor with null type");const s=this.actorFactory.createSync(t,e,r);return this.addActor(s,e,r),s}addActor(t,e,r){e&&t.object.position.copy(e),r&&t.object.rotation.copy(r),null==t.object.parent&&this.scene.add(t.object),this.actors.push(t),j(t,t=>t.onBeginPlay(),this.actorFactory.inEditor),this.actorAdded.next(t)}async preloadVisualEffects(t){await(this.materializer?.preloadVisualEffects(t))}removeActor(t){for(const[e,r]of[...this.sceneEventGraphs])r.binding.mainActor===t&&this.deactivateSceneEventGraph(e);j(t,t=>t.onEndPlay(),this.actorFactory.inEditor);const e=this.actors.indexOf(t);e>=0&&this.actors.splice(e,1),t.object.removeFromParent(),t.disposed.next(!0),this.actorRemoved.next(t),this.physics.removeActor(t)}findActorByType(t,e){return this.actors.find(r=>r instanceof t&&(null==e||r.object.name==e))}findActorsByType(t,e){return this.actors.filter(r=>r instanceof t&&(null==e||r.object.name==e))}resolveSceneActor(t){return this.materializer?.resolveSceneActor(t)}async startSceneEventGraphs(t){this.stopSceneEventGraphs(),this.sceneEventGraphSubscriptions.push(t.prefabEventGraphAdded$.subscribe(t=>{this.activateSceneEventGraph(t).catch(e=>{console.error(`Failed to start scene prefab event graph ${JSON.stringify(t.id)}`,e)})}),t.prefabEventGraphRemoved$.subscribe(t=>{this.deactivateSceneEventGraph(t.id);for(const e of t.actors)this.actors.includes(e)&&this.removeActor(e)}));for(const e of t.prefabEventGraphInstances)await this.activateSceneEventGraph(e)}stopSceneEventGraphs(){for(const t of this.sceneEventGraphSubscriptions)t.unsubscribe();this.sceneEventGraphSubscriptions.length=0;for(const t of[...this.sceneEventGraphs.keys()])this.deactivateSceneEventGraph(t)}async activateSceneEventGraph(t){if(this.sceneEventGraphs.has(t.id))return;for(const e of t.actors)this.actors.includes(e)||this.addActor(e);const e=new y(t.graph,{world:this,actorsById:t.actorsById,mainActor:t.mainActor,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});this.sceneEventGraphs.set(t.id,{binding:t,runtime:e});try{await e.beginPlay()}catch(r){throw this.sceneEventGraphs.delete(t.id),e.endPlay(),r}}deactivateSceneEventGraph(t){const e=this.sceneEventGraphs.get(t);null!=e&&(this.sceneEventGraphs.delete(t),e.runtime.endPlay())}async spawnPrefab(t,e,r){if(null==this.materializer)return console.error("Internal error: Materializer is missing on World"),null;const s=new p,n=new i;null!=e&&n.position.copy(e),null!=r&&n.rotation.copy(r),this.materializer.setScene(this.scene),this.materializer.inEditor=this.actorFactory.inEditor;const o=null!=t.asset.id?await(this.assetsProvider?.getAsset(t.asset.id))??t.asset:t.asset,{object:a,actors:c,actorsById:l,mainActor:d,instanceId:m}=await this.materializer.createFromPrefabAsset(o,{sceneObjectChain:["r-"+h()],runtimeSpawn:!0},n,void 0,!1);s.object=a,s.actors=c,s.mainActor=d,s.__materializerInstanceId=m,this.scene.attach(a),c.forEach(t=>{this.addActor(t)}),this.physics.addFromScene(a);const f=o.prefab?.eventGraph;if(!this.actorFactory.inEditor&&E(f)){s.eventGraph=new y(f,{world:this,actorsById:l,mainActor:d,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});try{await s.eventGraph.beginPlay()}catch(t){throw this.removePrefab(s),t}}return s}removePrefab(t){if(t.destroyed)return;t.destroyed=!0,t.eventGraph?.endPlay(),t.eventGraph=void 0,null!=t.__materializerInstanceId&&(this.materializer.unregisterLivePrefabInstance?.(t.__materializerInstanceId),t.__materializerInstanceId=void 0);t.actors.splice(0).forEach(t=>this.removeActor(t)),t.object?.removeFromParent(),this.physics.removeRemoved(t.object)}};G=t([e()],G);export{G as World};function j(t,e,s=!1,i=new WeakSet){if(!i.has(t))return i.add(t),e(t),t instanceof r&&t.attachedComponents.forEach(t=>{m(t,s)&&j(t,e,s,i)}),Object.entries(t).filter(([t,e])=>e instanceof o&&m(e,s)).forEach(([t,r])=>{j(r,e,s,i)})}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
package/dist/index.d.ts CHANGED
@@ -2,12 +2,12 @@ export { loadScene } from './scene/bootstrap.js';
2
2
  export { BaseGameController } from './controllers/base-game-controller.js';
3
3
  export * from './scene/collision/collision-shape.js';
4
4
  export { AssetMeshInstance } from './scene/asset-resource-loader.js';
5
- export { registerWorker, initWorker } from './worker';
6
- export * from './shader';
5
+ export { registerWorker, initWorker } from './worker/index.js';
6
+ export * from './shader/index.js';
7
7
  export * from './gameplay/actors/builtin/post-process-volume-actor.js';
8
8
  export * from './scene/objects/prefab.js';
9
9
  export * from './scene/objects/data-asset.js';
10
- export * from './effects/sequence';
10
+ export * from './effects/sequence/index.js';
11
11
  export * from './data/surface-definition.js';
12
12
  export * from './scene/surface-query.js';
13
13
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export{loadScene}from"./scene/bootstrap.js";export{BaseGameController}from"./controllers/base-game-controller.js";export*from"./scene/collision/collision-shape.js";export{AssetMeshInstance}from"./scene/asset-resource-loader.js";export{registerWorker,initWorker}from"./worker";export*from"./shader";export*from"./gameplay/actors/builtin/post-process-volume-actor.js";export*from"./scene/objects/prefab.js";export*from"./scene/objects/data-asset.js";export*from"./effects/sequence";export*from"./data/surface-definition.js";export*from"./scene/surface-query.js";/*
1
+ export{loadScene}from"./scene/bootstrap.js";export{BaseGameController}from"./controllers/base-game-controller.js";export*from"./scene/collision/collision-shape.js";export{AssetMeshInstance}from"./scene/asset-resource-loader.js";export{registerWorker,initWorker}from"./worker/index.js";export*from"./shader/index.js";export*from"./gameplay/actors/builtin/post-process-volume-actor.js";export*from"./scene/objects/prefab.js";export*from"./scene/objects/data-asset.js";export*from"./effects/sequence/index.js";export*from"./data/surface-definition.js";export*from"./scene/surface-query.js";/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,5 @@
1
- import { BatchedMesh, Box3, Box3Helper, Mesh, Object3D } from "three";
1
+ import type { Object3D } from "three";
2
+ import { BatchedMesh, Box3, Box3Helper, Mesh } from "three";
2
3
  declare class BatchInstanceRef {
3
4
  readonly mesh: BatchedMesh;
4
5
  readonly instance: number;
@@ -1,6 +1,6 @@
1
1
  import { Color } from "three";
2
2
  import { BaseActor } from "../../gameplay/actors/actor.js";
3
- import { ScatteringMode } from "./fog-volume-object";
3
+ import { ScatteringMode } from "./fog-volume-object.js";
4
4
  export declare class FogVolume extends BaseActor {
5
5
  baseDensity: number;
6
6
  heightFalloff: number;
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as e}from"tslib";import{Color as i}from"three";import{Actor as o,BaseActor as s}from"../../gameplay/actors/actor.js";import{Parameter as r}from"../../shader/parameter.js";import{attach as n}from"../../gameplay/actors/component.js";import{FogVolumeObject as a}from"./fog-volume-object";import{EditorSpriteComponent as l}from"../../gameplay/actors/builtin/components/editor-sprite-component";let h=class extends s{constructor(){super(...arguments),this.baseDensity=.5,this.heightFalloff=1,this.heightOffset=0,this.startDistance=3,this.scatteringDistribution=0,this.albedo=new i(1,1,.6),this.emissive=new i(0,0,0),this.ambientIntensity=1,this.scatteringMode="volumetric",this.sprite=n(l,{file:"assets/cloud-icon.webp"})}onInit(){this.object.add(new a(this))}};t([r({range:[0,5],stepSize:.01,help:"The density (or thickness) of fog."}),e("design:type",Number)],h.prototype,"baseDensity",void 0),t([r(),e("design:type",Number)],h.prototype,"heightFalloff",void 0),t([r(),e("design:type",Number)],h.prototype,"heightOffset",void 0),t([r(),e("design:type",Number)],h.prototype,"startDistance",void 0),t([r({range:[-1,1],help:"\n Controls the direction in which light scatters inside the fog.\n\n - Positive values (> 0): More light is scattered forward, making beams and shafts more visible when looking toward the directional light source. (for dramatic god rays).\n - Zero: Even scattering in all directions—fog appears uniform.\n - Negative values (< 0): Fog is brighter when looking away from the directional light source.\n "}),e("design:type",Number)],h.prototype,"scatteringDistribution",void 0),t([r(),e("design:type",i)],h.prototype,"albedo",void 0),t([r({help:"Self-illumination color - makes fog visible even without light sources. Useful for stylized fog that should always be visible."}),e("design:type",i)],h.prototype,"emissive",void 0),t([r({range:[0,2],stepSize:.1,help:"Multiplier for ambient light contribution. Higher values make fog more visible in shadows. Set to 0 for god rays that only appear in direct light."}),e("design:type",Number)],h.prototype,"ambientIntensity",void 0),t([r({options:[{name:"Volumetric",value:"volumetric"},{name:"Light shaft",value:"lightShaft"}],help:"\n Controls how fog interacts with lighting:\n \n - volumetric: Standard fog. Occludes background, can appear dark in shadows. Good for realistic fog.\n - lightShaft: God rays/light scattering. Only visible where light hits (shadow map). Good for dramatic light shafts.\n "}),e("design:type",String)],h.prototype,"scatteringMode",void 0),h=t([o()],h);export{h as FogVolume};/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import{Color as i}from"three";import{Actor as o,BaseActor as s}from"../../gameplay/actors/actor.js";import{Parameter as r}from"../../shader/parameter.js";import{attach as n}from"../../gameplay/actors/component.js";import{FogVolumeObject as a}from"./fog-volume-object.js";import{EditorSpriteComponent as l}from"../../gameplay/actors/builtin/components/editor-sprite-component.js";let h=class extends s{constructor(){super(...arguments),this.baseDensity=.5,this.heightFalloff=1,this.heightOffset=0,this.startDistance=3,this.scatteringDistribution=0,this.albedo=new i(1,1,.6),this.emissive=new i(0,0,0),this.ambientIntensity=1,this.scatteringMode="volumetric",this.sprite=n(l,{file:"assets/cloud-icon.webp"})}onInit(){this.object.add(new a(this))}};t([r({range:[0,5],stepSize:.01,help:"The density (or thickness) of fog."}),e("design:type",Number)],h.prototype,"baseDensity",void 0),t([r(),e("design:type",Number)],h.prototype,"heightFalloff",void 0),t([r(),e("design:type",Number)],h.prototype,"heightOffset",void 0),t([r(),e("design:type",Number)],h.prototype,"startDistance",void 0),t([r({range:[-1,1],help:"\n Controls the direction in which light scatters inside the fog.\n\n - Positive values (> 0): More light is scattered forward, making beams and shafts more visible when looking toward the directional light source. (for dramatic god rays).\n - Zero: Even scattering in all directions—fog appears uniform.\n - Negative values (< 0): Fog is brighter when looking away from the directional light source.\n "}),e("design:type",Number)],h.prototype,"scatteringDistribution",void 0),t([r(),e("design:type",i)],h.prototype,"albedo",void 0),t([r({help:"Self-illumination color - makes fog visible even without light sources. Useful for stylized fog that should always be visible."}),e("design:type",i)],h.prototype,"emissive",void 0),t([r({range:[0,2],stepSize:.1,help:"Multiplier for ambient light contribution. Higher values make fog more visible in shadows. Set to 0 for god rays that only appear in direct light."}),e("design:type",Number)],h.prototype,"ambientIntensity",void 0),t([r({options:[{name:"Volumetric",value:"volumetric"},{name:"Light shaft",value:"lightShaft"}],help:"\n Controls how fog interacts with lighting:\n \n - volumetric: Standard fog. Occludes background, can appear dark in shadows. Good for realistic fog.\n - lightShaft: God rays/light scattering. Only visible where light hits (shadow map). Good for dramatic light shafts.\n "}),e("design:type",String)],h.prototype,"scatteringMode",void 0),h=t([o()],h);export{h as FogVolume};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,5 @@
1
- import { Color, Object3D } from 'three';
1
+ import type { Color } from 'three';
2
+ import { Object3D } from 'three';
2
3
  /**
3
4
  * Controls how fog affects the scene:
4
5
  * - "volumetric": Standard fog. Fog always has opacity based on density, can appear dark in shadows.
@@ -1,6 +1,8 @@
1
1
  import * as THREE from 'three';
2
- import { Camera, RenderTarget, Scene, WebGLRenderer, WebGLRenderTarget } from "three";
3
- import { CSM, Pass } from "three/examples/jsm/Addons.js";
2
+ import type { Camera, RenderTarget, Scene, WebGLRenderer } from "three";
3
+ import { WebGLRenderTarget } from "three";
4
+ import type { CSM } from "three/examples/jsm/Addons.js";
5
+ import { Pass } from "three/examples/jsm/Addons.js";
4
6
  export declare class VolumetricFogPass extends Pass {
5
7
  private resolution;
6
8
  private material;