@hology/core 0.0.246 → 0.0.248

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 (87) hide show
  1. package/dist/gameplay/actors/actor.js +1 -1
  2. package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
  3. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  4. package/dist/gameplay/actors/builtin/components/spline-component.d.ts +65 -0
  5. package/dist/gameplay/actors/builtin/components/spline-component.js +4 -0
  6. package/dist/gameplay/actors/builtin/components/water-post-process-settings.d.ts +24 -0
  7. package/dist/gameplay/actors/builtin/components/water-post-process-settings.js +4 -0
  8. package/dist/gameplay/actors/builtin/index.d.ts +6 -0
  9. package/dist/gameplay/actors/builtin/index.js +1 -1
  10. package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
  11. package/dist/gameplay/actors/builtin/post-process-volume-actor.d.ts +1 -2
  12. package/dist/gameplay/actors/builtin/spline-actor.d.ts +6 -0
  13. package/dist/gameplay/actors/builtin/spline-actor.js +4 -0
  14. package/dist/gameplay/actors/builtin/water-spline-volume-actor.d.ts +23 -0
  15. package/dist/gameplay/actors/builtin/water-spline-volume-actor.js +4 -0
  16. package/dist/gameplay/actors/builtin/water-volume-actor.d.ts +19 -0
  17. package/dist/gameplay/actors/builtin/water-volume-actor.js +4 -0
  18. package/dist/gameplay/actors/camera/camera-component.js +1 -1
  19. package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
  20. package/dist/gameplay/actors/component.d.ts +0 -1
  21. package/dist/gameplay/actors/component.js +1 -1
  22. package/dist/gameplay/actors/index.d.ts +4 -0
  23. package/dist/gameplay/actors/index.js +1 -1
  24. package/dist/gameplay/actors/internal/component-init.d.ts +1 -1
  25. package/dist/gameplay/actors/internal/component-init.js +1 -1
  26. package/dist/gameplay/ai/build-tile.d.ts +3 -1
  27. package/dist/gameplay/ai/build-tile.js +1 -1
  28. package/dist/gameplay/ai/dynamic-tiled-navmesh.d.ts +4 -21
  29. package/dist/gameplay/ai/dynamic-tiled-navmesh.js +1 -1
  30. package/dist/gameplay/ai/dynamic-tiled-navmesh.worker.d.ts +10 -1
  31. package/dist/gameplay/ai/dynamic-tiled-navmesh.worker.js +1 -1
  32. package/dist/gameplay/ai/index.d.ts +1 -0
  33. package/dist/gameplay/ai/index.js +1 -1
  34. package/dist/gameplay/ai/navigation-areas.d.ts +22 -0
  35. package/dist/gameplay/ai/navigation-areas.js +4 -0
  36. package/dist/gameplay/ai/navigation.d.ts +28 -4
  37. package/dist/gameplay/ai/navigation.js +1 -1
  38. package/dist/gameplay/inject.d.ts +3 -0
  39. package/dist/gameplay/inject.js +1 -1
  40. package/dist/gameplay/services/actor-update-registry.d.ts +13 -0
  41. package/dist/gameplay/services/actor-update-registry.js +4 -0
  42. package/dist/gameplay/services/render.d.ts +1 -0
  43. package/dist/gameplay/services/render.js +1 -1
  44. package/dist/gameplay/services/world.js +1 -1
  45. package/dist/index.d.ts +3 -0
  46. package/dist/index.js +1 -1
  47. package/dist/rendering/webgpu-experimental-backend.js +1 -1
  48. package/dist/rendering.d.ts +8 -0
  49. package/dist/rendering.js +1 -1
  50. package/dist/scene/materializer.js +1 -1
  51. package/dist/shader/graph/compiler.js +1 -1
  52. package/dist/shader/graph/model.d.ts +1 -1
  53. package/dist/shader/graph/registry.js +1 -1
  54. package/dist/shader/parameter.d.ts +3 -0
  55. package/dist/shader/post-process-shader.js +1 -1
  56. package/dist/shader-nodes/depth.d.ts +3 -1
  57. package/dist/shader-nodes/depth.js +1 -1
  58. package/dist/shader-nodes/index.d.ts +1 -0
  59. package/dist/shader-nodes/index.js +1 -1
  60. package/dist/shader-nodes/water-volume.d.ts +9 -0
  61. package/dist/shader-nodes/water-volume.js +4 -0
  62. package/dist/shader-nodes/water.d.ts +12 -0
  63. package/dist/shader-nodes/water.js +4 -0
  64. package/dist/test/build-tile.test.js +1 -1
  65. package/dist/test/materializer-dynamic-transform.test.js +1 -1
  66. package/dist/test/navmesh-worker-pool.test.js +1 -1
  67. package/dist/test/node-material-webgpu-resolver.test.js +1 -1
  68. package/dist/test/post-process-effect.test.js +1 -1
  69. package/dist/test/shader-graph.test.js +1 -1
  70. package/dist/test/spline-component.test.d.ts +2 -0
  71. package/dist/test/spline-component.test.js +4 -0
  72. package/dist/test/view-controller-updates.test.d.ts +2 -0
  73. package/dist/test/view-controller-updates.test.js +4 -0
  74. package/dist/test/water-spline-volume-actor.test.d.ts +2 -0
  75. package/dist/test/water-spline-volume-actor.test.js +4 -0
  76. package/dist/test/worker-task-executor.test.d.ts +2 -0
  77. package/dist/test/worker-task-executor.test.js +4 -0
  78. package/dist/worker/index.d.ts +11 -2
  79. package/dist/worker/index.js +1 -1
  80. package/dist/worker/task-executor.d.ts +22 -0
  81. package/dist/worker/task-executor.js +4 -0
  82. package/dist/worker/task-worker.d.ts +3 -0
  83. package/dist/worker/task-worker.js +4 -0
  84. package/dist/worker/task.d.ts +39 -0
  85. package/dist/worker/task.js +4 -0
  86. package/package.json +3 -3
  87. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as e}from"tslib";import o,{ignore as i}from"@plumier/reflect";import{Subject as s,skipWhile as r}from"rxjs";import{Group as n}from"three";import a,{Service as p}from"typedi";import{ActorComponent as c}from"./component.js";import{initComponentsSync as d}from"./internal/component-init.js";import{activeContainerInstance as m,containerRefMap as l}from"./internal/container-map.js";import{randomString as h}from"../../utils/math.js";import{inject as u}from"../inject.js";import{ViewController as f}from"../services/render.js";import{actorConstructContext as y}from"./factory.js";import{NetRole as j}from"../net/service/net-actor-role.js";import{registerActorClass as b}from"./type-registry.js";export{getActorClassById,getActorClassId,getRegisteredActorClasses}from"./type-registry.js";export const $actorOptions=Symbol("actor-options");const g={replicate:!1};export function Actor(t=g){const e=p({transient:!0});return function(i){const s=arguments[1],r=t.typeId??s?.name??i.name,n=b(r,i);null!=n&&n!==i&&console.warn(`Duplicate actor class name ${r}`),i.__actorId=r,i.__isActor=!0,e(i),o.noop()(i),o.parameterProperties()(i),i[$actorOptions]=t}}let U=0;export class BaseActor{get position(){return this.object?.position}get quaternion(){return this.object?.quaternion}get rotation(){return this.object?.rotation}onInit(){}onBeginPlay(){}onEndPlay(){}applySceneParameters(t,e){return!1}onUpdate(t){}onLateUpdate(t){}constructor(){this.id=++U,this.netRole=j.authority,this.__isInitialised=!1,this.object=new n,this.disposed=new s,this.attachedComponents=[],y.actor=this,this.onUpdate!==BaseActor.prototype.onUpdate&&u(f).onUpdate(this).pipe(r(()=>!this.__isInitialised)).subscribe(t=>this.onUpdate(t)),this.onLateUpdate!==BaseActor.prototype.onLateUpdate&&u(f).onLateUpdate(this).pipe(r(()=>!this.__isInitialised)).subscribe(t=>this.onLateUpdate(t))}attach(t,e){const o=m.value,i=l.get(this)??m.value??a.of("default");m.value=i;const s=h();i.set({id:s,type:t,transient:!0});const r=i.get(s);if(m.value=o,null!=e)for(const t of Object.keys(e))r[t]=e[t];return this.__isInitialised&&(r.actor=this,r.onInit(),d(r,this)),this.attachedComponents.push(r),r}getComponent(t){for(const e of Object.values(this))if(e instanceof t)return e;for(const e of this.attachedComponents)if(e instanceof t)return e}}t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"position",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"quaternion",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"rotation",null);export function _setupActorUpdateEventHandlers(){this.onUpdate!==c.prototype.onUpdate&&u(f).onUpdate(this.actor).pipe(r(()=>!this.actor?.__isInitialised)).subscribe(t=>this.onUpdate(t)),this.onLateUpdate!==c.prototype.onLateUpdate&&u(f).onLateUpdate(this.actor).pipe(r(()=>!this.actor?.__isInitialised)).subscribe(t=>this.onLateUpdate(t))}/*
1
+ import{__decorate as t,__metadata as e}from"tslib";import o,{ignore as r}from"@plumier/reflect";import{Subject as i}from"rxjs";import{Group as s}from"three";import n,{Service as a}from"typedi";import{ActorComponent as p}from"./component.js";import{initComponentsSync as c}from"./internal/component-init.js";import{activeContainerInstance as d,containerRefMap as m}from"./internal/container-map.js";import{randomString as l}from"../../utils/math.js";import{inject as h}from"../inject.js";import{ViewController as f}from"../services/render.js";import{actorConstructContext as u}from"./factory.js";import{NetRole as y}from"../net/service/net-actor-role.js";import{registerActorClass as g}from"./type-registry.js";export{getActorClassById,getActorClassId,getRegisteredActorClasses}from"./type-registry.js";export const $actorOptions=Symbol("actor-options");const j={replicate:!1};export function Actor(t=j){const e=a({transient:!0});return function(r){const i=arguments[1],s=t.typeId??i?.name??r.name,n=g(s,r);null!=n&&n!==r&&console.warn(`Duplicate actor class name ${s}`),r.__actorId=s,r.__isActor=!0,e(r),o.noop()(r),o.parameterProperties()(r),r[$actorOptions]=t}}let U=0;export class BaseActor{get position(){return this.object?.position}get quaternion(){return this.object?.quaternion}get rotation(){return this.object?.rotation}onInit(){}onBeginPlay(){}onEndPlay(){}applySceneParameters(t,e){return!1}onUpdate(t){}onLateUpdate(t){}constructor(){this.id=++U,this.netRole=y.authority,this.__isInitialised=!1,this.object=new s,this.disposed=new i,this.attachedComponents=[],u.actor=this,this.onUpdate!==BaseActor.prototype.onUpdate&&h(f).registerActorUpdate(this,t=>{this.__isInitialised&&this.onUpdate(t)}),this.onLateUpdate!==BaseActor.prototype.onLateUpdate&&h(f).registerActorUpdate(this,t=>{this.__isInitialised&&this.onLateUpdate(t)},!0)}attach(t,e){const o=d.value,r=m.get(this)??d.value??n.of("default");d.value=r;const i=l();r.set({id:i,type:t,transient:!0});const s=r.get(i);if(d.value=o,null!=e)for(const t of Object.keys(e))s[t]=e[t];return this.__isInitialised&&(s.actor=this,s.onInit(),c(s,this)),this.attachedComponents.push(s),s}getComponent(t){for(const e of Object.values(this))if(e instanceof t)return e;for(const e of this.attachedComponents)if(e instanceof t)return e}}t([r(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"position",null),t([r(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"quaternion",null),t([r(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"rotation",null);export function _setupActorUpdateEventHandlers(){this.onUpdate!==p.prototype.onUpdate&&h(f).registerActorUpdate(this.actor,t=>{this.actor?.__isInitialised&&this.onUpdate(t)}),this.onLateUpdate!==p.prototype.onLateUpdate&&h(f).registerActorUpdate(this.actor,t=>{this.actor?.__isInitialised&&this.onLateUpdate(t)},!0)}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -8,6 +8,7 @@ import { PositionalAudioComponent } from '../positional-audio-actor.js';
8
8
  import { CameraComponent } from '../../camera/camera-component.js';
9
9
  import { FirstPersonCameraComponent } from '../../camera/first-person-camera-component.js';
10
10
  import { ThirdPersonCameraComponent } from '../../camera/third-person-camera-component.js';
11
+ import { SplineComponent } from './spline-component.js';
11
12
  export declare const builtInComponents: {
12
13
  MeshComponent: typeof MeshComponent;
13
14
  TweenComponent: typeof TweenComponent;
@@ -19,6 +20,7 @@ export declare const builtInComponents: {
19
20
  CameraComponent: typeof CameraComponent;
20
21
  FirstPersonCameraComponent: typeof FirstPersonCameraComponent;
21
22
  ThirdPersonCameraComponent: typeof ThirdPersonCameraComponent;
23
+ SplineComponent: typeof SplineComponent;
22
24
  };
23
25
  export default builtInComponents;
24
26
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- import{MeshComponent as o}from"./mesh-component.js";import{OldCharacterMovementComponent as r}from"./character/old-character-movement.js";import{CharacterMovementComponent as e}from"./character/character-movement.js";import{CharacterAnimationComponent as m}from"./character/character-animation.js";import{TweenComponent as t}from"./tween-component.js";import{TriggerVolumeComponent as n}from"../trigger-volume.js";import{PositionalAudioComponent as a}from"../positional-audio-actor.js";import{CameraComponent as p}from"../../camera/camera-component.js";import{FirstPersonCameraComponent as c}from"../../camera/first-person-camera-component.js";import{ThirdPersonCameraComponent as i}from"../../camera/third-person-camera-component.js";export const builtInComponents={MeshComponent:o,TweenComponent:t,OldCharacterMovementComponent:r,CharacterMovementComponent:e,CharacterAnimationComponent:m,TriggerVolumeComponent:n,PositionalAudioComponent:a,CameraComponent:p,FirstPersonCameraComponent:c,ThirdPersonCameraComponent:i};export default builtInComponents;/*
1
+ import{MeshComponent as o}from"./mesh-component.js";import{OldCharacterMovementComponent as e}from"./character/old-character-movement.js";import{CharacterMovementComponent as r}from"./character/character-movement.js";import{CharacterAnimationComponent as m}from"./character/character-animation.js";import{TweenComponent as n}from"./tween-component.js";import{TriggerVolumeComponent as t}from"../trigger-volume.js";import{PositionalAudioComponent as a}from"../positional-audio-actor.js";import{CameraComponent as p}from"../../camera/camera-component.js";import{FirstPersonCameraComponent as i}from"../../camera/first-person-camera-component.js";import{ThirdPersonCameraComponent as c}from"../../camera/third-person-camera-component.js";import{SplineComponent as s}from"./spline-component.js";export const builtInComponents={MeshComponent:o,TweenComponent:n,OldCharacterMovementComponent:e,CharacterMovementComponent:r,CharacterAnimationComponent:m,TriggerVolumeComponent:t,PositionalAudioComponent:a,CameraComponent:p,FirstPersonCameraComponent:i,ThirdPersonCameraComponent:c,SplineComponent:s};export default builtInComponents;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -0,0 +1,65 @@
1
+ import { Subject } from 'rxjs';
2
+ import { Vector3 } from 'three';
3
+ import { ActorComponent } from '../../component.js';
4
+ export interface SplinePoint {
5
+ /** Actor-local point position. */
6
+ position: Vector3;
7
+ /** Actor-local offset from position to the incoming Bezier handle. */
8
+ inTangent: Vector3;
9
+ /** Actor-local offset from position to the outgoing Bezier handle. */
10
+ outTangent: Vector3;
11
+ }
12
+ export interface ClosestSplinePoint {
13
+ position: Vector3;
14
+ tangent: Vector3;
15
+ t: number;
16
+ distance: number;
17
+ distanceAlongSpline: number;
18
+ }
19
+ /** A generic cubic Bezier spline whose points and tangents are actor-local. */
20
+ export declare class SplineComponent extends ActorComponent {
21
+ /** Compact JSON is intentional: scene files keep the complete spline on one line. */
22
+ splineData: string;
23
+ /** Emits after an in-place authoring/runtime edit. Consumers can update incrementally. */
24
+ readonly changed: Subject<SplineComponent>;
25
+ private _points;
26
+ private _closed;
27
+ private arcLengths;
28
+ private arcTs;
29
+ private _length;
30
+ onInit(): void;
31
+ onEndPlay(): void;
32
+ get points(): readonly SplinePoint[];
33
+ get closed(): boolean;
34
+ get length(): number;
35
+ setData(data: string, emit?: boolean): void;
36
+ setPoints(points: readonly SplinePoint[], closed?: boolean): void;
37
+ updatePoint(index: number, point: SplinePoint): void;
38
+ addPoint(point: SplinePoint, index?: number): void;
39
+ /** Splits a Bezier segment without changing the shape of the spline. */
40
+ insertPointOnSegment(segmentIndex: number, t?: number): number;
41
+ removePoint(index: number): void;
42
+ setClosed(closed: boolean): void;
43
+ applySceneParameters(parameters: {
44
+ splineData?: string;
45
+ }, changed: Set<'splineData'>): boolean;
46
+ /** Samples an actor-local position using normalized t. */
47
+ samplePosition(t: number, target?: Vector3): Vector3;
48
+ sampleTangent(t: number, target?: Vector3): Vector3;
49
+ samplePositionAtDistance(distance: number, target?: Vector3): Vector3;
50
+ sampleTangentAtDistance(distance: number, target?: Vector3): Vector3;
51
+ /** Finds the closest actor-local point to an actor-local query position. */
52
+ closestPoint(point: Vector3, target?: Vector3): ClosestSplinePoint;
53
+ private commitChange;
54
+ private get segmentCount();
55
+ private resolveSegment;
56
+ private rebuildArcLengths;
57
+ private tAtDistance;
58
+ private distanceAtT;
59
+ }
60
+ export declare function packSplineData(points: readonly SplinePoint[], closed: boolean): string;
61
+ export declare function parseSplineData(data: string): {
62
+ points: SplinePoint[];
63
+ closed: boolean;
64
+ };
65
+ //# sourceMappingURL=spline-component.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{__decorate as t,__metadata as n}from"tslib";import{Subject as s}from"rxjs";import{Vector3 as i}from"three";import{Parameter as e}from"../../../../shader/parameter.js";import{ActorComponent as o,Component as a}from"../../component.js";const h='{"closed":false,"points":[[0,0,0,0,0,0,2,0,0],[5,0,0,-2,0,0,0,0,0]]}';let r=class extends o{constructor(){super(...arguments),this.splineData=h,this.changed=new s,this._points=[],this._closed=!1,this.arcLengths=new Float32Array(0),this.arcTs=new Float32Array(0),this._length=0}onInit(){this.setData(this.splineData,!1)}onEndPlay(){this.changed.complete()}get points(){return this._points}get closed(){return this._closed}get length(){return this._length}setData(t,n=!0){const s=parseSplineData(t);this._closed=s.closed,this._points=s.points,this.splineData=packSplineData(this._points,this._closed),this.rebuildArcLengths(),n&&this.changed.next(this)}setPoints(t,n=this._closed){this._points=t.map(p),this._closed=n,this.commitChange()}updatePoint(t,n){t<0||t>=this._points.length||(this._points[t]=p(n),this.commitChange())}addPoint(t,n=this._points.length){this._points.splice(Math.max(0,Math.min(n,this._points.length)),0,p(t)),this.commitChange()}insertPointOnSegment(t,n=.5){const s=this.segmentCount;if(t<0||t>=s)return-1;const i=(t+1)%this._points.length,e=this._points[t],o=this._points[i],a=e.position,h=e.position.clone().add(e.outTangent),r=o.position.clone().add(o.inTangent),p=o.position,l=a.clone().lerp(h,n),c=h.clone().lerp(r,n),g=r.clone().lerp(p,n),m=l.clone().lerp(c,n),u=c.clone().lerp(g,n),T=m.clone().lerp(u,n);e.outTangent.copy(l).sub(a),o.inTangent.copy(g).sub(p);const d=t+1;return this._points.splice(d,0,{position:T,inTangent:m.sub(T),outTangent:u.sub(T)}),this.commitChange(),d}removePoint(t){t<0||t>=this._points.length||(this._points.splice(t,1),this.commitChange())}setClosed(t){t!==this._closed&&(this._closed=t,this.commitChange())}applySceneParameters(t,n){return!(1!==n.size||!n.has("splineData")||"string"!=typeof t.splineData)&&(this.setData(t.splineData),!0)}samplePosition(t,n=new i){const s=this.resolveSegment(t);return s?function(t,n,s,i){const e=1-s,o=e*e*e,a=3*e*e*s,h=3*e*s*s,r=s*s*s;return i.set(t.position.x*o+(t.position.x+t.outTangent.x)*a+(n.position.x+n.inTangent.x)*h+n.position.x*r,t.position.y*o+(t.position.y+t.outTangent.y)*a+(n.position.y+n.inTangent.y)*h+n.position.y*r,t.position.z*o+(t.position.z+t.outTangent.z)*a+(n.position.z+n.inTangent.z)*h+n.position.z*r)}(s.a,s.b,s.u,n):n.set(0,0,0)}sampleTangent(t,n=new i){const s=this.resolveSegment(t);return s?function(t,n,s,i){const e=1-s;return i.set(3*e*e*t.outTangent.x+6*e*s*(n.position.x+n.inTangent.x-t.position.x-t.outTangent.x)-3*s*s*n.inTangent.x,3*e*e*t.outTangent.y+6*e*s*(n.position.y+n.inTangent.y-t.position.y-t.outTangent.y)-3*s*s*n.inTangent.y,3*e*e*t.outTangent.z+6*e*s*(n.position.z+n.inTangent.z-t.position.z-t.outTangent.z)-3*s*s*n.inTangent.z)}(s.a,s.b,s.u,n).normalize():n.set(0,0,0)}samplePositionAtDistance(t,n=new i){return this.samplePosition(this.tAtDistance(t),n)}sampleTangentAtDistance(t,n=new i){return this.sampleTangent(this.tAtDistance(t),n)}closestPoint(t,n=new i){if(0===this.arcTs.length)return{position:n.set(0,0,0),tangent:new i,t:0,distance:t.length(),distanceAlongSpline:0};let s=0,e=1/0;const o=new i;for(let n=0;n<this.arcTs.length;n++){this.samplePosition(this.arcTs[n],o);const i=o.distanceToSquared(t);i<e&&(e=i,s=this.arcTs[n])}const a=this.arcTs.length>1?1/(this.arcTs.length-1):1;let h=Math.max(0,s-a),r=Math.min(1,s+a);for(let n=0;n<8;n++){const n=h+(r-h)/3,s=r-(r-h)/3;this.samplePosition(n,o);const i=o.distanceToSquared(t);this.samplePosition(s,o),i<o.distanceToSquared(t)?r=s:h=n}return s=.5*(h+r),this.samplePosition(s,n),{position:n,tangent:this.sampleTangent(s),t:s,distance:n.distanceTo(t),distanceAlongSpline:this.distanceAtT(s)}}commitChange(){this.splineData=packSplineData(this._points,this._closed),this.rebuildArcLengths(),this.changed.next(this)}get segmentCount(){return this._points.length<2?0:this._closed?this._points.length:this._points.length-1}resolveSegment(t){const n=this.segmentCount;if(0===n)return this._points[0]?{a:this._points[0],b:this._points[0],u:0}:null;const s=Math.max(0,Math.min(1,t))*n,i=Math.min(Math.floor(s),n-1);return{a:this._points[i],b:this._points[(i+1)%this._points.length],u:s-i}}rebuildArcLengths(){const t=24*this.segmentCount;if(0===t)return this.arcTs=this._points.length?new Float32Array([0]):new Float32Array(0),this.arcLengths=this._points.length?new Float32Array([0]):new Float32Array(0),void(this._length=0);this.arcTs=new Float32Array(t+1),this.arcLengths=new Float32Array(t+1);const n=this.samplePosition(0,new i),s=new i;let e=0;for(let i=1;i<=t;i++){const o=i/t;this.samplePosition(o,s),e+=n.distanceTo(s),this.arcTs[i]=o,this.arcLengths[i]=e,n.copy(s)}this._length=e}tAtDistance(t){if(0===this._length)return 0;const n=Math.max(0,Math.min(this._length,t));let s=0,i=this.arcLengths.length-1;for(;s<i;){const t=s+i>>>1;this.arcLengths[t]<n?s=t+1:i=t}const e=s,o=Math.max(0,e-1),a=this.arcLengths[e]-this.arcLengths[o],h=a>0?(n-this.arcLengths[o])/a:0;return this.arcTs[o]+(this.arcTs[e]-this.arcTs[o])*h}distanceAtT(t){if(this.arcTs.length<2)return 0;const n=Math.max(0,Math.min(1,t))*(this.arcTs.length-1),s=Math.floor(n),i=Math.min(s+1,this.arcLengths.length-1);return this.arcLengths[s]+(this.arcLengths[i]-this.arcLengths[s])*(n-s)}};t([e({label:"Spline Data",type:String}),n("design:type",String)],r.prototype,"splineData",void 0),r=t([a({inEditor:!0,typeId:"SplineComponent"})],r);export{r as SplineComponent};export function packSplineData(t,n){return JSON.stringify({closed:n,points:t.map(t=>[...t.position.toArray(),...t.inTangent.toArray(),...t.outTangent.toArray()])})}export function parseSplineData(t){let n;try{n=JSON.parse(t)}catch{n=JSON.parse(h)}return{closed:!0===n.closed,points:(n.points??[]).filter(t=>t.length>=9).map(t=>({position:(new i).fromArray(t,0),inTangent:(new i).fromArray(t,3),outTangent:(new i).fromArray(t,6)}))}}function p(t){return{position:t.position.clone(),inTangent:t.inTangent.clone(),outTangent:t.outTangent.clone()}}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,24 @@
1
+ import { Material, Matrix4, Object3D, Vector3 } from 'three';
2
+ import { ActorComponent } from '../../component.js';
3
+ /** Artist-facing underwater rendering controls shared by every water volume. */
4
+ export declare class WaterPostProcessSettings extends ActorComponent {
5
+ private view?;
6
+ onInit(): void;
7
+ onEndPlay(): void;
8
+ applySceneParameters(parameters: Partial<Pick<WaterPostProcessSettings, 'enabled' | 'priority' | 'transitionDistance' | 'postProcessMaterial'>>, changed: ReadonlySet<string>): boolean;
9
+ enabled: boolean;
10
+ priority: number;
11
+ transitionDistance: number;
12
+ postProcessMaterial?: Material;
13
+ }
14
+ /** Renderer contract implemented by box and spline water actors. */
15
+ export interface WaterPostProcessVolume {
16
+ readonly object: Object3D;
17
+ readonly underwater: WaterPostProcessSettings;
18
+ containsWaterPoint(point: Vector3): boolean;
19
+ /** Box volumes expose this for the depth-reconstructed per-pixel mask. */
20
+ getWaterPostProcessWorldToLocal?(target: Matrix4, cameraPosition: Vector3): Matrix4;
21
+ isWaterPostProcessRelevant?(cameraPosition: Vector3, transitionDistance: number): boolean;
22
+ }
23
+ export declare function boxContainsWorldPoint(object: Object3D, point: Vector3): boolean;
24
+ //# sourceMappingURL=water-post-process-settings.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{__decorate as e,__metadata as t}from"tslib";import{Material as r,Matrix4 as o,Vector3 as s}from"three";import{ActorComponent as i,Component as a}from"../../component.js";import{Parameter as n}from"../../../../shader/parameter.js";import{injectFromActor as p}from"../../../inject.js";import{RenderingView as d}from"../../../../rendering.js";let c=class extends i{constructor(){super(...arguments),this.enabled=!0,this.priority=0,this.transitionDistance=.5}onInit(){this.view=p(this.actor,d),this.view.addWaterPostProcessVolume(this.actor)}onEndPlay(){this.view?.removeWaterPostProcessVolume(this.actor)}applySceneParameters(e,t){for(const e of t)if("enabled"!==e&&"priority"!==e&&"transitionDistance"!==e&&"postProcessMaterial"!==e)return!1;return Object.assign(this,e),!0}};e([n({group:"Underwater"}),t("design:type",Boolean)],c.prototype,"enabled",void 0),e([n({group:"Underwater",precision:0}),t("design:type",Number)],c.prototype,"priority",void 0),e([n({range:[0,5],group:"Underwater",help:"How close the camera must be to the top surface before the depth-masked transition pass is enabled."}),t("design:type",Number)],c.prototype,"transitionDistance",void 0),e([n({type:r,shaderGraphTarget:"postProcess",optional:!0,group:"Underwater",help:"Shared post-process shader graph used while the camera is inside this volume."}),t("design:type",r)],c.prototype,"postProcessMaterial",void 0),c=e([a({inEditor:!0})],c);export{c as WaterPostProcessSettings};const h=new o,m=new s;export function boxContainsWorldPoint(e,t){return e.updateWorldMatrix(!0,!1),m.copy(t).applyMatrix4(h.copy(e.matrixWorld).invert()),Math.abs(m.x)<=.5&&Math.abs(m.y)<=.5&&Math.abs(m.z)<=.5}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -7,6 +7,9 @@ import { TriggerVolume } from './trigger-volume.js';
7
7
  import { FogVolume } from '../../../rendering/fog/fog-volume-actor.js';
8
8
  import { SequenceActor } from '../../../effects/sequence/sequence-actor.js';
9
9
  import { LightProbeVolume } from '../../../rendering/light-probes/light-probe-volume-actor.js';
10
+ import { WaterVolume } from './water-volume-actor.js';
11
+ import { SplineActor } from './spline-actor.js';
12
+ import { WaterSplineVolume } from './water-spline-volume-actor.js';
10
13
  export declare const builtInActors: {
11
14
  Camera: typeof CameraActor;
12
15
  SpawnPoint: typeof SpawnPoint;
@@ -17,6 +20,9 @@ export declare const builtInActors: {
17
20
  FogVolume: typeof FogVolume;
18
21
  Sequence: typeof SequenceActor;
19
22
  LightProbeVolume: typeof LightProbeVolume;
23
+ WaterVolume: typeof WaterVolume;
24
+ Spline: typeof SplineActor;
25
+ WaterSplineVolume: typeof WaterSplineVolume;
20
26
  };
21
27
  export default builtInActors;
22
28
  export declare const experimentalActors: string[];
@@ -1,4 +1,4 @@
1
- import{PostProcessVolume as o}from"./post-process-volume-actor.js";import{CameraActor as r}from"./camera-actor.js";import e from"./navmesh-actor.js";import{PositionalAudioActor as t}from"./positional-audio-actor.js";import{SpawnPoint as m}from"./spawn-point.js";import{TriggerVolume as s}from"./trigger-volume.js";import{FogVolume as i}from"../../../rendering/fog/fog-volume-actor.js";import{SequenceActor as p}from"../../../effects/sequence/sequence-actor.js";import{LightProbeVolume as a}from"../../../rendering/light-probes/light-probe-volume-actor.js";export const builtInActors={Camera:r,SpawnPoint:m,TriggerVolume:s,PositionalAudio:t,NavMesh:e,PostProcessVolume:o,FogVolume:i,Sequence:p,LightProbeVolume:a};export default builtInActors;export const experimentalActors=["LightProbeVolume"];/*
1
+ import{PostProcessVolume as o}from"./post-process-volume-actor.js";import{CameraActor as r}from"./camera-actor.js";import e from"./navmesh-actor.js";import{PositionalAudioActor as t}from"./positional-audio-actor.js";import{SpawnPoint as m}from"./spawn-point.js";import{TriggerVolume as i}from"./trigger-volume.js";import{FogVolume as s}from"../../../rendering/fog/fog-volume-actor.js";import{SequenceActor as p}from"../../../effects/sequence/sequence-actor.js";import{LightProbeVolume as a}from"../../../rendering/light-probes/light-probe-volume-actor.js";import{WaterVolume as l}from"./water-volume-actor.js";import{SplineActor as n}from"./spline-actor.js";import{WaterSplineVolume as c}from"./water-spline-volume-actor.js";export const builtInActors={Camera:r,SpawnPoint:m,TriggerVolume:i,PositionalAudio:t,NavMesh:e,PostProcessVolume:o,FogVolume:s,Sequence:p,LightProbeVolume:a,WaterVolume:l,Spline:n,WaterSplineVolume:c};export default builtInActors;export const experimentalActors=["LightProbeVolume"];/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{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 b,filter as w,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 j,PhysicsSystem as z,ViewController as A,World as k,attach as C,inject as D}from"../../index.js";import{sleepDelay as P}from"../../../utils/async.js";import{hasSharedArrayBufferSupport as F,toSharedFloat32Array as I,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(w(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=D(z),this.view=D(A),this.world=D(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)&&(null==this.debugDrawer.parent&&this.object.parent?.add(this.debugDrawer),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,w=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 P(t)})(),()=>{n=!0}}(async()=>{if(B)return;const e=new x.Box3,t=m();for(const n of t){const t=w.get(n);!0!==t?.equals(n.position)&&(null!=t&&e.expandByPoint(t),e.expandByObject(n),w.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),F&&(o=I(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),b(200)).subscribe(()=>{h.clear(),h.drawNavMesh(r.navMesh)}),console.log("Create navmesh with debug",this.debug),h.visible=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 j=performance.now()-l;j>1e3&&console.warn(`NavMesh update took ${j} ms. Consider changing tileSize or other parameter that may affect performance`)}};e([j(),t("design:type",Boolean)],O.prototype,"debug",void 0),e([j(),t("design:type",Number)],O.prototype,"walkableClimb",void 0),e([j({range:[0,89]}),t("design:type",Number)],O.prototype,"walkableSlopeAngle",void 0),e([j(),t("design:type",Number)],O.prototype,"walkableHeight",void 0),e([j({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 c,ShapeType as l,TriMesh as h}from"@dimforge/rapier3d-simd-compat";import{init as u}from"@recast-navigation/core";import{DebugDrawer as p,getPositionsAndIndices as d}from"@recast-navigation/three";import{BehaviorSubject as f,Subject as m,debounceTime as w,filter as g,firstValueFrom as b,takeUntil as y}from"rxjs";import*as x from"three";import{BufferGeometryUtils as M,ConvexHull as v}from"three/examples/jsm/Addons.js";import{Actor as B,BaseActor as S,Parameter as z,PhysicsSystem as j,ViewController as k,World as A,attach as C,inject as P}from"../../index.js";import{sleepDelay as V}from"../../../utils/async.js";import{hasSharedArrayBufferSupport as D,toSharedFloat32Array as F,toSharedUint32Array as I}from"../../../utils/buffer.js";import{DynamicTiledNavMesh as N,MAX_NAV_MESH_WORKERS as H}from"../../ai/dynamic-tiled-navmesh.js";import{isNavigationAreaContributor as G}from"../../ai/navigation-areas.js";import{TriggerVolumeMesh as E}from"./components/volume-editor-component.js";var R;!function(e){e[e.none=0]="none",e[e.starting=1]="starting",e[e.started=2]="started"}(R||(R={}));let T=R.none,U=new f(!1);export async function safeRecastInit(){return T===R.none?(T=R.starting,u().then(()=>{U.next(!0),T=R.started})):b(U.pipe(g(e=>e)))}new x.Box3(new x.Vector3(-100,-100,-100),new x.Vector3(100,100,100));const O=Math.max(1,Math.min(H,(navigator.hardwareConcurrency??2)-1));let q=!1,W=class extends S{constructor(){super(...arguments),this.physics=P(j),this.view=P(k),this.world=P(A),this.editorVisualisation=C(E),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;K.setFromCenterAndSize(this.position,this.object.scale).equals(this.bounds)||(this.disposed.next(!0),this.disposed=new m,this.init())},2e3)}onEndPlay(){clearInterval(this.recreateInterval)}applySceneParameters(e,t){return!(null==this.debugDrawer||!t.has("debug")||"boolean"!=typeof e.debug)&&(null==this.debugDrawer.parent&&this.object.parent?.add(this.debugDrawer),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 N({navMeshBounds:this.bounds,recastConfig:i,maxTiles:1024,workers:O,cacheId:"nav"+this.object.userData?.src?.id});this.navMesh=r.navMesh;const a=this.tileSize*i.cs*2,c=performance.now(),l=new Map,h=new p;h.userData.isDebugDrawer=!0,this.debugDrawer=h;r.navMesh;const u=this.bounds,f=()=>{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=l.get(r)?.mesh,c=a??J(i);if($(i,c),null!=c){o.copy(c.geometry.boundingBox),o.min.add(c.position),o.max.add(c.position);const e=o.intersectsBox(t)||!0,s=o.intersectsBox(this.bounds);l.set(r,{pos:i.translation(),mesh:c}),e&&s&&n.push(c)}}return n},m=new x.Box3,g=new Map,b=new Map,M=new Map,v=new Map;let B=!0,S=performance.now(),z=!1;const j=function(e,t){let n=!1;return(async()=>{for(;!n;)await e(),await V(t)})(),()=>{n=!0}}(async()=>{if(z)return;const e=new x.Box3,t=f();for(const n of t){const t=g.get(n);!0!==t?.equals(n.position)&&(null!=t&&e.expandByPoint(t),e.expandByObject(n),g.set(n,n.position.clone()))}const n=[],s=new Set;for(const t of this.world.actors){if(!G(t))continue;s.add(t);const o=t.getNavigationAreaModifiers();n.push(...o);const i=Q(o),r=JSON.stringify(o);if(M.get(t)!==r){const n=b.get(t);null!=n&&e.union(n),e.union(i),b.set(t,i),M.set(t,r)}}for(const t of[...b.keys()])s.has(t)||(e.union(b.get(t)),b.delete(t),M.delete(t));const o=e.isEmpty()?[]:r.getTilesForBounds(e.expandByScalar(50));o.length>500&&console.warn("Too many tiles to update. Consider increasing tile size");const i=o.slice(0,500);if(0!=i.length){const s=[];for(const n of t)m.setFromObject(n),m.intersectsBox(e)&&s.push(n);let[o,a]=d(s);a=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,a,u),D&&(o=F(o),a=I(a));const c=B;B=!1,await Promise.all(i.map(e=>{S=performance.now();const t=function(e,t,n){const s=(e.recastConfig.walkableRadius+3)*e.recastConfig.cs,o=new x.Vector3(e.navMeshBoundsMin.x+t[0]*e.tcs-s,e.navMeshBoundsMin.y,e.navMeshBoundsMin.z+t[1]*e.tcs-s),i=new x.Vector3(o.x+e.tcs+2*s,e.navMeshBoundsMax.y,o.z+e.tcs+2*s),r=new x.Box3(o,i);return n.filter(e=>Q([e]).intersectsBox(r))}(r,e,n);return r.buildTile(o,a,e,c,t).then(()=>{const t=e[0]+","+e[1];v.set(t,(v.get(t)??0)+1),this.debug})})).then(()=>{this.debug,z=!1})}else z=!1},this.refreshMs??1e4);this.disposed.subscribe(()=>j()),r.onNavMeshUpdate.pipe(y(this.disposed),w(200)).subscribe(()=>{h.clear(),h.drawNavMesh(r.navMesh)}),console.log("Create navmesh with debug",this.debug),h.visible=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 k=performance.now()-c;k>1e3&&console.warn(`NavMesh update took ${k} ms. Consider changing tileSize or other parameter that may affect performance`)}};e([z(),t("design:type",Boolean)],W.prototype,"debug",void 0),e([z(),t("design:type",Number)],W.prototype,"walkableClimb",void 0),e([z({range:[0,89]}),t("design:type",Number)],W.prototype,"walkableSlopeAngle",void 0),e([z(),t("design:type",Number)],W.prototype,"walkableHeight",void 0),e([z({range:[.01,10]}),t("design:type",Number)],W.prototype,"cellSize",void 0),W=e([B()],W);export default W;const _=new Map,L=new WeakMap;function X(e){if(e.shape instanceof c)return function(e){const t=e.shape;if(t.type!==l.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,c=s.scale.z,h=s.scale.y,u=i+1,p=new x.PlaneGeometry(c,a,r,i);p.rotateX(-Math.PI/2);const d=p.attributes.position.array;let f=0;for(let e=0;e<u;e++)for(let t=0;t<u;t++)d[f+1]=o[t*u+e]*h,f+=3,0!=d[f+1]&&(n=!0);if(!n){const e=new x.PlaneGeometry(a,c,2,2);return e.rotateX(-Math.PI/2),e}return p}(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=L.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 L.set(e,s),s}(e.shape.vertices);let n=_.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 v).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),_.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=M.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 J(e){const t=X(e);if(null==t)return null;const n=Y,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 K=new x.Box3;function Q(e){const t=new x.Box3;for(const n of e)for(const e of n.vertices)t.expandByPoint(new x.Vector3(e[0],n.minHeight,e[2])),t.expandByPoint(new x.Vector3(e[0],n.maxHeight,e[2]));return t}const Y=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,9 +1,8 @@
1
1
  import { BaseActor } from "../../index.js";
2
- import { Texture } from 'three';
2
+ import { Texture, type ToneMapping } from 'three';
3
3
  import { Vector3 } from 'three';
4
4
  import * as THREE from 'three';
5
5
  import { ActorComponent } from "../../actors/component.js";
6
- import { ToneMapping } from '../../../../../../node_modules/@types/three/src/constants.js';
7
6
  export type PostProcessingVolumeShape = {
8
7
  kind: 'box';
9
8
  box: THREE.Box3;
@@ -0,0 +1,6 @@
1
+ import { BaseActor } from '../actor.js';
2
+ import { SplineComponent } from './components/spline-component.js';
3
+ export declare class SplineActor extends BaseActor {
4
+ readonly spline: SplineComponent;
5
+ }
6
+ //# sourceMappingURL=spline-actor.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{__decorate as o}from"tslib";import{Actor as t,BaseActor as p}from"../actor.js";import{attach as r}from"../component.js";import{SplineComponent as s}from"./components/spline-component.js";let e=class extends p{constructor(){super(...arguments),this.spline=r(s)}};e=o([t({typeId:"Spline"})],e);export{e as SplineActor};/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,23 @@
1
+ import { BufferGeometry, Material, Vector3 } from 'three';
2
+ import { type NavigationAreaContributor, type NavigationAreaModifier } from '../../ai/navigation-areas.js';
3
+ import { BaseActor } from '../actor.js';
4
+ import { SplineComponent } from './components/spline-component.js';
5
+ import { WaterPostProcessSettings, type WaterPostProcessVolume } from './components/water-post-process-settings.js';
6
+ /** A spline-shaped water volume. The spline runs along the center of its surface. */
7
+ export declare class WaterSplineVolume extends BaseActor implements NavigationAreaContributor, WaterPostProcessVolume {
8
+ readonly spline: SplineComponent;
9
+ private readonly surface;
10
+ private readonly editorVisual;
11
+ readonly underwater: WaterPostProcessSettings;
12
+ width: number;
13
+ depth: number;
14
+ showSurface: boolean;
15
+ surfaceMaterial?: Material;
16
+ surfaceSampleDistance: number;
17
+ surfaceWidthSubdivisions: number;
18
+ applySceneParameters(parameters: Record<string, unknown>, changedParameters: ReadonlySet<string>): boolean;
19
+ containsWaterPoint(point: Vector3): boolean;
20
+ getNavigationAreaModifiers(): NavigationAreaModifier[];
21
+ }
22
+ export declare function createWaterSplineSurfaceGeometry(spline: SplineComponent, width: number, sampleDistance: number, widthSubdivisions: number): BufferGeometry;
23
+ //# sourceMappingURL=water-spline-volume-actor.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{__decorate as t,__metadata as e}from"tslib";import{BufferGeometry as i,EdgesGeometry as s,Float32BufferAttribute as r,Group as o,DoubleSide as a,LineBasicMaterial as n,LineSegments as l,Mesh as h,MeshBasicMaterial as c,Material as u,Matrix4 as p,Vector3 as d}from"three";import{takeUntil as f}from"rxjs";import{NavigationArea as m}from"../../ai/navigation-areas.js";import{Parameter as g}from"../../../shader/parameter.js";import{Actor as w,BaseActor as y}from"../actor.js";import{ActorComponent as b,Component as S,attach as x}from"../component.js";import{SplineComponent as M}from"./components/spline-component.js";import{WaterPostProcessSettings as z}from"./components/water-post-process-settings.js";const v=1477586;let A=class extends b{constructor(){super(...arguments),this.fallbackMaterial=new c({color:v,transparent:!0,opacity:.65,side:a}),this.surface=new h(new i,this.fallbackMaterial),this.initialized=!1}onInit(){this.initialized=!0,this.surface.name="Water Surface",this.actor.object.add(this.surface),this.actor.spline.changed.pipe(f(this.disposed)).subscribe(()=>this.rebuild()),this.setMaterial(this.actor.surfaceMaterial),this.rebuild()}setMaterial(t){this.surface.material=t??this.fallbackMaterial}rebuild(){if(!this.initialized)return;const t=this.surface.geometry;this.surface.geometry=F(this.actor.spline,this.actor.width,this.actor.surfaceSampleDistance,this.actor.surfaceWidthSubdivisions),this.surface.visible=this.actor.showSurface,t.dispose()}onEndPlay(){this.surface.geometry.dispose(),this.fallbackMaterial.dispose(),this.surface.removeFromParent()}};A=t([S({inEditor:!0})],A);let T=class extends b{constructor(){super(...arguments),this.visual=new o,this.fillMaterial=new c({color:v,transparent:!0,opacity:.18,depthWrite:!1}),this.edgeMaterial=new n({color:3520767}),this.fill=new h(new i,this.fillMaterial),this.edges=new l(new i,this.edgeMaterial),this.initialized=!1}onInit(){this.initialized=!0,this.visual.name="Water Spline Volume Visualization",this.visual.userData.isEditorVisualization=!0,this.fill.frustumCulled=!1,this.edges.frustumCulled=!1,this.visual.add(this.fill,this.edges),this.actor.object.add(this.visual),this.actor.spline.changed.pipe(f(this.disposed)).subscribe(()=>this.rebuild()),this.rebuild()}rebuild(){if(!this.initialized)return;const t=function(t,e,s,o=!1,a=.5){const n=new i,l=D(t,e,s,a);if(l.length<2)return n.setAttribute("position",new r([],3)),n;const h=l.flatMap(t=>[...t.leftTop.toArray(),...t.rightTop.toArray(),...t.leftBottom.toArray(),...t.rightBottom.toArray()]),c=[];for(let t=1;t<l.length;t++){const e=4*(t-1),i=4*t;o||k(c,e,i,i+1,e+1),k(c,e+2,e+3,i+3,i+2),k(c,e,e+2,i+2,i),k(c,e+1,i+1,i+3,e+3)}if(!t.closed){k(c,0,1,3,2);const t=4*(l.length-1);k(c,t,t+2,t+3,t+1)}return n.setAttribute("position",new r(h,3)),n.setIndex(c),n.computeVertexNormals(),n.computeBoundingBox(),n.computeBoundingSphere(),n}(this.actor.spline,this.actor.width,this.actor.depth,this.actor.showSurface,this.actor.surfaceSampleDistance),e=0===t.getAttribute("position").count?new i:new s(t,20),o=this.fill.geometry,a=this.edges.geometry;this.fill.geometry=t,this.edges.geometry=e,o.dispose(),a.dispose(),this.visual.updateMatrixWorld(!0)}onEndPlay(){this.fill.geometry.dispose(),this.edges.geometry.dispose(),this.fillMaterial.dispose(),this.edgeMaterial.dispose(),this.visual.removeFromParent()}};T=t([S({inEditor:!0,editorOnly:!0})],T);let W=class extends y{constructor(){super(...arguments),this.spline=x(M),this.surface=x(A),this.editorVisual=x(T),this.underwater=x(z),this.width=5,this.depth=2,this.showSurface=!0,this.surfaceSampleDistance=1,this.surfaceWidthSubdivisions=1}applySceneParameters(t,e){if(![...e].every(t=>["width","depth","showSurface","surfaceMaterial","surfaceSampleDistance","surfaceWidthSubdivisions"].includes(t)))return!1;const i=e.has("width")?t.width:this.width,s=e.has("depth")?t.depth:this.depth;if("number"!=typeof i||!Number.isFinite(i)||i<=0)return!1;if("number"!=typeof s||!Number.isFinite(s)||s<=0)return!1;if(e.has("showSurface")&&"boolean"!=typeof t.showSurface)return!1;if(e.has("surfaceMaterial")&&null!=t.surfaceMaterial&&!(t.surfaceMaterial instanceof u))return!1;const r=e.has("surfaceSampleDistance")?t.surfaceSampleDistance:this.surfaceSampleDistance,o=e.has("surfaceWidthSubdivisions")?t.surfaceWidthSubdivisions:this.surfaceWidthSubdivisions;return!("number"!=typeof r||!Number.isFinite(r)||r<=0)&&(!("number"!=typeof o||!Number.isFinite(o)||o<1)&&(this.width=i,this.depth=s,e.has("showSurface")&&(this.showSurface=t.showSurface),e.has("surfaceMaterial")&&(this.surfaceMaterial=t.surfaceMaterial,this.surface.setMaterial(this.surfaceMaterial)),this.surfaceSampleDistance=r,this.surfaceWidthSubdivisions=Math.round(o),this.editorVisual.rebuild(),this.surface.rebuild(),!0))}containsWaterPoint(t){this.object.updateWorldMatrix(!0,!1);const e=E.copy(t).applyMatrix4(q.copy(this.object.matrixWorld).invert()),i=D(this.spline,this.width,this.depth,this.surfaceSampleDistance);for(let t=1;t<i.length;t++){const s=i[t-1],r=i[t];if(C(e,s.leftTop,s.rightTop,r.rightTop,r.leftTop,this.depth))return!0}return!1}getNavigationAreaModifiers(){const t=D(this.spline,this.width,this.depth);if(t.length<2)return[];this.object.updateWorldMatrix(!0,!1);const e=this.object.matrixWorld,i=[];for(let s=1;s<t.length;s++){const r=t[s-1],o=t[s],a=[r.leftTop,r.rightTop,o.rightTop,o.leftTop,r.leftBottom,r.rightBottom,o.rightBottom,o.leftBottom].map(t=>t.clone().applyMatrix4(e));i.push({area:m.Water,vertices:a.slice(0,4).map(t=>t.toArray()),minHeight:Math.min(...a.map(t=>t.y)),maxHeight:Math.max(...a.map(t=>t.y))})}return i}};t([g({range:[.01,1e3]}),e("design:type",Number)],W.prototype,"width",void 0),t([g({range:[.01,1e3]}),e("design:type",Number)],W.prototype,"depth",void 0),t([g({group:"Surface"}),e("design:type",Boolean)],W.prototype,"showSurface",void 0),t([g({type:u,group:"Surface",requires:{showSurface:!0},help:"Optional. Uses a translucent debug material when unset."}),e("design:type",u)],W.prototype,"surfaceMaterial",void 0),t([g({range:[.1,100],group:"Surface",requires:{showSurface:!0},help:"Target spacing in world units between sections along the spline."}),e("design:type",Number)],W.prototype,"surfaceSampleDistance",void 0),t([g({range:[1,64],stepSize:1,group:"Surface",requires:{showSurface:!0},help:"Subdivisions across the water. Increase for vertex displacement and detailed bank effects."}),e("design:type",Number)],W.prototype,"surfaceWidthSubdivisions",void 0),W=t([w({typeId:"WaterSplineVolume"})],W);export{W as WaterSplineVolume};function D(t,e,i,s=.5){if(t.points.length<2||t.length<=0||e<=0||i<0)return[];const r=Math.min(513,Math.max(2,Math.ceil(t.length/Math.max(.01,s))+1)),o=[],a=Array.from({length:r},(e,i)=>t.samplePositionAtDistance(t.length*i/(r-1),new d)),n=Math.min(.5*e,.25*t.length),l=Array.from({length:r},(e,i)=>{const s=t.length*i/(r-1),o=V(t,s-n,new d),a=V(t,s+n,new d).sub(o).setY(0);return a.lengthSq()<1e-8&&t.sampleTangentAtDistance(s,a).setY(0),a.lengthSq()<1e-8&&a.set(1,0,0),a.normalize(),new d(-a.z,0,a.x)}),h=.5*e,c=Array(r).fill(h),u=Array(r).fill(h);for(let e=0;e<r;e++){if(!t.closed&&(0===e||e===r-1))continue;const i=a[0===e?r-2:e-1],s=a[e],o=a[e===r-1?1:e+1],n=Math.min(h,.6*P(i,s,o)),l=N(i,s,o);l>1e-8?c[e]=n:l<-1e-8&&(u[e]=n)}j(c,a),j(u,a);for(let e=0;e<r;e++){const s=l[e],n=a[e].clone().addScaledVector(s,c[e]),h=a[e].clone().addScaledVector(s,-u[e]);o.push({leftTop:n,rightTop:h,leftBottom:n.clone().addScaledVector(I,i),rightBottom:h.clone().addScaledVector(I,i),flowDirection:t.sampleTangentAtDistance(t.length*e/(r-1),new d).normalize(),distanceAlongSpline:t.length*e/(r-1),surfaceWidth:c[e]+u[e]})}return function(t,e,i){B(t.map(t=>t.leftTop),e),B(t.map(t=>t.rightTop),e);for(const e of t)e.leftBottom.copy(e.leftTop).addScaledVector(I,i),e.rightBottom.copy(e.rightTop).addScaledVector(I,i),e.surfaceWidth=e.leftTop.distanceTo(e.rightTop)}(o,t.closed,i),o}function B(t,e){const i=e?t.length-1:t.length;if(!(i<3))for(let s=0;s<2;s++){const s=t.map(t=>t.clone()),r=e?i:i-1;for(let o=e?0:1;o<r;o++){const e=s[(o-1+i)%i],r=s[(o+1)%i];t[o].lerpVectors(e,r,.5).lerp(s[o],.5)}e&&t[t.length-1].copy(t[0])}}function V(t,e,i){if(!t.closed)return t.samplePositionAtDistance(e,i);const s=(e%t.length+t.length)%t.length;return t.samplePositionAtDistance(s,i)}function j(t,e){for(let i=1;i<t.length;i++)t[i]=Math.min(t[i],t[i-1]+.5*e[i].distanceTo(e[i-1]));for(let i=t.length-2;i>=0;i--)t[i]=Math.min(t[i],t[i+1]+.5*e[i].distanceTo(e[i+1]))}function N(t,e,i){return(e.x-t.x)*(i.z-e.z)-(e.z-t.z)*(i.x-e.x)}function P(t,e,i){const s=Math.hypot(e.x-t.x,e.z-t.z),r=Math.hypot(i.x-e.x,i.z-e.z),o=Math.hypot(i.x-t.x,i.z-t.z),a=Math.abs((e.x-t.x)*(i.z-t.z)-(e.z-t.z)*(i.x-t.x));return s<1e-6||r<1e-6||o<1e-6||a<1e-8?1/0:s*r*o/(2*a)}export function createWaterSplineSurfaceGeometry(t,e,i,s){return F(t,e,i,s)}function F(t,e,s,o){const a=new i,n=D(t,e,0,s),l=Math.max(1,Math.round(o))+1;if(n.length<2)return a.setAttribute("position",new r([],3)),a;const h=[],c=[],u=[],p=[],d=[];for(const e of n)for(let i=0;i<l;i++){const s=i/(l-1);h.push(...e.leftTop.clone().lerp(e.rightTop,s).toArray()),c.push(s,t.length>0?e.distanceAlongSpline/t.length:0),u.push(...e.flowDirection.toArray()),p.push(Math.min(s,1-s)*e.surfaceWidth),d.push(e.distanceAlongSpline)}const f=[];for(let t=1;t<n.length;t++)for(let e=1;e<l;e++){const i=(t-1)*l+e-1,s=t*l+e-1;k(f,i,s,s+1,i+1)}return a.setAttribute("position",new r(h,3)),a.setAttribute("uv",new r(c,2)),a.setAttribute("waterFlowDirection",new r(u,3)),a.setAttribute("waterDistanceFromBank",new r(p,1)),a.setAttribute("waterDistanceAlongSpline",new r(d,1)),a.setIndex(f),a.computeVertexNormals(),a.computeBoundingBox(),a.computeBoundingSphere(),a}function k(t,e,i,s,r){t.push(e,i,s,e,s,r)}const I=new d(0,-1,0),q=new p,E=new d;function C(t,e,i,s,r,o){const a=H(t,e,i,s)??H(t,e,s,r);return null!=a&&t.y<=a&&t.y>=a-o}function H(t,e,i,s){const r=(i.z-s.z)*(e.x-s.x)+(s.x-i.x)*(e.z-s.z);if(Math.abs(r)<1e-8)return null;const o=((i.z-s.z)*(t.x-s.x)+(s.x-i.x)*(t.z-s.z))/r,a=((s.z-e.z)*(t.x-s.x)+(e.x-s.x)*(t.z-s.z))/r,n=1-o-a;return o>=0&&a>=0&&n>=0?o*e.y+a*i.y+n*s.y:null}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,19 @@
1
+ import { Material, Matrix4, Vector3 } from 'three';
2
+ import { BaseActor } from '../../index.js';
3
+ import { type NavigationAreaContributor, type NavigationAreaModifier } from '../../ai/navigation-areas.js';
4
+ import { WaterPostProcessSettings, type WaterPostProcessVolume } from './components/water-post-process-settings.js';
5
+ /** A semantic box of water. Its top face is the future water surface. */
6
+ export declare class WaterVolume extends BaseActor implements NavigationAreaContributor, WaterPostProcessVolume {
7
+ private surface;
8
+ private editorVisual;
9
+ readonly underwater: WaterPostProcessSettings;
10
+ showSurface: boolean;
11
+ surfaceMaterial?: Material;
12
+ surfaceSubdivisions: number;
13
+ applySceneParameters(parameters: Record<string, unknown>, changed: ReadonlySet<string>): boolean;
14
+ getNavigationAreaModifiers(): NavigationAreaModifier[];
15
+ containsWaterPoint(point: Vector3): boolean;
16
+ getWaterPostProcessWorldToLocal(target: Matrix4): Matrix4;
17
+ isWaterPostProcessRelevant(cameraPosition: Vector3, transitionDistance: number): boolean;
18
+ }
19
+ //# sourceMappingURL=water-volume-actor.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{__decorate as e,__metadata as t}from"tslib";import{BoxGeometry as a,DoubleSide as r,EdgesGeometry as s,Group as i,LineBasicMaterial as o,LineSegments as n,Material as c,Matrix4 as u,Mesh as h,MeshBasicMaterial as l,PlaneGeometry as f,Vector3 as p}from"three";import{Actor as d,BaseActor as m,Component as b,ActorComponent as w,attach as M}from"../../index.js";import{NavigationArea as y}from"../../ai/navigation-areas.js";import{Parameter as v}from"../../../shader/parameter.js";import{WaterPostProcessSettings as S,boxContainsWorldPoint as x}from"./components/water-post-process-settings.js";let g=class extends w{constructor(){super(...arguments),this.fallbackMaterial=new l({color:1477586,transparent:!0,opacity:.65,side:r}),this.surface=new h(new f,this.fallbackMaterial)}onInit(){this.surface.name="Water Surface",this.surface.position.y=.5,this.actor.object.add(this.surface),this.rebuild()}rebuild(){const e=this.surface.geometry,t=Math.max(1,Math.round(this.actor.surfaceSubdivisions));this.surface.geometry=new f(1,1,t,t).rotateX(-Math.PI/2),this.surface.material=this.actor.surfaceMaterial??this.fallbackMaterial,this.surface.visible=this.actor.showSurface,e.dispose()}onEndPlay(){this.surface.geometry.dispose(),this.fallbackMaterial.dispose(),this.surface.removeFromParent()}};g=e([b({inEditor:!0})],g);let W=class extends w{constructor(){super(...arguments),this.visual=new i}onInit(){const e=new a(1,1,1);this.visual.add(new h(e,new l({color:1477586,transparent:!0,opacity:.18,depthWrite:!1})),new n(new s(e),new o({color:3520767}))),this.actor.object.add(this.visual)}};W=e([b({inEditor:!0,editorOnly:!0})],W);let j=class extends m{constructor(){super(...arguments),this.surface=M(g),this.editorVisual=M(W),this.underwater=M(S),this.showSurface=!0,this.surfaceSubdivisions=1}applySceneParameters(e,t){if(![...t].every(e=>"showSurface"===e||"surfaceMaterial"===e||"surfaceSubdivisions"===e))return!1;if(t.has("showSurface")&&"boolean"!=typeof e.showSurface)return!1;if(t.has("surfaceMaterial")&&null!=e.surfaceMaterial&&!(e.surfaceMaterial instanceof c))return!1;const a=t.has("surfaceSubdivisions")?e.surfaceSubdivisions:this.surfaceSubdivisions;return!("number"!=typeof a||!Number.isFinite(a)||a<1)&&(t.has("showSurface")&&(this.showSurface=e.showSurface),t.has("surfaceMaterial")&&(this.surfaceMaterial=e.surfaceMaterial),this.surfaceSubdivisions=Math.round(a),this.surface.rebuild(),!0)}getNavigationAreaModifiers(){this.object.updateWorldMatrix(!0,!1);const e=this.object.matrixWorld,t=P.map(t=>t.clone().applyMatrix4(e).toArray());let a=1/0,r=-1/0;for(const t of I){const s=k.copy(t).applyMatrix4(e).y;a=Math.min(a,s),r=Math.max(r,s)}return[{area:y.Water,vertices:t,minHeight:a,maxHeight:r}]}containsWaterPoint(e){return x(this.object,e)}getWaterPostProcessWorldToLocal(e){return this.object.updateWorldMatrix(!0,!1),e.copy(this.object.matrixWorld).invert()}isWaterPostProcessRelevant(e,t){this.object.updateWorldMatrix(!0,!1),N.copy(e).applyMatrix4(E.copy(this.object.matrixWorld).invert());const a=this.object.matrixWorld.elements,r=Math.max(1e-6,Math.hypot(a[4],a[5],a[6])),s=Math.max(0,t);return Math.abs(N.y-.5)*r<=s&&Math.abs(N.x)<=.5&&Math.abs(N.z)<=.5}};e([v({group:"Surface"}),t("design:type",Boolean)],j.prototype,"showSurface",void 0),e([v({type:c,group:"Surface",requires:{showSurface:!0},help:"Optional. Uses a translucent debug material when unset."}),t("design:type",c)],j.prototype,"surfaceMaterial",void 0),e([v({range:[1,256],stepSize:1,group:"Surface",requires:{showSurface:!0},help:"Grid subdivisions per axis. Increase only when the material displaces vertices."}),t("design:type",Number)],j.prototype,"surfaceSubdivisions",void 0),j=e([d({typeId:"WaterVolume"})],j);export{j as WaterVolume};const P=[new p(-.5,0,-.5),new p(.5,0,-.5),new p(.5,0,.5),new p(-.5,0,.5)],I=[-.5,.5].flatMap(e=>[-.5,.5].flatMap(t=>[-.5,.5].map(a=>new p(e,t,a)))),k=new p,E=new u,N=new p;/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{ArrowHelper as r,ConeGeometry as i,EdgesGeometry as o,LineBasicMaterial as s,LineSegments as n,MeshStandardMaterial as a,PerspectiveCamera as l,Vector3 as h}from"three";import{Parameter as c}from"../../../shader/parameter.js";import{ViewController as d}from"../../services/render.js";import{ActorComponent as p,attach as m,Component as w}from"../component.js";import{inject as v}from"../../../gameplay/inject.js";const b=void 0!==window&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let y=class extends p{constructor(){super(...arguments),this.near=.5,this.far=500,this.viewAngle=b?30:45,this.viewController=v(d),this.debugMesh=m(f),this.aspect=this.viewController.htmlElement.clientWidth/this.viewController.htmlElement.clientHeight,this.instance=new l(this.viewAngle,this.aspect,this.near,this.far)}onInit(){this.actor.object.add(this.instance),this.instance.near=this.near,this.instance.far=this.far,this.instance.fov=this.viewAngle}};e([c(),t("design:type",Number)],y.prototype,"near",void 0),e([c(),t("design:type",Number)],y.prototype,"far",void 0),e([c(),t("design:type",Number)],y.prototype,"viewAngle",void 0),y=e([w({inEditor:!0})],y);export{y as CameraComponent};let f=class extends p{constructor(){super(...arguments),this.arrowColor=16101442}onInit(){const e=new i(1,1,4);e.rotateX(Math.PI/2),e.rotateZ(Math.PI/4),e.scale(1,9/16,1);const t=new o(e),l=(new a({color:3355443}),new n(t,new s({color:16777215}))),c=new r(new h(0,0,-1),new h(0,0,0),1.2,this.arrowColor,.15,.2);l.add(c),c.layers.disableAll(),c.layers.enable(19),c.traverse(e=>{e.layers.disableAll(),e.layers.enable(19)}),this.actor.object.add(l)}};f=e([w({inEditor:!0,editorOnly:!0})],f);export{f as CameraMesh};/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{ArrowHelper as r,ConeGeometry as i,EdgesGeometry as o,LineBasicMaterial as s,LineSegments as n,MeshStandardMaterial as a,PerspectiveCamera as l,Vector3 as h}from"three";import{Parameter as c}from"../../../shader/parameter.js";import{ViewController as d}from"../../services/render.js";import{ActorComponent as p,attach as m,Component as w}from"../component.js";import{inject as v}from"../../../gameplay/inject.js";const b=void 0!==window&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let y=class extends p{constructor(){super(...arguments),this.near=.1,this.far=500,this.viewAngle=b?30:45,this.viewController=v(d),this.debugMesh=m(f),this.aspect=this.viewController.htmlElement.clientWidth/this.viewController.htmlElement.clientHeight,this.instance=new l(this.viewAngle,this.aspect,this.near,this.far)}onInit(){this.actor.object.add(this.instance),this.instance.near=this.near,this.instance.far=this.far,this.instance.fov=this.viewAngle}};e([c(),t("design:type",Number)],y.prototype,"near",void 0),e([c(),t("design:type",Number)],y.prototype,"far",void 0),e([c(),t("design:type",Number)],y.prototype,"viewAngle",void 0),y=e([w({inEditor:!0})],y);export{y as CameraComponent};let f=class extends p{constructor(){super(...arguments),this.arrowColor=16101442}onInit(){const e=new i(1,1,4);e.rotateX(Math.PI/2),e.rotateZ(Math.PI/4),e.scale(1,9/16,1);const t=new o(e),l=(new a({color:3355443}),new n(t,new s({color:16777215}))),c=new r(new h(0,0,-1),new h(0,0,0),1.2,this.arrowColor,.15,.2);l.add(c),c.layers.disableAll(),c.layers.enable(19),c.traverse(e=>{e.layers.disableAll(),e.layers.enable(19)}),this.actor.object.add(l)}};f=e([w({inEditor:!0,editorOnly:!0})],f);export{f as CameraMesh};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as o}from"tslib";import{ActorComponent as e,Component as i}from"../component.js";import{Vector3 as s,MathUtils as r,PerspectiveCamera as n,Object3D as h}from"three";import{ViewController as a}from"../../services/render.js";import{DecimalInput as l,RestrictedRotationInput as c}from"../../input/index.js";import{PhysicsSystem as p}from"../../services/physics/physics-system.js";import{Parameter as m}from"../../../shader/parameter.js";import{World as d}from"../../services/world.js";import{inject as u}from"../../inject.js";import{ease as y}from"@hology/nebula";const f=void 0!==window&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let C=class extends e{constructor(){super(),this.viewController=u(a),this.physicsSystem=u(p),this.aspect=this.viewController.htmlElement.clientWidth/this.viewController.htmlElement.clientHeight,this.near=.5,this.far=500,this.viewAngle=f?30:45,this.collision=!0,this.collisionSphereRadius=.25,this.smoothCamera=!1,this.smoothSpeed=10,this.teleportSnapDistance=5,this.camera=new n(this.viewAngle,this.aspect,this.near,this.far),this.distance=9,this.minDistance=1.5,this.maxDistance=this.distance,this.height=3,this.offsetX=-1,this.offsetY=2,this.offsetZ=1.5,this.autoActivate=!0,this.bounceBackSpeed=3,this.restrictedDistance=0,this.hasCollisionRestriction=!1,this.rotationInput=new c(-Math.PI/4,Math.PI/2-.7),this.zoomInput=new l(1,0,1),this.offset=new s,this.lookAtOffset=new s(this.offsetX,0,this.offsetZ),this.fixedBehind=!0,this.world=u(d),this.activated=!1,this.isMouseLocked=!1,this.prevFixedBehind=!1,this.blendDurationLeft=0,this.pointerEventsRegistered=!1,this.temporaryControlActive=!1,this.temporaryControlWeight=0,this.temporaryControlTargetWeight=0,this.temporaryControlBlendInDuration=.5,this.temporaryControlBlendOutDuration=.5,this.temporaryControlPositionEnabled=!1,this.temporaryControlBaseFieldOfView=this.camera.fov,this.temporaryControlFieldOfView=null,this.temporaryControlPosition=new s,this.temporaryControlLookAt=new s,this.pointerLockInactivatedAt=null,this.onMouseDown=t=>{this.isMouseLocked||"mouse"!==t.pointerType||this.hideCursor()},this.onKeyDown=t=>{"Escape"===t.key&&this.showCursor()},this.onPointerLockChange=()=>{this.isMouseLocked=null!=document.pointerLockElement||null!=document.mozPointerLockElement,this.element.style.cursor=this.isMouseLocked?"none":"default",this.isMouseLocked||(this.pointerLockInactivatedAt=performance.now())},this.prevLookAt=new s,this.smoothedLookAt=new s,this.previousTargetLookAt=new s,this.hasSmoothedLookAt=!1,this.smoothedRotX=0,this.smoothedRotY=0,this.smoothZoom=0}async onInit(){this.prevFixedBehind=this.fixedBehind,this.world.scene.add(this.camera),this.rotationInput.rotation.copy(this.actor.rotation),this.smoothedRotX=this.rotationInput.rotation.x,this.smoothedRotY=this.rotationInput.rotation.y,this.hasCollisionRestriction=!1,this.lookAtOffset.set(this.offsetX,0,this.offsetZ),this.smoothZoom=this.zoomInput.value,this.autoActivate&&this.activate(),this.disposed.subscribe(()=>{this.unregisterPointerEvents()})}activate(){this.activated=!0,this.hasSmoothedLookAt=!1,this.viewController.setCamera(this.camera),this.isMouseLocked=null!=document.pointerLockElement||null!=document.mozPointerLockElement,this.registerPointerEvents()}deactivate(){this.activated=!1,this.isMouseLocked=!1,this.unregisterPointerEvents()}setTemporaryControl(t,o,e={}){this.temporaryControlPosition.copy(t),this.temporaryControlLookAt.copy(o),this.temporaryControlPositionEnabled=!0,this.activateTemporaryControl(e)}setTemporaryLookAt(t,o={}){this.temporaryControlLookAt.copy(t),this.temporaryControlPositionEnabled=!1,this.activateTemporaryControl(o)}activateTemporaryControl(t){this.temporaryControlActive||(this.temporaryControlBaseFieldOfView=this.camera.fov),this.temporaryControlFieldOfView=null==t.fieldOfView?null:r.clamp(t.fieldOfView,1,179),null!=t.blendInDuration&&(this.temporaryControlBlendInDuration=Math.max(0,t.blendInDuration)),null!=t.blendOutDuration&&(this.temporaryControlBlendOutDuration=Math.max(0,t.blendOutDuration)),this.temporaryControlActive=!0,this.temporaryControlTargetWeight=1}clearTemporaryControl(t){this.temporaryControlActive&&(null!=t&&(this.temporaryControlBlendOutDuration=Math.max(0,t)),this.temporaryControlTargetWeight=0)}registerPointerEvents(){if(this.pointerEventsRegistered||null==document.body.requestPointerLock)return;const t=this.element;t.addEventListener("pointerdown",this.onMouseDown),t.addEventListener("keydown",this.onKeyDown),document.addEventListener("pointerlockchange",this.onPointerLockChange,!1),this.pointerEventsRegistered=!0}unregisterPointerEvents(){if(!this.pointerEventsRegistered)return;const t=this.element;t.removeEventListener("pointerdown",this.onMouseDown),t.removeEventListener("keydown",this.onKeyDown),document.removeEventListener("pointerlockchange",this.onPointerLockChange,!1),this.pointerEventsRegistered=!1}onLateUpdate(t){this.activated&&this.setFromRotation(t)}get element(){return this.viewController.htmlElement}hideCursor({ignoreRecentUnlock:t=!1}={}){!t&&null!=this.pointerLockInactivatedAt&&performance.now()-this.pointerLockInactivatedAt<1600||this.requestPointerLock()}requestPointerLock(){const t=this.element.getElementsByTagName("canvas")[0];if(null!=t&&t.isConnected&&t.ownerDocument===document&&null!=t.requestPointerLock)try{const o=t.requestPointerLock({unadjustedMovement:!0});o?.catch(()=>this.onPointerLockChange())}catch{this.onPointerLockChange()}else this.onPointerLockChange()}showCursor(){this.pointerLockInactivatedAt=performance.now(),this.element.style.cursor="default",null==document.pointerLockElement&&null==document.mozPointerLockElement||window.document.exitPointerLock(),this.isMouseLocked=!1}setFromRotation(t){this.lookAtOffset.set(this.offsetX,0,this.offsetZ),this.fixedBehind!==this.prevFixedBehind?(this.blendDurationLeft=1,this.prevFixedBehind=this.fixedBehind):this.blendDurationLeft>0&&(this.blendDurationLeft-=t);let o=this.zoomInput.value,e=this.rotationInput.rotation.x,i=this.rotationInput.rotation.y;if(this.smoothCamera){const s=1-Math.exp(-this.smoothSpeed*t*2);this.smoothedRotX=r.lerp(this.smoothedRotX,e,s),this.smoothedRotY=r.lerp(this.smoothedRotY,i,s),e=this.smoothedRotX,i=this.smoothedRotY,this.smoothZoom=r.lerp(this.smoothZoom,o,.4*s),o=this.smoothZoom}else this.smoothedRotX=e,this.smoothedRotY=i;const s=r.clamp(this.distance,this.minDistance,Math.max(this.distance*o,this.minDistance)),n=Math.cos(e)*s,h=this.fixedBehind?0:i;this.offset.x=Math.sin(-h)*n,this.offset.y=Math.sin(e)*s+this.offsetY,this.offset.z=Math.cos(-h)*-n,this.fixedBehind&&this.offset.add(this.lookAtOffset),this.updateCameraPosition(t)}checkForCollision(t,o){const e=g.subVectors(this.camera.position,t),i=e.length();if(i<.001)return;e.divideScalar(i);const s=this.physicsSystem.sphereCast(t,this.collisionSphereRadius,e,i,void 0,{excludeActor:this.actor,excludeTriggers:!0,collisionFilter:-2}),n=s.hasHit?Math.max(this.minDistance,s.distance-.05):i;if(!this.hasCollisionRestriction||n<=this.restrictedDistance)this.restrictedDistance=n,this.hasCollisionRestriction=!0;else{const t=1-Math.exp(-this.bounceBackSpeed*o);this.restrictedDistance=r.lerp(this.restrictedDistance,n,t)}this.camera.position.copy(t).addScaledVector(e,Math.min(i,this.restrictedDistance))}getLookAtPosition(){const t=k;return t.set(0,0,0),t.y=this.height,this.fixedBehind&&t.add(this.lookAtOffset),t.applyMatrix4(this.actor.object.matrixWorld),t}updateCameraPosition(t){this.actor.object.updateWorldMatrix(!0,!1),this.fixedBehind?(v.position.set(this.offset.x,this.offset.y,this.offset.z),v.rotation.set(0,0,0),v.scale.set(1,1,1),v.applyMatrix4(this.actor.object.matrix)):v.position.copy(this.actor.position).add(this.offset);const o=y.easeInOutCubic(1-this.blendDurationLeft);if(this.blendDurationLeft>0){const t=this.getLookAtPosition();this.prevLookAt.lerp(t,o),this.camera.lookAt(this.prevLookAt),this.camera.position.lerp(v.position,o),this.smoothedLookAt.copy(this.prevLookAt),this.previousTargetLookAt.copy(t),this.hasSmoothedLookAt=!0}else{const o=this.getLookAtPosition();if(this.smoothCamera){const e=1-Math.exp(-this.smoothSpeed*t),i=Math.max(0,this.teleportSnapDistance);!this.hasSmoothedLookAt||this.previousTargetLookAt.distanceToSquared(o)>i*i?this.smoothedLookAt.copy(o):this.smoothedLookAt.lerp(o,e)}else this.smoothedLookAt.copy(o);this.previousTargetLookAt.copy(o),this.hasSmoothedLookAt=!0,L.subVectors(v.position,o),this.camera.position.copy(this.smoothedLookAt).add(L),this.camera.lookAt(this.smoothedLookAt),this.prevLookAt.copy(this.smoothedLookAt)}this.collision&&(this.checkForCollision(this.prevLookAt,t),this.camera.lookAt(this.prevLookAt)),this.applyTemporaryControl(t)}applyTemporaryControl(t){if(!this.temporaryControlActive)return;this.temporaryControlTargetWeight>this.temporaryControlWeight?this.temporaryControlWeight=0===this.temporaryControlBlendInDuration?1:Math.min(1,this.temporaryControlWeight+t/this.temporaryControlBlendInDuration):this.temporaryControlTargetWeight<this.temporaryControlWeight&&(this.temporaryControlWeight=0===this.temporaryControlBlendOutDuration?0:Math.max(0,this.temporaryControlWeight-t/this.temporaryControlBlendOutDuration));const o=y.easeInOutCubic(this.temporaryControlWeight);this.temporaryControlPositionEnabled&&this.camera.position.lerp(this.getTemporaryControlPosition(),o),x.position.copy(this.camera.position),x.up.copy(this.camera.up),x.lookAt(this.temporaryControlLookAt),this.camera.quaternion.slerp(x.quaternion,o);const e=this.temporaryControlFieldOfView??this.temporaryControlBaseFieldOfView,i=r.lerp(this.temporaryControlBaseFieldOfView,e,o);this.camera.fov!==i&&(this.camera.fov=i,this.camera.updateProjectionMatrix()),0===this.temporaryControlTargetWeight&&0===this.temporaryControlWeight&&(this.temporaryControlActive=!1)}getTemporaryControlPosition(){if(!this.collision)return this.temporaryControlPosition;A.subVectors(this.temporaryControlPosition,this.temporaryControlLookAt);const t=A.length();if(t<.001)return this.temporaryControlPosition;A.divideScalar(t);const o=this.physicsSystem.sphereCast(this.temporaryControlLookAt,this.collisionSphereRadius,A,t,void 0,{excludeActor:this.actor,excludeTriggers:!0,collisionFilter:-2});return!o.hasHit||o.distance>=t?this.temporaryControlPosition:w.copy(this.temporaryControlLookAt).addScaledVector(A,Math.max(0,o.distance-.05))}};t([m(),o("design:type",Number)],C.prototype,"near",void 0),t([m(),o("design:type",Number)],C.prototype,"far",void 0),t([m(),o("design:type",Number)],C.prototype,"viewAngle",void 0),t([m(),o("design:type",Boolean)],C.prototype,"collision",void 0),t([m(),o("design:type",Number)],C.prototype,"collisionSphereRadius",void 0),t([m(),o("design:type",Boolean)],C.prototype,"smoothCamera",void 0),t([m(),o("design:type",Number)],C.prototype,"smoothSpeed",void 0),t([m(),o("design:type",Number)],C.prototype,"teleportSnapDistance",void 0),C=t([i(),o("design:paramtypes",[])],C);export{C as ThirdPersonCameraComponent};const v=new h,k=new s,L=new s,g=new s,A=new s,w=new s,x=new n;export class ThirdPartyCameraComponent extends C{}/*
1
+ import{__decorate as t,__metadata as o}from"tslib";import{ActorComponent as e,Component as i}from"../component.js";import{Vector3 as s,MathUtils as r,PerspectiveCamera as n,Object3D as h}from"three";import{ViewController as a}from"../../services/render.js";import{DecimalInput as l,RestrictedRotationInput as c}from"../../input/index.js";import{PhysicsSystem as p}from"../../services/physics/physics-system.js";import{Parameter as m}from"../../../shader/parameter.js";import{World as d}from"../../services/world.js";import{inject as u}from"../../inject.js";import{ease as y}from"@hology/nebula";const f=void 0!==window&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let C=class extends e{constructor(){super(),this.viewController=u(a),this.physicsSystem=u(p),this.aspect=this.viewController.htmlElement.clientWidth/this.viewController.htmlElement.clientHeight,this.near=.1,this.far=500,this.viewAngle=f?30:45,this.collision=!0,this.collisionSphereRadius=.25,this.smoothCamera=!1,this.smoothSpeed=10,this.teleportSnapDistance=5,this.camera=new n(this.viewAngle,this.aspect,this.near,this.far),this.distance=9,this.minDistance=1.5,this.maxDistance=this.distance,this.height=3,this.offsetX=-1,this.offsetY=2,this.offsetZ=1.5,this.autoActivate=!0,this.bounceBackSpeed=3,this.restrictedDistance=0,this.hasCollisionRestriction=!1,this.rotationInput=new c(-Math.PI/4,Math.PI/2-.7),this.zoomInput=new l(1,0,1),this.offset=new s,this.lookAtOffset=new s(this.offsetX,0,this.offsetZ),this.fixedBehind=!0,this.world=u(d),this.activated=!1,this.isMouseLocked=!1,this.prevFixedBehind=!1,this.blendDurationLeft=0,this.pointerEventsRegistered=!1,this.temporaryControlActive=!1,this.temporaryControlWeight=0,this.temporaryControlTargetWeight=0,this.temporaryControlBlendInDuration=.5,this.temporaryControlBlendOutDuration=.5,this.temporaryControlPositionEnabled=!1,this.temporaryControlBaseFieldOfView=this.camera.fov,this.temporaryControlFieldOfView=null,this.temporaryControlPosition=new s,this.temporaryControlLookAt=new s,this.pointerLockInactivatedAt=null,this.onMouseDown=t=>{this.isMouseLocked||"mouse"!==t.pointerType||this.hideCursor()},this.onKeyDown=t=>{"Escape"===t.key&&this.showCursor()},this.onPointerLockChange=()=>{this.isMouseLocked=null!=document.pointerLockElement||null!=document.mozPointerLockElement,this.element.style.cursor=this.isMouseLocked?"none":"default",this.isMouseLocked||(this.pointerLockInactivatedAt=performance.now())},this.prevLookAt=new s,this.smoothedLookAt=new s,this.previousTargetLookAt=new s,this.hasSmoothedLookAt=!1,this.smoothedRotX=0,this.smoothedRotY=0,this.smoothZoom=0}async onInit(){this.prevFixedBehind=this.fixedBehind,this.world.scene.add(this.camera),this.rotationInput.rotation.copy(this.actor.rotation),this.smoothedRotX=this.rotationInput.rotation.x,this.smoothedRotY=this.rotationInput.rotation.y,this.hasCollisionRestriction=!1,this.lookAtOffset.set(this.offsetX,0,this.offsetZ),this.smoothZoom=this.zoomInput.value,this.autoActivate&&this.activate(),this.disposed.subscribe(()=>{this.unregisterPointerEvents()})}activate(){this.activated=!0,this.hasSmoothedLookAt=!1,this.viewController.setCamera(this.camera),this.isMouseLocked=null!=document.pointerLockElement||null!=document.mozPointerLockElement,this.registerPointerEvents()}deactivate(){this.activated=!1,this.isMouseLocked=!1,this.unregisterPointerEvents()}setTemporaryControl(t,o,e={}){this.temporaryControlPosition.copy(t),this.temporaryControlLookAt.copy(o),this.temporaryControlPositionEnabled=!0,this.activateTemporaryControl(e)}setTemporaryLookAt(t,o={}){this.temporaryControlLookAt.copy(t),this.temporaryControlPositionEnabled=!1,this.activateTemporaryControl(o)}activateTemporaryControl(t){this.temporaryControlActive||(this.temporaryControlBaseFieldOfView=this.camera.fov),this.temporaryControlFieldOfView=null==t.fieldOfView?null:r.clamp(t.fieldOfView,1,179),null!=t.blendInDuration&&(this.temporaryControlBlendInDuration=Math.max(0,t.blendInDuration)),null!=t.blendOutDuration&&(this.temporaryControlBlendOutDuration=Math.max(0,t.blendOutDuration)),this.temporaryControlActive=!0,this.temporaryControlTargetWeight=1}clearTemporaryControl(t){this.temporaryControlActive&&(null!=t&&(this.temporaryControlBlendOutDuration=Math.max(0,t)),this.temporaryControlTargetWeight=0)}registerPointerEvents(){if(this.pointerEventsRegistered||null==document.body.requestPointerLock)return;const t=this.element;t.addEventListener("pointerdown",this.onMouseDown),t.addEventListener("keydown",this.onKeyDown),document.addEventListener("pointerlockchange",this.onPointerLockChange,!1),this.pointerEventsRegistered=!0}unregisterPointerEvents(){if(!this.pointerEventsRegistered)return;const t=this.element;t.removeEventListener("pointerdown",this.onMouseDown),t.removeEventListener("keydown",this.onKeyDown),document.removeEventListener("pointerlockchange",this.onPointerLockChange,!1),this.pointerEventsRegistered=!1}onLateUpdate(t){this.activated&&this.setFromRotation(t)}get element(){return this.viewController.htmlElement}hideCursor({ignoreRecentUnlock:t=!1}={}){!t&&null!=this.pointerLockInactivatedAt&&performance.now()-this.pointerLockInactivatedAt<1600||this.requestPointerLock()}requestPointerLock(){const t=this.element.getElementsByTagName("canvas")[0];if(null!=t&&t.isConnected&&t.ownerDocument===document&&null!=t.requestPointerLock)try{const o=t.requestPointerLock({unadjustedMovement:!0});o?.catch(()=>this.onPointerLockChange())}catch{this.onPointerLockChange()}else this.onPointerLockChange()}showCursor(){this.pointerLockInactivatedAt=performance.now(),this.element.style.cursor="default",null==document.pointerLockElement&&null==document.mozPointerLockElement||window.document.exitPointerLock(),this.isMouseLocked=!1}setFromRotation(t){this.lookAtOffset.set(this.offsetX,0,this.offsetZ),this.fixedBehind!==this.prevFixedBehind?(this.blendDurationLeft=1,this.prevFixedBehind=this.fixedBehind):this.blendDurationLeft>0&&(this.blendDurationLeft-=t);let o=this.zoomInput.value,e=this.rotationInput.rotation.x,i=this.rotationInput.rotation.y;if(this.smoothCamera){const s=1-Math.exp(-this.smoothSpeed*t*2);this.smoothedRotX=r.lerp(this.smoothedRotX,e,s),this.smoothedRotY=r.lerp(this.smoothedRotY,i,s),e=this.smoothedRotX,i=this.smoothedRotY,this.smoothZoom=r.lerp(this.smoothZoom,o,.4*s),o=this.smoothZoom}else this.smoothedRotX=e,this.smoothedRotY=i;const s=r.clamp(this.distance,this.minDistance,Math.max(this.distance*o,this.minDistance)),n=Math.cos(e)*s,h=this.fixedBehind?0:i;this.offset.x=Math.sin(-h)*n,this.offset.y=Math.sin(e)*s+this.offsetY,this.offset.z=Math.cos(-h)*-n,this.fixedBehind&&this.offset.add(this.lookAtOffset),this.updateCameraPosition(t)}checkForCollision(t,o){const e=g.subVectors(this.camera.position,t),i=e.length();if(i<.001)return;e.divideScalar(i);const s=this.physicsSystem.sphereCast(t,this.collisionSphereRadius,e,i,void 0,{excludeActor:this.actor,excludeTriggers:!0,collisionFilter:-2}),n=s.hasHit?Math.max(this.minDistance,s.distance-.05):i;if(!this.hasCollisionRestriction||n<=this.restrictedDistance)this.restrictedDistance=n,this.hasCollisionRestriction=!0;else{const t=1-Math.exp(-this.bounceBackSpeed*o);this.restrictedDistance=r.lerp(this.restrictedDistance,n,t)}this.camera.position.copy(t).addScaledVector(e,Math.min(i,this.restrictedDistance))}getLookAtPosition(){const t=k;return t.set(0,0,0),t.y=this.height,this.fixedBehind&&t.add(this.lookAtOffset),t.applyMatrix4(this.actor.object.matrixWorld),t}updateCameraPosition(t){this.actor.object.updateWorldMatrix(!0,!1),this.fixedBehind?(v.position.set(this.offset.x,this.offset.y,this.offset.z),v.rotation.set(0,0,0),v.scale.set(1,1,1),v.applyMatrix4(this.actor.object.matrix)):v.position.copy(this.actor.position).add(this.offset);const o=y.easeInOutCubic(1-this.blendDurationLeft);if(this.blendDurationLeft>0){const t=this.getLookAtPosition();this.prevLookAt.lerp(t,o),this.camera.lookAt(this.prevLookAt),this.camera.position.lerp(v.position,o),this.smoothedLookAt.copy(this.prevLookAt),this.previousTargetLookAt.copy(t),this.hasSmoothedLookAt=!0}else{const o=this.getLookAtPosition();if(this.smoothCamera){const e=1-Math.exp(-this.smoothSpeed*t),i=Math.max(0,this.teleportSnapDistance);!this.hasSmoothedLookAt||this.previousTargetLookAt.distanceToSquared(o)>i*i?this.smoothedLookAt.copy(o):this.smoothedLookAt.lerp(o,e)}else this.smoothedLookAt.copy(o);this.previousTargetLookAt.copy(o),this.hasSmoothedLookAt=!0,L.subVectors(v.position,o),this.camera.position.copy(this.smoothedLookAt).add(L),this.camera.lookAt(this.smoothedLookAt),this.prevLookAt.copy(this.smoothedLookAt)}this.collision&&(this.checkForCollision(this.prevLookAt,t),this.camera.lookAt(this.prevLookAt)),this.applyTemporaryControl(t)}applyTemporaryControl(t){if(!this.temporaryControlActive)return;this.temporaryControlTargetWeight>this.temporaryControlWeight?this.temporaryControlWeight=0===this.temporaryControlBlendInDuration?1:Math.min(1,this.temporaryControlWeight+t/this.temporaryControlBlendInDuration):this.temporaryControlTargetWeight<this.temporaryControlWeight&&(this.temporaryControlWeight=0===this.temporaryControlBlendOutDuration?0:Math.max(0,this.temporaryControlWeight-t/this.temporaryControlBlendOutDuration));const o=y.easeInOutCubic(this.temporaryControlWeight);this.temporaryControlPositionEnabled&&this.camera.position.lerp(this.getTemporaryControlPosition(),o),x.position.copy(this.camera.position),x.up.copy(this.camera.up),x.lookAt(this.temporaryControlLookAt),this.camera.quaternion.slerp(x.quaternion,o);const e=this.temporaryControlFieldOfView??this.temporaryControlBaseFieldOfView,i=r.lerp(this.temporaryControlBaseFieldOfView,e,o);this.camera.fov!==i&&(this.camera.fov=i,this.camera.updateProjectionMatrix()),0===this.temporaryControlTargetWeight&&0===this.temporaryControlWeight&&(this.temporaryControlActive=!1)}getTemporaryControlPosition(){if(!this.collision)return this.temporaryControlPosition;A.subVectors(this.temporaryControlPosition,this.temporaryControlLookAt);const t=A.length();if(t<.001)return this.temporaryControlPosition;A.divideScalar(t);const o=this.physicsSystem.sphereCast(this.temporaryControlLookAt,this.collisionSphereRadius,A,t,void 0,{excludeActor:this.actor,excludeTriggers:!0,collisionFilter:-2});return!o.hasHit||o.distance>=t?this.temporaryControlPosition:w.copy(this.temporaryControlLookAt).addScaledVector(A,Math.max(0,o.distance-.05))}};t([m(),o("design:type",Number)],C.prototype,"near",void 0),t([m(),o("design:type",Number)],C.prototype,"far",void 0),t([m(),o("design:type",Number)],C.prototype,"viewAngle",void 0),t([m(),o("design:type",Boolean)],C.prototype,"collision",void 0),t([m(),o("design:type",Number)],C.prototype,"collisionSphereRadius",void 0),t([m(),o("design:type",Boolean)],C.prototype,"smoothCamera",void 0),t([m(),o("design:type",Number)],C.prototype,"smoothSpeed",void 0),t([m(),o("design:type",Number)],C.prototype,"teleportSnapDistance",void 0),C=t([i(),o("design:paramtypes",[])],C);export{C as ThirdPersonCameraComponent};const v=new h,k=new s,L=new s,g=new s,A=new s,w=new s,x=new n;export class ThirdPartyCameraComponent extends C{}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -8,7 +8,6 @@ type ActorComponentParamKey<T extends ActorComponent> = Extract<keyof ActorCompo
8
8
  export type ActorComponentParamSet<T extends ActorComponent> = Set<ActorComponentParamKey<T>>;
9
9
  export declare abstract class ActorComponent<ActorType extends BaseActor = BaseActor> {
10
10
  actor: ActorType;
11
- constructor();
12
11
  onInit(): Promise<void> | void;
13
12
  onBeginPlay(): void;
14
13
  onEndPlay(): void;
@@ -1,4 +1,4 @@
1
- import{Container as t,Service as o,Inject as e}from"typedi";import{_setupActorUpdateEventHandlers as n}from"./actor.js";import{activeContainerInstance as r}from"./internal/container-map.js";import{randomString as i}from"../../utils/math.js";import{actorConstructContext as a}from"./factory.js";import{registerComponentClass as s}from"./type-registry.js";export{getComponentClassById,getComponentClassId,getRegisteredComponentClasses}from"./type-registry.js";export class ActorComponent{constructor(){this.actor=a.actor,n.call(this)}onInit(){}onBeginPlay(){}onEndPlay(){}applySceneParameters(t,o){return!1}onUpdate(t){}onLateUpdate(t){}get disposed(){return this.actor.disposed}attach(t,o){return this.actor.attach(t,o)}}ActorComponent.__isActorComponent=!0;export function Component(t={inEditor:!1,editorOnly:!1}){const e=o({transient:!0});return function(o){const n=arguments[1],r=t.typeId??n?.name?.toString()??o.name,i=s(r,o);null!=i&&i!==o&&console.warn(`Duplicate component class id ${r}`),o.__componentId=r,o.__inEditor=t.inEditor,o.__onlyEditor=t.editorOnly,e(o)}}export function Attach(o={},n){return function(r,i,a){if(null==r)return void Reflect.defineMetadata("design:type",n,n.prototype,i);const s=n??Reflect.getMetadata("design:type",r,i);e(()=>s)(r,i,a);const c=t.handlers.find(t=>t.object===r&&t.propertyName===i&&t.index===a),p=c.value;c.value=t=>{const e=p(t);return Object.assign(e,o)}}}export function attach(o,e){const n=r.value??t.of("default"),a=i();n.set({id:a,type:o,transient:!0});const s=n.get(a);if(null!=e)for(const t of Object.keys(e))s[t]=e[t];return s}/*
1
+ import{Container as t,Service as e,Inject as n}from"typedi";import{activeContainerInstance as o}from"./internal/container-map.js";import{randomString as r}from"../../utils/math.js";import{actorConstructContext as i}from"./factory.js";import{registerComponentClass as a}from"./type-registry.js";export{getComponentClassById,getComponentClassId,getRegisteredComponentClasses}from"./type-registry.js";export class ActorComponent{constructor(){this.actor=i.actor}onInit(){}onBeginPlay(){}onEndPlay(){}applySceneParameters(t,e){return!1}onUpdate(t){}onLateUpdate(t){}get disposed(){return this.actor.disposed}attach(t,e){return this.actor.attach(t,e)}}ActorComponent.__isActorComponent=!0;export function Component(t={inEditor:!1,editorOnly:!1}){const n=e({transient:!0});return function(e){const o=arguments[1],r=t.typeId??o?.name?.toString()??e.name,i=a(r,e);null!=i&&i!==e&&console.warn(`Duplicate component class id ${r}`),e.__componentId=r,e.__inEditor=t.inEditor,e.__onlyEditor=t.editorOnly,n(e)}}export function Attach(e={},o){return function(r,i,a){if(null==r)return void Reflect.defineMetadata("design:type",o,o.prototype,i);const s=o??Reflect.getMetadata("design:type",r,i);n(()=>s)(r,i,a);const c=t.handlers.find(t=>t.object===r&&t.propertyName===i&&t.index===a),p=c.value;c.value=t=>{const n=p(t);return Object.assign(n,e)}}}export function attach(e,n){const i=o.value??t.of("default"),a=r();i.set({id:a,type:e,transient:!0});const s=i.get(a);if(null!=n)for(const t of Object.keys(n))s[t]=n[t];return s}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -4,7 +4,11 @@ export { FirstPersonCameraComponent } from './camera/first-person-camera-compone
4
4
  export { ThirdPersonCameraComponent, ThirdPartyCameraComponent, type TemporaryThirdPersonCameraControlOptions } from './camera/third-person-camera-component.js';
5
5
  export { SpawnPoint } from './builtin/spawn-point.js';
6
6
  export { TriggerVolume, TriggerVolumeComponent } from './builtin/trigger-volume.js';
7
+ export { WaterVolume } from './builtin/water-volume-actor.js';
7
8
  export { PositionalAudioActor, PositionalAudioComponent } from './builtin/positional-audio-actor.js';
9
+ export { SplineActor } from './builtin/spline-actor.js';
10
+ export { WaterSplineVolume } from './builtin/water-spline-volume-actor.js';
11
+ export * from './builtin/components/spline-component.js';
8
12
  export * from './builtin/components/mesh-component.js';
9
13
  export * from './builtin/components/character/character-movement.js';
10
14
  export * from './builtin/components/character/root-motion-constraint.js';
@@ -1,4 +1,4 @@
1
- export{CameraActor}from"./builtin/camera-actor.js";export{CameraComponent}from"./camera/camera-component.js";export{FirstPersonCameraComponent}from"./camera/first-person-camera-component.js";export{ThirdPersonCameraComponent,ThirdPartyCameraComponent}from"./camera/third-person-camera-component.js";export{SpawnPoint}from"./builtin/spawn-point.js";export{TriggerVolume,TriggerVolumeComponent}from"./builtin/trigger-volume.js";export{PositionalAudioActor,PositionalAudioComponent}from"./builtin/positional-audio-actor.js";export*from"./builtin/components/mesh-component.js";export*from"./builtin/components/character/character-movement.js";export*from"./builtin/components/character/root-motion-constraint.js";export*from"./builtin/components/character/character-movement-policy.js";export*from"./builtin/components/character/old-character-movement.js";export*from"./builtin/components/character/character-movement-like.js";export*from"./builtin/components/character/modes.js";export*from"./builtin/components/character/character-animation.js";export*from"./controller/actor-controller.js";export{builtInComponents}from"./builtin/components/index.js";/*
1
+ export{CameraActor}from"./builtin/camera-actor.js";export{CameraComponent}from"./camera/camera-component.js";export{FirstPersonCameraComponent}from"./camera/first-person-camera-component.js";export{ThirdPersonCameraComponent,ThirdPartyCameraComponent}from"./camera/third-person-camera-component.js";export{SpawnPoint}from"./builtin/spawn-point.js";export{TriggerVolume,TriggerVolumeComponent}from"./builtin/trigger-volume.js";export{WaterVolume}from"./builtin/water-volume-actor.js";export{PositionalAudioActor,PositionalAudioComponent}from"./builtin/positional-audio-actor.js";export{SplineActor}from"./builtin/spline-actor.js";export{WaterSplineVolume}from"./builtin/water-spline-volume-actor.js";export*from"./builtin/components/spline-component.js";export*from"./builtin/components/mesh-component.js";export*from"./builtin/components/character/character-movement.js";export*from"./builtin/components/character/root-motion-constraint.js";export*from"./builtin/components/character/character-movement-policy.js";export*from"./builtin/components/character/old-character-movement.js";export*from"./builtin/components/character/character-movement-like.js";export*from"./builtin/components/character/modes.js";export*from"./builtin/components/character/character-animation.js";export*from"./controller/actor-controller.js";export{builtInComponents}from"./builtin/components/index.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,4 @@
1
- import type { 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,4 +1,4 @@
1
- import{ActorComponent as n}from"../component.js";const o=new WeakMap;export const $actorComponents=Symbol("actor_components");export async function initComponents(n,s,e=!1){const r=[];for(const i of c(n,s,e)){if(o.has(i))continue;t(s,i),o.set(i,!0);const n=(async()=>{await i.onInit(),await initComponents(i,s,e)})();r.push(n)}return Promise.all(r)}export function initComponentsSync(n,s,e=!1){for(const r of c(n,s,e))o.has(r)||(t(s,r),o.set(r,!0),r.onInit(),initComponentsSync(r,s,e))}function t(n,o){null==n[$actorComponents]&&(n[$actorComponents]=[]),n[$actorComponents].push(o),o.__netid=n[$actorComponents].length}function c(o,t,c=!1){const s=[...Object.values(o)];o===t&&t.attachedComponents.forEach(n=>s.push(n));const e=[];for(const o of s)if(o instanceof n||null!=o?.constructor&&!0===o.constructor.__isActorComponent){const n=o;if(!isComponentEnabledInEnvironment(n,c))continue;n.actor=t,e.push(n)}return e}export function isComponentEnabledInEnvironment(n,o=!1){return!(o&&!n.constructor.__inEditor)&&!(!o&&n.constructor.__onlyEditor)}/*
1
+ import{_setupActorUpdateEventHandlers as n}from"../actor.js";import{ActorComponent as o}from"../component.js";const t=new WeakMap,c=new WeakSet;export const $actorComponents=Symbol("actor_components");export async function initComponents(n,o,c=!1){const i=[];for(const a of r(n,o,c)){if(t.has(a))continue;s(o,a),t.set(a,!0),e(a);const n=(async()=>{await a.onInit(),await initComponents(a,o,c)})();i.push(n)}return Promise.all(i)}export function initComponentsSync(n,o,c=!1){for(const i of r(n,o,c))t.has(i)||(s(o,i),t.set(i,!0),e(i),i.onInit(),initComponentsSync(i,o,c))}function s(n,o){null==n[$actorComponents]&&(n[$actorComponents]=[]),n[$actorComponents].push(o),o.__netid=n[$actorComponents].length}function e(o){c.has(o)||(c.add(o),n.call(o))}function r(n,t,c=!1){const s=[...Object.values(n)];n===t&&t.attachedComponents.forEach(n=>s.push(n));const e=[];for(const n of s)if(n instanceof o||null!=n?.constructor&&!0===n.constructor.__isActorComponent){const o=n;if(!isComponentEnabledInEnvironment(o,c))continue;o.actor=t,e.push(o)}return e}export function isComponentEnabledInEnvironment(n,o=!1){return!(o&&!n.constructor.__inEditor)&&!(!o&&n.constructor.__onlyEditor)}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,6 @@
1
1
  import type { RecastCompactHeightfield, RecastConfig, RecastContourSet, RecastHeightfield, UnsignedCharArray, Vector3Tuple } from '@recast-navigation/core';
2
2
  import { RecastBuildContext } from '@recast-navigation/core';
3
+ import { type NavigationAreaModifier } from './navigation-areas.js';
3
4
  type BuildConfigProps = {
4
5
  recastConfig: RecastConfig;
5
6
  navMeshBounds: [min: Vector3Tuple, max: Vector3Tuple];
@@ -36,6 +37,7 @@ export type BuildTileMeshProps = {
36
37
  tileBoundsMax: Vector3Tuple;
37
38
  navMeshBounds: [Vector3Tuple, Vector3Tuple];
38
39
  keepIntermediates: boolean;
40
+ areaModifiers?: NavigationAreaModifier[];
39
41
  };
40
42
  export type BuildTileMeshResult = ({
41
43
  success: true;
@@ -47,6 +49,6 @@ export type BuildTileMeshResult = ({
47
49
  tileIntermediates?: TileIntermediates;
48
50
  buildContext: RecastBuildContext;
49
51
  };
50
- export declare const buildTile: ({ positions, indices, navMeshBounds, recastConfig, tileX, tileY, tileBoundsMin, tileBoundsMax, keepIntermediates, }: BuildTileMeshProps) => BuildTileMeshResult;
52
+ export declare const buildTile: ({ positions, indices, navMeshBounds, recastConfig, tileX, tileY, tileBoundsMin, tileBoundsMax, keepIntermediates, areaModifiers, }: BuildTileMeshProps) => BuildTileMeshResult;
51
53
  export {};
52
54
  //# sourceMappingURL=build-tile.d.ts.map