@hology/core 0.0.275 → 0.0.276
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/effects/sequence/sequence-player.d.ts +1 -0
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/gameplay/actors/builtin/components/index.d.ts +6 -0
- package/dist/gameplay/actors/builtin/components/index.js +1 -1
- package/dist/gameplay/actors/builtin/components/primitive-mesh-component.d.ts +66 -0
- package/dist/gameplay/actors/builtin/components/primitive-mesh-component.js +4 -0
- package/dist/gameplay/actors/builtin/index.d.ts +6 -0
- package/dist/gameplay/actors/builtin/index.js +1 -1
- package/dist/gameplay/actors/builtin/light-actor.d.ts +54 -0
- package/dist/gameplay/actors/builtin/light-actor.js +4 -0
- package/dist/gameplay/actors/builtin/mesh-actor.d.ts +9 -0
- package/dist/gameplay/actors/builtin/mesh-actor.js +4 -0
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.d.ts +5 -0
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/index.d.ts +1 -0
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/rendering-host.d.ts +1 -0
- package/dist/gameplay/rendering-host.js +1 -1
- package/dist/gameplay/services/asset-loader.d.ts +3 -0
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/rendering/node-material-webgpu-resolver.d.ts +1 -0
- package/dist/rendering/node-material-webgpu-resolver.js +1 -1
- package/dist/rendering/post-process-color.d.ts +9 -0
- package/dist/rendering/post-process-color.js +4 -0
- package/dist/rendering/webgl-backend.d.ts +243 -9
- package/dist/rendering/webgl-backend.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.d.ts +4 -1
- package/dist/rendering/webgpu-experimental-backend.js +1 -1
- package/dist/rendering.d.ts +45 -209
- package/dist/rendering.js +1 -1
- package/dist/scene/actor-material-parameters.d.ts +19 -0
- package/dist/scene/actor-material-parameters.js +4 -0
- package/dist/scene/actor-mesh-provider.d.ts +2 -0
- package/dist/scene/actor-mesh-provider.js +4 -0
- package/dist/scene/actor-mesh-renderer.d.ts +40 -0
- package/dist/scene/actor-mesh-renderer.js +4 -0
- package/dist/scene/asset-resource-loader.d.ts +2 -0
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/batched-mesh-2.js +1 -1
- package/dist/scene/custom-param-deserialize.js +1 -1
- package/dist/scene/custom-param-runtime-types.js +1 -1
- package/dist/scene/material-ref.d.ts +7 -0
- package/dist/scene/material-ref.js +4 -0
- package/dist/scene/materializer.d.ts +16 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +2 -1
- package/dist/scene/model.js +1 -1
- package/dist/scene/runtime-bundled-backend-service.d.ts +1 -0
- package/dist/scene/runtime-bundled-backend-service.js +1 -1
- package/dist/scene/scene-object-actor-conversion.d.ts +10 -0
- package/dist/scene/scene-object-actor-conversion.js +4 -0
- package/dist/shader/parameter.d.ts +5 -2
- package/dist/shader-nodes/particle.d.ts +2 -2
- package/dist/test/actor-mesh-renderer.test.d.ts +2 -0
- package/dist/test/actor-mesh-renderer.test.js +4 -0
- package/dist/test/actor-persistence-runtime.test.js +1 -1
- package/dist/test/asset-resource-loader-converted-fbx.test.js +1 -1
- package/dist/test/asset-resource-loader-skinned-merge.test.js +1 -1
- package/dist/test/landscape-static-draw-sets.test.js +1 -1
- package/dist/test/node-material-webgpu-resolver.test.js +1 -1
- package/dist/test/physics-ray-object.test.js +1 -1
- package/dist/test/primitive-actors.test.d.ts +2 -0
- package/dist/test/primitive-actors.test.js +4 -0
- package/dist/test/rendering-host.test.js +1 -1
- package/dist/test/runtime-bundled-backend-service.test.d.ts +2 -0
- package/dist/test/runtime-bundled-backend-service.test.js +4 -0
- package/dist/test/scene-object-actor-conversion.test.d.ts +2 -0
- package/dist/test/scene-object-actor-conversion.test.js +4 -0
- package/dist/test/webgl-backend.test.d.ts +2 -0
- package/dist/test/webgl-backend.test.js +4 -0
- package/dist/utils/async.d.ts +2 -0
- package/dist/utils/async.js +1 -1
- package/dist/utils/mesh.js +1 -1
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseActor } from '../actor.js';
|
|
2
|
+
import { ModelMeshComponent, ShapeMeshComponent } from './components/primitive-mesh-component.js';
|
|
3
|
+
export declare class MeshActor extends BaseActor {
|
|
4
|
+
readonly mesh: ModelMeshComponent;
|
|
5
|
+
}
|
|
6
|
+
export declare class ShapeActor extends BaseActor {
|
|
7
|
+
readonly mesh: ShapeMeshComponent;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=mesh-actor.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{__decorate as t}from"tslib";import{Actor as e,BaseActor as o}from"../actor.js";import{attach as s}from"../component.js";import{ModelMeshComponent as r,ShapeMeshComponent as m}from"./components/primitive-mesh-component.js";let p=class extends o{constructor(){super(...arguments),this.mesh=s(r)}};p=t([e({typeId:"Mesh",icon:"cube"})],p);export{p as MeshActor};let c=class extends o{constructor(){super(...arguments),this.mesh=s(m)}};c=t([e({typeId:"Shape",icon:"cube"})],c);export{c as ShapeActor};/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as i}from"tslib";import{ContainerInstance as n}from"typedi";import{Service as
|
|
1
|
+
import{__decorate as t,__metadata as i}from"tslib";import{ContainerInstance as n}from"typedi";import{Service as r}from"typedi";import{ActorMeshProvider as o}from"../../scene/actor-mesh-provider.js";import{initComponents as e,initComponentsSync as s}from"./internal/component-init.js";import{activeContainerInstance as c,containerRefMap as a}from"./internal/container-map.js";export let actorConstructContext={actor:null};let p=class{constructor(t,i){this.container=t,this.env=i,this.classes={}}setMeshProvider(t){this.container.set(o,t)}get inEditor(){return this.env.inEditor??!1}async create(t,i,n,r){const o=this._createActor(t,i,n);return!0!==r&&await this.initActor(o),o}createSync(t,i,n,r){const o=this._createActor(t,i,n);return!0!==r&&this.initActorSync(o),o}_createActor(t,i,n){const r=this.container;c.value=r;const o=(1e4*Math.random()).toString();r.set({id:o,type:t,transient:!0});const e=r.get(o);return actorConstructContext.actor=null,c.value=null,r.remove(t),a.set(e,r),i&&e.object.position.copy(i),n&&e.object.rotation.copy(n),e}async initActor(t){await e(t,t,this.env.inEditor??!1),await t.onInit(),t.__isInitialised=!0}initActorSync(t){s(t,t,this.env.inEditor??!1),t.onInit(),t.__isInitialised=!0}};p=t([r(),i("design:paramtypes",[n,Object])],p);export{p as ActorFactory};/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export { CameraActor } from './builtin/camera-actor.js';
|
|
2
|
+
export { MeshActor, ShapeActor } from './builtin/mesh-actor.js';
|
|
3
|
+
export { PointLightActor, SpotLightActor, PointLightComponent, SpotLightComponent } from './builtin/light-actor.js';
|
|
4
|
+
export { ModelMeshComponent, ShapeMeshComponent, MeshMaterialSlot, ShapeGeometry, createShapeGeometry } from './builtin/components/primitive-mesh-component.js';
|
|
5
|
+
export type { ActorMeshHandle, ActorMeshMobility, ActorMeshRenderOptions } from '../../scene/actor-mesh-renderer.js';
|
|
6
|
+
export type { ActorMaterialHandle, MaterialParameterValue } from '../../scene/actor-material-parameters.js';
|
|
2
7
|
export { CameraComponent } from './camera/camera-component.js';
|
|
3
8
|
export { FirstPersonCameraComponent } from './camera/first-person-camera-component.js';
|
|
4
9
|
export { ThirdPersonCameraComponent, ThirdPartyCameraComponent, type TemporaryThirdPersonCameraControlOptions } from './camera/third-person-camera-component.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export{CameraActor}from"./builtin/camera-actor.js";export{CameraComponent}from"./camera/camera-component.js";export{FirstPersonCameraComponent}from"./camera/first-person-camera-component.js";export{ThirdPersonCameraComponent,ThirdPartyCameraComponent}from"./camera/third-person-camera-component.js";export{SpawnPoint}from"./builtin/spawn-point.js";export{TriggerVolume,TriggerVolumeComponent}from"./builtin/trigger-volume.js";export{WaterVolume}from"./builtin/water-volume-actor.js";export{PositionalAudioActor,PositionalAudioComponent}from"./builtin/positional-audio-actor.js";export{SplineActor}from"./builtin/spline-actor.js";export{WaterSplineVolume}from"./builtin/water-spline-volume-actor.js";export*from"./builtin/components/spline-component.js";export*from"./builtin/components/mesh-component.js";export*from"./builtin/components/character/character-movement.js";export*from"./builtin/components/character/root-motion-constraint.js";export*from"./builtin/components/character/character-movement-policy.js";export*from"./builtin/components/character/old-character-movement.js";export*from"./builtin/components/character/character-movement-like.js";export*from"./builtin/components/character/modes.js";export*from"./builtin/components/character/character-animation.js";export*from"./controller/actor-controller.js";export*from"./controller/game-state.js";export{builtInComponents}from"./builtin/components/index.js";/*
|
|
1
|
+
export{CameraActor}from"./builtin/camera-actor.js";export{MeshActor,ShapeActor}from"./builtin/mesh-actor.js";export{PointLightActor,SpotLightActor,PointLightComponent,SpotLightComponent}from"./builtin/light-actor.js";export{ModelMeshComponent,ShapeMeshComponent,MeshMaterialSlot,ShapeGeometry,createShapeGeometry}from"./builtin/components/primitive-mesh-component.js";export{CameraComponent}from"./camera/camera-component.js";export{FirstPersonCameraComponent}from"./camera/first-person-camera-component.js";export{ThirdPersonCameraComponent,ThirdPartyCameraComponent}from"./camera/third-person-camera-component.js";export{SpawnPoint}from"./builtin/spawn-point.js";export{TriggerVolume,TriggerVolumeComponent}from"./builtin/trigger-volume.js";export{WaterVolume}from"./builtin/water-volume-actor.js";export{PositionalAudioActor,PositionalAudioComponent}from"./builtin/positional-audio-actor.js";export{SplineActor}from"./builtin/spline-actor.js";export{WaterSplineVolume}from"./builtin/water-spline-volume-actor.js";export*from"./builtin/components/spline-component.js";export*from"./builtin/components/mesh-component.js";export*from"./builtin/components/character/character-movement.js";export*from"./builtin/components/character/root-motion-constraint.js";export*from"./builtin/components/character/character-movement-policy.js";export*from"./builtin/components/character/old-character-movement.js";export*from"./builtin/components/character/character-movement-like.js";export*from"./builtin/components/character/modes.js";export*from"./builtin/components/character/character-animation.js";export*from"./controller/actor-controller.js";export*from"./controller/game-state.js";export{builtInComponents}from"./builtin/components/index.js";/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/gameplay/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export { VisualEffect } from '../effects/vfx/vfx-param.js';
|
|
|
31
31
|
export { DataAssetRef } from '../scene/objects/data-asset.js';
|
|
32
32
|
export { SceneRef, sceneId, type SceneId } from '../scene/scene-ref.js';
|
|
33
33
|
export { ModelRef } from '../scene/model-ref.js';
|
|
34
|
+
export { MaterialRef } from '../scene/material-ref.js';
|
|
34
35
|
export * from '../shader/parameter.js';
|
|
35
36
|
export * from './ai/index.js';
|
|
36
37
|
export * from '../effects/vfx/index.js';
|
package/dist/gameplay/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./game-mode.js";export*from"./player-lifecycle-coordinator.js";export*from"./player-sessions.js";export*from"./game-state-context.js";export*from"./network-travel-coordinator.js";export*from"./rendering-host.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,ActorLifetime,BaseActor,getActorClassById,getActorClassId,getRegisteredActorClasses,getActorOptions}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach,getComponentClassById,getComponentClassId,getRegisteredComponentClasses}from"./actors/component.js";export*from"./services/world.js";export*from"./services/scene-transition.js";export*from"./services/game-time-scheduler.js";export*from"./services/camera-shake.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./animation/retarget.js";export*from"./animation/locomotion-body.js";export*from"./animation/foot-contact.js";export*from"./animation/foot-contact-baker.js";export*from"./animation/pose-inertialization.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export{DataAssetRef}from"../scene/objects/data-asset.js";export{SceneRef,sceneId}from"../scene/scene-ref.js";export{ModelRef}from"../scene/model-ref.js";export*from"../shader/parameter.js";export*from"./ai/index.js";export*from"../effects/vfx/index.js";export*from"./services/shader-provider.js";export{EventGraphCallable,EventGraphEventSource,EventGraphProperty,getEventGraphCallableInfo,getEventGraphCallableInfos,getEventGraphCallableMethods,getEventGraphEventSourceInfo,getEventGraphEventSourceInfos,getEventGraphEventSourceMethods,getEventGraphPropertyInfo,getEventGraphPropertyInfos,getEventGraphProperties,isEventGraphEventSource}from"./event-graph/decorators.js";export{EventGraphCompiler,validateEventGraphDocument}from"./event-graph/document-compiler.js";export{createDefaultEventGraphDocument,hasExecutableEventGraphDocument}from"./event-graph/model.js";export{EVENT_GRAPH_NODE_DEFINITIONS,getEventGraphNodePorts,getEventGraphPortDefinition}from"./event-graph/registry.js";export{EventGraphInstance}from"./event-graph/runtime.js";export{analyzeEventGraphTypes,assertEventGraphTypes,createEventGraphTypeContext,getEventGraphMembersForType}from"./event-graph/type-inference.js";export{EVENT_GRAPH_ACTOR_TYPE,EVENT_GRAPH_ACTOR_CLASS_TYPE,EVENT_GRAPH_ANY_TYPE,EVENT_GRAPH_BOOLEAN_TYPE,EVENT_GRAPH_COMPONENT_TYPE,EVENT_GRAPH_NUMBER_TYPE,EVENT_GRAPH_OBJECT_TYPE,EVENT_GRAPH_STRING_TYPE,EVENT_GRAPH_VOID_TYPE,EVENT_GRAPH_VECTOR2_TYPE,EVENT_GRAPH_VECTOR3_TYPE,eventGraphActorClassType,eventGraphActorType,eventGraphComponentType,eventGraphTypeName,isEventGraphTypeAssignable}from"./event-graph/types.js";export*from"./net/net-connection.js";export*from"./net/net-session.js";export*from"./services/actor-persistence.js";export*from"./actors/builtin/components/actor-transform-persistence.js";/*
|
|
1
|
+
import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./game-mode.js";export*from"./player-lifecycle-coordinator.js";export*from"./player-sessions.js";export*from"./game-state-context.js";export*from"./network-travel-coordinator.js";export*from"./rendering-host.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,ActorLifetime,BaseActor,getActorClassById,getActorClassId,getRegisteredActorClasses,getActorOptions}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach,getComponentClassById,getComponentClassId,getRegisteredComponentClasses}from"./actors/component.js";export*from"./services/world.js";export*from"./services/scene-transition.js";export*from"./services/game-time-scheduler.js";export*from"./services/camera-shake.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./animation/retarget.js";export*from"./animation/locomotion-body.js";export*from"./animation/foot-contact.js";export*from"./animation/foot-contact-baker.js";export*from"./animation/pose-inertialization.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export{DataAssetRef}from"../scene/objects/data-asset.js";export{SceneRef,sceneId}from"../scene/scene-ref.js";export{ModelRef}from"../scene/model-ref.js";export{MaterialRef}from"../scene/material-ref.js";export*from"../shader/parameter.js";export*from"./ai/index.js";export*from"../effects/vfx/index.js";export*from"./services/shader-provider.js";export{EventGraphCallable,EventGraphEventSource,EventGraphProperty,getEventGraphCallableInfo,getEventGraphCallableInfos,getEventGraphCallableMethods,getEventGraphEventSourceInfo,getEventGraphEventSourceInfos,getEventGraphEventSourceMethods,getEventGraphPropertyInfo,getEventGraphPropertyInfos,getEventGraphProperties,isEventGraphEventSource}from"./event-graph/decorators.js";export{EventGraphCompiler,validateEventGraphDocument}from"./event-graph/document-compiler.js";export{createDefaultEventGraphDocument,hasExecutableEventGraphDocument}from"./event-graph/model.js";export{EVENT_GRAPH_NODE_DEFINITIONS,getEventGraphNodePorts,getEventGraphPortDefinition}from"./event-graph/registry.js";export{EventGraphInstance}from"./event-graph/runtime.js";export{analyzeEventGraphTypes,assertEventGraphTypes,createEventGraphTypeContext,getEventGraphMembersForType}from"./event-graph/type-inference.js";export{EVENT_GRAPH_ACTOR_TYPE,EVENT_GRAPH_ACTOR_CLASS_TYPE,EVENT_GRAPH_ANY_TYPE,EVENT_GRAPH_BOOLEAN_TYPE,EVENT_GRAPH_COMPONENT_TYPE,EVENT_GRAPH_NUMBER_TYPE,EVENT_GRAPH_OBJECT_TYPE,EVENT_GRAPH_STRING_TYPE,EVENT_GRAPH_VOID_TYPE,EVENT_GRAPH_VECTOR2_TYPE,EVENT_GRAPH_VECTOR3_TYPE,eventGraphActorClassType,eventGraphActorType,eventGraphComponentType,eventGraphTypeName,isEventGraphTypeAssignable}from"./event-graph/types.js";export*from"./net/net-connection.js";export*from"./net/net-session.js";export*from"./services/actor-persistence.js";export*from"./actors/builtin/components/actor-transform-persistence.js";/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{setWebGpuPipelineLoading as e}from"../rendering/webgpu-runtime-bridge.js";import t from"typedi";import{BehaviorSubject as i,Subject as n}from"rxjs";import{loadScene as s}from"../scene/bootstrap.js";import{ActorFactory as r}from"./actors/factory.js";import{SceneMaterializer as o}from"../scene/materializer.js";import{SceneDataService as a}from"../scene/scene-data-service.js";import{World as c}from"./services/world.js";import{ViewController as l}from"./services/render.js";import{RenderingView as p,GraphicsRuntime as h}from"../rendering.js";import{PhysicsSystem as d}from"./services/physics/physics-system.js";import{MeshComponent as m}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as u}from"./actors/builtin/components/index.js";import{InputService as g}from"./input/index.js";import{RuntimeAssetsService as w}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as f}from"../scene/asset-resource-loader.js";import{AssetLoader as y}from"./services/asset-loader.js";import{RuntimeBundledBackendService as v}from"../scene/runtime-bundled-backend-service.js";import{AssetsProvider as S}from"../scene/assets-provider.js";import{ShaderProvider as b}from"./services/shader-provider.js";import{PointerEvents as j}from"./services/pointer-events.js";import{GpuVfxWorldService as I}from"../effects/vfx/gpu-vfx-world-service.js";import{NetMode as A}from"./net/net-session.js";import{GameStateContext as V}from"./game-state-context.js";import{PlayerSessions as P}from"./player-sessions.js";import{polyfillClient as N}from"./polyfill.js";import{withInjectionContext as C}from"./inject.js";import{RenderingHost as G}from"./rendering-host.js";import{SceneTransitionService as H}from"./services/scene-transition.js";import{SceneRef as R}from"../scene/scene-ref.js";import{ActorPersistence as z}from"./services/actor-persistence.js";let x=0;export function initiateApplication(e,i){const n="function"==typeof e?e:void 0,s=i??e;var r;N(),"element"in s&&null!=s.element&&(r=s.element,Object.assign(r.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"}));const o=s.renderingHost??(null!=s.renderingView?new G(s.renderingView,!1,("renderingViewFactory"in s?s.renderingViewFactory:void 0)??(()=>new p(s.renderingView.container,s.renderingView.options))):function(e,t,i){const n=new h,s=()=>function(e,t,i,n){return new p(e,{graphicsRuntime:n,backend:t?.backend??"webgpu",enableXR:!0===i?.enabled,maxPixelRatio:t?.maxPixelRatio,resolutionScale:t?.resolutionScale,dynamicResolution:t?.dynamicResolution,upscaling:t?.upscaling,webgpuPostProcessing:t?.webgpuPostProcessing,webgpuDirectionalShadows:t?.webgpuDirectionalShadows,webgpuVfx:t?.webgpuVfx??"auto",msaa:t?.msaa,fpsCap:t?.fpsCap,depthPrepass:{enabled:!0===t?.depthPrepass?.enabled},bloom:{enabled:!1!==t?.bloom?.enabled},reflection:{enabled:!1!==t?.reflection?.enabled},occlusionCulling:{enabled:!1!==t?.occlusionCulling?.enabled},shadows:{enabled:t?.shadows?.enabled??!0,autoUpdate:t?.shadows?.autoUpdate??!0,cascadeUpdateIntervals:[22,40,60,120]}})}(e,t,i,n);return new G(s(),!0,s)}(s.element,s.rendering,s.xr)),a=t.of("hology-application-"+ ++x),c=new HologyApplicationRuntime(s,a,o,n??s.defaultGameClass);return c.startInitialization(),c}export function initiateGame(e,t){const{sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o,...a}=t,c=initiateApplication(e,a),l=c.ready.then(()=>c.loadGame({sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o}));return new HologyRuntime(c,l)}export class GameInstance{onPreload(){}onStart(){}onUnload(){return this.onShutdown()}onShutdown(){}}export class HologyApplicationRuntime{constructor(e,t,s,r){this.config=e,this.applicationContainer=t,this.renderingHost=s,this.defaultGameClass=r,this.stateSubject=new i({type:"initializing"}),this.state=this.stateSubject.asObservable(),this.shutdownSubject=new n,this.shutdownStarted=this.shutdownSubject.asObservable(),this.transitionTail=Promise.resolve(),this.initializationPromise=Promise.resolve(),this.transitionIntent=0,this.shutdownFlag=!1,this.ready=new Promise((e,t)=>{this.resolveReady=e,this.rejectReady=t})}get renderingView(){return this.renderingHost.activeView}get currentState(){return this.stateSubject.value}startInitialization(){this.initializationPromise=this.initialize()}async initialize(){try{if(this.registerApplicationServices(),await this.renderingHost.applicationView.compileAsync(),this.shutdownFlag)return void this.rejectReady(k());const e=this.getApplicationService(g);this.renderingHost.start(t=>e.update(t),t=>e.sampleGamepadButtons(t)),this.setState({type:"menu"}),this.resolveReady()}catch(e){this.setState({type:"error",operation:"initialize",error:e}),this.rejectReady(e)}}loadGame(e,t){const i="function"==typeof e?e:this.defaultGameClass,n=t??e;if(null==i)return Promise.reject(new Error("loadGame() requires a game class because no default was configured"));const s=++this.transitionIntent;return this.enqueue(async()=>(await this.ready,this.assertRunning(),this.checkIntent(s),null!=this.session&&await this.disposeSession(this.session,!0),this.checkIntent(s),this.performLoad(i,n,s)))}unloadGame(){const e=++this.transitionIntent;return this.enqueue(async()=>{if(await this.ready,!this.shutdownFlag&&e===this.transitionIntent){try{null!=this.session&&await this.disposeSession(this.session,!0)}catch(t){throw this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"error",operation:"unload",error:t}),t}this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"menu"})}})}transitionScene(e){const t="string"==typeof e?{scene:new R(e,e)}:e instanceof R?{scene:e}:e,i=this.transitionIntent;return this.enqueue(async()=>{await this.ready,this.assertRunning(),this.checkIntent(i);const e=this.session;if(null==e)throw new Error("transitionScene() requires an active game session");try{return await this.performSceneTransition(e,t,i),e}catch(e){throw F(e)||this.shutdownFlag||i!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}})}async shutdown(){this.shutdownFlag||(this.shutdownFlag=!0,++this.transitionIntent,this.shutdownSubject.next(),this.shutdownSubject.complete(),await this.initializationPromise.catch(()=>{}),await this.transitionTail.catch(()=>{}),null!=this.session&&await this.disposeSession(this.session,!1),this.getApplicationService(g).stop(),this.getOptionalApplicationService(j)?.stop(),this.getApplicationService(f).disposeAll(),this.getApplicationService(w).dispose(),this.getApplicationService(l).dispose(!1),this.renderingHost.shutdown(),t.reset(this.applicationContainer.id),this.setState({type:"stopped"}),this.stateSubject.complete())}getWorld(){return this.session?.world}getGameInstance(){return this.session?.gameInstance}getApplicationService(e){return this.applicationContainer.get(e)}getSessionService(e){return this.session?.container.get(e)}getService(e){return null!=this.session?this.session.container.get(e):this.applicationContainer.get(e)}registerRenderStage(e){return this.renderingHost.registerStage(e)}registerApplicationServices(){const e=new l(this.renderingView);this.applicationContainer.set(p,this.renderingHost.applicationView),this.applicationContainer.set(l,e);const t=new v(this.config.runtimeDataUrl),i=new w(t),n=new f;n.setDataDir(this.config.dataDir),n.setDirectFileLoading(!0===this.config.directAssetFileLoading),"webgpu"===this.renderingHost.applicationView.requestedBackend?n.initKtx2ForWebGpu(this.renderingHost.applicationView.webGpuDevice??void 0):n.initKtx2(this.renderingHost.applicationView.renderer);const s=Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t}));this.applicationContainer.set(v,t),this.applicationContainer.set(S,i),this.applicationContainer.set(w,i),this.applicationContainer.set(f,n),this.applicationContainer.set(y,new y(n,i,s)),this.applicationContainer.set(b,new b(s));const r=C(this.applicationContainer,e=>e.get(g));this.applicationContainer.set(g,r)}async performLoad(i,n,r){if(null!=n.persistence&&null!=n.multi?.session&&n.multi.session.mode!==A.none)throw new Error("Actor persistence currently supports single-player sessions only");const a=this.createSession(n);this.session=a;try{this.loading(n.sceneName,"physics",.08),await Promise.all([a.physics.start(),a.renderingView.initializeBackend()]),await e(a.renderingView.webGpuDevice,!0,"loading: "+n.sceneName),this.checkIntent(r),this.loading(n.sceneName,"runtime-data",.2),await this.getApplicationService(v).preloadData(),this.checkIntent(r),this.loading(n.sceneName,"scene",.42);const c=await s(a.renderingView,n.sceneName,this.config.dataDir,this.config.shaders,this.config.actors,a.components,a.actorFactory,this.getApplicationService(v),this.getApplicationService(w),this.getApplicationService(f),{detailTier:n.detailTier,nodeMode:n.multi?.session.mode??A.none,persistence:a.world.persistence});if(a.materializer.dispose(),a.materializer=c.materializer,a.sceneRoots=c.sceneRoots,a.container.set(o,c.materializer),a.world.materializer=c.materializer,a.world.scene=c.scene,a.physics.scene=c.scene,this.checkIntent(r),null!=n.multi?.session){const{NetService:e}=await import("./net/service/net-service.js"),t=C(a.container,t=>t.get(e));t.session=n.multi.session,t.start(),a.stopPlayers=()=>t.stop()}if(t.import([m]),await this.restoreSceneActors(a,c.materializer,c.actors,r),a.physics.addFromScene(c.scene),await a.world.startSceneEventGraphs(c.materializer),this.checkIntent(r),a.gameInstance=C(a.container,e=>(e.set({id:i,type:i}),e.get(i))),this.loading(n.sceneName,"game-preload",.58),a.gameInstance instanceof GameInstance&&await a.gameInstance.onPreload(),this.checkIntent(r),this.loading(n.sceneName,"shaders",.7),await a.renderingView.compileAsync(),this.checkIntent(r),this.loading(n.sceneName,"textures",.82),await a.renderingView.initTexturesAsync(),this.checkIntent(r),"webgpu"===a.renderingView.activeBackend){this.loading(n.sceneName,"vfx-warmup",.94);const e=C(a.container,e=>e.get(I).beginPipelineWarmup());try{const e=performance.now();console.info("[Hology GPU VFX warmup] Rendering loading frame",n.sceneName),a.renderingView.render(0),console.info("[Hology GPU VFX warmup] Render returned; waiting for GPU queue",{sceneName:n.sceneName,renderMs:performance.now()-e}),await(a.renderingView.webGpuDevice?.queue.onSubmittedWorkDone()),console.info("[Hology GPU VFX warmup] GPU queue completed",{sceneName:n.sceneName,totalMs:performance.now()-e})}finally{e()}}return this.checkIntent(r),await e(a.renderingView.webGpuDevice,!1,"playing: "+n.sceneName),a.gameInstance instanceof GameInstance&&await a.gameInstance.onStart(),this.checkIntent(r),a.viewController.paused=!1,this.renderingHost.activate(a.renderingView),this.setState({type:"playing",sceneName:n.sceneName}),a}catch(e){throw await this.disposeSession(a,!1),F(e)||this.shutdownFlag||r!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}}createSession(e){const i=t.of("hology-session-"+ ++x);this.copyApplicationServices(i);const n=this.renderingHost.createView(),s=new l(n);s.paused=!0,i.set(p,n),i.set(l,s);const h={...u,...this.config.components??{}},m=new z;null!=e.persistence&&m.configure(e.persistence),i.set(z,m);const g=new r(i,{inEditor:!1});g.classes=this.config.actors,i.set(r,g);const y=new o(n.scene,new a,this.getApplicationService(w),this.getApplicationService(f),n,Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t})),Object.entries(this.config.actors).map(([e,t])=>({name:e,type:t})),g,Object.entries(h).map(([e,t])=>({name:e,type:t})));y.inEditor=!1,y.netMode=e.multi?.session.mode??A.none,i.set(o,y);const v=C(i,e=>e.get(c));m.enabled&&(v.persistence=m),v.scene=n.scene,i.set(c,v);const S=C(i,e=>e.get(d));i.set(d,S);const b=new H;b.bind(async e=>{await this.transitionScene(e)}),i.set(H,b);const j=C(i,e=>e.get(P));i.set(P,j);const I=C(i,e=>e.get(V));return i.set(V,I),null==e.multi?.session&&j.startStandalone(e.localPlayer??{id:"local-player",displayName:"Player"}),{sceneName:e.sceneName,detailTier:e.detailTier,container:i,renderingView:n,viewController:s,actorFactory:g,materializer:y,world:v,physics:S,components:h,sceneTransition:b,sceneRoots:[],netMode:e.multi?.session.mode??A.none,stopPlayers:null==e.multi?.session?()=>{j.stop(),I.stop()}:void 0}}async performSceneTransition(t,i,n){if(t.netMode!==A.none)throw new Error("In-session scene transitions are not yet supported for network sessions");const r=i.scene.id.trim();if(0===r.length)throw new Error("A destination scene id is required");await e(t.renderingView.webGpuDevice,!0,"transition: "+r);const a=t.sceneName,c=t.viewController.paused;t.viewController.paused=!0,this.renderingHost.activate(this.renderingHost.applicationView),t.world.persistence?.captureAll(),this.setState({type:"unloading",sceneName:a}),t.world.stopSceneEventGraphs();const l=t.world.removeSceneLifetimeActors(t.sceneRoots);for(const e of t.sceneRoots)t.physics.removeRemoved(e),e.removeFromParent();t.sceneRoots=[],t.materializer.dispose(l),this.checkIntent(n),this.loading(r,"scene",.42);const p=await s(t.renderingView,r,this.config.dataDir,this.config.shaders,this.config.actors,t.components,t.actorFactory,this.getApplicationService(v),this.getApplicationService(w),this.getApplicationService(f),{detailTier:t.detailTier,nodeMode:t.netMode,persistence:t.world.persistence});this.checkIntent(n),t.materializer=p.materializer,t.sceneRoots=p.sceneRoots,t.sceneName=r,t.container.set(o,p.materializer),t.world.materializer=p.materializer,await this.restoreSceneActors(t,p.materializer,p.actors,n),t.physics.addFromScene(p.scene),await t.world.startSceneEventGraphs(p.materializer),await(i.afterLoad?.(t.world)),this.checkIntent(n),this.loading(r,"shaders",.7),await t.renderingView.compileAsync(),this.checkIntent(n),this.loading(r,"textures",.82),await t.renderingView.initTexturesAsync(),this.checkIntent(n),await e(t.renderingView.webGpuDevice,!1,"playing: "+r),t.sceneTransition.publish({previousSceneName:a,sceneName:r}),t.viewController.paused=c,this.renderingHost.activate(t.renderingView),this.setState({type:"playing",sceneName:r})}async restoreSceneActors(e,t,i,n){if(null==e.world.persistence){for(const t of i)e.world.addActor(t);return}const s=i.filter(t=>!e.world.actors.includes(t));for(const t of s)e.world.addActor(t,void 0,void 0,void 0,!0);const r=t.registerPersistentActors();await e.world.persistence.restore(r,()=>this.checkIntent(n)),this.checkIntent(n);for(const t of s)e.world.beginActorPlay(t)}copyApplicationServices(e){const t=[g,S,w,v,f,y,b];for(const i of t)e.set(i,this.applicationContainer.get(i))}async disposeSession(e,i){if(e.disposed)return;let n;e.disposed=!0,i&&this.setState({type:"unloading",sceneName:e.sceneName});try{e.viewController.paused=!0,e.world.persistence?.captureAll(),e.stopPlayers?.(),e.sceneTransition.dispose(),e.world.stopSceneEventGraphs(),e.gameInstance instanceof GameInstance&&await e.gameInstance.onUnload()}catch(e){n=e}finally{for(const t of[...e.world.actors])e.world.removeActor(t);e.physics.stop(),e.materializer.dispose(),this.renderingHost.activeView===e.renderingView&&this.renderingHost.activate(this.renderingHost.applicationView),e.viewController.dispose(!1),this.renderingHost.releaseView(e.renderingView),t.reset(e.container.id),this.session===e&&(this.session=void 0)}if(null!=n)throw n}enqueue(e){const t=this.transitionTail.then(e,e);return this.transitionTail=t.catch(()=>{}),t}checkIntent(e){if(this.assertRunning(),e!==this.transitionIntent)throw k()}assertRunning(){if(this.shutdownFlag)throw new Error("Hology application has been shut down")}loading(e,t,i){this.setState({type:"loading",sceneName:e,stage:t,progress:i})}setState(e){const t=this.renderingHost.applicationView;"loading"===e.type?t.stopAnimationLoop():"menu"!==e.type&&("error"!==e.type||"initialize"===e.operation)||this.renderingHost.activeView!==t||t.running||this.renderingHost.activate(t),this.stateSubject.next(e)}getOptionalApplicationService(e){return this.applicationContainer.has(e)?this.applicationContainer.get(e):void 0}}export class HologyRuntime{constructor(e,t){this.application=e,this.ready=t.then(()=>!0),this.shutdownStarted=e.shutdownStarted}get status(){return"playing"===this.application.currentState.type?5:"stopped"===this.application.currentState.type||"error"===this.application.currentState.type?10:0}get gameInstance(){return this.application.getGameInstance()}get isShutdown(){return"stopped"===this.application.currentState.type}getWorld(){return this.application.getWorld()}getService(e){return this.application.getService(e)}shutdown(){return this.application.shutdown()}}function k(){return new DOMException("Superseded by a newer game transition","AbortError")}function F(e){return e instanceof DOMException&&"AbortError"===e.name}/*
|
|
1
|
+
import{setWebGpuPipelineLoading as e}from"../rendering/webgpu-runtime-bridge.js";import t from"typedi";import{BehaviorSubject as i,Subject as n}from"rxjs";import{loadScene as s}from"../scene/bootstrap.js";import{ActorFactory as r}from"./actors/factory.js";import{SceneMaterializer as o}from"../scene/materializer.js";import{SceneDataService as a}from"../scene/scene-data-service.js";import{World as c}from"./services/world.js";import{ViewController as l}from"./services/render.js";import{RenderingView as p,GraphicsRuntime as h}from"../rendering.js";import{PhysicsSystem as d}from"./services/physics/physics-system.js";import{MeshComponent as m}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as g}from"./actors/builtin/components/index.js";import{InputService as u}from"./input/index.js";import{RuntimeAssetsService as w}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as f}from"../scene/asset-resource-loader.js";import{AssetLoader as y}from"./services/asset-loader.js";import{RuntimeBundledBackendService as v}from"../scene/runtime-bundled-backend-service.js";import{AssetsProvider as S}from"../scene/assets-provider.js";import{ShaderProvider as b}from"./services/shader-provider.js";import{PointerEvents as I}from"./services/pointer-events.js";import{GpuVfxWorldService as j}from"../effects/vfx/gpu-vfx-world-service.js";import{NetMode as A}from"./net/net-session.js";import{GameStateContext as V}from"./game-state-context.js";import{PlayerSessions as H}from"./player-sessions.js";import{polyfillClient as P}from"./polyfill.js";import{withInjectionContext as R}from"./inject.js";import{RenderingHost as N}from"./rendering-host.js";import{SceneTransitionService as C}from"./services/scene-transition.js";import{SceneRef as G}from"../scene/scene-ref.js";import{ActorPersistence as z}from"./services/actor-persistence.js";let k=0;export function initiateApplication(e,i){const n="function"==typeof e?e:void 0,s=i??e;var r;P(),"element"in s&&null!=s.element&&(r=s.element,Object.assign(r.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"}));const o=s.renderingHost??(null!=s.renderingView?new N(s.renderingView,!1,("renderingViewFactory"in s?s.renderingViewFactory:void 0)??(()=>new p(s.renderingView.container,s.renderingView.options))):function(e,t,i){const n=new h,s=()=>function(e,t,i,n){return new p(e,{graphicsRuntime:n,backend:t?.backend??"webgpu",enableXR:!0===i?.enabled,maxPixelRatio:t?.maxPixelRatio,resolutionScale:t?.resolutionScale,dynamicResolution:t?.dynamicResolution,upscaling:t?.upscaling,webgpuPostProcessing:t?.webgpuPostProcessing,webgpuDirectionalShadows:t?.webgpuDirectionalShadows,webgpuVfx:t?.webgpuVfx??"auto",msaa:t?.msaa,fpsCap:t?.fpsCap,depthPrepass:{enabled:!0===t?.depthPrepass?.enabled},bloom:{enabled:!1!==t?.bloom?.enabled},reflection:{enabled:!1!==t?.reflection?.enabled},occlusionCulling:{enabled:!1!==t?.occlusionCulling?.enabled},shadows:{enabled:t?.shadows?.enabled??!0,autoUpdate:t?.shadows?.autoUpdate??!0,cascadeUpdateIntervals:[22,40,60,120]}})}(e,t,i,n);return new N(s(),!0,s)}(s.element,s.rendering,s.xr)),a=t.of("hology-application-"+ ++k),c=new HologyApplicationRuntime(s,a,o,n??s.defaultGameClass);return c.startInitialization(),c}export function initiateGame(e,t){const{sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o,...a}=t,c=initiateApplication(e,a),l=c.ready.then(()=>c.loadGame({sceneName:i,detailTier:n,multi:s,localPlayer:r,persistence:o}));return new HologyRuntime(c,l)}export class GameInstance{onPreload(){}onStart(){}onUnload(){return this.onShutdown()}onShutdown(){}}export class HologyApplicationRuntime{constructor(e,t,s,r){this.config=e,this.applicationContainer=t,this.renderingHost=s,this.defaultGameClass=r,this.stateSubject=new i({type:"initializing"}),this.state=this.stateSubject.asObservable(),this.shutdownSubject=new n,this.shutdownStarted=this.shutdownSubject.asObservable(),this.transitionTail=Promise.resolve(),this.initializationPromise=Promise.resolve(),this.transitionIntent=0,this.shutdownFlag=!1,this.ready=new Promise((e,t)=>{this.resolveReady=e,this.rejectReady=t})}get renderingView(){return this.renderingHost.activeView}get currentState(){return this.stateSubject.value}startInitialization(){this.initializationPromise=this.initialize()}async initialize(){try{if(this.registerApplicationServices(),await this.renderingHost.applicationView.compileAsync(),this.shutdownFlag)return void this.rejectReady(x());const e=this.getApplicationService(u);this.renderingHost.start(t=>e.update(t),t=>e.sampleGamepadButtons(t)),this.setState({type:"menu"}),this.resolveReady()}catch(e){this.setState({type:"error",operation:"initialize",error:e}),this.rejectReady(e)}}loadGame(e,t){const i="function"==typeof e?e:this.defaultGameClass,n=t??e;if(null==i)return Promise.reject(new Error("loadGame() requires a game class because no default was configured"));const s=++this.transitionIntent;return this.enqueue(async()=>(await this.ready,this.assertRunning(),this.checkIntent(s),null!=this.session&&await this.disposeSession(this.session,!0),this.checkIntent(s),this.performLoad(i,n,s)))}unloadGame(){const e=++this.transitionIntent;return this.enqueue(async()=>{if(await this.ready,!this.shutdownFlag&&e===this.transitionIntent){try{null!=this.session&&await this.disposeSession(this.session,!0)}catch(t){throw this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"error",operation:"unload",error:t}),t}this.shutdownFlag||e!==this.transitionIntent||this.setState({type:"menu"})}})}transitionScene(e){const t="string"==typeof e?{scene:new G(e,e)}:e instanceof G?{scene:e}:e,i=this.transitionIntent;return this.enqueue(async()=>{await this.ready,this.assertRunning(),this.checkIntent(i);const e=this.session;if(null==e)throw new Error("transitionScene() requires an active game session");try{return await this.performSceneTransition(e,t,i),e}catch(e){throw F(e)||this.shutdownFlag||i!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}})}async shutdown(){this.shutdownFlag||(this.shutdownFlag=!0,++this.transitionIntent,this.shutdownSubject.next(),this.shutdownSubject.complete(),await this.initializationPromise.catch(()=>{}),await this.transitionTail.catch(()=>{}),null!=this.session&&await this.disposeSession(this.session,!1),this.getApplicationService(u).stop(),this.getOptionalApplicationService(I)?.stop(),this.getApplicationService(f).disposeAll(),this.getApplicationService(w).dispose(),this.getApplicationService(l).dispose(!1),this.renderingHost.shutdown(),t.reset(this.applicationContainer.id),this.setState({type:"stopped"}),this.stateSubject.complete())}getWorld(){return this.session?.world}getGameInstance(){return this.session?.gameInstance}getApplicationService(e){return this.applicationContainer.get(e)}getSessionService(e){return this.session?.container.get(e)}getService(e){return null!=this.session?this.session.container.get(e):this.applicationContainer.get(e)}registerRenderStage(e){return this.renderingHost.registerStage(e)}registerApplicationServices(){const e=new l(this.renderingView);this.applicationContainer.set(p,this.renderingHost.applicationView),this.applicationContainer.set(l,e);const t=new v(this.config.runtimeDataUrl),i=new w(t),n=new f;n.setDataDir(this.config.dataDir),n.setDirectFileLoading(!0===this.config.directAssetFileLoading),"webgpu"===this.renderingHost.applicationView.requestedBackend?n.initKtx2ForWebGpu(this.renderingHost.applicationView.webGpuDevice??void 0):n.initKtx2(this.renderingHost.applicationView.renderer);const s=Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t}));this.applicationContainer.set(v,t),this.applicationContainer.set(S,i),this.applicationContainer.set(w,i),this.applicationContainer.set(f,n),this.applicationContainer.set(y,new y(n,i,s)),this.applicationContainer.set(b,new b(s));const r=R(this.applicationContainer,e=>e.get(u));this.applicationContainer.set(u,r)}async performLoad(i,n,r){if(null!=n.persistence&&null!=n.multi?.session&&n.multi.session.mode!==A.none)throw new Error("Actor persistence currently supports single-player sessions only");const a=this.createSession(n);this.session=a;try{this.loading(n.sceneName,"physics",.08),await Promise.all([a.physics.start(),a.renderingView.initializeBackend()]),await e(a.renderingView.webGpuDevice,!0,"loading: "+n.sceneName),this.checkIntent(r),this.loading(n.sceneName,"runtime-data",.2),await this.getApplicationService(v).preloadData(),this.checkIntent(r),this.loading(n.sceneName,"scene",.42);const c=await s(a.renderingView,n.sceneName,this.config.dataDir,this.config.shaders,this.config.actors,a.components,a.actorFactory,this.getApplicationService(v),this.getApplicationService(w),this.getApplicationService(f),{detailTier:n.detailTier,nodeMode:n.multi?.session.mode??A.none,persistence:a.world.persistence});if(a.materializer.dispose(),a.materializer=c.materializer,a.sceneRoots=c.sceneRoots,a.container.set(o,c.materializer),a.world.materializer=c.materializer,a.world.scene=c.scene,a.physics.scene=c.scene,this.checkIntent(r),null!=n.multi?.session){const{NetService:e}=await import("./net/service/net-service.js"),t=R(a.container,t=>t.get(e));t.session=n.multi.session,t.start(),a.stopPlayers=()=>t.stop()}if(t.import([m]),await this.restoreSceneActors(a,c.materializer,c.actors,r),a.physics.addFromScene(c.scene),await a.world.startSceneEventGraphs(c.materializer),this.checkIntent(r),a.gameInstance=R(a.container,e=>(e.set({id:i,type:i}),e.get(i))),this.loading(n.sceneName,"game-preload",.58),a.gameInstance instanceof GameInstance&&await a.gameInstance.onPreload(),this.checkIntent(r),this.loading(n.sceneName,"shaders",.7),await a.renderingView.compileAsync(),this.checkIntent(r),this.loading(n.sceneName,"textures",.82),await a.renderingView.initTexturesAsync(),this.checkIntent(r),"webgpu"===a.renderingView.activeBackend){this.loading(n.sceneName,"vfx-warmup",.94);const e=R(a.container,e=>e.get(j).beginPipelineWarmup());try{const e=performance.now();console.info("[Hology GPU VFX warmup] Rendering loading frame",n.sceneName),a.renderingView.render(0),console.info("[Hology GPU VFX warmup] Render returned; waiting for GPU queue",{sceneName:n.sceneName,renderMs:performance.now()-e}),await(a.renderingView.webGpuDevice?.queue.onSubmittedWorkDone()),console.info("[Hology GPU VFX warmup] GPU queue completed",{sceneName:n.sceneName,totalMs:performance.now()-e})}finally{e()}}return this.checkIntent(r),a.gameInstance instanceof GameInstance&&await a.gameInstance.onStart(),this.checkIntent(r),await e(a.renderingView.webGpuDevice,!1,"playing: "+n.sceneName),this.checkIntent(r),a.viewController.paused=!1,this.renderingHost.activate(a.renderingView),this.setState({type:"playing",sceneName:n.sceneName}),a}catch(e){throw await this.disposeSession(a,!1),F(e)||this.shutdownFlag||r!==this.transitionIntent||this.setState({type:"error",operation:"load",error:e}),e}}createSession(e){const i=t.of("hology-session-"+ ++k);this.copyApplicationServices(i);const n=this.renderingHost.createView(),s=new l(n);s.paused=!0,i.set(p,n),i.set(l,s);const h={...g,...this.config.components??{}},m=new z;null!=e.persistence&&m.configure(e.persistence),i.set(z,m);const u=new r(i,{inEditor:!1});u.classes=this.config.actors,i.set(r,u);const y=new o(n.scene,new a,this.getApplicationService(w),this.getApplicationService(f),n,Object.entries(this.config.shaders).map(([e,t])=>({name:e,type:t})),Object.entries(this.config.actors).map(([e,t])=>({name:e,type:t})),u,Object.entries(h).map(([e,t])=>({name:e,type:t})));y.inEditor=!1,y.netMode=e.multi?.session.mode??A.none,i.set(o,y);const v=R(i,e=>e.get(c));m.enabled&&(v.persistence=m),v.scene=n.scene,i.set(c,v);const S=R(i,e=>e.get(d));i.set(d,S);const b=new C;b.bind(async e=>{await this.transitionScene(e)}),i.set(C,b);const I=R(i,e=>e.get(H));i.set(H,I);const j=R(i,e=>e.get(V));return i.set(V,j),null==e.multi?.session&&I.startStandalone(e.localPlayer??{id:"local-player",displayName:"Player"}),{sceneName:e.sceneName,detailTier:e.detailTier,container:i,renderingView:n,viewController:s,actorFactory:u,materializer:y,world:v,physics:S,components:h,sceneTransition:b,sceneRoots:[],netMode:e.multi?.session.mode??A.none,stopPlayers:null==e.multi?.session?()=>{I.stop(),j.stop()}:void 0}}async performSceneTransition(t,i,n){if(t.netMode!==A.none)throw new Error("In-session scene transitions are not yet supported for network sessions");const r=i.scene.id.trim();if(0===r.length)throw new Error("A destination scene id is required");await e(t.renderingView.webGpuDevice,!0,"transition: "+r);const a=t.sceneName,c=t.viewController.paused;t.viewController.paused=!0,this.renderingHost.activate(this.renderingHost.applicationView),t.world.persistence?.captureAll(),this.setState({type:"unloading",sceneName:a}),t.world.stopSceneEventGraphs();const l=t.world.removeSceneLifetimeActors(t.sceneRoots);for(const e of t.sceneRoots)t.physics.removeRemoved(e),e.removeFromParent();t.sceneRoots=[],t.materializer.dispose(l),this.checkIntent(n),this.loading(r,"scene",.42);const p=await s(t.renderingView,r,this.config.dataDir,this.config.shaders,this.config.actors,t.components,t.actorFactory,this.getApplicationService(v),this.getApplicationService(w),this.getApplicationService(f),{detailTier:t.detailTier,nodeMode:t.netMode,persistence:t.world.persistence});this.checkIntent(n),t.materializer=p.materializer,t.sceneRoots=p.sceneRoots,t.sceneName=r,t.container.set(o,p.materializer),t.world.materializer=p.materializer,await this.restoreSceneActors(t,p.materializer,p.actors,n),t.physics.addFromScene(p.scene),await t.world.startSceneEventGraphs(p.materializer),await(i.afterLoad?.(t.world)),this.checkIntent(n),this.loading(r,"shaders",.7),await t.renderingView.compileAsync(),this.checkIntent(n),this.loading(r,"textures",.82),await t.renderingView.initTexturesAsync(),this.checkIntent(n),await e(t.renderingView.webGpuDevice,!1,"playing: "+r),t.sceneTransition.publish({previousSceneName:a,sceneName:r}),t.viewController.paused=c,this.renderingHost.activate(t.renderingView),this.setState({type:"playing",sceneName:r})}async restoreSceneActors(e,t,i,n){if(null==e.world.persistence){for(const t of i)e.world.addActor(t);return}const s=i.filter(t=>!e.world.actors.includes(t));for(const t of s)e.world.addActor(t,void 0,void 0,void 0,!0);const r=t.registerPersistentActors();await e.world.persistence.restore(r,()=>this.checkIntent(n)),this.checkIntent(n);for(const t of s)e.world.beginActorPlay(t)}copyApplicationServices(e){const t=[u,S,w,v,f,y,b];for(const i of t)e.set(i,this.applicationContainer.get(i))}async disposeSession(e,i){if(e.disposed)return;let n;e.disposed=!0,i&&this.setState({type:"unloading",sceneName:e.sceneName});try{e.viewController.paused=!0,e.world.persistence?.captureAll(),e.stopPlayers?.(),e.sceneTransition.dispose(),e.world.stopSceneEventGraphs(),e.gameInstance instanceof GameInstance&&await e.gameInstance.onUnload()}catch(e){n=e}finally{for(const t of[...e.world.actors])e.world.removeActor(t);e.physics.stop(),e.materializer.dispose(),this.renderingHost.activeView===e.renderingView&&this.renderingHost.activate(this.renderingHost.applicationView),e.viewController.dispose(!1),this.renderingHost.releaseView(e.renderingView),t.reset(e.container.id),this.session===e&&(this.session=void 0)}if(null!=n)throw n}enqueue(e){const t=this.transitionTail.then(e,e);return this.transitionTail=t.catch(()=>{}),t}checkIntent(e){if(this.assertRunning(),e!==this.transitionIntent)throw x()}assertRunning(){if(this.shutdownFlag)throw new Error("Hology application has been shut down")}loading(e,t,i){this.setState({type:"loading",sceneName:e,stage:t,progress:i})}setState(e){const t=this.renderingHost.applicationView,i=t.presentationOnly;t.presentationOnly="loading"===e.type&&this.renderingHost.hasRenderStages,"loading"!==e.type||this.renderingHost.hasRenderStages?("menu"===e.type||"loading"===e.type&&this.renderingHost.hasRenderStages||"error"===e.type&&"initialize"!==e.operation)&&this.renderingHost.activeView===t&&(!t.running||i&&!t.presentationOnly)&&this.renderingHost.activate(t):t.stopAnimationLoop(),this.stateSubject.next(e)}getOptionalApplicationService(e){return this.applicationContainer.has(e)?this.applicationContainer.get(e):void 0}}export class HologyRuntime{constructor(e,t){this.application=e,this.ready=t.then(()=>!0),this.shutdownStarted=e.shutdownStarted}get status(){return"playing"===this.application.currentState.type?5:"stopped"===this.application.currentState.type||"error"===this.application.currentState.type?10:0}get gameInstance(){return this.application.getGameInstance()}get isShutdown(){return"stopped"===this.application.currentState.type}getWorld(){return this.application.getWorld()}getService(e){return this.application.getService(e)}shutdown(){return this.application.shutdown()}}function x(){return new DOMException("Superseded by a newer game transition","AbortError")}function F(e){return e instanceof DOMException&&"AbortError"===e.name}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -28,6 +28,7 @@ export declare class RenderingHost {
|
|
|
28
28
|
get activeView(): RenderingView;
|
|
29
29
|
get device(): GPUDevice;
|
|
30
30
|
get graphicsRuntime(): import("../rendering.js").GraphicsRuntime;
|
|
31
|
+
get hasRenderStages(): boolean;
|
|
31
32
|
createView(): RenderingView;
|
|
32
33
|
start(onFrame: (deltaTime: number) => void, onInputFrame?: (inactive: boolean) => void): void;
|
|
33
34
|
activate(view: RenderingView): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export class RenderingHost{constructor(e,t,s){this.applicationView=e,this.ownsApplicationView=t,this.viewFactory=s,this.views=new Set,this.frameDelta=new Map,this.stages=new Map,this.stageDisposers=new Map,this.nextStageId=0,this.stopped=!1,this.frameCallback=()=>{},this._activeView=e,this.views.add(e)}get activeView(){return this._activeView}get device(){return this._activeView.webGpuDevice}get graphicsRuntime(){return this.applicationView.sharedGraphicsRuntime}createView(){if(this.stopped)throw new Error("RenderingHost has been shut down");const e=this.viewFactory();if(this.views.has(e))throw new Error("RenderingViewFactory must return a new view");return e.suspendPresentation(),this.views.add(e),this.installStages(e),e}start(e,t){this.frameCallback=e,this.inputFrameCallback=t,this.activate(this.applicationView)}activate(e){if(!this.views.has(e))throw new Error("RenderingView is not owned by this host");this._activeView!==e&&this._activeView.suspendPresentation(),this._activeView=e,this.installStages(e),e.activatePresentation(),e.loop(t=>{this.frameDelta.set(e,t),this.frameCallback(t)},!1,this.inputFrameCallback)}releaseView(e){if(e===this.applicationView)throw new Error("Cannot release the application view");this.views.delete(e)&&(this.removeStages(e),this.frameDelta.delete(e),e.stop())}registerStage(e){const t=++this.nextStageId;this.stages.set(t,e);for(const s of this.views)this.installStage(s,t,e);return()=>{this.stages.delete(t);for(const e of this.stageDisposers.values())e.get(t)?.(),e.delete(t)}}shutdown(){if(!this.stopped){this.stopped=!0;for(const e of this.views)this.removeStages(e),e!==this.applicationView||this.ownsApplicationView?e.stop():e.suspendPresentation();this.views.clear(),this.frameDelta.clear()}}installStages(e){for(const[t,s]of this.stages)this.installStage(e,t,s)}installStage(e,t,s){let i=this.stageDisposers.get(e);if(null==i&&(i=new Map,this.stageDisposers.set(e,i)),i.has(t))return;const a=this;i.set(t,e.registerWebGpuPresentationExtension(t=>{const i=t;i.deltaTime=a.frameDelta.get(e)??0,i.elapsedTime=e.simulationTime,s(i)}))}removeStages(e){const t=this.stageDisposers.get(e);if(null!=t){for(const e of t.values())e();this.stageDisposers.delete(e)}}}/*
|
|
1
|
+
export class RenderingHost{constructor(e,t,s){this.applicationView=e,this.ownsApplicationView=t,this.viewFactory=s,this.views=new Set,this.frameDelta=new Map,this.stages=new Map,this.stageDisposers=new Map,this.nextStageId=0,this.stopped=!1,this.frameCallback=()=>{},this._activeView=e,this.views.add(e)}get activeView(){return this._activeView}get device(){return this._activeView.webGpuDevice}get graphicsRuntime(){return this.applicationView.sharedGraphicsRuntime}get hasRenderStages(){return this.stages.size>0}createView(){if(this.stopped)throw new Error("RenderingHost has been shut down");const e=this.viewFactory();if(this.views.has(e))throw new Error("RenderingViewFactory must return a new view");return e.suspendPresentation(),this.views.add(e),this.installStages(e),e}start(e,t){this.frameCallback=e,this.inputFrameCallback=t,this.activate(this.applicationView)}activate(e){if(!this.views.has(e))throw new Error("RenderingView is not owned by this host");this._activeView!==e&&this._activeView.suspendPresentation(),this._activeView=e,this.installStages(e),e.activatePresentation(),e.loop(t=>{this.frameDelta.set(e,t),this.frameCallback(t)},!1,this.inputFrameCallback)}releaseView(e){if(e===this.applicationView)throw new Error("Cannot release the application view");this.views.delete(e)&&(this.removeStages(e),this.frameDelta.delete(e),e.stop())}registerStage(e){const t=++this.nextStageId;this.stages.set(t,e);for(const s of this.views)this.installStage(s,t,e);return()=>{this.stages.delete(t);for(const e of this.stageDisposers.values())e.get(t)?.(),e.delete(t)}}shutdown(){if(!this.stopped){this.stopped=!0;for(const e of this.views)this.removeStages(e),e!==this.applicationView||this.ownsApplicationView?e.stop():e.suspendPresentation();this.views.clear(),this.frameDelta.clear()}}installStages(e){for(const[t,s]of this.stages)this.installStage(e,t,s)}installStage(e,t,s){let i=this.stageDisposers.get(e);if(null==i&&(i=new Map,this.stageDisposers.set(e,i)),i.has(t))return;const a=this;i.set(t,e.registerWebGpuPresentationExtension(t=>{const i=t;i.deltaTime=a.frameDelta.get(e)??0,i.elapsedTime=e.simulationTime,s(i)}))}removeStages(e){const t=this.stageDisposers.get(e);if(null!=t){for(const e of t.values())e();this.stageDisposers.delete(e)}}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -5,6 +5,7 @@ import { AssetResourceLoader, LoadedMesh } from '../../scene/asset-resource-load
|
|
|
5
5
|
import { type AssetsProvider } from '../../scene/assets-provider.js';
|
|
6
6
|
import { Asset, AssetId } from '../../scene/model.js';
|
|
7
7
|
import { ModelRef } from '../../scene/model-ref.js';
|
|
8
|
+
import { MaterialRef } from '../../scene/material-ref.js';
|
|
8
9
|
import { Prefab } from '../../scene/objects/prefab.js';
|
|
9
10
|
import { ShaderImpl } from '../../shader/shader.js';
|
|
10
11
|
import type { ShaderGraphDocument } from '../../shader/graph/model.js';
|
|
@@ -66,6 +67,8 @@ export declare class AssetLoader {
|
|
|
66
67
|
getDataAssetsByType<T>(type: Type<T>): Promise<T[]>;
|
|
67
68
|
getShaderGraphByAssetId(id: AssetId): Promise<ShaderGraphDocument>;
|
|
68
69
|
prepareShaderGraphParameters(graph: ShaderGraphDocument, params?: Record<string, any>): Promise<Record<string, unknown>>;
|
|
70
|
+
/** Explicitly load a material when gameplay needs the rendered resource. */
|
|
71
|
+
getMaterialByRef(ref: MaterialRef): Promise<Material>;
|
|
69
72
|
getMaterialByAssetId(id: AssetId): Promise<Material>;
|
|
70
73
|
getAsset(id: AssetId): Promise<Asset>;
|
|
71
74
|
getPrefabByName(name: string): Promise<Prefab>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as n,MTLLoader as o,OBJLoader as d,TGALoader as h}from"three-stdlib";import{KTX2Loader as c}from"three/examples/jsm/Addons.js";import{Service as l}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as g}from"../../scene/materializer.js";import{materialFromAsset as w,materializeDataAssetRef as f,prepareShaderGraphParameters as m}from"../../scene/materializer.js";import{Prefab as y}from"../../scene/objects/prefab.js";import{pathJoin as A}from"../../utils/files.js";import{Sequence as p}from"../../effects/sequence/sequence-data.js";import{resolveAnimationClipAssetForTarget as b}from"../animation/retarget.js";import{getDataAssetDefinitionId as v}from"@hology/core/shader/parameter";let
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as n,MTLLoader as o,OBJLoader as d,TGALoader as h}from"three-stdlib";import{KTX2Loader as c}from"three/examples/jsm/Addons.js";import{Service as l}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as g}from"../../scene/materializer.js";import{materialFromAsset as w,materializeDataAssetRef as f,prepareShaderGraphParameters as m}from"../../scene/materializer.js";import{Prefab as y}from"../../scene/objects/prefab.js";import{pathJoin as A}from"../../utils/files.js";import{Sequence as p}from"../../effects/sequence/sequence-data.js";import{resolveAnimationClipAssetForTarget as b}from"../animation/retarget.js";import{getDataAssetDefinitionId as v}from"@hology/core/shader/parameter";let B=class{constructor(e,t,l){this.assetResourceLoader=e,this.assetService=t,this.shaders=l,this.baseUrl="",this.urlSuffix="",this.loadingManager=new a,this.glbLoader=new n(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new d(this.loadingManager),this.mtlLoader=new o(this.loadingManager),this.tgaLoader=new h(this.loadingManager),this.ktx2Loader=new c(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager),this.animationVariantIds=new Map,this.assetResourceLoader.materialProvider=e=>this.getMaterialByAssetId(e),this.assetResourceLoader.animationRigProvider=async e=>(await this.assetService.getAsset(e))?.animationRig}resolvePath(e){return A(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}getModelByRef(e){return this.getModelByAssetId(e.id)}async getAnimationClipByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No animation clip could be found with asset id ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async getAnimationClipForTargetByAssetId(e,t){const s=await this.assetService.getAsset(e);if(null==s)throw new Error(`No animation clip could be found with asset id ${e}`);let a=s;if(null!=t&&s.anim?.rigId!==t){const r=`${e}|${t}`,i=this.animationVariantIds.get(r);null!=i?a=await this.assetService.getAsset(i):(a=b(s,await this.assetService.getAssets(),t),this.animationVariantIds.set(r,a.id))}return this.assetResourceLoader.getAnimationClip(a)}async getAnimationClipByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No animation clip could be found with asset name ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async applyMaterials(e,t){for(const s of e.materialAssignments??[])await g(t,s,async e=>this.getMaterialByAssetId(e))}async getTextureByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No texture could be found with asset name ${e}`);return this.assetResourceLoader.getTexture(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getSequenceById(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No sequence could be found with asset id ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new p(t.sequence)}async getSequenceByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No sequence could be found with asset name ${e}`);if(null==t.sequence)throw new Error(`Missing sequence data in asset ${e}`);return new p(t.sequence)}async getDataAssetById(e,t){const s=await f(e,this.assetService,this.assetResourceLoader,void 0,void 0,this.shaders);if(null!=t&&null!=s&&!(s.value instanceof t))throw new Error(`Invalid type. Expecting asset with id ${e} to be of type ${t.name} but got:`+s.value);return s}async getDataAssetByName(e,t){const s=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==s)throw new Error(`No data asset could be found with name ${e}`);return this.getDataAssetById(s.id,t)}async getDataAssetsByDefinition(e,t){const s=(await this.assetService.getAssets()).filter(t=>t.dataAsset?.definition===e);if(0===s.length)throw new Error(`No data assets could be found with definition ${e}`);return Promise.all(s.map(e=>this.getDataAssetById(e.id,t).then(e=>e?.value)))}async getDataAssetsByType(e){const t=v(e);return this.getDataAssetsByDefinition(t,e)}async getShaderGraphByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No shader graph could be found with asset id ${e}`);if("shaderGraph"!==t.type||null==t.shaderGraph)throw new Error(`Missing shader graph data in asset ${e}`);return t.shaderGraph}async prepareShaderGraphParameters(e,t={}){return m(t,e,this.assetService,this.assetResourceLoader,void 0,this.shaders)}getMaterialByRef(e){return this.getMaterialByAssetId(e.id)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return w(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}async getPrefabByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if("prefab"!==t.type)throw`Asset with name ${e} is not a prefab`;return new y(t)}async getPrefabById(e){const t=await this.getAsset(e);if("prefab"!==t.type)throw`Asset with name ${name} is not a prefab`;return new y(t)}clearCache(e){this.animationVariantIds.clear(),this.assetResourceLoader.clearCache(e)}clearCacheById(e){this.animationVariantIds.clear(),this.assetResourceLoader.clearCacheById(e)}};B=e([l(),t("design:paramtypes",[u,Function,Array])],B);export{B as AssetLoader};/*
|
|
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 e}from"tslib";import{createRapierCollisionShape as i}from"../../../scene/collision/rapier-shape.js";import*as s from"@dimforge/rapier3d-simd-compat";import{QueryFilterFlags as o}from"@dimforge/rapier3d-simd-compat";import{BehaviorSubject as n,distinctUntilChanged as r,filter as a,map as l,Subject as c,takeUntil as d}from"rxjs";import*as h from"three";import{ArrowHelper as u,BufferAttribute as p,BufferGeometry as y,Group as g,LineSegments as m,Matrix4 as b,Object3D as w,Quaternion as f,Raycaster as v,Scene as x,Vector3 as B}from"three";import{Service as D}from"typedi";import{ActorComponent as S,Component as A}from"../../../gameplay/actors/component.js";import{inject as C}from"../../../gameplay/inject.js";import{ConvexPolyhedronCollisionShape as R,PhysicalShapeMesh as E,toInstancedCollisionShape as M}from"../../../scene/collision/collision-shape.js";import{AssetMeshInstance as T}from"../../../scene/asset-resource-loader.js";import{LandscapeGroup as P,LandscapeMesh as z}from"../../../scene/landscape/landscape.js";import{ViewController as F}from"../render.js";import{World as j}from"../world.js";import{AbstractPhysicsSystem as I}from"./abstract-physics-system.js";import{NetRole as _}from"../../net/index.js";export{ActorComponent,attach,Attach,Component}from"../../actors/component.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.hitNormal=new B}}export class ShapeCastResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.normal=new B}reset(){this.actor=void 0,this.hasHit=!1,this.distance=0,this.hitPoint.set(0,0,0),this.normal.set(0,0,0)}}ShapeCastResult.shared=new ShapeCastResult;export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));const N=new B,W=new B,O=new f,L=new f,k=new f;let V=class extends I{isLandscapeNavigationCollider(t){return this.colliderObjects.get(t)?.object instanceof z}forEachStaticActorNavigationCollider(t,e){const i=this.actorBodies.get(t.id);if(i?.isFixed()&&i.isEnabled()&&!0!==i.userData?.ignoreForNavMesh)for(let t=0;t<i.numColliders();t++){const s=i.collider(t);s.isEnabled()&&!s.isSensor()&&e(s)}}set showDebug(t){this.shouldRenderDebug=t,t||this.clearRayDebugArrows(),this.debugMesh&&(this.debugMesh.visible=t),this.staticDebugMesh&&(this.staticDebugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.colliderObjects=new WeakMap,this.rayDebugArrowPool=[],this.activeRayDebugArrows=[],this.nonFixedBodies=new Set,this.collisionEvents=new c,this.beforeStep=new c,this.afterStep=new c,this.shouldRenderDebug=!1,this.viewController=C(F),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this.staticDebugNeedsUpdate=!0,this.invalidateStaticDebug=()=>{this.staticDebugNeedsUpdate=!0},this.handleCollisionEvent=(t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})},this._raycaster=new v,this._reusableResult=new RayTestResult,this._raytestDiff=new B,this._raytestDirection=new B,this.controlledActors=new Set,this._isStopped=!1,this.ready=this.setup()}getBallShape(t){let e=this.shapeCacheBall.get(t);return null==e&&(e=new this.rapier.Ball(t),this.shapeCacheBall.set(t,e)),e}getBoxShape(t,e,i){const s=t+1e6*e+1e12*i;let o=this.shapeCacheBox.get(s);return null==o&&(o=new this.rapier.Cuboid(t,e,i),this.shapeCacheBox.set(s,o)),o}hasBoxIntersection(t){const e=t.getCenter(N),i=t.getSize(W),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,O,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,O,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,n]of this.bodyActors)if(null==i||n instanceof i)for(let i=0,r=e.numColliders();i<r;i++){e.collider(i).intersectsShape(s,t,O)&&o.push(n)}return o}createDebugMesh(){const t=new m(new y,new h.LineBasicMaterial({color:255}));return t.frustumCulled=!1,t}updateDebugMesh(t,e){const i=t.geometry,s=i.getAttribute("position");if(null==s||s.array.length<e.length){null!=s&&i.dispose();const t=new Float32Array(e.length);t.set(e);const o=new p(t,3);o.setUsage(h.DynamicDrawUsage),i.setAttribute("position",o)}else e.length>0&&(s.array.set(e),s.clearUpdateRanges(),s.addUpdateRange(0,e.length),s.needsUpdate=!0);i.setDrawRange(0,e.length/3)}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;if(null==this.staticDebugMesh&&(this.staticDebugMesh=this.createDebugMesh(),this.staticDebugMesh.visible=this.shouldRenderDebug,this.staticDebugMesh.raycast=function(){},this.scene.add(this.staticDebugMesh)),null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene.add(this.debugMesh)),this.staticDebugNeedsUpdate){const t=this.world.debugRender(o.ONLY_FIXED);this.updateDebugMesh(this.staticDebugMesh,t.vertices),this.staticDebugNeedsUpdate=!1}const t=this.world.debugRender(o.EXCLUDE_FIXED);this.updateDebugMesh(this.debugMesh,t.vertices)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await nt(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{if(!(this._isStopped||t<=0)){t=Math.min(.04,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.releaseExpiredRayDebugArrows();for(const t of this.nonFixedBodies){let e,i=this.staticMeshes.get(t);if(null==i){if(e=this.bodyActors.get(t),e?.netRole===_.simulatedProxy)continue;i=e?.object}null!=i&&i.parent instanceof x&&(t.translation(i.position),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(e?.id))&&t.rotation(i.quaternion),i.matrixWorldNeedsUpdate=!0)}this.afterStep.next(t)}})}_updateWorld(){this.lastEmptyPhysicsWorld=void 0,this.world.timestep=0,this.world.step()}updatePhysics(t){if(this._isStopped)return;this.world.timestep=t;const e=0===this.world.bodies.len()&&0===this.world.colliders.len();e&&this.lastEmptyPhysicsWorld===this.world||this.world.step(this.eventQueue),this.lastEmptyPhysicsWorld=e?this.world:void 0,this.eventQueue.drainCollisionEvents(this.handleCollisionEvent)}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(et,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult),i.hasHit=!1,i.actor=void 0,i.object=void 0,i.instanceId=void 0,i.batchId=void 0;const n=this._raytestDiff,r=this._raytestDirection;n.subVectors(e,t);const a=n.length();if(0===a)return console.warn("Ray test called with to and from being equal"),i;r.copy(n).multiplyScalar(1/a),null==yt&&(yt=new this.rapier.Ray(new this.rapier.Vector3(0,0,0),new this.rapier.Vector3(0,1,0))),rt(yt.origin,t),rt(yt.dir,r);const l=this.world.castRayAndGetNormal(yt,a,!1,s?.excludeTriggers?o.EXCLUDE_SENSORS:void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0);if(i.hasHit=null!=l,i.actor=void 0,i.hasHit){const e=this.colliderObjects.get(l.collider);if(i.object=e?.object,i.instanceId=e?.instanceId,i.batchId=e?.batchId,i._internal=l,lt(i.hitNormal,l.normal),i.hitPoint.copy(t).addScaledVector(r,l.timeOfImpact),i.distance=l.timeOfImpact,!1!==s?.resolveActor){const t=l.collider.parent();i.actor=null!=t?this.bodyActors.get(t):null}}return this.showDebug&&!1!==s?.debug&&null!=this.scene&&this.drawRayDebugArrow(r,t,a,s?.debugColor,s?.debugLifetime),i}drawRayDebugArrow(t,e,i,s=255,o=200){let n=this.rayDebugArrowPool.pop();null==n?n=new u(t,e,i,s,.2,.1):(n.setDirection(t),n.position.copy(e),n.setLength(i,.2,.1),n.setColor(s)),n.userData.physicsRayDebugExpiresAt=performance.now()+o,this.activeRayDebugArrows.push(n),this.scene.add(n)}releaseExpiredRayDebugArrows(){if(0===this.activeRayDebugArrows.length)return;const t=performance.now();let e=0;for(let i=0;i<this.activeRayDebugArrows.length;i++){const s=this.activeRayDebugArrows[i];s.userData.physicsRayDebugExpiresAt<=t?(s.removeFromParent(),this.rayDebugArrowPool.push(s)):this.activeRayDebugArrows[e++]=s}this.activeRayDebugArrows.length=e}clearRayDebugArrows(){for(const t of this.activeRayDebugArrows)t.removeFromParent(),this.rayDebugArrowPool.push(t);this.activeRayDebugArrows.length=0}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return X.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())ct(t,t=>t.setActiveEvents(s.ActiveEvents.COLLISION_EVENTS))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof E&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof T){const e=!1!==t.userData?.src?.collisionDetection;if(t.children[0]&&(t.children[0].instanceMatrix&&e||t.children[0].isBatchedMesh))this.createForInstancedMesh(t.children[0],t.collisionShapes);else if(e&&t.children.length>0){const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}0===t.children.length&&(t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1)}else t instanceof P?this.addLandscapeGroup(t):(t instanceof g||t instanceof x)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new b;if(t instanceof h.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map,o=t.userData.collisionMatrices;for(let n=0;n<e.length;n++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[n])continue;const e=t.userData.collisionShapes;let r=e?.[n];if(null==r&&null==e&&t.parent instanceof T&&(r=t.parent.collisionShapes),null==r)continue;const a=o?.[n];let l=r;null==a&&(l=s.get(r),null==l&&(l=this.instancedShapeReset(r),s.set(r,l)));const c=new w;c.matrix.identity(),null!=a?i.copy(a):t.getMatrixAt(n,i),c.applyMatrix4(i);const d=this.createStaticBody(c,l),h={object:t,batchId:n};ct(d,t=>this.colliderObjects.set(t,h))}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new w;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);const n=this.createStaticBody(o,s),r={object:t,instanceId:e};ct(n,t=>this.colliderObjects.set(t,r))}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>M(t))}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,s=null){const n=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=n.collider(0);e.computeColliderMovement(r,i,o.EXCLUDE_SENSORS,s,void 0);const a=e.computedMovement();return lt(dt,a),dt}setActorCapsuleCollider(t,e,i,s){const o=this.actorBodies.get(t.id),n=o?.collider(0);if(null==o||null==n)return!1;const r=t.object?.getWorldScale(pt)??q,a=Math.max(0,e*Math.abs(r.y)),l=Math.max(.001,i*Math.max(Math.abs(r.x),Math.abs(r.z)));return n.setHalfHeight(a/2),n.setRadius(l),J.set(0,s,0).multiply(r),rt(H,J),n.setTranslationWrtParent(H),o.recomputeMassPropertiesFromColliders(),o.isFixed()&&this.invalidateStaticDebug(),!0}hasActorCapsuleIntersection(t,e,i,s,n,r=null){const a=this.actorBodies.get(t.id),l=t.object?.getWorldScale(pt)??q,c=Math.max(0,i*Math.abs(l.y)),d=Math.max(.001,s*Math.max(Math.abs(l.x),Math.abs(l.z))),h=new this.rapier.Capsule(c/2,d),u=t.object?.getWorldQuaternion(k)??O;J.set(0,n,0).multiply(l).applyQuaternion(u).add(e);return null!=this.world.intersectionWithShape(J,u,h,o.EXCLUDE_SENSORS,r??void 0,void 0,a,ut)}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world,this.invalidateStaticDebug);return this.colliders.set(i.handle,s),(null==e||e.body.isFixed())&&this.invalidateStaticDebug(),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const i=(()=>{switch(t){case PhysicsBodyType.dynamic:return this.rapier.RigidBodyDesc.dynamic();case PhysicsBodyType.static:return this.rapier.RigidBodyDesc.fixed();case PhysicsBodyType.kinematic:return this.rapier.RigidBodyDesc.kinematicPositionBased();case PhysicsBodyType.kinematicVelocityBased:return this.rapier.RigidBodyDesc.kinematicVelocityBased();default:return this.rapier.RigidBodyDesc.dynamic()}})();e.position&&i.setTranslation(e.position.x,e.position.y,e.position.z),e.rotation&&i.setRotation({x:e.rotation.x,y:e.rotation.y,z:e.rotation.z,w:e.rotation.w}),"boolean"==typeof e.canSleep&&i.setCanSleep(e.canSleep),"boolean"==typeof e.ccdEnabled&&i.setCcdEnabled(e.ccdEnabled),"number"==typeof e.gravityScale&&i.setGravityScale(e.gravityScale),"number"==typeof e.mass&&i.setAdditionalMass(e.mass),void 0!==e.userData&&(i.userData=e.userData);const s=this.world.createRigidBody(i);return s.isFixed()?this.invalidateStaticDebug():this.nonFixedBodies.add(s),new PhysicsBody(s,this.world,this.invalidateStaticDebug)}createJoint(t,e,i){let s,o;switch(i.type){case"fixed":s=this.rapier.JointData.fixed(i.anchor1,i.frame1,i.anchor2,i.frame2);break;case"spherical":s=this.rapier.JointData.spherical(i.anchor1,i.anchor2);break;case"revolute":s=this.rapier.JointData.revolute(i.anchor1,i.anchor2,i.axis),null!=i.limits&&(o=i.limits)}const n=this.world.createImpulseJoint(s,t.body,e.body,!0);if(null!=o){n.setLimits(o[0],o[1])}return n.setContactsEnabled(i.contactsEnabled??!1),new PhysicsJoint(n,this.world)}getCharacterComputedMovement(t,e,i,s=null){const n=t.collider;e.computeColliderMovement(n,i,o.EXCLUDE_SENSORS,s,void 0);const r=e.computedMovement();return lt(dt,r),dt}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation(H);s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition(U),s=e.getWorldQuaternion(K);t.setNextKinematicTranslation(it(i)),t.setNextKinematicRotation(st(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.setAngvel(H,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.setLinvel(H,!0)}getLinearVelocity(t,e=new B){const i=this.actorBodies.get(t.id);if(null==i)return e.set(0,0,0);const s=i.linvel();return e.x=s.x,e.y=s.y,e.z=s.z,e}getAngularVelocity(t,e=new B){const i=this.actorBodies.get(t.id);if(null==i)return e.set(0,0,0);const s=i.angvel();return e.x=s.x,e.y=s.y,e.z=s.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(it(e),!1)}getPosition(t,e=new B){const i=this.actorBodies.get(t.id);i&&i.translation(e)}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setRotation(st(e),!1)}getRotation(t,e=new f){const i=this.actorBodies.get(t.id);i&&function(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}addLandscapeGroup(t){this.invalidateStaticDebug();const e=t.userData.src,i=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));var o=n.getWorldPosition(new B);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===n.name&&0!==t.w[0])){const t=n.geometry.clone(),i=n.scale,s=n.geometry.getAttribute("hole"),r=new Float32Array(t.getAttribute("position").array);for(let t=0;t<r.length;t+=3)r[t]*=i.x,r[t+1]*=i.y,r[t+2]*=i.z;const a=t.index;for(let t=0;t<a.count;t+=3){const e=s.getX(a.getX(t)),i=s.getX(a.getY(t)),o=s.getX(a.getZ(t));(e>.5||i>.5||o>.5)&&(a.setX(t,0),a.setY(t,0),a.setZ(t,0))}const l=this.rapier.ColliderDesc.trimesh(r,new Uint32Array(t.getIndex().array));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);rt(e,o),t.setTranslation(e,!1);const i=this.world.createCollider(l,t);this.colliderObjects.set(i,{object:n}),this.staticBodies.set(n,t)}continue}const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=i.find(t=>t.x===n.x&&t.y==n.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=s.ColliderDesc.heightfield(c,c,new Float32Array(d),new this.rapier.Vector3(r,r,r));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);rt(e,o),t.setTranslation(e,!1);const i=this.world.createCollider(h,t);this.colliderObjects.set(i,{object:n}),this.staticBodies.set(n,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e),i?.isFixed()&&this.invalidateStaticDebug()}addActor(t,e,i={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const s=t.object;let o;switch(i.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:o=this.rapier.RigidBodyDesc.dynamic(),o.mass=i.mass??1;break;case PhysicsBodyType.kinematic:o=this.rapier.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:o=this.rapier.RigidBodyDesc.kinematicVelocityBased();break;default:o=i.isTrigger?this.rapier.RigidBodyDesc.kinematicVelocityBased():this.rapier.RigidBodyDesc.fixed()}const n=this.world.createRigidBody(o);n.enableCcd(1==i.continousCollisionDetection);for(const t of e){const e=this.addShape(n,t,s);ht.set(e,!i.isTrigger)}return i.type!==PhysicsBodyType.static&&this.nonFixedBodies.add(n),ct(n,t=>{null!=i.isTrigger&&(t.setSensor(i.isTrigger),t.setActiveCollisionTypes(this.rapier.ActiveCollisionTypes.ALL),t.setActiveEvents(this.rapier.ActiveEvents.COLLISION_EVENTS)),null!=i.friction&&t.setFriction(i.friction),null!=i.density&&t.setDensity(i.density),null!=i.mass&&t.setMass(i.mass),null!=i.restitution&&t.setRestitution(i.restitution)}),G(n,s),!0===i.ignoreForNavMesh&&(n.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,n),this.bodyActors.set(n,t),n.isFixed()&&this.invalidateStaticDebug(),new PhysicsBody(n,this.world,this.invalidateStaticDebug)}applyTorque(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.addTorque(H,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.applyTorqueImpulse(H,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.addForce(H,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.applyImpulse(H,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);rt(H,e),null==i?s?.addForce(H,!0):(rt(Q,i),s?.addForceAtPoint(H,Q,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);rt(H,e),null==i?s.applyImpulse(H,!0):(rt(Q,i),s.applyImpulseAtPoint(H,Q,!0))}applyRadialImpulse(t,e,i){return e<=0||0===i?0:this.applyImpulseToBodiesInRadius(t,e,(t,s,o)=>{o<=1e-6?s.set(0,1,0):s.multiplyScalar(1/o),s.multiplyScalar(i*Math.max(0,1-o/e)),rt(H,s),t.applyImpulse(H,!0)})}applyDirectionalImpulse(t,e,i,s,o){if(i<=0||0===o||e.lengthSq()<=1e-12)return 0;Y.copy(e).normalize();const n=Math.cos(Math.max(0,Math.min(Math.PI,s)));return this.applyImpulseToBodiesInRadius(t,i,(t,e,i)=>{if(i>1e-6&&e.multiplyScalar(1/i).dot(Y)<n)return!1;H.x=Y.x*o,H.y=Y.y*o,H.z=Y.z*o,t.applyImpulse(H,!0)})}applyImpulseToBodiesInRadius(t,e,i){const s=$,n=tt;s.clear(),n.length=0;let r=0;this.world.intersectionsWithShape(t,O,this.getBallShape(e),t=>{const e=t.parent();return null==e||s.has(e.handle)||(s.add(e.handle),n.push(e)),!0},o.ONLY_DYNAMIC|o.EXCLUDE_SENSORS);for(const e of n)lt(Z,e.worldCom()),Z.sub(t),!1!==i(e,Z,Z.length())&&r++;return s.clear(),n.length=0,r}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(e.isFixed()&&this.invalidateStaticDebug(),this.bodyActors.delete(e),this.world.removeRigidBody(e),this.nonFixedBodies.delete(e)),this.actorBodies.delete(t.id)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.invalidateStaticDebug(),this.staticBodies.delete(t),this.world.removeRigidBody(i),this.nonFixedBodies.delete(i))}removeSceneObject(t){if(t instanceof P){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&(this.invalidateStaticDebug(),this.world.removeRigidBody(e),this.nonFixedBodies.delete(e)),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(d(t.disposed),a(({started:t})=>t===i),l(({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t)?.parent()),a2:this.bodyActors.get(this.world.getCollider(e)?.parent()),started:i})),a(({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s)),l(({a2:t})=>t))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(d(t.disposed),a(t=>t.started),a(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),l(t=>t.handle2))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(d(t.disposed),a(t=>!t.started),a(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),l(t=>t.handle2))}onHasContactChanged(t){const e=new Set,i=new n(!1);return this.onBeginContact(t).subscribe(t=>{e.add(t),i.next(e.size>0)}),this.onEndContact(t).subscribe(t=>{e.delete(t),i.next(e.size>0)}),i.pipe(r())}onBeginOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!0)}onEndOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!1)}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e&&(G(e,t.object),e.isFixed()&&this.invalidateStaticDebug())}flushModifiedBodyPositionsToColliders(){this.world.propagateModifiedBodyPositionsToColliders()}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t,this.invalidateStaticDebug()}sphereCast(t,e,i,s,n=ShapeCastResult.shared,r){n.reset();const a=this.getBallShape(e);H.x=i.x,H.y=i.y,H.z=i.z;const l=r?.excludeActor?this.actorBodies.get(r.excludeActor.id):null,c=this.world.castShape(t,O,H,a,.01,s,r?.stopAtPenetration??!0,r?.excludeTriggers?o.EXCLUDE_SENSORS:void 0,r?.collisionFilter??void 0,null,l);if(null!=c){lt(n.hitPoint,c.witness1),n.normal.set(c.normal1.x,c.normal1.y,c.normal1.z),n.distance=c.time_of_impact,n.hasHit=!0;const t=c.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(n.actor=e)}}return n}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const n=this.actorBodies.get(t.id);if(n&&n.numColliders()>0){for(let t=0;t<n.numColliders();t++){const r=n.collider(t);let a=r.shape,l=r.translation(),c=r.rotation(),d=e,h=i;const u=this.world.castShape(l,c,d,a,.01,h,!0,null,o,null,n,void 0);if(null!=u){u.collider;const t=r;return lt(s.hitPoint,u.witness1),mt(t.rotation(),u.normal1,s.normal,L),s.distance=u.time_of_impact,s.actor=this.bodyActors.get(u.collider.parent()),s.hasHit=!0,s}}return s}return console.warn("Actor is not added to the physics system"),s}stop(){if(!this._isStopped){this._isStopped=!0,this.bodyActors.clear(),this.actorBodies.clear(),this.staticBodies.clear(),this.staticMeshes.clear(),this.colliders.clear(),this.fixedupdateSub?.unsubscribe(),this.collisionSub?.unsubscribe(),this.world?.bodies.forEach(t=>{this.world.removeRigidBody(t),this.nonFixedBodies.delete(t)});try{this.eventQueue?.free()}catch(t){console.warn("Error when freeing physics event queue",t)}try{this.world?.free(),this.world=void 0}catch(t){console.warn("Error while freeing physics world",t)}this.clearRayDebugArrows();for(const t of this.rayDebugArrowPool)t.dispose();this.rayDebugArrowPool.length=0}}createStaticBody(t,e,i){const o=i?.type===PhysicsBodyType.dynamic?s.RigidBodyDesc.dynamic():s.RigidBodyDesc.fixed(),n=this.world.createRigidBody(o);i?.type===PhysicsBodyType.dynamic&&this.nonFixedBodies.add(n);let r=0;for(const s of e){if(r>128){console.warn("Too many collision shapes for object",t);break}if(r++,null==s){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(n,s,t);null!=o&&(null!=i?.friction&&o.setFriction(i.friction),null!=i?.density&&o.setDensity(i.density),null!=i?.mass&&o.setMass(i.mass/e.length),null!=i?.restitution&&o.setRestitution(i.restitution))}return G(n,t),n.userData=t.uuid,n.isFixed()&&this.invalidateStaticDebug(),n}addShape(t=void 0,e,i){const s=i?.getWorldScale(pt)??q,o=this.createShape(e,s);if(null==o)return void console.error("Failed to create physics shape. This can happen if the geometry is degenerate or zero-scaled.",{shapeInfo:e,object:i});this.applyShapeSettings(o,e);const n=e.offset.clone().multiply(s);rt(o.translation,n);const r=(new f).setFromEuler(e.rotation);at(o.rotation,r),null!=t&&t.numColliders()>128&&console.warn(`Rigid body has many colliders (${t.numColliders()}). Consider using a Trimesh if this is static geometry.`,t);try{const s=this.world.createCollider(o,t),n=i??(e instanceof R&&e.mesh instanceof w?e.mesh:void 0);return null!=n&&this.colliderObjects.set(s,{object:n}),s}catch(t){return void console.error("Failed to create collider",t)}}applyShapeSettings(t,e){null!=e.collisionGroup&&t.setCollisionGroups(e.collisionGroup),t.friction=e.friction??.1,null!=e.restitution&&(t.restitution=e.restitution),null!=e.density&&(t.density=e.density,t.massPropsMode=s.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=s.MassPropsMode.Mass)}createShape(t,e){return i(this.rapier,t,e)}createCharacterCollision(){return new this.rapier.CharacterCollision}};V=t([D(),e("design:paramtypes",[])],V);export{V as PhysicsSystem};const U=new B,K=new h.Quaternion;function G(t,e){const i=e.getWorldPosition(U),s=e.getWorldQuaternion(K);t.setTranslation(it(i),!1),t.setRotation(st(s),!1)}const X=new B,q=new B(1,1,1),H=new s.Vector3(0,0,0),Q=new s.Vector3(0,0,0),J=new B,Y=new B,Z=new B,$=new Set,tt=[],et=new h.Vector2;function it(t){return rt(H,t),H}function st(t){return at(L,t),L}let ot=null;const nt=async()=>(null==ot&&(ot=(async()=>{let t=await import("@dimforge/rapier3d-simd-compat");return await t.init(),t})()),ot);function rt(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function at(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function lt(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function ct(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const dt=new B,ht=new WeakMap,ut=t=>ht.get(t)??!0,pt=new B;let yt,gt=class extends S{constructor(){super(...arguments),this._active=!0,this.physics=C(V),this.world=C(j)}set active(t){this._active=t,t?(this.world.scene.remove(this.actor.object),this.physics.setEnabled(this.actor,t)):(this.world.scene.add(this.actor.object),this.physics.setEnabled(this.actor,t))}get active(){return this._active}};gt=t([A()],gt);export{extractFloat32Array}from"../../../scene/collision/rapier-shape.js";function mt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e,i){this.collider=t,this.world=e,this.invalidateStaticDebug=i,this.disposed=new c,this.onBeginOverlapActor=new c,this.onEndOverlapActor=new c}dispose(){const t=this.collider.parent();(null==t||t.isFixed())&&this.invalidateStaticDebug?.(),this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t);const e=this.collider.parent();(null==e||e.isFixed())&&this.invalidateStaticDebug?.()}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e,i){this.invalidateStaticDebug=i,this.body=t,this.world=e}dispose(){this.body.isFixed()&&this.invalidateStaticDebug?.(),this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t),this.body.isFixed()&&this.invalidateStaticDebug?.()}isEnabled(){return this.body.isEnabled()}getPosition(t){return this.body.translation(t)}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0),this.body.isFixed()&&this.invalidateStaticDebug?.()}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0),this.body.isFixed()&&this.invalidateStaticDebug?.()}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}setLinearDamping(t){this.body.setLinearDamping(t)}setAngularDamping(t){this.body.setAngularDamping(t)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){const e=this.body.isFixed();this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return s.RigidBodyType.Dynamic;case PhysicsBodyType.static:return s.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return s.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return s.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static),(e||this.body.isFixed())&&this.invalidateStaticDebug?.()}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}export class PhysicsJoint{constructor(t,e){this.joint=t,this.world=e}dispose(){this.joint.isValid()&&this.world.removeImpulseJoint(this.joint,!0)}setContactsEnabled(t){this.joint.setContactsEnabled(t)}get contactsEnabled(){return this.joint.contactsEnabled()}}/*
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import{createRapierCollisionShape as i}from"../../../scene/collision/rapier-shape.js";import*as s from"@dimforge/rapier3d-simd-compat";import{QueryFilterFlags as o}from"@dimforge/rapier3d-simd-compat";import{BehaviorSubject as n,distinctUntilChanged as r,filter as a,map as l,Subject as c,takeUntil as d}from"rxjs";import*as h from"three";import{ArrowHelper as u,BufferAttribute as p,BufferGeometry as y,Group as g,LineSegments as m,Matrix4 as b,Object3D as w,Quaternion as f,Raycaster as v,Scene as x,Vector3 as B}from"three";import{Service as D}from"typedi";import{ActorComponent as S,Component as A}from"../../../gameplay/actors/component.js";import{inject as C}from"../../../gameplay/inject.js";import{ConvexPolyhedronCollisionShape as R,PhysicalShapeMesh as E,toInstancedCollisionShape as M}from"../../../scene/collision/collision-shape.js";import{AssetMeshInstance as T}from"../../../scene/asset-resource-loader.js";import{LandscapeGroup as P,LandscapeMesh as z}from"../../../scene/landscape/landscape.js";import{ViewController as F}from"../render.js";import{World as j}from"../world.js";import{AbstractPhysicsSystem as I}from"./abstract-physics-system.js";import{NetRole as _}from"../../net/index.js";export{ActorComponent,attach,Attach,Component}from"../../actors/component.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.hitNormal=new B}}export class ShapeCastResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.normal=new B}reset(){this.actor=void 0,this.hasHit=!1,this.distance=0,this.hitPoint.set(0,0,0),this.normal.set(0,0,0)}}ShapeCastResult.shared=new ShapeCastResult;export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));const N=new B,W=new B,O=new f,L=new f,k=new f;let V=class extends I{isLandscapeNavigationCollider(t){return this.colliderObjects.get(t)?.object instanceof z}forEachStaticActorNavigationCollider(t,e){const i=this.actorBodies.get(t.id);if(i?.isFixed()&&i.isEnabled()&&!0!==i.userData?.ignoreForNavMesh)for(let t=0;t<i.numColliders();t++){const s=i.collider(t);s.isEnabled()&&!s.isSensor()&&e(s)}}set showDebug(t){this.shouldRenderDebug=t,t||this.clearRayDebugArrows(),this.debugMesh&&(this.debugMesh.visible=t),this.staticDebugMesh&&(this.staticDebugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.colliderObjects=new WeakMap,this.rayDebugArrowPool=[],this.activeRayDebugArrows=[],this.nonFixedBodies=new Set,this.collisionEvents=new c,this.beforeStep=new c,this.afterStep=new c,this.shouldRenderDebug=!1,this.viewController=C(F),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this.staticDebugNeedsUpdate=!0,this.invalidateStaticDebug=()=>{this.staticDebugNeedsUpdate=!0},this.handleCollisionEvent=(t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})},this._raycaster=new v,this._reusableResult=new RayTestResult,this._raytestDiff=new B,this._raytestDirection=new B,this.controlledActors=new Set,this._isStopped=!1,this.ready=this.setup()}getBallShape(t){let e=this.shapeCacheBall.get(t);return null==e&&(e=new this.rapier.Ball(t),this.shapeCacheBall.set(t,e)),e}getBoxShape(t,e,i){const s=t+1e6*e+1e12*i;let o=this.shapeCacheBox.get(s);return null==o&&(o=new this.rapier.Cuboid(t,e,i),this.shapeCacheBox.set(s,o)),o}hasBoxIntersection(t){const e=t.getCenter(N),i=t.getSize(W),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,O,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,O,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,n]of this.bodyActors)if(null==i||n instanceof i)for(let i=0,r=e.numColliders();i<r;i++){e.collider(i).intersectsShape(s,t,O)&&o.push(n)}return o}createDebugMesh(){const t=new m(new y,new h.LineBasicMaterial({color:255}));return t.frustumCulled=!1,t}updateDebugMesh(t,e){const i=t.geometry,s=i.getAttribute("position");if(null==s||s.array.length<e.length){null!=s&&i.dispose();const t=new Float32Array(e.length);t.set(e);const o=new p(t,3);o.setUsage(h.DynamicDrawUsage),i.setAttribute("position",o)}else e.length>0&&(s.array.set(e),s.clearUpdateRanges(),s.addUpdateRange(0,e.length),s.needsUpdate=!0);i.setDrawRange(0,e.length/3)}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;if(null==this.staticDebugMesh&&(this.staticDebugMesh=this.createDebugMesh(),this.staticDebugMesh.visible=this.shouldRenderDebug,this.staticDebugMesh.raycast=function(){},this.scene.add(this.staticDebugMesh)),null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene.add(this.debugMesh)),this.staticDebugNeedsUpdate){const t=this.world.debugRender(o.ONLY_FIXED);this.updateDebugMesh(this.staticDebugMesh,t.vertices),this.staticDebugNeedsUpdate=!1}const t=this.world.debugRender(o.EXCLUDE_FIXED);this.updateDebugMesh(this.debugMesh,t.vertices)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await nt(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{if(!(this._isStopped||t<=0)){t=Math.min(.04,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.releaseExpiredRayDebugArrows();for(const t of this.nonFixedBodies){let e,i=this.staticMeshes.get(t);if(null==i){if(e=this.bodyActors.get(t),e?.netRole===_.simulatedProxy)continue;i=e?.object}null!=i&&i.parent instanceof x&&(t.translation(i.position),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(e?.id))&&t.rotation(i.quaternion),i.matrixWorldNeedsUpdate=!0)}this.afterStep.next(t)}})}_updateWorld(){this.lastEmptyPhysicsWorld=void 0,this.world.timestep=0,this.world.step()}updatePhysics(t){if(this._isStopped)return;this.world.timestep=t;const e=0===this.world.bodies.len()&&0===this.world.colliders.len();e&&this.lastEmptyPhysicsWorld===this.world||this.world.step(this.eventQueue),this.lastEmptyPhysicsWorld=e?this.world:void 0,this.eventQueue.drainCollisionEvents(this.handleCollisionEvent)}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(et,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult),i.hasHit=!1,i.actor=void 0,i.object=void 0,i.instanceId=void 0,i.batchId=void 0;const n=this._raytestDiff,r=this._raytestDirection;n.subVectors(e,t);const a=n.length();if(0===a)return console.warn("Ray test called with to and from being equal"),i;r.copy(n).multiplyScalar(1/a),null==yt&&(yt=new this.rapier.Ray(new this.rapier.Vector3(0,0,0),new this.rapier.Vector3(0,1,0))),rt(yt.origin,t),rt(yt.dir,r);const l=this.world.castRayAndGetNormal(yt,a,!1,s?.excludeTriggers?o.EXCLUDE_SENSORS:void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0);if(i.hasHit=null!=l,i.actor=void 0,i.hasHit){const e=this.colliderObjects.get(l.collider);if(i.object=e?.object,i.instanceId=e?.instanceId,i.batchId=e?.batchId,i._internal=l,lt(i.hitNormal,l.normal),i.hitPoint.copy(t).addScaledVector(r,l.timeOfImpact),i.distance=l.timeOfImpact,!1!==s?.resolveActor){const t=l.collider.parent();i.actor=null!=t?this.bodyActors.get(t):null}}return this.showDebug&&!1!==s?.debug&&null!=this.scene&&this.drawRayDebugArrow(r,t,a,s?.debugColor,s?.debugLifetime),i}drawRayDebugArrow(t,e,i,s=255,o=200){let n=this.rayDebugArrowPool.pop();null==n?n=new u(t,e,i,s,.2,.1):(n.setDirection(t),n.position.copy(e),n.setLength(i,.2,.1),n.setColor(s)),n.userData.physicsRayDebugExpiresAt=performance.now()+o,this.activeRayDebugArrows.push(n),this.scene.add(n)}releaseExpiredRayDebugArrows(){if(0===this.activeRayDebugArrows.length)return;const t=performance.now();let e=0;for(let i=0;i<this.activeRayDebugArrows.length;i++){const s=this.activeRayDebugArrows[i];s.userData.physicsRayDebugExpiresAt<=t?(s.removeFromParent(),this.rayDebugArrowPool.push(s)):this.activeRayDebugArrows[e++]=s}this.activeRayDebugArrows.length=e}clearRayDebugArrows(){for(const t of this.activeRayDebugArrows)t.removeFromParent(),this.rayDebugArrowPool.push(t);this.activeRayDebugArrows.length=0}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return X.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())ct(t,t=>t.setActiveEvents(s.ActiveEvents.COLLISION_EVENTS))}addRecursively(t){if(this.removeSceneObject(t),!function(t){const e=t.userData?.src??t.userData?._src;return null!=t.userData?.actor||"actor"===e?.type}(t))if(t instanceof E&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof T){const e=!1!==t.userData?.src?.collisionDetection;if(t.children[0]&&(t.children[0].instanceMatrix&&e||t.children[0].isBatchedMesh))this.createForInstancedMesh(t.children[0],t.collisionShapes);else if(e&&t.children.length>0){const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}0===t.children.length&&(t.matrixAutoUpdate=!1,t.matrixWorldAutoUpdate=!1)}else t instanceof P?this.addLandscapeGroup(t):(t instanceof g||t instanceof x)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new b;if(t instanceof h.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map,o=t.userData.collisionMatrices;for(let n=0;n<e.length;n++){if(!e[n].active)continue;if(null!=t.userData.hasCollision&&!t.userData.hasCollision[n])continue;const r=t.userData.collisionShapes;let a=r?.[n];if(null==a&&null==r&&t.parent instanceof T&&(a=t.parent.collisionShapes),null==a)continue;const l=o?.[n];let c=a;null==l&&(c=s.get(a),null==c&&(c=this.instancedShapeReset(a),s.set(a,c)));const d=new w;d.matrix.identity(),null!=l?i.copy(l):t.getMatrixAt(n,i),d.applyMatrix4(i);const h=this.createStaticBody(d,c),u={object:t,batchId:n};ct(h,t=>this.colliderObjects.set(t,u))}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new w;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);const n=this.createStaticBody(o,s),r={object:t,instanceId:e};ct(n,t=>this.colliderObjects.set(t,r))}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>M(t))}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,s=null){const n=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=n.collider(0);e.computeColliderMovement(r,i,o.EXCLUDE_SENSORS,s,void 0);const a=e.computedMovement();return lt(dt,a),dt}setActorCapsuleCollider(t,e,i,s){const o=this.actorBodies.get(t.id),n=o?.collider(0);if(null==o||null==n)return!1;const r=t.object?.getWorldScale(pt)??q,a=Math.max(0,e*Math.abs(r.y)),l=Math.max(.001,i*Math.max(Math.abs(r.x),Math.abs(r.z)));return n.setHalfHeight(a/2),n.setRadius(l),J.set(0,s,0).multiply(r),rt(H,J),n.setTranslationWrtParent(H),o.recomputeMassPropertiesFromColliders(),o.isFixed()&&this.invalidateStaticDebug(),!0}hasActorCapsuleIntersection(t,e,i,s,n,r=null){const a=this.actorBodies.get(t.id),l=t.object?.getWorldScale(pt)??q,c=Math.max(0,i*Math.abs(l.y)),d=Math.max(.001,s*Math.max(Math.abs(l.x),Math.abs(l.z))),h=new this.rapier.Capsule(c/2,d),u=t.object?.getWorldQuaternion(k)??O;J.set(0,n,0).multiply(l).applyQuaternion(u).add(e);return null!=this.world.intersectionWithShape(J,u,h,o.EXCLUDE_SENSORS,r??void 0,void 0,a,ut)}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world,this.invalidateStaticDebug);return this.colliders.set(i.handle,s),(null==e||e.body.isFixed())&&this.invalidateStaticDebug(),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const i=(()=>{switch(t){case PhysicsBodyType.dynamic:return this.rapier.RigidBodyDesc.dynamic();case PhysicsBodyType.static:return this.rapier.RigidBodyDesc.fixed();case PhysicsBodyType.kinematic:return this.rapier.RigidBodyDesc.kinematicPositionBased();case PhysicsBodyType.kinematicVelocityBased:return this.rapier.RigidBodyDesc.kinematicVelocityBased();default:return this.rapier.RigidBodyDesc.dynamic()}})();e.position&&i.setTranslation(e.position.x,e.position.y,e.position.z),e.rotation&&i.setRotation({x:e.rotation.x,y:e.rotation.y,z:e.rotation.z,w:e.rotation.w}),"boolean"==typeof e.canSleep&&i.setCanSleep(e.canSleep),"boolean"==typeof e.ccdEnabled&&i.setCcdEnabled(e.ccdEnabled),"number"==typeof e.gravityScale&&i.setGravityScale(e.gravityScale),"number"==typeof e.mass&&i.setAdditionalMass(e.mass),void 0!==e.userData&&(i.userData=e.userData);const s=this.world.createRigidBody(i);return s.isFixed()?this.invalidateStaticDebug():this.nonFixedBodies.add(s),new PhysicsBody(s,this.world,this.invalidateStaticDebug)}createJoint(t,e,i){let s,o;switch(i.type){case"fixed":s=this.rapier.JointData.fixed(i.anchor1,i.frame1,i.anchor2,i.frame2);break;case"spherical":s=this.rapier.JointData.spherical(i.anchor1,i.anchor2);break;case"revolute":s=this.rapier.JointData.revolute(i.anchor1,i.anchor2,i.axis),null!=i.limits&&(o=i.limits)}const n=this.world.createImpulseJoint(s,t.body,e.body,!0);if(null!=o){n.setLimits(o[0],o[1])}return n.setContactsEnabled(i.contactsEnabled??!1),new PhysicsJoint(n,this.world)}getCharacterComputedMovement(t,e,i,s=null){const n=t.collider;e.computeColliderMovement(n,i,o.EXCLUDE_SENSORS,s,void 0);const r=e.computedMovement();return lt(dt,r),dt}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation(H);s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition(U),s=e.getWorldQuaternion(K);t.setNextKinematicTranslation(it(i)),t.setNextKinematicRotation(st(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.setAngvel(H,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.setLinvel(H,!0)}getLinearVelocity(t,e=new B){const i=this.actorBodies.get(t.id);if(null==i)return e.set(0,0,0);const s=i.linvel();return e.x=s.x,e.y=s.y,e.z=s.z,e}getAngularVelocity(t,e=new B){const i=this.actorBodies.get(t.id);if(null==i)return e.set(0,0,0);const s=i.angvel();return e.x=s.x,e.y=s.y,e.z=s.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(it(e),!1)}getPosition(t,e=new B){const i=this.actorBodies.get(t.id);i&&i.translation(e)}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setRotation(st(e),!1)}getRotation(t,e=new f){const i=this.actorBodies.get(t.id);i&&function(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}addLandscapeGroup(t){this.invalidateStaticDebug();const e=t.userData.src,i=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));var o=n.getWorldPosition(new B);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===n.name&&0!==t.w[0])){const t=n.geometry.clone(),i=n.scale,s=n.geometry.getAttribute("hole"),r=new Float32Array(t.getAttribute("position").array);for(let t=0;t<r.length;t+=3)r[t]*=i.x,r[t+1]*=i.y,r[t+2]*=i.z;const a=t.index;for(let t=0;t<a.count;t+=3){const e=s.getX(a.getX(t)),i=s.getX(a.getY(t)),o=s.getX(a.getZ(t));(e>.5||i>.5||o>.5)&&(a.setX(t,0),a.setY(t,0),a.setZ(t,0))}const l=this.rapier.ColliderDesc.trimesh(r,new Uint32Array(t.getIndex().array));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);rt(e,o),t.setTranslation(e,!1);const i=this.world.createCollider(l,t);this.colliderObjects.set(i,{object:n}),this.staticBodies.set(n,t)}continue}const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=i.find(t=>t.x===n.x&&t.y==n.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=s.ColliderDesc.heightfield(c,c,new Float32Array(d),new this.rapier.Vector3(r,r,r));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);rt(e,o),t.setTranslation(e,!1);const i=this.world.createCollider(h,t);this.colliderObjects.set(i,{object:n}),this.staticBodies.set(n,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e),i?.isFixed()&&this.invalidateStaticDebug()}addActor(t,e,i={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const s=t.object;let o;switch(i.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:o=this.rapier.RigidBodyDesc.dynamic(),o.mass=i.mass??1;break;case PhysicsBodyType.kinematic:o=this.rapier.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:o=this.rapier.RigidBodyDesc.kinematicVelocityBased();break;default:o=i.isTrigger?this.rapier.RigidBodyDesc.kinematicVelocityBased():this.rapier.RigidBodyDesc.fixed()}const n=this.world.createRigidBody(o);n.enableCcd(1==i.continousCollisionDetection);for(const t of e){const e=this.addShape(n,t,s);ht.set(e,!i.isTrigger)}return i.type!==PhysicsBodyType.static&&this.nonFixedBodies.add(n),ct(n,t=>{null!=i.isTrigger&&(t.setSensor(i.isTrigger),t.setActiveCollisionTypes(this.rapier.ActiveCollisionTypes.ALL),t.setActiveEvents(this.rapier.ActiveEvents.COLLISION_EVENTS)),null!=i.friction&&t.setFriction(i.friction),null!=i.density&&t.setDensity(i.density),null!=i.mass&&t.setMass(i.mass),null!=i.restitution&&t.setRestitution(i.restitution)}),G(n,s),!0===i.ignoreForNavMesh&&(n.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,n),this.bodyActors.set(n,t),n.isFixed()&&this.invalidateStaticDebug(),new PhysicsBody(n,this.world,this.invalidateStaticDebug)}applyTorque(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.addTorque(H,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.applyTorqueImpulse(H,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.addForce(H,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);H.x=e.x,H.y=e.y,H.z=e.z,i?.applyImpulse(H,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);rt(H,e),null==i?s?.addForce(H,!0):(rt(Q,i),s?.addForceAtPoint(H,Q,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);rt(H,e),null==i?s.applyImpulse(H,!0):(rt(Q,i),s.applyImpulseAtPoint(H,Q,!0))}applyRadialImpulse(t,e,i){return e<=0||0===i?0:this.applyImpulseToBodiesInRadius(t,e,(t,s,o)=>{o<=1e-6?s.set(0,1,0):s.multiplyScalar(1/o),s.multiplyScalar(i*Math.max(0,1-o/e)),rt(H,s),t.applyImpulse(H,!0)})}applyDirectionalImpulse(t,e,i,s,o){if(i<=0||0===o||e.lengthSq()<=1e-12)return 0;Y.copy(e).normalize();const n=Math.cos(Math.max(0,Math.min(Math.PI,s)));return this.applyImpulseToBodiesInRadius(t,i,(t,e,i)=>{if(i>1e-6&&e.multiplyScalar(1/i).dot(Y)<n)return!1;H.x=Y.x*o,H.y=Y.y*o,H.z=Y.z*o,t.applyImpulse(H,!0)})}applyImpulseToBodiesInRadius(t,e,i){const s=$,n=tt;s.clear(),n.length=0;let r=0;this.world.intersectionsWithShape(t,O,this.getBallShape(e),t=>{const e=t.parent();return null==e||s.has(e.handle)||(s.add(e.handle),n.push(e)),!0},o.ONLY_DYNAMIC|o.EXCLUDE_SENSORS);for(const e of n)lt(Z,e.worldCom()),Z.sub(t),!1!==i(e,Z,Z.length())&&r++;return s.clear(),n.length=0,r}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(e.isFixed()&&this.invalidateStaticDebug(),this.bodyActors.delete(e),this.world.removeRigidBody(e),this.nonFixedBodies.delete(e)),this.actorBodies.delete(t.id)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.invalidateStaticDebug(),this.staticBodies.delete(t),this.world.removeRigidBody(i),this.nonFixedBodies.delete(i))}removeSceneObject(t){if(t instanceof P){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&(this.invalidateStaticDebug(),this.world.removeRigidBody(e),this.nonFixedBodies.delete(e)),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(d(t.disposed),a(({started:t})=>t===i),l(({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t)?.parent()),a2:this.bodyActors.get(this.world.getCollider(e)?.parent()),started:i})),a(({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s)),l(({a2:t})=>t))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(d(t.disposed),a(t=>t.started),a(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),l(t=>t.handle2))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(d(t.disposed),a(t=>!t.started),a(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),l(t=>t.handle2))}onHasContactChanged(t){const e=new Set,i=new n(!1);return this.onBeginContact(t).subscribe(t=>{e.add(t),i.next(e.size>0)}),this.onEndContact(t).subscribe(t=>{e.delete(t),i.next(e.size>0)}),i.pipe(r())}onBeginOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!0)}onEndOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!1)}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e&&(G(e,t.object),e.isFixed()&&this.invalidateStaticDebug())}flushModifiedBodyPositionsToColliders(){this.world.propagateModifiedBodyPositionsToColliders()}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t,this.invalidateStaticDebug()}sphereCast(t,e,i,s,n=ShapeCastResult.shared,r){n.reset();const a=this.getBallShape(e);H.x=i.x,H.y=i.y,H.z=i.z;const l=r?.excludeActor?this.actorBodies.get(r.excludeActor.id):null,c=this.world.castShape(t,O,H,a,.01,s,r?.stopAtPenetration??!0,r?.excludeTriggers?o.EXCLUDE_SENSORS:void 0,r?.collisionFilter??void 0,null,l);if(null!=c){lt(n.hitPoint,c.witness1),n.normal.set(c.normal1.x,c.normal1.y,c.normal1.z),n.distance=c.time_of_impact,n.hasHit=!0;const t=c.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(n.actor=e)}}return n}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const n=this.actorBodies.get(t.id);if(n&&n.numColliders()>0){for(let t=0;t<n.numColliders();t++){const r=n.collider(t);let a=r.shape,l=r.translation(),c=r.rotation(),d=e,h=i;const u=this.world.castShape(l,c,d,a,.01,h,!0,null,o,null,n,void 0);if(null!=u){u.collider;const t=r;return lt(s.hitPoint,u.witness1),mt(t.rotation(),u.normal1,s.normal,L),s.distance=u.time_of_impact,s.actor=this.bodyActors.get(u.collider.parent()),s.hasHit=!0,s}}return s}return console.warn("Actor is not added to the physics system"),s}stop(){if(!this._isStopped){this._isStopped=!0,this.bodyActors.clear(),this.actorBodies.clear(),this.staticBodies.clear(),this.staticMeshes.clear(),this.colliders.clear(),this.fixedupdateSub?.unsubscribe(),this.collisionSub?.unsubscribe(),this.world?.bodies.forEach(t=>{this.world.removeRigidBody(t),this.nonFixedBodies.delete(t)});try{this.eventQueue?.free()}catch(t){console.warn("Error when freeing physics event queue",t)}try{this.world?.free(),this.world=void 0}catch(t){console.warn("Error while freeing physics world",t)}this.clearRayDebugArrows();for(const t of this.rayDebugArrowPool)t.dispose();this.rayDebugArrowPool.length=0}}createStaticBody(t,e,i){const o=i?.type===PhysicsBodyType.dynamic?s.RigidBodyDesc.dynamic():s.RigidBodyDesc.fixed(),n=this.world.createRigidBody(o);i?.type===PhysicsBodyType.dynamic&&this.nonFixedBodies.add(n);let r=0;for(const s of e){if(r>128){console.warn("Too many collision shapes for object",t);break}if(r++,null==s){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(n,s,t);null!=o&&(null!=i?.friction&&o.setFriction(i.friction),null!=i?.density&&o.setDensity(i.density),null!=i?.mass&&o.setMass(i.mass/e.length),null!=i?.restitution&&o.setRestitution(i.restitution))}return G(n,t),n.userData=t.uuid,n.isFixed()&&this.invalidateStaticDebug(),n}addShape(t=void 0,e,i){const s=i?.getWorldScale(pt)??q,o=this.createShape(e,s);if(null==o)return void console.error("Failed to create physics shape. This can happen if the geometry is degenerate or zero-scaled.",{shapeInfo:e,object:i});this.applyShapeSettings(o,e);const n=e.offset.clone().multiply(s);rt(o.translation,n);const r=(new f).setFromEuler(e.rotation);at(o.rotation,r),null!=t&&t.numColliders()>128&&console.warn(`Rigid body has many colliders (${t.numColliders()}). Consider using a Trimesh if this is static geometry.`,t);try{const s=this.world.createCollider(o,t),n=i??(e instanceof R&&e.mesh instanceof w?e.mesh:void 0);return null!=n&&this.colliderObjects.set(s,{object:n}),s}catch(t){return void console.error("Failed to create collider",t)}}applyShapeSettings(t,e){null!=e.collisionGroup&&t.setCollisionGroups(e.collisionGroup),t.friction=e.friction??.1,null!=e.restitution&&(t.restitution=e.restitution),null!=e.density&&(t.density=e.density,t.massPropsMode=s.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=s.MassPropsMode.Mass)}createShape(t,e){return i(this.rapier,t,e)}createCharacterCollision(){return new this.rapier.CharacterCollision}};V=t([D(),e("design:paramtypes",[])],V);export{V as PhysicsSystem};const U=new B,K=new h.Quaternion;function G(t,e){const i=e.getWorldPosition(U),s=e.getWorldQuaternion(K);t.setTranslation(it(i),!1),t.setRotation(st(s),!1)}const X=new B,q=new B(1,1,1),H=new s.Vector3(0,0,0),Q=new s.Vector3(0,0,0),J=new B,Y=new B,Z=new B,$=new Set,tt=[],et=new h.Vector2;function it(t){return rt(H,t),H}function st(t){return at(L,t),L}let ot=null;const nt=async()=>(null==ot&&(ot=(async()=>{let t=await import("@dimforge/rapier3d-simd-compat");return await t.init(),t})()),ot);function rt(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function at(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function lt(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function ct(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const dt=new B,ht=new WeakMap,ut=t=>ht.get(t)??!0,pt=new B;let yt,gt=class extends S{constructor(){super(...arguments),this._active=!0,this.physics=C(V),this.world=C(j)}set active(t){this._active=t,t?(this.world.scene.remove(this.actor.object),this.physics.setEnabled(this.actor,t)):(this.world.scene.add(this.actor.object),this.physics.setEnabled(this.actor,t))}get active(){return this._active}};gt=t([A()],gt);export{extractFloat32Array}from"../../../scene/collision/rapier-shape.js";function mt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e,i){this.collider=t,this.world=e,this.invalidateStaticDebug=i,this.disposed=new c,this.onBeginOverlapActor=new c,this.onEndOverlapActor=new c}dispose(){const t=this.collider.parent();(null==t||t.isFixed())&&this.invalidateStaticDebug?.(),this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t);const e=this.collider.parent();(null==e||e.isFixed())&&this.invalidateStaticDebug?.()}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e,i){this.invalidateStaticDebug=i,this.body=t,this.world=e}dispose(){this.body.isFixed()&&this.invalidateStaticDebug?.(),this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t),this.body.isFixed()&&this.invalidateStaticDebug?.()}isEnabled(){return this.body.isEnabled()}getPosition(t){return this.body.translation(t)}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0),this.body.isFixed()&&this.invalidateStaticDebug?.()}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0),this.body.isFixed()&&this.invalidateStaticDebug?.()}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}setLinearDamping(t){this.body.setLinearDamping(t)}setAngularDamping(t){this.body.setAngularDamping(t)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){const e=this.body.isFixed();this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return s.RigidBodyType.Dynamic;case PhysicsBodyType.static:return s.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return s.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return s.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static),(e||this.body.isFixed())&&this.invalidateStaticDebug?.()}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}export class PhysicsJoint{constructor(t,e){this.joint=t,this.world=e}dispose(){this.joint.isValid()&&this.world.removeImpulseJoint(this.joint,!0)}setContactsEnabled(t){this.joint.setContactsEnabled(t)}get contactsEnabled(){return this.joint.contactsEnabled()}}/*
|
|
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
|
@@ -12,6 +12,7 @@ export * from './scene/objects/prefab.js';
|
|
|
12
12
|
export * from './scene/objects/data-asset.js';
|
|
13
13
|
export * from './scene/scene-ref.js';
|
|
14
14
|
export * from './scene/model-ref.js';
|
|
15
|
+
export * from './scene/material-ref.js';
|
|
15
16
|
export * from './effects/sequence/index.js';
|
|
16
17
|
export * from './data/surface-definition.js';
|
|
17
18
|
export * from './scene/surface-query.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"./gameplay/actors/builtin/components/water-post-process-settings.js";export*from"./scene/objects/prefab.js";export*from"./scene/objects/data-asset.js";export*from"./scene/scene-ref.js";export*from"./scene/model-ref.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"./scene/scene-ref.js";export*from"./scene/model-ref.js";export*from"./scene/material-ref.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
|
*/
|
|
@@ -20,6 +20,7 @@ export interface NodeMaterialWebGpuModule {
|
|
|
20
20
|
readonly WGSLShaderMaterial: new (parameters: {
|
|
21
21
|
vertexShader: string;
|
|
22
22
|
fragmentShader: string;
|
|
23
|
+
defines?: Record<string, boolean>;
|
|
23
24
|
depthVertexShader?: string | null;
|
|
24
25
|
depthFragmentShader?: string | null;
|
|
25
26
|
pointShadowVertexShader?: string | null;
|