@hology/core 0.0.247 → 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.
- package/dist/gameplay/actors/actor.js +1 -1
- package/dist/gameplay/actors/builtin/components/spline-component.js +1 -1
- package/dist/gameplay/actors/builtin/components/water-post-process-settings.d.ts +24 -0
- package/dist/gameplay/actors/builtin/components/water-post-process-settings.js +4 -0
- package/dist/gameplay/actors/builtin/post-process-volume-actor.d.ts +1 -2
- package/dist/gameplay/actors/builtin/water-spline-volume-actor.d.ts +11 -1
- package/dist/gameplay/actors/builtin/water-spline-volume-actor.js +1 -1
- package/dist/gameplay/actors/builtin/water-volume-actor.d.ts +12 -1
- package/dist/gameplay/actors/builtin/water-volume-actor.js +1 -1
- package/dist/gameplay/actors/camera/camera-component.js +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/actors/component.d.ts +0 -1
- package/dist/gameplay/actors/component.js +1 -1
- package/dist/gameplay/actors/internal/component-init.d.ts +1 -1
- package/dist/gameplay/actors/internal/component-init.js +1 -1
- package/dist/gameplay/inject.d.ts +3 -0
- package/dist/gameplay/inject.js +1 -1
- package/dist/gameplay/services/actor-update-registry.d.ts +13 -0
- package/dist/gameplay/services/actor-update-registry.js +4 -0
- package/dist/gameplay/services/render.d.ts +1 -0
- package/dist/gameplay/services/render.js +1 -1
- package/dist/gameplay/services/world.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.js +1 -1
- package/dist/rendering.d.ts +8 -0
- package/dist/rendering.js +1 -1
- package/dist/scene/materializer.js +1 -1
- package/dist/shader/graph/compiler.js +1 -1
- package/dist/shader/graph/model.d.ts +1 -1
- package/dist/shader/graph/registry.js +1 -1
- package/dist/shader/parameter.d.ts +3 -0
- package/dist/shader/post-process-shader.js +1 -1
- package/dist/shader-nodes/depth.d.ts +3 -1
- package/dist/shader-nodes/depth.js +1 -1
- package/dist/shader-nodes/index.d.ts +1 -0
- package/dist/shader-nodes/index.js +1 -1
- package/dist/shader-nodes/water-volume.d.ts +9 -0
- package/dist/shader-nodes/water-volume.js +4 -0
- package/dist/shader-nodes/water.d.ts +12 -0
- package/dist/shader-nodes/water.js +4 -0
- package/dist/test/materializer-dynamic-transform.test.js +1 -1
- package/dist/test/post-process-effect.test.js +1 -1
- package/dist/test/spline-component.test.js +1 -1
- package/dist/test/view-controller-updates.test.d.ts +2 -0
- package/dist/test/view-controller-updates.test.js +4 -0
- package/dist/test/water-spline-volume-actor.test.js +1 -1
- package/package.json +3 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import o,{ignore as
|
|
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
|
*/
|
|
@@ -1,4 +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"}),n("design:type",
|
|
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
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
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
|
+
*/
|
|
@@ -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;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
+
import { BufferGeometry, Material, Vector3 } from 'three';
|
|
1
2
|
import { type NavigationAreaContributor, type NavigationAreaModifier } from '../../ai/navigation-areas.js';
|
|
2
3
|
import { BaseActor } from '../actor.js';
|
|
3
4
|
import { SplineComponent } from './components/spline-component.js';
|
|
5
|
+
import { WaterPostProcessSettings, type WaterPostProcessVolume } from './components/water-post-process-settings.js';
|
|
4
6
|
/** A spline-shaped water volume. The spline runs along the center of its surface. */
|
|
5
|
-
export declare class WaterSplineVolume extends BaseActor implements NavigationAreaContributor {
|
|
7
|
+
export declare class WaterSplineVolume extends BaseActor implements NavigationAreaContributor, WaterPostProcessVolume {
|
|
6
8
|
readonly spline: SplineComponent;
|
|
9
|
+
private readonly surface;
|
|
7
10
|
private readonly editorVisual;
|
|
11
|
+
readonly underwater: WaterPostProcessSettings;
|
|
8
12
|
width: number;
|
|
9
13
|
depth: number;
|
|
14
|
+
showSurface: boolean;
|
|
15
|
+
surfaceMaterial?: Material;
|
|
16
|
+
surfaceSampleDistance: number;
|
|
17
|
+
surfaceWidthSubdivisions: number;
|
|
10
18
|
applySceneParameters(parameters: Record<string, unknown>, changedParameters: ReadonlySet<string>): boolean;
|
|
19
|
+
containsWaterPoint(point: Vector3): boolean;
|
|
11
20
|
getNavigationAreaModifiers(): NavigationAreaModifier[];
|
|
12
21
|
}
|
|
22
|
+
export declare function createWaterSplineSurfaceGeometry(spline: SplineComponent, width: number, sampleDistance: number, widthSubdivisions: number): BufferGeometry;
|
|
13
23
|
//# sourceMappingURL=water-spline-volume-actor.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import{BufferGeometry as i,EdgesGeometry as o,Float32BufferAttribute as s,Group as r,LineBasicMaterial as n,LineSegments as l,Mesh as a,MeshBasicMaterial as h,Vector3 as p}from"three";import{takeUntil as d}from"rxjs";import{NavigationArea as m}from"../../ai/navigation-areas.js";import{Parameter as c}from"../../../shader/parameter.js";import{Actor as u,BaseActor as g}from"../actor.js";import{ActorComponent as f,Component as y,attach as w}from"../component.js";import{SplineComponent as b}from"./components/spline-component.js";let M=class extends f{constructor(){super(...arguments),this.visual=new r,this.fillMaterial=new h({color:1477586,transparent:!0,opacity:.18,depthWrite:!1}),this.edgeMaterial=new n({color:3520767}),this.fill=new a(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(d(this.disposed)).subscribe(()=>this.rebuild()),this.rebuild()}rebuild(){if(!this.initialized)return;const t=function(t,e,o){const r=new i,n=v(t,e,o);if(n.length<2)return r.setAttribute("position",new s([],3)),r;const l=n.flatMap(t=>[...t.leftTop.toArray(),...t.rightTop.toArray(),...t.leftBottom.toArray(),...t.rightBottom.toArray()]),a=[];for(let t=1;t<n.length;t++){const e=4*(t-1),i=4*t;A(a,e,i,i+1,e+1),A(a,e+2,e+3,i+3,i+2),A(a,e,e+2,i+2,i),A(a,e+1,i+1,i+3,e+3)}if(!t.closed){A(a,0,1,3,2);const t=4*(n.length-1);A(a,t,t+2,t+3,t+1)}return r.setAttribute("position",new s(l,3)),r.setIndex(a),r.computeVertexNormals(),r.computeBoundingBox(),r.computeBoundingSphere(),r}(this.actor.spline,this.actor.width,this.actor.depth),e=0===t.getAttribute("position").count?new i:new o(t,20),r=this.fill.geometry,n=this.edges.geometry;this.fill.geometry=t,this.edges.geometry=e,r.dispose(),n.dispose(),this.visual.updateMatrixWorld(!0)}onEndPlay(){this.fill.geometry.dispose(),this.edges.geometry.dispose(),this.fillMaterial.dispose(),this.edgeMaterial.dispose(),this.visual.removeFromParent()}};M=t([y({inEditor:!0,editorOnly:!0})],M);let x=class extends g{constructor(){super(...arguments),this.spline=w(b),this.editorVisual=w(M),this.width=5,this.depth=2}applySceneParameters(t,e){if(![...e].every(t=>"width"===t||"depth"===t))return!1;const i=e.has("width")?t.width:this.width,o=e.has("depth")?t.depth:this.depth;return!("number"!=typeof i||!Number.isFinite(i)||i<=0)&&(!("number"!=typeof o||!Number.isFinite(o)||o<=0)&&(this.width=i,this.depth=o,this.editorVisual.rebuild(),!0))}getNavigationAreaModifiers(){const t=v(this.spline,this.width,this.depth);if(t.length<2)return[];this.object.updateWorldMatrix(!0,!1);const e=this.object.matrixWorld,i=[];for(let o=1;o<t.length;o++){const s=t[o-1],r=t[o],n=[s.leftTop,s.rightTop,r.rightTop,r.leftTop,s.leftBottom,s.rightBottom,r.rightBottom,r.leftBottom].map(t=>t.clone().applyMatrix4(e));i.push({area:m.Water,vertices:n.slice(0,4).map(t=>t.toArray()),minHeight:Math.min(...n.map(t=>t.y)),maxHeight:Math.max(...n.map(t=>t.y))})}return i}};t([c({range:[.01,1e3]}),e("design:type",Number)],x.prototype,"width",void 0),t([c({range:[.01,1e3]}),e("design:type",Number)],x.prototype,"depth",void 0),x=t([u({typeId:"WaterSplineVolume"})],x);export{x as WaterSplineVolume};function v(t,e,i){if(t.points.length<2||t.length<=0||e<=0||i<=0)return[];const o=Math.min(513,Math.max(2,Math.ceil(t.length/.5)+1)),s=[],r=Array.from({length:o},(e,i)=>t.samplePositionAtDistance(t.length*i/(o-1),new p)),n=Array.from({length:o-1},(e,i)=>{const s=r[i+1].clone().sub(r[i]);return s.y=0,s.lengthSq()<1e-8&&(t.sampleTangentAtDistance(t.length*(i+.5)/(o-1),s),s.y=0),s.lengthSq()<1e-8&&s.set(1,0,0),s.normalize(),new p(-s.z,0,s.x)}),l=.5*e;for(let e=0;e<o;e++){const a=t.closed&&(0===e||e===o-1),h=n[a?n.length-1:Math.max(0,e-1)],p=n[a?0:Math.min(n.length-1,e)],d=h.clone().add(p),m=d.lengthSq()<1e-8?0:d.normalize().dot(p);m<=1e-4?d.copy(p).multiplyScalar(l):d.multiplyScalar(Math.min(l/m,1.5*l));const c=r[e].clone().add(d),u=r[e].clone().sub(d);s.push({leftTop:c,rightTop:u,leftBottom:c.clone().addScaledVector(B,i),rightBottom:u.clone().addScaledVector(B,i)})}return s}function A(t,e,i,o,s){t.push(e,i,o,e,o,s)}const B=new p(0,-1,0);/*
|
|
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
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
import { Material, Matrix4, Vector3 } from 'three';
|
|
1
2
|
import { BaseActor } from '../../index.js';
|
|
2
3
|
import { type NavigationAreaContributor, type NavigationAreaModifier } from '../../ai/navigation-areas.js';
|
|
4
|
+
import { WaterPostProcessSettings, type WaterPostProcessVolume } from './components/water-post-process-settings.js';
|
|
3
5
|
/** A semantic box of water. Its top face is the future water surface. */
|
|
4
|
-
export declare class WaterVolume extends BaseActor implements NavigationAreaContributor {
|
|
6
|
+
export declare class WaterVolume extends BaseActor implements NavigationAreaContributor, WaterPostProcessVolume {
|
|
7
|
+
private surface;
|
|
5
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;
|
|
6
14
|
getNavigationAreaModifiers(): NavigationAreaModifier[];
|
|
15
|
+
containsWaterPoint(point: Vector3): boolean;
|
|
16
|
+
getWaterPostProcessWorldToLocal(target: Matrix4): Matrix4;
|
|
17
|
+
isWaterPostProcessRelevant(cameraPosition: Vector3, transitionDistance: number): boolean;
|
|
7
18
|
}
|
|
8
19
|
//# sourceMappingURL=water-volume-actor.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t}from"tslib";import{BoxGeometry as
|
|
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
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{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
|
+
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
|
|
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
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
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{
|
|
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,6 +1,9 @@
|
|
|
1
1
|
import type { ContainerInstance } from 'typedi';
|
|
2
|
+
import type { BaseActor } from './actors/actor.js';
|
|
2
3
|
type Constructable<T> = abstract new (...args: any[]) => T;
|
|
3
4
|
export declare function inject<T>(type: Constructable<T>): T;
|
|
5
|
+
/** Resolve a service from the scoped container that created an actor. */
|
|
6
|
+
export declare function injectFromActor<T>(actor: BaseActor, type: Constructable<T>): T;
|
|
4
7
|
export declare function withInjectionContext<T>(containerInstance: ContainerInstance, fn: (diContainer: ContainerInstance) => T): T;
|
|
5
8
|
export {};
|
|
6
9
|
//# sourceMappingURL=inject.d.ts.map
|
package/dist/gameplay/inject.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import t from"typedi";import{activeContainerInstance as e}from"./actors/internal/container-map.js";export function inject(
|
|
1
|
+
import t from"typedi";import{activeContainerInstance as n}from"./actors/internal/container-map.js";import{containerRefMap as e}from"./actors/internal/container-map.js";export function inject(e){return n.value?.get(e)??t.get(e)}export function injectFromActor(t,n){return e.get(t)?.get(n)??inject(n)}export function withInjectionContext(t,e){const r=n.value;n.value=t;try{return e(t)}finally{n.value=r}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BaseActor } from '../actors/actor.js';
|
|
2
|
+
/** Direct, allocation-free-per-frame dispatch for framework-managed actor updates. */
|
|
3
|
+
export declare class ActorUpdateRegistry {
|
|
4
|
+
private readonly updatePhase;
|
|
5
|
+
private readonly lateUpdatePhase;
|
|
6
|
+
private readonly registrationsByActor;
|
|
7
|
+
register(actor: BaseActor, update: (deltaTime: number) => void, late?: boolean): void;
|
|
8
|
+
unregister(actor: BaseActor): void;
|
|
9
|
+
update(deltaTime: number): void;
|
|
10
|
+
lateUpdate(deltaTime: number): void;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=actor-update-registry.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
class t{constructor(){this.registrations=[],this.needsCompaction=!1}add(t){const s={update:t,phase:this,index:this.registrations.length};return this.registrations.push(s),s}remove(t){this.registrations[t.index]===t&&(this.registrations[t.index]=null,t.index=-1,this.needsCompaction=!0)}dispatch(t){for(let s=0,e=this.registrations.length;s<e;s++){const e=this.registrations[s];null!==e&&e.update(t)}this.needsCompaction&&this.compact()}clear(){this.registrations.length=0,this.needsCompaction=!1}compact(){let t=0;for(let s=0;s<this.registrations.length;s++){const e=this.registrations[s];null!=e&&(this.registrations[t]=e,e.index=t++)}this.registrations.length=t,this.needsCompaction=!1}}export class ActorUpdateRegistry{constructor(){this.updatePhase=new t,this.lateUpdatePhase=new t,this.registrationsByActor=new Map}register(t,s,e=!1){const i=(e?this.lateUpdatePhase:this.updatePhase).add(s);let r=this.registrationsByActor.get(t);null==r&&(r={registrations:[],disposal:t.disposed.subscribe(()=>this.unregister(t))},this.registrationsByActor.set(t,r)),r.registrations.push(i)}unregister(t){const s=this.registrationsByActor.get(t);if(null!=s){for(const t of s.registrations)t.phase.remove(t);s.disposal.unsubscribe(),this.registrationsByActor.delete(t)}}update(t){this.updatePhase.dispatch(t)}lateUpdate(t){this.lateUpdatePhase.dispatch(t)}dispose(){this.updatePhase.clear(),this.lateUpdatePhase.clear();for(const t of this.registrationsByActor.values())t.disposal.unsubscribe();this.registrationsByActor.clear()}}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -24,6 +24,7 @@ export declare class ViewController {
|
|
|
24
24
|
private view;
|
|
25
25
|
private readonly tick;
|
|
26
26
|
private readonly lateTick;
|
|
27
|
+
private readonly actorUpdates;
|
|
27
28
|
readonly audioListener: THREE.AudioListener;
|
|
28
29
|
readonly pausedChanged: BehaviorSubject<boolean>;
|
|
29
30
|
readonly mutedChanged: BehaviorSubject<boolean>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{Service as a}from"typedi";import{Camera as i}from"three";import{RenderingView as r}from"../../rendering.js";import{BehaviorSubject as s,Subject as n,takeUntil as h}from"rxjs";import*as o from"three";import{GameTimeScheduler as m}from"./game-time-scheduler.js";import{createCameraShakeSample as l,resetCameraShakeSample as u,sampleCameraShake as c}from"./camera-shake.js";export{defaultPostProcessEffectStage,postProcessEffectStages}from"../../rendering/post-process-effect.js";let d=class{constructor(e){this.view=e,this.tick=new n,this.lateTick=new n,this.audioListener=new o.AudioListener,this.pausedChanged=new s(!1),this.mutedChanged=new s(!1),this._muted=!1,this._masterVolume=1,this._cameraShakeIntensity=1,this._timeScale=1,this._hitStopRemaining=0,this.scheduler=new m,this.cameraOverrideId=0,this.cameraOverrides=[],this.cameraShakeId=0,this.gameplayCameraShakes=[],this.cameraShakeContributions=new Map,this.presentationCamera=null,this.accumulatedCameraShakeSample=l(),this.scratchCameraShakeSample=l(),this.outlined=[],this.baseCamera=e.camera,this.sourceCamera=e.camera,e.onLoop(e=>{this.handleFrame(e)}),e.camera.add(this.audioListener),window.hology_view=this}get activeBackend(){return this.view.activeBackend}get requestedBackend(){return this.view.requestedBackend}get vfxBackendPreference(){return this.view.vfxBackendPreference}get webgpuVfxInstancesPerTemplate(){return this.view.webgpuVfxInstancesPerTemplate}get webgpuVfxTemplateMemoryBudgetBytes(){return this.view.webgpuVfxTemplateMemoryBudgetBytes}get webgpuVfxWorldMemoryBudgetBytes(){return this.view.webgpuVfxWorldMemoryBudgetBytes}get webgpuVfxColdTemplateSeconds(){return this.view.webgpuVfxColdTemplateSeconds}get experimentalWebGpuDevice(){return this.view.experimentalWebGpuDevice}registerExperimentalWebGpuRenderGraphExtension(e){return this.view.registerExperimentalWebGpuRenderGraphExtension(e)}handleFrame(e){let t=this._timeScale,a=0;this._hitStopRemaining>0?(this._hitStopRemaining-=1e3*e,this._hitStopRemaining<=0&&(this._hitStopRemaining=0),t=0):a=e*this._timeScale,this.advanceGameplayCameraShakes(a),this.tick.next(a),this.scheduler.update(1e3*a),this.lateTick.next(a),this.view.simulationTimeScale=t,this.refreshCameraPresentation()}set timeScale(e){this._timeScale=Math.max(0,e)}get timeScale(){return this._timeScale}applyHitStop(e){this._hitStopRemaining=Math.max(this._hitStopRemaining,e)}set fpsCap(e){this.view.fpsCap=e}get fpsCap(){return this.view.fpsCap}set showStats(e){this.view.showStats=e}get showStats(){return this.view.showStats}setLightVolume(e){this.view.lightVolume=e}getLightVolume(){return this.view.lightVolume}addPostProcessVolume(e){this.view.addPostProcessVolume(e)}removePostProcessVolume(e){this.view.removePostProcessVolume(e)}addPostProcessEffect(e,t){return this.view.addPostProcessEffect(e,t)}onUpdate(e){return null!=e&&this.tick.pipe(h(e.disposed)),this.tick}onLateUpdate(e){return null!=e&&this.lateTick.pipe(h(e.disposed)),this.lateTick}setCamera(e){const t=e instanceof i?e:e.camera.instance;this.baseCamera=t,0===this.cameraOverrides.length&&(this.sourceCamera=t,this.refreshCameraPresentation())}getCamera(){return this.view.camera}getSourceCamera(){return this.sourceCamera}getBaseCamera(){return this.baseCamera}applyCameraShake(e){const t=function(e){return{duration:Math.max(0,e.duration??0),attack:e.attack??0,decay:e.decay??0,frequency:e.frequency??24,positionAmplitude:e.positionAmplitude?[...e.positionAmplitude]:[0,0,0],rotationAmplitude:e.rotationAmplitude?[...e.rotationAmplitude]:[0,0,0],seed:e.seed}}(e);if(t.duration<=0)return{release:()=>{}};const a={id:++this.cameraShakeId,request:t,elapsedTime:0,seedOverride:t.seed};this.gameplayCameraShakes.push(a),this.refreshCameraPresentation();let i=!1;return{release:()=>{i||(i=!0,this.releaseGameplayCameraShake(a.id))}}}setCameraShakeContribution(e,t,a,i,r){if(a.duration<=0)return void this.removeCameraShakeContribution(e,t);let s=this.cameraShakeContributions.get(e);s||(s=new Map,this.cameraShakeContributions.set(e,s));const n=s.get(t);n?(n.request=a,n.elapsedTime=Math.max(0,i),n.seedOverride=r):s.set(t,{key:t,request:a,elapsedTime:Math.max(0,i),seedOverride:r}),this.refreshCameraPresentation()}removeCameraShakeContribution(e,t){const a=this.cameraShakeContributions.get(e);a?.delete(t)&&(0===a.size&&this.cameraShakeContributions.delete(e),this.refreshCameraPresentation())}clearCameraShakeContributionsForOwner(e){this.cameraShakeContributions.delete(e)&&this.refreshCameraPresentation()}pushCameraOverride(e,t,a=0){const i={id:++this.cameraOverrideId,camera:e,owner:t,priority:a};this.cameraOverrides.push(i),this.applyTopCameraOverride();let r=!1;return{release:()=>{r||(r=!0,this.releaseCameraOverrideEntry(i))}}}releaseCameraOverridesForOwner(e){const t=this.cameraOverrides.filter(t=>t.owner!==e);t.length!==this.cameraOverrides.length&&(this.cameraOverrides=t,this.applyTopCameraOverride())}releaseCameraOverrideEntry(e){const t=this.cameraOverrides.indexOf(e);-1!==t&&(this.cameraOverrides.splice(t,1),this.applyTopCameraOverride())}applyTopCameraOverride(){const e=this.getTopCameraOverride();this.sourceCamera=e?.camera??this.baseCamera,this.refreshCameraPresentation()}getTopCameraOverride(){let e;for(const t of this.cameraOverrides)(!e||t.priority>e.priority||t.priority===e.priority&&t.id>e.id)&&(e=t);return e}applyRenderedCamera(e){this.view.camera!==e&&this.view.setCamera(e),e.add(this.audioListener)}releaseGameplayCameraShake(e){const t=this.gameplayCameraShakes.findIndex(t=>t.id===e);-1!==t&&(this.gameplayCameraShakes.splice(t,1),this.refreshCameraPresentation())}advanceGameplayCameraShakes(e){if(!(e<=0||0===this.gameplayCameraShakes.length))for(let t=this.gameplayCameraShakes.length-1;t>=0;t--){const a=this.gameplayCameraShakes[t];a.elapsedTime+=e,a.elapsedTime>a.request.duration&&this.gameplayCameraShakes.splice(t,1)}}refreshCameraPresentation(){if(!this.hasActiveCameraShake())return void this.applyRenderedCamera(this.sourceCamera);const e=this.ensurePresentationCamera();this.copyCameraState(this.sourceCamera,e),this.accumulateCameraShakeSamples(),this.applyCameraShakeSample(e),this.applyRenderedCamera(e)}hasActiveCameraShake(){if(this.gameplayCameraShakes.length>0)return!0;for(const e of this.cameraShakeContributions.values())if(e.size>0)return!0;return!1}ensurePresentationCamera(){return this.presentationCamera||(this.presentationCamera=new o.PerspectiveCamera,this.presentationCamera.name="View Controller Presentation Camera"),this.presentationCamera}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(v)),t.quaternion.copy(e.getWorldQuaternion(w)),t.scale.copy(e.getWorldScale(f)),t.layers.mask=e.layers.mask,e instanceof o.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect,t.zoom=e.zoom,t.focus=e.focus,t.filmGauge=e.filmGauge,t.filmOffset=e.filmOffset,t.view=null==e.view?null:{enabled:e.view.enabled,fullWidth:e.view.fullWidth,fullHeight:e.view.fullHeight,offsetX:e.view.offsetX,offsetY:e.view.offsetY,width:e.view.width,height:e.view.height},t.updateProjectionMatrix()):(t.projectionMatrix.copy(e.projectionMatrix),t.projectionMatrixInverse.copy(e.projectionMatrixInverse))}accumulateCameraShakeSamples(){u(this.accumulatedCameraShakeSample);for(let e=0;e<this.gameplayCameraShakes.length;e++)this.accumulateCameraShakeEntry(this.gameplayCameraShakes[e]);for(const e of this.cameraShakeContributions.values())for(const t of e.values())this.accumulateCameraShakeEntry(t)}accumulateCameraShakeEntry(e){const t=c(e.request,e.elapsedTime,this.scratchCameraShakeSample,e.seedOverride);if(t)for(let e=0;e<3;e++)this.accumulatedCameraShakeSample.position[e]+=t.position[e],this.accumulatedCameraShakeSample.rotation[e]+=t.rotation[e]}applyCameraShakeSample(e){k.copy(e.quaternion),y.set(this.accumulatedCameraShakeSample.position[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[2]*this._cameraShakeIntensity),y.applyQuaternion(k),e.position.add(y),x.set(this.accumulatedCameraShakeSample.rotation[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[2]*this._cameraShakeIntensity),O.setFromEuler(x),e.quaternion.copy(k).multiply(O),e.updateMatrixWorld(!0)}setMuted(e){this._muted=e,this.applyAudioGain(),this.mutedChanged.next(e)}getMuted(){return this._muted}set masterVolume(e){this._masterVolume=Math.min(Math.max(e,0),1),this.applyAudioGain()}get masterVolume(){return this._masterVolume}set cameraShakeIntensity(e){this._cameraShakeIntensity=Math.min(Math.max(e,0),1),this.refreshCameraPresentation()}get cameraShakeIntensity(){return this._cameraShakeIntensity}applyAudioGain(){this.audioListener.gain.gain.setValueAtTime(this._muted?0:this._masterVolume,this.audioListener.context.currentTime)}setOutlined(e){this.outlined.length=0;const t=this.outlined;for(let a=0;a<e.length;a++)t[a]=e[a];this.view.setSelectedObjects(t),this.view.setEnableOutlines(e.length>0)}getOutlined(){return this.outlined}addOutlined(e){this.outlined.includes(e)||(this.outlined.push(e),this.view.setSelectedObjects(this.outlined),this.view.setEnableOutlines(!0))}removeOutlined(e){const t=this.outlined.indexOf(e);-1!==t&&(this.outlined.splice(t,1),this.view.setSelectedObjects(this.outlined))}setOutlineColor(e){this.view.outlinePass?.visibleEdgeColor.copy(e)}getOutlineColor(){return this.view.outlinePass?.visibleEdgeColor}setOutlineThickness(e){this.view.outlinePass.edgeThickness=e}getOutlineThickness(){return this.view.outlinePass.edgeThickness}get htmlElement(){return this.view.container}getViewportSize(e=S){return this.view.getClientSize(e)}get paused(){return this.view.paused}set paused(e){e!=this.paused&&(e?this.pauseRendering():this.unpauseRendering())}pauseRendering(){this.view.paused=!0,this.pausedChanged.next(this.view.paused),this.scheduler.pause()}unpauseRendering(){this.view.paused=!1,this.pausedChanged.next(this.view.paused),this.scheduler.resume()}setInterval(e,t,a){return this.scheduler.setInterval(e,t,a)}clearInterval(e){this.scheduler.clearInterval(e)}dispose(){this.view.running&&this.view.stop(),this.scheduler.dispose(),this.cameraOverrides.length=0,this.gameplayCameraShakes.length=0,this.cameraShakeContributions.clear(),this.audioListener.removeFromParent(),this.tick.complete(),this.lateTick.complete(),this.paused=!0}createTimer(e){return this.scheduler.createTimer(e)}getScreenPosition(e,t=C,a=this.getViewportSize()){const i=this.getCamera();return p.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),i instanceof o.PerspectiveCamera&&(g.setFromProjectionMatrix(p),!g.containsPoint(e))?null:(t.copy(e),t.project(i),t.x=(t.x+1)/2*a.x,t.y=(1-t.y)/2*a.y,t)}};d=e([a(),t("design:paramtypes",[r])],d);export{d as ViewController};const p=new o.Matrix4,C=new o.Vector3,S=new o.Vector2,g=new o.Frustum,v=new o.Vector3,f=new o.Vector3,w=new o.Quaternion,k=new o.Quaternion,y=new o.Vector3,x=new o.Euler(0,0,0,"XYZ"),O=new o.Quaternion;/*
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{Service as a}from"typedi";import{Camera as i}from"three";import{RenderingView as r}from"../../rendering.js";import{BehaviorSubject as s,Subject as n,takeUntil as h}from"rxjs";import*as o from"three";import{GameTimeScheduler as m}from"./game-time-scheduler.js";import{ActorUpdateRegistry as l}from"./actor-update-registry.js";import{createCameraShakeSample as u,resetCameraShakeSample as c,sampleCameraShake as p}from"./camera-shake.js";export{defaultPostProcessEffectStage,postProcessEffectStages}from"../../rendering/post-process-effect.js";let d=class{constructor(e){this.view=e,this.tick=new n,this.lateTick=new n,this.actorUpdates=new l,this.audioListener=new o.AudioListener,this.pausedChanged=new s(!1),this.mutedChanged=new s(!1),this._muted=!1,this._masterVolume=1,this._cameraShakeIntensity=1,this._timeScale=1,this._hitStopRemaining=0,this.scheduler=new m,this.cameraOverrideId=0,this.cameraOverrides=[],this.cameraShakeId=0,this.gameplayCameraShakes=[],this.cameraShakeContributions=new Map,this.presentationCamera=null,this.accumulatedCameraShakeSample=u(),this.scratchCameraShakeSample=u(),this.outlined=[],this.baseCamera=e.camera,this.sourceCamera=e.camera,e.onLoop(e=>{this.handleFrame(e)}),e.camera.add(this.audioListener),window.hology_view=this}get activeBackend(){return this.view.activeBackend}get requestedBackend(){return this.view.requestedBackend}get vfxBackendPreference(){return this.view.vfxBackendPreference}get webgpuVfxInstancesPerTemplate(){return this.view.webgpuVfxInstancesPerTemplate}get webgpuVfxTemplateMemoryBudgetBytes(){return this.view.webgpuVfxTemplateMemoryBudgetBytes}get webgpuVfxWorldMemoryBudgetBytes(){return this.view.webgpuVfxWorldMemoryBudgetBytes}get webgpuVfxColdTemplateSeconds(){return this.view.webgpuVfxColdTemplateSeconds}get experimentalWebGpuDevice(){return this.view.experimentalWebGpuDevice}registerExperimentalWebGpuRenderGraphExtension(e){return this.view.registerExperimentalWebGpuRenderGraphExtension(e)}handleFrame(e){let t=this._timeScale,a=0;this._hitStopRemaining>0?(this._hitStopRemaining-=1e3*e,this._hitStopRemaining<=0&&(this._hitStopRemaining=0),t=0):a=e*this._timeScale,this.advanceGameplayCameraShakes(a),this.tick.next(a),this.actorUpdates.update(a),this.scheduler.update(1e3*a),this.lateTick.next(a),this.actorUpdates.lateUpdate(a),this.view.simulationTimeScale=t,this.refreshCameraPresentation()}set timeScale(e){this._timeScale=Math.max(0,e)}get timeScale(){return this._timeScale}applyHitStop(e){this._hitStopRemaining=Math.max(this._hitStopRemaining,e)}set fpsCap(e){this.view.fpsCap=e}get fpsCap(){return this.view.fpsCap}set showStats(e){this.view.showStats=e}get showStats(){return this.view.showStats}setLightVolume(e){this.view.lightVolume=e}getLightVolume(){return this.view.lightVolume}addPostProcessVolume(e){this.view.addPostProcessVolume(e)}removePostProcessVolume(e){this.view.removePostProcessVolume(e)}addPostProcessEffect(e,t){return this.view.addPostProcessEffect(e,t)}onUpdate(e){return null==e?this.tick:this.tick.pipe(h(e.disposed))}onLateUpdate(e){return null==e?this.lateTick:this.lateTick.pipe(h(e.disposed))}registerActorUpdate(e,t,a=!1){this.actorUpdates.register(e,t,a)}unregisterActorUpdates(e){this.actorUpdates.unregister(e)}setCamera(e){const t=e instanceof i?e:e.camera.instance;this.baseCamera=t,0===this.cameraOverrides.length&&(this.sourceCamera=t,this.refreshCameraPresentation())}getCamera(){return this.view.camera}getSourceCamera(){return this.sourceCamera}getBaseCamera(){return this.baseCamera}applyCameraShake(e){const t=function(e){return{duration:Math.max(0,e.duration??0),attack:e.attack??0,decay:e.decay??0,frequency:e.frequency??24,positionAmplitude:e.positionAmplitude?[...e.positionAmplitude]:[0,0,0],rotationAmplitude:e.rotationAmplitude?[...e.rotationAmplitude]:[0,0,0],seed:e.seed}}(e);if(t.duration<=0)return{release:()=>{}};const a={id:++this.cameraShakeId,request:t,elapsedTime:0,seedOverride:t.seed};this.gameplayCameraShakes.push(a),this.refreshCameraPresentation();let i=!1;return{release:()=>{i||(i=!0,this.releaseGameplayCameraShake(a.id))}}}setCameraShakeContribution(e,t,a,i,r){if(a.duration<=0)return void this.removeCameraShakeContribution(e,t);let s=this.cameraShakeContributions.get(e);s||(s=new Map,this.cameraShakeContributions.set(e,s));const n=s.get(t);n?(n.request=a,n.elapsedTime=Math.max(0,i),n.seedOverride=r):s.set(t,{key:t,request:a,elapsedTime:Math.max(0,i),seedOverride:r}),this.refreshCameraPresentation()}removeCameraShakeContribution(e,t){const a=this.cameraShakeContributions.get(e);a?.delete(t)&&(0===a.size&&this.cameraShakeContributions.delete(e),this.refreshCameraPresentation())}clearCameraShakeContributionsForOwner(e){this.cameraShakeContributions.delete(e)&&this.refreshCameraPresentation()}pushCameraOverride(e,t,a=0){const i={id:++this.cameraOverrideId,camera:e,owner:t,priority:a};this.cameraOverrides.push(i),this.applyTopCameraOverride();let r=!1;return{release:()=>{r||(r=!0,this.releaseCameraOverrideEntry(i))}}}releaseCameraOverridesForOwner(e){const t=this.cameraOverrides.filter(t=>t.owner!==e);t.length!==this.cameraOverrides.length&&(this.cameraOverrides=t,this.applyTopCameraOverride())}releaseCameraOverrideEntry(e){const t=this.cameraOverrides.indexOf(e);-1!==t&&(this.cameraOverrides.splice(t,1),this.applyTopCameraOverride())}applyTopCameraOverride(){const e=this.getTopCameraOverride();this.sourceCamera=e?.camera??this.baseCamera,this.refreshCameraPresentation()}getTopCameraOverride(){let e;for(const t of this.cameraOverrides)(!e||t.priority>e.priority||t.priority===e.priority&&t.id>e.id)&&(e=t);return e}applyRenderedCamera(e){this.view.camera!==e&&this.view.setCamera(e),e.add(this.audioListener)}releaseGameplayCameraShake(e){const t=this.gameplayCameraShakes.findIndex(t=>t.id===e);-1!==t&&(this.gameplayCameraShakes.splice(t,1),this.refreshCameraPresentation())}advanceGameplayCameraShakes(e){if(!(e<=0||0===this.gameplayCameraShakes.length))for(let t=this.gameplayCameraShakes.length-1;t>=0;t--){const a=this.gameplayCameraShakes[t];a.elapsedTime+=e,a.elapsedTime>a.request.duration&&this.gameplayCameraShakes.splice(t,1)}}refreshCameraPresentation(){if(!this.hasActiveCameraShake())return void this.applyRenderedCamera(this.sourceCamera);const e=this.ensurePresentationCamera();this.copyCameraState(this.sourceCamera,e),this.accumulateCameraShakeSamples(),this.applyCameraShakeSample(e),this.applyRenderedCamera(e)}hasActiveCameraShake(){if(this.gameplayCameraShakes.length>0)return!0;for(const e of this.cameraShakeContributions.values())if(e.size>0)return!0;return!1}ensurePresentationCamera(){return this.presentationCamera||(this.presentationCamera=new o.PerspectiveCamera,this.presentationCamera.name="View Controller Presentation Camera"),this.presentationCamera}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(f)),t.quaternion.copy(e.getWorldQuaternion(k)),t.scale.copy(e.getWorldScale(w)),t.layers.mask=e.layers.mask,e instanceof o.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect,t.zoom=e.zoom,t.focus=e.focus,t.filmGauge=e.filmGauge,t.filmOffset=e.filmOffset,t.view=null==e.view?null:{enabled:e.view.enabled,fullWidth:e.view.fullWidth,fullHeight:e.view.fullHeight,offsetX:e.view.offsetX,offsetY:e.view.offsetY,width:e.view.width,height:e.view.height},t.updateProjectionMatrix()):(t.projectionMatrix.copy(e.projectionMatrix),t.projectionMatrixInverse.copy(e.projectionMatrixInverse))}accumulateCameraShakeSamples(){c(this.accumulatedCameraShakeSample);for(let e=0;e<this.gameplayCameraShakes.length;e++)this.accumulateCameraShakeEntry(this.gameplayCameraShakes[e]);for(const e of this.cameraShakeContributions.values())for(const t of e.values())this.accumulateCameraShakeEntry(t)}accumulateCameraShakeEntry(e){const t=p(e.request,e.elapsedTime,this.scratchCameraShakeSample,e.seedOverride);if(t)for(let e=0;e<3;e++)this.accumulatedCameraShakeSample.position[e]+=t.position[e],this.accumulatedCameraShakeSample.rotation[e]+=t.rotation[e]}applyCameraShakeSample(e){y.copy(e.quaternion),x.set(this.accumulatedCameraShakeSample.position[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[2]*this._cameraShakeIntensity),x.applyQuaternion(y),e.position.add(x),O.set(this.accumulatedCameraShakeSample.rotation[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[2]*this._cameraShakeIntensity),P.setFromEuler(O),e.quaternion.copy(y).multiply(P),e.updateMatrixWorld(!0)}setMuted(e){this._muted=e,this.applyAudioGain(),this.mutedChanged.next(e)}getMuted(){return this._muted}set masterVolume(e){this._masterVolume=Math.min(Math.max(e,0),1),this.applyAudioGain()}get masterVolume(){return this._masterVolume}set cameraShakeIntensity(e){this._cameraShakeIntensity=Math.min(Math.max(e,0),1),this.refreshCameraPresentation()}get cameraShakeIntensity(){return this._cameraShakeIntensity}applyAudioGain(){this.audioListener.gain.gain.setValueAtTime(this._muted?0:this._masterVolume,this.audioListener.context.currentTime)}setOutlined(e){this.outlined.length=0;const t=this.outlined;for(let a=0;a<e.length;a++)t[a]=e[a];this.view.setSelectedObjects(t),this.view.setEnableOutlines(e.length>0)}getOutlined(){return this.outlined}addOutlined(e){this.outlined.includes(e)||(this.outlined.push(e),this.view.setSelectedObjects(this.outlined),this.view.setEnableOutlines(!0))}removeOutlined(e){const t=this.outlined.indexOf(e);-1!==t&&(this.outlined.splice(t,1),this.view.setSelectedObjects(this.outlined))}setOutlineColor(e){this.view.outlinePass?.visibleEdgeColor.copy(e)}getOutlineColor(){return this.view.outlinePass?.visibleEdgeColor}setOutlineThickness(e){this.view.outlinePass.edgeThickness=e}getOutlineThickness(){return this.view.outlinePass.edgeThickness}get htmlElement(){return this.view.container}getViewportSize(e=S){return this.view.getClientSize(e)}get paused(){return this.view.paused}set paused(e){e!=this.paused&&(e?this.pauseRendering():this.unpauseRendering())}pauseRendering(){this.view.paused=!0,this.pausedChanged.next(this.view.paused),this.scheduler.pause()}unpauseRendering(){this.view.paused=!1,this.pausedChanged.next(this.view.paused),this.scheduler.resume()}setInterval(e,t,a){return this.scheduler.setInterval(e,t,a)}clearInterval(e){this.scheduler.clearInterval(e)}dispose(){this.view.running&&this.view.stop(),this.scheduler.dispose(),this.cameraOverrides.length=0,this.gameplayCameraShakes.length=0,this.cameraShakeContributions.clear(),this.audioListener.removeFromParent(),this.tick.complete(),this.lateTick.complete(),this.actorUpdates.dispose(),this.paused=!0}createTimer(e){return this.scheduler.createTimer(e)}getScreenPosition(e,t=g,a=this.getViewportSize()){const i=this.getCamera();return C.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),i instanceof o.PerspectiveCamera&&(v.setFromProjectionMatrix(C),!v.containsPoint(e))?null:(t.copy(e),t.project(i),t.x=(t.x+1)/2*a.x,t.y=(1-t.y)/2*a.y,t)}};d=e([a(),t("design:paramtypes",[r])],d);export{d as ViewController};const C=new o.Matrix4,g=new o.Vector3,S=new o.Vector2,v=new o.Frustum,f=new o.Vector3,w=new o.Vector3,k=new o.Quaternion,y=new o.Quaternion,x=new o.Vector3,O=new o.Euler(0,0,0,"XYZ"),P=new o.Quaternion;/*
|
|
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}from"tslib";import{Service as e}from"typedi";import{BaseActor as r}from"../actors/actor.js";import{ActorFactory as s}from"../actors/factory.js";import{Group as i,Vector3 as n}from"three";import{ActorComponent as o}from"../../gameplay/actors/component.js";import{Subject as a}from"rxjs";import{RenderingView as c}from"../../rendering.js";import{randomUUID as h}from"../../utils/uuid.js";import{PrefabInstance as
|
|
1
|
+
import{__decorate as t}from"tslib";import{Service as e}from"typedi";import{BaseActor as r}from"../actors/actor.js";import{ActorFactory as s}from"../actors/factory.js";import{Group as i,Vector3 as n}from"three";import{ActorComponent as o}from"../../gameplay/actors/component.js";import{Subject as a}from"rxjs";import{RenderingView as c}from"../../rendering.js";import{randomUUID as h}from"../../utils/uuid.js";import{PrefabInstance as l}from"../../scene/objects/prefab.js";import{PhysicsSystem as p}from"./physics/physics-system.js";import{inject as d}from"../../gameplay/inject.js";import{isComponentEnabledInEnvironment as m}from"../actors/internal/component-init.js";import{NetRole as f}from"../net/service/net-actor-role.js";import{BasePlayerController as v}from"../actors/controller/actor-controller.js";import{EventGraphInstance as y}from"../event-graph/runtime.js";import{ViewController as w}from"./render.js";import{AssetsProvider as u}from"../../scene/assets-provider.js";import{WorldEventGraphAssetRuntime as b}from"../event-graph/runtime-assets.js";import{hasExecutableEventGraphDocument as E}from"../event-graph/model.js";const A=new n;class g{constructor(t){this.view=t}get direction(){return this.view.csm.lightDirection}set intensity(t){this.view.csm.lightIntensity=t,this.view.csm.lights.forEach(t=>t.intensity=this.view.csm.lightIntensity)}get intensity(){return this.view.csm.lightIntensity}get position(){return 0==this.view.csm.lights.length?A:this.view.csm.lights[0].position}}let G=class{constructor(){this.actorFactory=d(s),this.view=d(c),this.viewController=d(w),this.physics=d(p),this.assetsProvider=d(u),this.eventGraphAssets=new b(this,this.assetsProvider),this.actors=[],this.actorAdded=new a,this.actorRemoved=new a,this.directionalLight=new g(this.view),this.sceneEventGraphs=new Map,this.sceneEventGraphSubscriptions=[]}async spawnActor(t,e,r,s){if(null==t)throw new Error("Cannot spawn actor with null type");if("prefab"in t){const i=t.prefab,n=await this.spawnPrefab(i,e,r),o=n.mainActor;if(null==o)throw new Error(`Prefab has no main actor or there was an error when spwaning it. Prefab: ${JSON.stringify(i)}`);return o.disposed.subscribe(()=>{const t=n.actors.findIndex(t=>t===o);t>=0&&n.actors.splice(t,1),this.removePrefab(n)}),null!=s?.owner&&(o.owner=s.owner),o}const i=await this.actorFactory.create(t,e,r);return null!=s?.owner&&(i.owner=s.owner),this.addActor(i,e,r),i}async spawnActorWithNetInfo(t,e,r,s,i,n){const o=await this.actorFactory.create(t,i,n,!0),a=null!=s&&0!==s?this.actors.find(t=>t.__netid===s):null;return o.__netid=e,o.netRole=r,o.owner=a,o instanceof v&&(o.isLocallyControlled=r===f.autonomousProxy),this.actorFactory.initActor(o),this.addActor(o,i,n),o}async spawnLocalPlayerController(t,e,r){const s=await this.actorFactory.create(t,e,r,!0);return s.isLocallyControlled=!0,this.actorFactory.initActor(s),this.addActor(s,e,r),s}spawnActorSync(t,e,r){if(null==t)throw new Error("Cannot spawn actor with null type");const s=this.actorFactory.createSync(t,e,r);return this.addActor(s,e,r),s}addActor(t,e,r){e&&t.object.position.copy(e),r&&t.object.rotation.copy(r),null==t.object.parent&&this.scene.add(t.object),this.actors.push(t),j(t,t=>t.onBeginPlay(),this.actorFactory.inEditor),this.actorAdded.next(t)}async preloadVisualEffects(t){await(this.materializer?.preloadVisualEffects(t))}removeActor(t){for(const[e,r]of[...this.sceneEventGraphs])r.binding.mainActor===t&&this.deactivateSceneEventGraph(e);j(t,t=>t.onEndPlay(),this.actorFactory.inEditor);const e=this.actors.indexOf(t);e>=0&&this.actors.splice(e,1),t.object.removeFromParent(),this.viewController.unregisterActorUpdates(t),t.disposed.next(!0),this.actorRemoved.next(t),this.physics.removeActor(t)}findActorByType(t,e){return this.actors.find(r=>r instanceof t&&(null==e||r.object.name==e))}findActorsByType(t,e){return this.actors.filter(r=>r instanceof t&&(null==e||r.object.name==e))}resolveSceneActor(t){return this.materializer?.resolveSceneActor(t)}async startSceneEventGraphs(t){this.stopSceneEventGraphs(),this.sceneEventGraphSubscriptions.push(t.prefabEventGraphAdded$.subscribe(t=>{this.activateSceneEventGraph(t).catch(e=>{console.error(`Failed to start scene prefab event graph ${JSON.stringify(t.id)}`,e)})}),t.prefabEventGraphRemoved$.subscribe(t=>{this.deactivateSceneEventGraph(t.id);for(const e of t.actors)this.actors.includes(e)&&this.removeActor(e)}));for(const e of t.prefabEventGraphInstances)await this.activateSceneEventGraph(e)}stopSceneEventGraphs(){for(const t of this.sceneEventGraphSubscriptions)t.unsubscribe();this.sceneEventGraphSubscriptions.length=0;for(const t of[...this.sceneEventGraphs.keys()])this.deactivateSceneEventGraph(t)}async activateSceneEventGraph(t){if(this.sceneEventGraphs.has(t.id))return;for(const e of t.actors)this.actors.includes(e)||this.addActor(e);const e=new y(t.graph,{world:this,actorsById:t.actorsById,mainActor:t.mainActor,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});this.sceneEventGraphs.set(t.id,{binding:t,runtime:e});try{await e.beginPlay()}catch(r){throw this.sceneEventGraphs.delete(t.id),e.endPlay(),r}}deactivateSceneEventGraph(t){const e=this.sceneEventGraphs.get(t);null!=e&&(this.sceneEventGraphs.delete(t),e.runtime.endPlay())}async spawnPrefab(t,e,r){if(null==this.materializer)return console.error("Internal error: Materializer is missing on World"),null;const s=new l,n=new i;null!=e&&n.position.copy(e),null!=r&&n.rotation.copy(r),this.materializer.setScene(this.scene),this.materializer.inEditor=this.actorFactory.inEditor;const o=null!=t.asset.id?await(this.assetsProvider?.getAsset(t.asset.id))??t.asset:t.asset,{object:a,actors:c,actorsById:p,mainActor:d,instanceId:m}=await this.materializer.createFromPrefabAsset(o,{sceneObjectChain:["r-"+h()],runtimeSpawn:!0},n,void 0,!1);s.object=a,s.actors=c,s.mainActor=d,s.__materializerInstanceId=m,this.scene.attach(a),c.forEach(t=>{this.addActor(t)}),this.physics.addFromScene(a);const f=o.prefab?.eventGraph;if(!this.actorFactory.inEditor&&E(f)){s.eventGraph=new y(f,{world:this,actorsById:p,mainActor:d,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});try{await s.eventGraph.beginPlay()}catch(t){throw this.removePrefab(s),t}}return s}removePrefab(t){if(t.destroyed)return;t.destroyed=!0,t.eventGraph?.endPlay(),t.eventGraph=void 0,null!=t.__materializerInstanceId&&(this.materializer.unregisterLivePrefabInstance?.(t.__materializerInstanceId),t.__materializerInstanceId=void 0);t.actors.splice(0).forEach(t=>this.removeActor(t)),t.object?.removeFromParent(),this.physics.removeRemoved(t.object)}};G=t([e()],G);export{G as World};function j(t,e,s=!1,i=new WeakSet){if(!i.has(t))return i.add(t),e(t),t instanceof r&&t.attachedComponents.forEach(t=>{m(t,s)&&j(t,e,s,i)}),Object.entries(t).filter(([t,e])=>e instanceof o&&m(e,s)).forEach(([t,r])=>{j(r,e,s,i)})}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './shader/index.js';
|
|
|
7
7
|
export * from './gameplay/actors/builtin/post-process-volume-actor.js';
|
|
8
8
|
export * from './gameplay/actors/builtin/water-volume-actor.js';
|
|
9
9
|
export * from './gameplay/actors/builtin/water-spline-volume-actor.js';
|
|
10
|
+
export * from './gameplay/actors/builtin/components/water-post-process-settings.js';
|
|
10
11
|
export * from './scene/objects/prefab.js';
|
|
11
12
|
export * from './scene/objects/data-asset.js';
|
|
12
13
|
export * from './effects/sequence/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export{loadScene}from"./scene/bootstrap.js";export{BaseGameController}from"./controllers/base-game-controller.js";export*from"./scene/collision/collision-shape.js";export{AssetMeshInstance}from"./scene/asset-resource-loader.js";export{registerWorker,initWorker}from"./worker/index.js";export*from"./shader/index.js";export*from"./gameplay/actors/builtin/post-process-volume-actor.js";export*from"./gameplay/actors/builtin/water-volume-actor.js";export*from"./gameplay/actors/builtin/water-spline-volume-actor.js";export*from"./scene/objects/prefab.js";export*from"./scene/objects/data-asset.js";export*from"./effects/sequence/index.js";export*from"./data/surface-definition.js";export*from"./scene/surface-query.js";/*
|
|
1
|
+
export{loadScene}from"./scene/bootstrap.js";export{BaseGameController}from"./controllers/base-game-controller.js";export*from"./scene/collision/collision-shape.js";export{AssetMeshInstance}from"./scene/asset-resource-loader.js";export{registerWorker,initWorker}from"./worker/index.js";export*from"./shader/index.js";export*from"./gameplay/actors/builtin/post-process-volume-actor.js";export*from"./gameplay/actors/builtin/water-volume-actor.js";export*from"./gameplay/actors/builtin/water-spline-volume-actor.js";export*from"./gameplay/actors/builtin/components/water-post-process-settings.js";export*from"./scene/objects/prefab.js";export*from"./scene/objects/data-asset.js";export*from"./effects/sequence/index.js";export*from"./data/surface-definition.js";export*from"./scene/surface-query.js";/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|