@hology/core 0.0.211 → 0.0.212
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.js +1 -1
- package/dist/effects/vfx/initializsers.d.ts +8 -1
- package/dist/effects/vfx/initializsers.js +1 -1
- package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
- package/dist/effects/vfx/vfx-defs.d.ts +10 -1
- package/dist/effects/vfx/vfx-defs.js +1 -1
- package/dist/effects/vfx/vfx-renderers.d.ts +1 -0
- package/dist/effects/vfx/vfx-renderers.js +1 -1
- package/dist/gameplay/actors/actor.d.ts +23 -1
- package/dist/gameplay/actors/actor.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +23 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-like.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-policy.d.ts +26 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-policy.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +145 -55
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +125 -0
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/old-character-movement.d.ts +100 -0
- package/dist/gameplay/actors/builtin/components/character/old-character-movement.js +4 -0
- package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
- package/dist/gameplay/actors/builtin/components/index.js +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/actors/component.js +1 -1
- package/dist/gameplay/actors/controller/actor-controller.d.ts +16 -0
- package/dist/gameplay/actors/controller/actor-controller.js +4 -0
- package/dist/gameplay/actors/factory.d.ts +3 -0
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.d.ts +4 -0
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/actors/internal/component-init.js +1 -1
- package/dist/gameplay/ai/behavior-tree/move.d.ts +2 -2
- package/dist/gameplay/index.d.ts +3 -1
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.d.ts +4 -0
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/net/browser/index.d.ts +147 -0
- package/dist/gameplay/net/browser/index.js +4 -0
- package/dist/gameplay/net/index.d.ts +7 -0
- package/dist/gameplay/net/index.js +4 -0
- package/dist/gameplay/net/net-connection.d.ts +25 -0
- package/dist/gameplay/net/net-connection.js +4 -0
- package/dist/gameplay/net/net-session.d.ts +70 -0
- package/dist/gameplay/net/net-session.js +4 -0
- package/dist/gameplay/net/service/net-actor-role.d.ts +12 -0
- package/dist/gameplay/net/service/net-actor-role.js +4 -0
- package/dist/gameplay/net/service/net-decorator.d.ts +29 -0
- package/dist/gameplay/net/service/net-decorator.js +4 -0
- package/dist/gameplay/net/service/net-serializer.d.ts +15 -0
- package/dist/gameplay/net/service/net-serializer.js +4 -0
- package/dist/gameplay/net/service/net-service.d.ts +171 -0
- package/dist/gameplay/net/service/net-service.js +4 -0
- package/dist/gameplay/net/service/net-utils.d.ts +8 -0
- package/dist/gameplay/net/service/net-utils.js +4 -0
- package/dist/gameplay/net/service/replication.d.ts +31 -0
- package/dist/gameplay/net/service/replication.js +4 -0
- package/dist/gameplay/net/service/rpc-decorator.d.ts +21 -0
- package/dist/gameplay/net/service/rpc-decorator.js +4 -0
- package/dist/gameplay/net/service/rpc.d.ts +35 -0
- package/dist/gameplay/net/service/rpc.js +4 -0
- package/dist/gameplay/services/asset-loader.d.ts +3 -2
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +2 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/world.d.ts +13 -2
- package/dist/gameplay/services/world.js +1 -1
- package/dist/rendering/color-pass.js +1 -1
- package/dist/rendering.d.ts +2 -0
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/batched-mesh-2.d.ts +9 -0
- package/dist/scene/batched-mesh-2.js +1 -1
- package/dist/scene/bootstrap.d.ts +2 -0
- package/dist/scene/bootstrap.js +1 -1
- package/dist/scene/materializer.d.ts +4 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/storage/storage.d.ts +1 -1
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/toon-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/color-layer.js +1 -1
- package/dist/shader/parameter.d.ts +1 -1
- package/dist/shader/parameter.js +1 -1
- package/dist/shader-nodes/depth.js +1 -1
- package/dist/shader-nodes/scene-sample.js +1 -1
- package/dist/test/batched-mesh-2.test.d.ts +2 -0
- package/dist/test/batched-mesh-2.test.js +4 -0
- package/dist/test/browser-net-session.test.d.ts +2 -0
- package/dist/test/browser-net-session.test.js +4 -0
- package/dist/test/first-person-camera-component.test.js +1 -1
- package/dist/test/net-character-movement.test.d.ts +2 -0
- package/dist/test/net-character-movement.test.js +4 -0
- package/dist/test/net-property-snapshot.test.d.ts +2 -0
- package/dist/test/net-property-snapshot.test.js +4 -0
- package/dist/test/sequence-animation-retiming.test.js +1 -1
- package/dist/test/vfx-random-color-initializer.test.d.ts +2 -0
- package/dist/test/vfx-random-color-initializer.test.js +4 -0
- package/dist/test/world-prefab-spawn.test.d.ts +2 -0
- package/dist/test/world-prefab-spawn.test.js +4 -0
- package/dist/utils/three/placeholder-texture.d.ts +3 -0
- package/dist/utils/three/placeholder-texture.js +4 -0
- package/package.json +9 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare enum ReplOn {
|
|
2
|
+
/**
|
|
3
|
+
* The property will be replicated on all connected clients.
|
|
4
|
+
* This is usually the default behavior.
|
|
5
|
+
*/
|
|
6
|
+
all = 0,
|
|
7
|
+
/**
|
|
8
|
+
* The property will be replicated on the owning client and server
|
|
9
|
+
*
|
|
10
|
+
* Example use case:
|
|
11
|
+
* - Information that should be hidden from other players such as
|
|
12
|
+
* remaining ammunition or active spell cooldown but needs to be
|
|
13
|
+
* known by the player and server.
|
|
14
|
+
*/
|
|
15
|
+
owner = 1,
|
|
16
|
+
/**
|
|
17
|
+
* The property will be replicated on all clients and server but
|
|
18
|
+
* not the owner.
|
|
19
|
+
*
|
|
20
|
+
* Example use case:
|
|
21
|
+
* - Certain state is already set on the owning client
|
|
22
|
+
* that could for example drive visual effects or sound.
|
|
23
|
+
* We exclude the owner to avoid unnecesary networking and
|
|
24
|
+
* triggering effective twice.
|
|
25
|
+
* - Movement state like isJumping used to control animation state
|
|
26
|
+
* machines, which is likely already set
|
|
27
|
+
* on the owning client for immediate feedback.
|
|
28
|
+
*/
|
|
29
|
+
notOwner = 2
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=replication.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decorator for marking a method as an RPC.
|
|
3
|
+
* @param reliable - If the call on remotes has to happen. Set to false for better performance is ok to lose some calls
|
|
4
|
+
*/
|
|
5
|
+
export declare function RunOnServer(reliable?: boolean): any;
|
|
6
|
+
/**
|
|
7
|
+
* Decorator for marking a method as an RPC.
|
|
8
|
+
* @param reliable - If the call on remotes has to happen. Set to false for better performance is ok to lose some calls
|
|
9
|
+
*/
|
|
10
|
+
export declare function RunOnClient(reliable?: boolean): any;
|
|
11
|
+
/**
|
|
12
|
+
* Decorator for marking a method as an RPC.
|
|
13
|
+
* @param reliable - If the call on remotes has to happen. Set to false for better performance is ok to lose some calls
|
|
14
|
+
*/
|
|
15
|
+
export declare function RunOnNotOwner(reliable?: boolean): any;
|
|
16
|
+
/**
|
|
17
|
+
* Decorator for marking a method as an RPC.
|
|
18
|
+
* @param reliable - If the call on remotes has to happen. Set to false for better performance is ok to lose some calls
|
|
19
|
+
*/
|
|
20
|
+
export declare function RunOnAll(reliable?: boolean): any;
|
|
21
|
+
//# sourceMappingURL=rpc-decorator.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{inject as n}from"../../inject";import{NetService as t}from"./net-service";import{registerRpcMethod as e,RunsOn as r}from"./rpc";import{BaseActor as o}from"../../actors/actor";import{NetMode as i}from"../net-session";import{ActorComponent as c}from"../../actors/component";export function RunOnServer(n=!0){return s(r.server,n)}export function RunOnClient(n=!0){return s(r.client,n)}export function RunOnNotOwner(n=!0){return s(r.notOwner,n)}export function RunOnAll(n=!0){return s(r.all,n)}function s(r,o=!0){return function(...i){if(i.length>=3){const[c,s,u]=i,a=u.value,f=s.toString();let p;return e(c,f),u.value=l(a,f,r,o,()=>(p??(p=n(t)),p)),u}const[c,s]=i,u=s.name.toString();let a;return s.addInitializer(function(){e(Object.getPrototypeOf(this),u),a=n(t)}),l(c,u,r,o,()=>(a??(a=n(t)),a))}}function l(n,t,e,s,l){return function(...u){const a=l();if(!(this instanceof o||this instanceof c))return void console.warn("RPC is defined on a non actor");let f,p;if(this instanceof o)f=this;else if(f=this.actor,p=this,null==f)return void console.warn("Can't call RPC on component before actor is set");let m,v=!1;return a.isServer&&(e===r.all||e===r.server||e===r.notOwner&&!a.isLocalOwner(f)&&a.mode===i.listenServer||e===r.client&&!a.isDedicatedServer&&a.isLocalOwner(f))?v=!0:a.isServer||e!==r.all&&e!==r.client&&e!==r.notOwner||(v=!0),v&&(m=n.apply(this,u)),a&&"function"==typeof a.sendRpc?a.sendRpc(e,s,f,t,u,p):console.warn("Net service is not set up",{netService:a}),m}}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare enum RunsOn {
|
|
2
|
+
/**
|
|
3
|
+
* Runs on the owning client if sent from the server.
|
|
4
|
+
* Can be called on client as well and executes locally only.
|
|
5
|
+
*
|
|
6
|
+
* Example use case: correct player position
|
|
7
|
+
*/
|
|
8
|
+
client = 0,
|
|
9
|
+
/**
|
|
10
|
+
* Runs on clients (or listen server) if it is not the owner.
|
|
11
|
+
* Can only be called from the server.
|
|
12
|
+
* Does not run on dedicated server.
|
|
13
|
+
*
|
|
14
|
+
* Example use case: playing effects that already were played on the owning client
|
|
15
|
+
*/
|
|
16
|
+
notOwner = 1,
|
|
17
|
+
/**
|
|
18
|
+
* Runs on the server when sent from the client.
|
|
19
|
+
* Can be called on the server as well and executes locally only.
|
|
20
|
+
*
|
|
21
|
+
* Example use cases: process user input
|
|
22
|
+
*/
|
|
23
|
+
server = 2,
|
|
24
|
+
/**
|
|
25
|
+
* Runs on the server and all clients.
|
|
26
|
+
* If called on a client, it is only executed locally.
|
|
27
|
+
*
|
|
28
|
+
* May be used in combination with checking if not dedicated server
|
|
29
|
+
* to not perform unnecessary work that is purely visual.
|
|
30
|
+
*
|
|
31
|
+
* Example use cases: visual effects, playing sound, synchronize state
|
|
32
|
+
*/
|
|
33
|
+
all = 3
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=rpc.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export var RunsOn;!function(e){e[e.client=0]="client",e[e.notOwner=1]="notOwner",e[e.server=2]="server",e[e.all=3]="all"}(RunsOn||(RunsOn={}));const e=Symbol("rpc-method-registry");export function registerRpcMethod(n,o){const r=function(n){const o=Object.prototype.hasOwnProperty.call(n,e)?n[e]:void 0;if(null!=o)return o;const r=t(Object.getPrototypeOf(n)),s={methodNames:null!=r?[...r.methodNames]:[],methodIdsByName:null!=r?new Map(r.methodIdsByName):new Map};return Object.defineProperty(n,e,{value:s}),s}(n),s=r.methodIdsByName.get(o);if(null!=s)return s;if(r.methodNames.length>=256)return void console.warn(`Too many RPC methods registered on ${function(e){return e.constructor?.name??"target"}(n)}. A maximum of 256 methods can be encoded.`);const m=r.methodNames.length;return r.methodNames.push(o),r.methodIdsByName.set(o,m),m}export function getRpcMethodId(e,n){return t(e)?.methodIdsByName.get(n)}export function getRpcMethodName(e,n){return t(e)?.methodNames[n]}function t(t){let n=t;for(;null!=n;){const t=Object.prototype.hasOwnProperty.call(n,e)?n[e]:void 0;if(null!=t)return t;n=Object.getPrototypeOf(n)}}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -9,6 +9,7 @@ import { ShaderImpl } from '../../shader/shader.js';
|
|
|
9
9
|
import type { ShaderGraphDocument } from '../../shader/graph/model.js';
|
|
10
10
|
import { Sequence } from '../../effects/sequence/sequence-data.js';
|
|
11
11
|
import { DataAssetRef } from '../../scene/objects/data-asset.js';
|
|
12
|
+
import { Type } from '../../utils/type.js';
|
|
12
13
|
export declare class AssetLoader {
|
|
13
14
|
protected assetResourceLoader: AssetResourceLoader;
|
|
14
15
|
protected assetService: AssetsProvider;
|
|
@@ -49,8 +50,8 @@ export declare class AssetLoader {
|
|
|
49
50
|
getTextureByAssetId(id: AssetId): Promise<THREE.Texture>;
|
|
50
51
|
getSequenceById(id: AssetId): Promise<Sequence>;
|
|
51
52
|
getSequenceByName(name: string): Promise<Sequence>;
|
|
52
|
-
getDataAssetById<T = unknown>(id: AssetId): Promise<DataAssetRef<T> | null>;
|
|
53
|
-
getDataAssetByName<T = unknown>(name: string): Promise<DataAssetRef<T> | null>;
|
|
53
|
+
getDataAssetById<T = unknown>(id: AssetId, type?: Type<T>): Promise<DataAssetRef<T> | null>;
|
|
54
|
+
getDataAssetByName<T = unknown>(name: string, type?: Type<T>): Promise<DataAssetRef<T> | null>;
|
|
54
55
|
getShaderGraphByAssetId(id: AssetId): Promise<ShaderGraphDocument>;
|
|
55
56
|
prepareShaderGraphParameters(graph: ShaderGraphDocument, params?: Record<string, any>): Promise<Record<string, unknown>>;
|
|
56
57
|
getMaterialByAssetId(id: AssetId): Promise<Material>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as
|
|
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 o,MTLLoader as n,OBJLoader as h,TGALoader as d}from"three-stdlib";import{KTX2Loader as c}from"three/examples/jsm/Addons.js";import{Service as l}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as w}from"../../scene/materializer";import{materialFromAsset as g,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";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 o(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new h(this.loadingManager),this.mtlLoader=new n(this.loadingManager),this.tgaLoader=new d(this.loadingManager),this.ktx2Loader=new c(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager),this.assetResourceLoader.materialProvider=e=>this.getMaterialByAssetId(e)}resolvePath(e){return A(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);return this.assetResourceLoader.getMesh(t,{applyMaterials:!0,materialResolver:e=>this.getMaterialByAssetId(e)})}async getAnimationClipByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No animation clip could be found with asset id ${e}`);return this.assetResourceLoader.getAnimationClip(t)}async 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 w(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 getShaderGraphByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No shader graph could be found with asset id ${e}`);if("shaderGraph"!==t.type||null==t.shaderGraph)throw new Error(`Missing shader graph data in asset ${e}`);return t.shaderGraph}async prepareShaderGraphParameters(e,t={}){return m(t,e,this.assetService,this.assetResourceLoader,void 0,this.shaders)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return g(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.assetResourceLoader.clearCache(e)}clearCacheById(e){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
|
*/
|
|
@@ -7,7 +7,7 @@ import { AbstractType, Type } from '../../../utils/type.js';
|
|
|
7
7
|
import { BaseActor } from '../../actors/actor.js';
|
|
8
8
|
import { ViewController } from '../render.js';
|
|
9
9
|
import { AbstractPhysicsSystem, ActorPhysicsOptions } from './abstract-physics-system.js';
|
|
10
|
-
export {
|
|
10
|
+
export { ActorComponent, attach, Attach, Component, type ComponentOptions } from '../../actors/component.js';
|
|
11
11
|
/**
|
|
12
12
|
* Pairwise filtering using bit masks.
|
|
13
13
|
*
|
|
@@ -564,6 +564,7 @@ export declare class PhysicsSystem extends AbstractPhysicsSystem {
|
|
|
564
564
|
* @param actor - The actor to update
|
|
565
565
|
*/
|
|
566
566
|
updateActorTransform(actor: BaseActor): void;
|
|
567
|
+
flushModifiedBodyPositionsToColliders(): void;
|
|
567
568
|
/**
|
|
568
569
|
* Sets up the physics world with default gravity.
|
|
569
570
|
* @private
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-simd-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-simd-compat";import{BehaviorSubject as o,distinctUntilChanged as n,filter as r,map as a,Subject as l,takeUntil as c}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as y,Group as p,LineSegments as g,Matrix4 as m,Object3D as f,Quaternion as w,Raycaster as x,Scene as B,Vector3 as b}from"three";import{Service as v}from"typedi";import{AssetMeshInstance as C}from"../../../scene/asset-resource-loader.js";import{BoxCollisionShape as S,CapsuleCollisionShape as A,ConeCollisionShape as R,ConvexPolyhedronCollisionShape as D,CylinderCollisionShape as z,PhysicalShapeMesh as T,PlaneCollisionShape as E,SphereCollisionShape as M,toInstancedCollisionShape as P,TrimeshCollisionShape as _}from"../../../index.js";import{LandscapeGroup as F}from"../../../scene/landscape/landscape.js";import{ViewController as I}from"../render.js";import{World as V}from"../world.js";import*as k from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as j}from"../../../utils/three/traverse.js";import{AbstractPhysicsSystem as N}from"./abstract-physics-system.js";import{ActorComponent as W,Component as L}from"../../../gameplay/actors/component.js";import{inject as O}from"../../../gameplay/inject.js";export{Component,ActorComponent,attach,Attach}from"../../actors/component.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.hitNormal=new b}}export class ShapeCastResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.normal=new b}reset(){this.actor=void 0,this.hasHit=!1,this.distance=0,this.hitPoint.set(0,0,0),this.normal.set(0,0,0)}}ShapeCastResult.shared=new ShapeCastResult;export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));const G=new b,K=new b,U=new w,q=new w,H=(new w,[]);let Q=class extends N{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.collisionEvents=new l,this.beforeStep=new l,this.afterStep=new l,this.shouldRenderDebug=!1,this.viewController=O(I),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this._raycaster=new x,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(G),i=t.getSize(K),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,U,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,U,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,n]of this.bodyActors)if(n instanceof i||null==i)for(let i=0,r=e.numColliders();i<r;i++){e.collider(i).intersectsShape(s,t,U)&&o.push(n)}return o}createDebugMesh(){return new g(new y,new d.LineBasicMaterial({color:255}))}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene?.add(this.debugMesh));const t=this.world.debugRender().vertices,e=this.debugMesh.geometry,i=e.getAttribute("position");null==i||(i.array.length,t.length);{const i=new u(t,3);i.setUsage(d.DynamicDrawUsage),e.setAttribute("position",i)}e.setDrawRange(0,t.length/3)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await lt(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{this._isStopped||(t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach(t=>{if(t.isFixed())return;const e=this.staticMeshes.get(t)??this.bodyActors.get(t)?.object;null!=e&&e.parent instanceof B&&(ht(e.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&ut(e.quaternion,t.rotation()),e.matrixWorldNeedsUpdate=!0)}),this.afterStep.next(t))})}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this._isStopped||(this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})}))}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(ot,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult);const o=this._raytestDiff,n=this._raytestDirection;if(o.subVectors(e,t),n.copy(o).normalize(),0===n.length())return console.warn("Ray test called with to and from being equal"),i;null==wt&&(wt=new this.rapier.Ray(new this.rapier.Vector3(0,0,0),new this.rapier.Vector3(0,1,0))),ct(wt.origin,t),ct(wt.dir,n);const r=o.length(),a=this.world.castRayAndGetNormal(wt,r,!1,void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0,s?.excludeTriggers?t=>!t.isSensor():void 0);if(i.hasHit=null!=a,i.hasHit){const e=wt.pointAt(a.timeOfImpact);if(i._internal=a,ht(i.hitNormal,a.normal),ht(i.hitPoint,e),i.distance=pt.subVectors(i.hitPoint,t).length(),!1!==s?.resolveActor){const t=this.world.bodies.getAll().find(t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,t=>t===a.collider));i.actor=null!=t?this.bodyActors.get(t):null}}if(this.showDebug){let e;H.length>0?(e=H.pop(),e.setDirection(n),e.position.copy(t),e.setLength(r,.2,.1),e.setColor(s?.debugColor??255)):e=new h(n,t,r,s?.debugColor??255),this.scene?.add(e),setTimeout(()=>{this.scene?.remove(e),H.push(e)},s?.debugLifetime??200)}return i}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return Z.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())yt(t,t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof T&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof C){const e=!1!==t.userData?.src?.collisionDetection;if(t.children[0]&&(t.children[0].instanceMatrix&&e||t.children[0].isBatchedMesh))this.createForInstancedMesh(t.children[0],t.collisionShapes);else if(e&&t.children.length>0){const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}}else t instanceof F?this.addLandscapeGroup(t):(t instanceof p||t instanceof B)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new m;if(t instanceof d.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map;for(let o=0;o<e.length;o++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[o])continue;const e=t.userData.collisionShapes;let n=e?.[o];if(null==n&&null==e&&t.parent instanceof C&&(n=t.parent.collisionShapes),null==n)continue;let r=s.get(n);null==r&&(r=this.instancedShapeReset(n),s.set(n,r));const a=new f;a.matrix.identity(),t.getMatrixAt(o,i),a.applyMatrix4(i);this.createStaticBody(a,r)}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new f;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);this.createStaticBody(o,s)}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>P(t))}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,o=null){const n=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=n.collider(0);e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,o,mt);const a=e.computedMovement();return ht(gt,a),gt}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world);return this.colliders.set(i.handle,s),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const 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 new PhysicsBody(s,this.world)}getCharacterComputedMovement(t,e,i,o=null){const n=t.collider;e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,o,mt);const r=e.computedMovement();return ht(gt,r),gt}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition($),s=e.getWorldQuaternion(X);t.setNextKinematicTranslation(nt(i)),t.setNextKinematicRotation(rt(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);et.x=e.x,et.y=e.y,et.z=e.z,i?.setAngvel(et,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);et.x=e.x,et.y=e.y,et.z=e.z,i?.setLinvel(et,!0)}getLinearVelocity(t,e=new b){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new b){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(nt(e),!1)}getPosition(t,e=new b){const i=this.actorBodies.get(t.id);i&&ht(e,i.translation())}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(rt(e),!1)}getRotation(t,e=new w){const i=this.actorBodies.get(t.id);i&&ut(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}addLandscapeGroup(t){const e=t.userData.src,s=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));var o=n.getWorldPosition(new b);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===n.name&&0!==t.w[0])){const t=n.geometry.clone(),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);ct(e,o),t.setTranslation(e,!1),this.world.createCollider(l,t),this.staticBodies.set(n,t)}continue}const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=s.find(t=>t.x===n.x&&t.y==n.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=i.ColliderDesc.heightfield(c,c,new Float32Array(d),new 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);ct(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(n,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e)}addActor(t,e,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)this.addShape(n,t,s);return yt(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)}),Y(n,s),!0===i.ignoreForNavMesh&&(n.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,n),this.bodyActors.set(n,t),new PhysicsBody(n,this.world)}applyTorque(t,e){const i=this.actorBodies.get(t.id);et.x=e.x,et.y=e.y,et.z=e.z,i?.addTorque(et,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);et.x=e.x,et.y=e.y,et.z=e.z,i?.applyTorqueImpulse(et,!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);et.x=e.x,et.y=e.y,et.z=e.z,i?.addForce(et,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);et.x=e.x,et.y=e.y,et.z=e.z,i?.applyImpulse(et,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);ct(et,e),null==i?s?.addForce(et,!0):(ct(it,i),s?.addForceAtPoint(et,it,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);ct(et,e),null==i?s.applyImpulse(et,!0):(ct(it,i),s.applyImpulseAtPoint(et,it,!0))}applyRadiusImpulse(t,e,s){this.world.bodies.forEach(o=>{if(o.collider(0)?.isSensor())return;if(o.bodyType()!==i.RigidBodyType.Dynamic)return;const n=st;ht(n,o.translation());const r=n.clone().sub(t);if(r.length()>e)return;const a=r.clone().normalize().multiplyScalar(s);et.x=a.x,et.y=a.y,et.z=a.z,o.applyImpulse(et,!0)})}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.staticBodies.delete(t),this.world.removeRigidBody(i))}removeSceneObject(t){if(t instanceof F){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(({started:t})=>t===i),a(({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t)?.parent()),a2:this.bodyActors.get(this.world.getCollider(e)?.parent()),started:i})),r(({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s)),a(({a2:t})=>t))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>!t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onHasContactChanged(t){const e=new Set,i=new o(!1);return this.onBeginContact(t).subscribe(t=>{e.add(t),i.next(e.size>0)}),this.onEndContact(t).subscribe(t=>{e.delete(t),i.next(e.size>0)}),i.pipe(n())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e&&Y(e,t.object)}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t}sphereCast(t,e,i,s,o=ShapeCastResult.shared,n){o.reset();const r=this.getBallShape(e);this.shapeCacheBall.get;const a={x:t.x,y:t.y,z:t.z},l={x:i.x,y:i.y,z:i.z},c=n?.excludeActor?this.actorBodies.get(n.excludeActor.id):null,d=this.world.castShape(a,{x:0,y:0,z:0,w:1},l,r,.01,s,!0,null,n?.collisionFilter??void 0,null,c,n?.excludeTriggers?t=>!t.isSensor():void 0);if(null!=d){ht(o.hitPoint,d.witness1),o.normal.set(d.normal1.x,d.normal1.y,d.normal1.z),o.distance=d.time_of_impact,o.hasHit=!0;const t=d.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(o.actor=e)}}return o}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const n=this.actorBodies.get(t.id);if(n&&n.numColliders()>0){for(let t=0;t<n.numColliders();t++){const r=n.collider(t);let a=r.shape,l=r.translation(),c=r.rotation(),d=e,h=i;const 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 ht(s.hitPoint,u.witness1),Bt(t.rotation(),u.normal1,s.normal,q),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));try{this.world?.free(),this.world=void 0}catch(t){console.warn("Error while freeing physics world",t)}H.length=0}}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed();o.setSleeping(!0);const n=this.world.createRigidBody(o);let r=0;for(const i of e){if(r>128){console.warn("Too many collision shapes for object",t);break}if(r++,null==i){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(n,i,t);null!=o&&(null!=s?.friction&&o.setFriction(s.friction),null!=s?.density&&o.setDensity(s.density),null!=s?.mass&&o.setMass(s.mass/e.length),null!=s?.restitution&&o.setRestitution(s.restitution))}return Y(n,t),n.userData=t.uuid,n.sleep(),n}addShape(t=void 0,e,i){const s=i?.getWorldScale(ft)??tt,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);ct(o.translation,n);const r=(new w).setFromEuler(e.rotation);dt(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{return this.world.createCollider(o,t)}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=i.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=i.MassPropsMode.Mass)}createShape(t,e){if(t instanceof S)return this.rapier.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof A){return this.rapier.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof _){const i=null!=t.geometry.getIndex()?t.geometry:k.mergeVertices(t.geometry),s=extractFloat32Array(i.getAttribute("position"));for(let t=0;t<s.length;t+=3)s[t]*=e.x,s[t+1]*=e.y,s[t+2]*=e.z;const o=i.getIndex();return null==o?(console.error("Trimesh collision shape is missing an index buffer.",t),null):this.rapier.ColliderDesc.trimesh(s,new Uint32Array(o.array))}if(t instanceof D){let i,s;t.mesh instanceof d.Mesh?i=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?i=t.mesh:console.log("Unknownd shape",{shapeInfo:t}),t.mesh instanceof d.Mesh&&(s=j(t.mesh));const o=`${i.uuid}|${s?.x??1},${s?.y??1},${s?.z??1}|${e.x},${e.y},${e.z}`,n=J.get(o);if(void 0!==n)return n;const r=extractFloat32Array(i.getAttribute("position"));if(null!=s)for(let t=0;t<r.length;t+=3)r[t]*=s.x,r[t+1]*=s.y,r[t+2]*=s.z;for(let t=0;t<r.length;t+=3)r[t]*=e.x,r[t+1]*=e.y,r[t+2]*=e.z;const a=this.rapier.ColliderDesc.convexHull(r);return null==a&&console.error("Failed to compute convex hull. Points may be coplanar or too few.",{count:r.length/3}),J.set(o,a),a}if(t instanceof M){const i=2*e.x-e.y-e.z;return Math.abs(i)>.01?this.createShape(new D(new d.SphereGeometry(t.radius).scale(e.x,e.y,e.z)),new b(1,1,1)):this.rapier.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z))}return t instanceof z?this.rapier.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof R?this.rapier.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof E?this.rapier.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.001):(console.error("Unsupported shape",t),this.rapier.ColliderDesc.cuboid(1,1,1))}createCharacterCollision(){return new this.rapier.CharacterCollision}};Q=t([v(),e("design:paramtypes",[])],Q);export{Q as PhysicsSystem};const $=new b,X=new d.Quaternion;function Y(t,e){const i=e.getWorldPosition($),s=e.getWorldQuaternion(X);t.setTranslation(nt(i),!1),t.setRotation(rt(s),!1)}const Z=new b,J=new Map,tt=new b(1,1,1),et=new i.Vector3(0,0,0),it=new i.Vector3(0,0,0),st=new b,ot=new d.Vector2;function nt(t){return ct(et,t),et}function rt(t){return dt(q,t),q}let at=null;const lt=async()=>(null==at&&(at=(async()=>{let t=await import("@dimforge/rapier3d-simd-compat");return await t.init(),t})()),at);function ct(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function dt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function ht(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function ut(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function yt(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const pt=new b,gt=new b,mt=t=>!t.isSensor(),ft=new b;let wt,xt=class extends W{constructor(){super(...arguments),this._active=!0,this.physics=O(Q),this.world=O(V)}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}};xt=t([L()],xt);export function extractFloat32Array(t){const e=t.itemSize,i=t.count,s=new Float32Array(i*e);for(let o=0;o<i;o++)for(let i=0;i<e;i++)s[o*e+i]=t.getComponent(o,i);return s}function Bt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e){this.collider=t,this.world=e,this.disposed=new l,this.onBeginOverlapActor=new l,this.onEndOverlapActor=new l}dispose(){this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t)}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e){this.body=t,this.world=e}dispose(){this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t)}isEnabled(){return this.body.isEnabled()}getPosition(t){const e=this.body.translation();return t.set(e.x,e.y,e.z),t}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0)}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0)}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyType.Dynamic;case PhysicsBodyType.static:return i.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return i.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static)}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}/*
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-simd-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-simd-compat";import{BehaviorSubject as o,distinctUntilChanged as n,filter as r,map as a,Subject as l,takeUntil as c}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as y,Group as p,LineSegments as g,Matrix4 as m,Object3D as f,Quaternion as w,Raycaster as x,Scene as B,Vector3 as b}from"three";import*as v from"three/examples/jsm/utils/BufferGeometryUtils.js";import{Service as C}from"typedi";import{ActorComponent as S,Component as A}from"../../../gameplay/actors/component.js";import{inject as R}from"../../../gameplay/inject.js";import{BoxCollisionShape as D,CapsuleCollisionShape as T,ConeCollisionShape as z,ConvexPolyhedronCollisionShape as M,CylinderCollisionShape as E,PhysicalShapeMesh as P,PlaneCollisionShape as _,SphereCollisionShape as F,toInstancedCollisionShape as I,TrimeshCollisionShape as V}from"../../../index.js";import{AssetMeshInstance as k}from"../../../scene/asset-resource-loader.js";import{LandscapeGroup as j}from"../../../scene/landscape/landscape.js";import{calculateEffectiveScale as N}from"../../../utils/three/traverse.js";import{ViewController as W}from"../render.js";import{World as L}from"../world.js";import{AbstractPhysicsSystem as O}from"./abstract-physics-system.js";import{NetRole as G}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 K=new b,U=new b,q=new w,H=new w,Q=(new w,[]);let $=class extends O{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.collisionEvents=new l,this.beforeStep=new l,this.afterStep=new l,this.shouldRenderDebug=!1,this.viewController=R(W),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this._raycaster=new x,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(K),i=t.getSize(U),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,q,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,q,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,n]of this.bodyActors)if(n instanceof i||null==i)for(let i=0,r=e.numColliders();i<r;i++){e.collider(i).intersectsShape(s,t,q)&&o.push(n)}return o}createDebugMesh(){return new g(new y,new d.LineBasicMaterial({color:255}))}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene?.add(this.debugMesh));const t=this.world.debugRender().vertices,e=this.debugMesh.geometry,i=e.getAttribute("position");null==i||(i.array.length,t.length);{const i=new u(t,3);i.setUsage(d.DynamicDrawUsage),e.setAttribute("position",i)}e.setDrawRange(0,t.length/3)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await ct(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{this._isStopped||(t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach(t=>{if(t.isFixed())return;let e,i=this.staticMeshes.get(t);if(null==i&&(e=this.bodyActors.get(t),null!=e)){if(e.netRole===G.simulatedProxy)return;i=e.object}null!=i&&i.parent instanceof B&&(ut(i.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&yt(i.quaternion,t.rotation()),i.matrixWorldNeedsUpdate=!0)}),this.afterStep.next(t))})}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this._isStopped||(this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})}))}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(nt,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult);const o=this._raytestDiff,n=this._raytestDirection;if(o.subVectors(e,t),n.copy(o).normalize(),0===n.length())return console.warn("Ray test called with to and from being equal"),i;null==xt&&(xt=new this.rapier.Ray(new this.rapier.Vector3(0,0,0),new this.rapier.Vector3(0,1,0))),dt(xt.origin,t),dt(xt.dir,n);const r=o.length(),a=this.world.castRayAndGetNormal(xt,r,!1,void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0,s?.excludeTriggers?t=>!t.isSensor():void 0);if(i.hasHit=null!=a,i.hasHit){const e=xt.pointAt(a.timeOfImpact);if(i._internal=a,ut(i.hitNormal,a.normal),ut(i.hitPoint,e),i.distance=gt.subVectors(i.hitPoint,t).length(),!1!==s?.resolveActor){const t=this.world.bodies.getAll().find(t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,t=>t===a.collider));i.actor=null!=t?this.bodyActors.get(t):null}}if(this.showDebug){let e;Q.length>0?(e=Q.pop(),e.setDirection(n),e.position.copy(t),e.setLength(r,.2,.1),e.setColor(s?.debugColor??255)):e=new h(n,t,r,s?.debugColor??255),this.scene?.add(e),setTimeout(()=>{this.scene?.remove(e),Q.push(e)},s?.debugLifetime??200)}return i}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return J.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())pt(t,t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof P&&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 k){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)}}else t instanceof j?this.addLandscapeGroup(t):(t instanceof p||t instanceof B)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new m;if(t instanceof d.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map;for(let o=0;o<e.length;o++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[o])continue;const e=t.userData.collisionShapes;let n=e?.[o];if(null==n&&null==e&&t.parent instanceof k&&(n=t.parent.collisionShapes),null==n)continue;let r=s.get(n);null==r&&(r=this.instancedShapeReset(n),s.set(n,r));const a=new f;a.matrix.identity(),t.getMatrixAt(o,i),a.applyMatrix4(i);this.createStaticBody(a,r)}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new f;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);this.createStaticBody(o,s)}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>I(t))}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,o=null){const n=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=n.collider(0);e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,o,ft);const a=e.computedMovement();return ut(mt,a),mt}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world);return this.colliders.set(i.handle,s),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const 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 new PhysicsBody(s,this.world)}getCharacterComputedMovement(t,e,i,o=null){const n=t.collider;e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,o,ft);const r=e.computedMovement();return ut(mt,r),mt}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition(X),s=e.getWorldQuaternion(Y);t.setNextKinematicTranslation(rt(i)),t.setNextKinematicRotation(at(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.setAngvel(it,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.setLinvel(it,!0)}getLinearVelocity(t,e=new b){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new b){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(rt(e),!1)}getPosition(t,e=new b){const i=this.actorBodies.get(t.id);i&&ut(e,i.translation())}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(at(e),!1)}getRotation(t,e=new w){const i=this.actorBodies.get(t.id);i&&yt(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}addLandscapeGroup(t){const e=t.userData.src,s=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));var o=n.getWorldPosition(new b);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===n.name&&0!==t.w[0])){const t=n.geometry.clone(),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);dt(e,o),t.setTranslation(e,!1),this.world.createCollider(l,t),this.staticBodies.set(n,t)}continue}const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=s.find(t=>t.x===n.x&&t.y==n.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=i.ColliderDesc.heightfield(c,c,new Float32Array(d),new 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);dt(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(n,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e)}addActor(t,e,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)this.addShape(n,t,s);return pt(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)}),Z(n,s),!0===i.ignoreForNavMesh&&(n.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,n),this.bodyActors.set(n,t),new PhysicsBody(n,this.world)}applyTorque(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.addTorque(it,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.applyTorqueImpulse(it,!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);it.x=e.x,it.y=e.y,it.z=e.z,i?.addForce(it,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.applyImpulse(it,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);dt(it,e),null==i?s?.addForce(it,!0):(dt(st,i),s?.addForceAtPoint(it,st,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);dt(it,e),null==i?s.applyImpulse(it,!0):(dt(st,i),s.applyImpulseAtPoint(it,st,!0))}applyRadiusImpulse(t,e,s){this.world.bodies.forEach(o=>{if(o.collider(0)?.isSensor())return;if(o.bodyType()!==i.RigidBodyType.Dynamic)return;const n=ot;ut(n,o.translation());const r=n.clone().sub(t);if(r.length()>e)return;const a=r.clone().normalize().multiplyScalar(s);it.x=a.x,it.y=a.y,it.z=a.z,o.applyImpulse(it,!0)})}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.staticBodies.delete(t),this.world.removeRigidBody(i))}removeSceneObject(t){if(t instanceof j){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(({started:t})=>t===i),a(({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t)?.parent()),a2:this.bodyActors.get(this.world.getCollider(e)?.parent()),started:i})),r(({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s)),a(({a2:t})=>t))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(c(t.disposed),r(t=>!t.started),r(({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id}),a(t=>t.handle2))}onHasContactChanged(t){const e=new Set,i=new o(!1);return this.onBeginContact(t).subscribe(t=>{e.add(t),i.next(e.size>0)}),this.onEndContact(t).subscribe(t=>{e.delete(t),i.next(e.size>0)}),i.pipe(n())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>i instanceof e,!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,(t,i)=>e.id===i.id,!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e&&Z(e,t.object)}flushModifiedBodyPositionsToColliders(){this.world.propagateModifiedBodyPositionsToColliders()}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t}sphereCast(t,e,i,s,o=ShapeCastResult.shared,n){o.reset();const r=this.getBallShape(e);this.shapeCacheBall.get;const a={x:t.x,y:t.y,z:t.z},l={x:i.x,y:i.y,z:i.z},c=n?.excludeActor?this.actorBodies.get(n.excludeActor.id):null,d=this.world.castShape(a,{x:0,y:0,z:0,w:1},l,r,.01,s,!0,null,n?.collisionFilter??void 0,null,c,n?.excludeTriggers?t=>!t.isSensor():void 0);if(null!=d){ut(o.hitPoint,d.witness1),o.normal.set(d.normal1.x,d.normal1.y,d.normal1.z),o.distance=d.time_of_impact,o.hasHit=!0;const t=d.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(o.actor=e)}}return o}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const n=this.actorBodies.get(t.id);if(n&&n.numColliders()>0){for(let t=0;t<n.numColliders();t++){const r=n.collider(t);let a=r.shape,l=r.translation(),c=r.rotation(),d=e,h=i;const 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 ut(s.hitPoint,u.witness1),bt(t.rotation(),u.normal1,s.normal,H),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));try{this.world?.free(),this.world=void 0}catch(t){console.warn("Error while freeing physics world",t)}Q.length=0}}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed();o.setSleeping(!0);const n=this.world.createRigidBody(o);let r=0;for(const i of e){if(r>128){console.warn("Too many collision shapes for object",t);break}if(r++,null==i){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(n,i,t);null!=o&&(null!=s?.friction&&o.setFriction(s.friction),null!=s?.density&&o.setDensity(s.density),null!=s?.mass&&o.setMass(s.mass/e.length),null!=s?.restitution&&o.setRestitution(s.restitution))}return Z(n,t),n.userData=t.uuid,n.sleep(),n}addShape(t=void 0,e,i){const s=i?.getWorldScale(wt)??et,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);dt(o.translation,n);const r=(new w).setFromEuler(e.rotation);ht(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{return this.world.createCollider(o,t)}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=i.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=i.MassPropsMode.Mass)}createShape(t,e){if(t instanceof D)return this.rapier.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof T){return this.rapier.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof V){const i=null!=t.geometry.getIndex()?t.geometry:v.mergeVertices(t.geometry),s=extractFloat32Array(i.getAttribute("position"));for(let t=0;t<s.length;t+=3)s[t]*=e.x,s[t+1]*=e.y,s[t+2]*=e.z;const o=i.getIndex();return null==o?(console.error("Trimesh collision shape is missing an index buffer.",t),null):this.rapier.ColliderDesc.trimesh(s,new Uint32Array(o.array))}if(t instanceof M){let i,s;t.mesh instanceof d.Mesh?i=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?i=t.mesh:console.log("Unknownd shape",{shapeInfo:t}),t.mesh instanceof d.Mesh&&(s=N(t.mesh));const o=`${i.uuid}|${s?.x??1},${s?.y??1},${s?.z??1}|${e.x},${e.y},${e.z}`,n=tt.get(o);if(void 0!==n)return n;const r=extractFloat32Array(i.getAttribute("position"));if(null!=s)for(let t=0;t<r.length;t+=3)r[t]*=s.x,r[t+1]*=s.y,r[t+2]*=s.z;for(let t=0;t<r.length;t+=3)r[t]*=e.x,r[t+1]*=e.y,r[t+2]*=e.z;const a=this.rapier.ColliderDesc.convexHull(r);return null==a&&console.error("Failed to compute convex hull. Points may be coplanar or too few.",{count:r.length/3}),tt.set(o,a),a}if(t instanceof F){const i=2*e.x-e.y-e.z;return Math.abs(i)>.01?this.createShape(new M(new d.SphereGeometry(t.radius).scale(e.x,e.y,e.z)),new b(1,1,1)):this.rapier.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z))}return t instanceof E?this.rapier.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof z?this.rapier.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof _?this.rapier.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.001):(console.error("Unsupported shape",t),this.rapier.ColliderDesc.cuboid(1,1,1))}createCharacterCollision(){return new this.rapier.CharacterCollision}};$=t([C(),e("design:paramtypes",[])],$);export{$ as PhysicsSystem};const X=new b,Y=new d.Quaternion;function Z(t,e){const i=e.getWorldPosition(X),s=e.getWorldQuaternion(Y);t.setTranslation(rt(i),!1),t.setRotation(at(s),!1)}const J=new b,tt=new Map,et=new b(1,1,1),it=new i.Vector3(0,0,0),st=new i.Vector3(0,0,0),ot=new b,nt=new d.Vector2;function rt(t){return dt(it,t),it}function at(t){return ht(H,t),H}let lt=null;const ct=async()=>(null==lt&&(lt=(async()=>{let t=await import("@dimforge/rapier3d-simd-compat");return await t.init(),t})()),lt);function dt(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function ht(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function ut(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function yt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function pt(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const gt=new b,mt=new b,ft=t=>!t.isSensor(),wt=new b;let xt,Bt=class extends S{constructor(){super(...arguments),this._active=!0,this.physics=R($),this.world=R(L)}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}};Bt=t([A()],Bt);export function extractFloat32Array(t){const e=t.itemSize,i=t.count,s=new Float32Array(i*e);for(let o=0;o<i;o++)for(let i=0;i<e;i++)s[o*e+i]=t.getComponent(o,i);return s}function bt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e){this.collider=t,this.world=e,this.disposed=new l,this.onBeginOverlapActor=new l,this.onEndOverlapActor=new l}dispose(){this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t)}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e){this.body=t,this.world=e}dispose(){this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t)}isEnabled(){return this.body.isEnabled()}getPosition(t){const e=this.body.translation();return t.set(e.x,e.y,e.z),t}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0)}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0)}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyType.Dynamic;case PhysicsBodyType.static:return i.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return i.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static)}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -3,8 +3,9 @@ import { BaseActor } from '../actors/actor.js';
|
|
|
3
3
|
import { Euler, Scene, Vector3 } from 'three';
|
|
4
4
|
import { Observable } from 'rxjs';
|
|
5
5
|
import { RenderingView } from "../../rendering.js";
|
|
6
|
-
import { Prefab
|
|
6
|
+
import { Prefab } from "../../scene/objects/prefab.js";
|
|
7
7
|
import { PrefabInstance } from '../../scene/objects/prefab';
|
|
8
|
+
import { BasePlayerController } from "../actors/controller/actor-controller.js";
|
|
8
9
|
declare class DirectionalLightController {
|
|
9
10
|
private view;
|
|
10
11
|
constructor(view: RenderingView);
|
|
@@ -22,6 +23,9 @@ declare class DirectionalLightController {
|
|
|
22
23
|
*/
|
|
23
24
|
get position(): Vector3;
|
|
24
25
|
}
|
|
26
|
+
export type ActorSpawnOptions = {
|
|
27
|
+
owner: BaseActor;
|
|
28
|
+
};
|
|
25
29
|
export declare class World {
|
|
26
30
|
private actorFactory;
|
|
27
31
|
private view;
|
|
@@ -31,7 +35,14 @@ export declare class World {
|
|
|
31
35
|
readonly actorRemoved: Observable<BaseActor>;
|
|
32
36
|
scene: Scene;
|
|
33
37
|
readonly directionalLight: DirectionalLightController;
|
|
34
|
-
spawnActor<T extends BaseActor>(type: Constructable<T
|
|
38
|
+
spawnActor<T extends BaseActor>(type: Constructable<T>, position?: Vector3, rotation?: Euler, options?: ActorSpawnOptions): Promise<T>;
|
|
39
|
+
/**
|
|
40
|
+
* Spawn the player controller to run locally.
|
|
41
|
+
* This is only called by the server and if it is not a dedicated server in
|
|
42
|
+
* which case it doesn't have its own local player controller.
|
|
43
|
+
* It sets isLocallyControlled to true
|
|
44
|
+
*/
|
|
45
|
+
spawnLocalPlayerController<T extends BasePlayerController>(type: Constructable<T>, position?: Vector3, rotation?: Euler): Promise<T>;
|
|
35
46
|
addActor(actor: BaseActor, position?: Vector3, rotation?: Euler): void;
|
|
36
47
|
removeActor(actor: BaseActor): void;
|
|
37
48
|
findActorByType<T extends BaseActor>(type: Constructable<T>, name?: string): T;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t}from"tslib";import{Service as r}from"typedi";import{BaseActor as o}from"../actors/actor.js";import{ActorFactory as e}from"../actors/factory.js";import{Vector3 as
|
|
1
|
+
import{__decorate as t}from"tslib";import{Service as r}from"typedi";import{BaseActor as o}from"../actors/actor.js";import{ActorFactory as e}from"../actors/factory.js";import{Group as i,Vector3 as n}from"three";import{ActorComponent as s}from"../../gameplay/actors/component.js";import{Subject as c}from"rxjs";import{RenderingView as a}from"../../rendering.js";import{randomUUID as h}from"../../utils/uuid";import{PrefabInstance as l}from"../../scene/objects/prefab";import{PhysicsSystem as m}from"./physics/physics-system.js";import{inject as p}from"../../gameplay/inject.js";import{isComponentEnabledInEnvironment as d}from"../actors/internal/component-init.js";import{NetRole as f}from"../net/service/net-actor-role.js";import{BasePlayerController as y}from"../actors/controller/actor-controller.js";const w=new n;class u{constructor(t){this.view=t}get direction(){return this.view.csm.lightDirection}set intensity(t){this.view.csm.lightIntensity=t,this.view.csm.lights.forEach(t=>t.intensity=this.view.csm.lightIntensity)}get intensity(){return this.view.csm.lightIntensity}get position(){return 0==this.view.csm.lights.length?w:this.view.csm.lights[0].position}}let b=class{constructor(){this.actorFactory=p(e),this.view=p(a),this.physics=p(m),this.actors=[],this.actorAdded=new c,this.actorRemoved=new c,this.directionalLight=new u(this.view)}async spawnActor(t,r,o,e){if(null==t)throw new Error("Cannot spawn actor with null type");if("prefab"in t){const i=t.prefab,n=await this.spawnPrefab(i,r,o),s=n.mainActor;if(null==s)throw new Error(`Prefab has no main actor or there was an error when spwaning it. Prefab: ${JSON.stringify(i)}`);return s.disposed.subscribe(()=>{const t=n.actors.findIndex(t=>t===s);t>=0&&n.actors.splice(t,1),this.removePrefab(n)}),null!=e?.owner&&(s.owner=e.owner),s}const i=await this.actorFactory.create(t,r,o);return null!=e?.owner&&(i.owner=e.owner),this.addActor(i,r,o),i}async spawnActorWithNetInfo(t,r,o,e,i,n){const s=await this.actorFactory.create(t,i,n,!0),c=null!=e&&0!==e?this.actors.find(t=>t.__netid===e):null;return s.__netid=r,s.netRole=o,s.owner=c,s instanceof y&&(s.isLocallyControlled=o===f.autonomousProxy),this.actorFactory.initActor(s),this.addActor(s,i,n),s}async spawnLocalPlayerController(t,r,o){const e=await this.actorFactory.create(t,r,o,!0);return e.isLocallyControlled=!0,this.actorFactory.initActor(e),this.addActor(e,r,o),e}spawnActorSync(t,r,o){if(null==t)throw new Error("Cannot spawn actor with null type");const e=this.actorFactory.createSync(t,r,o);return this.addActor(e,r,o),e}addActor(t,r,o){r&&t.object.position.copy(r),o&&t.object.rotation.copy(o),null==t.object.parent&&this.scene.add(t.object),this.actors.push(t),j(t,t=>t.onBeginPlay(),this.actorFactory.inEditor),this.actorAdded.next(t)}removeActor(t){j(t,t=>t.onEndPlay(),this.actorFactory.inEditor);const r=this.actors.indexOf(t);r>=0&&this.actors.splice(r,1),t.object.removeFromParent(),t.disposed.next(!0),this.actorRemoved.next(t),this.physics.removeActor(t)}findActorByType(t,r){return this.actors.find(o=>o instanceof t&&(null==r||o.object.name==r))}findActorsByType(t,r){return this.actors.filter(o=>o instanceof t&&(null==r||o.object.name==r))}async spawnPrefab(t,r,o){if(null==this.materializer)return console.error("Internal error: Materializer is missing on World"),null;const e=new l,n=new i;null!=r&&n.position.copy(r),null!=o&&n.rotation.copy(o),this.materializer.setScene(this.scene),this.materializer.inEditor=this.actorFactory.inEditor;const{object:s,actors:c,mainActor:a}=await this.materializer.createFromPrefabAsset(t.asset,{sceneObjectChain:["r-"+h()]},n,void 0,!1);return e.object=s,e.actors=c,e.mainActor=a,this.scene.attach(s),c.forEach(t=>{this.addActor(t)}),this.physics.addFromScene(s),e}removePrefab(t){t.actors.forEach(t=>this.removeActor(t)),t.object?.removeFromParent(),this.physics.removeRemoved(t.object)}};b=t([r()],b);export{b as World};function j(t,r,e=!1,i=new WeakSet){if(!i.has(t))return i.add(t),r(t),t instanceof o&&t.attachedComponents.forEach(t=>{d(t,e)&&j(t,r,e,i)}),Object.entries(t).filter(([t,r])=>r instanceof s&&d(r,e)).forEach(([t,o])=>{j(o,r,e,i)})}/*
|
|
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{Color as t,NoToneMapping as n,Texture as e,Vector3 as i}from"three";import{ShaderPass as a}from"three-stdlib";export class ColorPass extends a{constructor(){super({uniforms:{tDiffuse:{value:new e},whiteBalanceEnabled:{value:!1},whiteBalanceScale:{value:new i(1,1,1)},vignetteEnabled:{value:!1},vignetteIntensity:{value:.5},colorTintEnabled:{value:!1},colorTint:{value:new i(1,1,1)},colorTintIntensity:{value:0},colorGradingEnabled:{value:!1},toneMappingMode:{value:n},toneMappingEnabled:{value:!1},toneMappingExposure:{value:1},globalSaturation:{value:new i(1,1,1)},globalContrast:{value:new i(1,1,1)},globalGamma:{value:new i(1,1,1)},globalGain:{value:new i(1,1,1)},globalOffset:{value:new i(0,0,0)},shadowsSaturation:{value:new i(1,1,1)},shadowsContrast:{value:new i(1,1,1)},shadowsGamma:{value:new i(1,1,1)},shadowsGain:{value:new i(1,1,1)},shadowsOffset:{value:new i(0,0,0)},shadowsMax:{value:.09},midtonesSaturation:{value:new i(1,1,1)},midtonesContrast:{value:new i(1,1,1)},midtonesGamma:{value:new i(1,1,1)},midtonesGain:{value:new i(1,1,1)},midtonesOffset:{value:new i(0,0,0)},highlightsSaturation:{value:new i(1,1,1)},highlightsContrast:{value:new i(1,1,1)},highlightsGamma:{value:new i(1,1,1)},highlightsGain:{value:new i(1,1,1)},highlightsOffset:{value:new i(0,0,0)},highlightsMin:{value:.5}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform bool whiteBalanceEnabled;\n uniform vec3 whiteBalanceScale;\n uniform bool vignetteEnabled;\n uniform float vignetteIntensity;\n uniform bool colorTintEnabled;\n uniform vec3 colorTint;\n uniform float colorTintIntensity;\n uniform bool colorGradingEnabled;\n uniform int toneMappingMode;\n uniform bool toneMappingEnabled;\n uniform vec3 globalSaturation;\n uniform vec3 globalContrast;\n uniform vec3 globalGamma;\n uniform vec3 globalGain;\n uniform vec3 globalOffset;\n uniform vec3 shadowsSaturation;\n uniform vec3 shadowsContrast;\n uniform vec3 shadowsGamma;\n uniform vec3 shadowsGain;\n uniform vec3 shadowsOffset;\n uniform float shadowsMax;\n uniform vec3 midtonesSaturation;\n uniform vec3 midtonesContrast;\n uniform vec3 midtonesGamma;\n uniform vec3 midtonesGain;\n uniform vec3 midtonesOffset;\n uniform vec3 highlightsSaturation;\n uniform vec3 highlightsContrast;\n uniform vec3 highlightsGamma;\n uniform vec3 highlightsGain;\n uniform vec3 highlightsOffset;\n uniform float highlightsMin;\n\n varying vec2 vUv;\n\n #include <tonemapping_pars_fragment>\n\n const vec3 LUMA = vec3(0.2126, 0.7152, 0.0722);\n\n vec3 applySaturation(vec3 color, vec3 saturation) {\n vec3 luminanceColor = vec3(dot(color, LUMA));\n return mix(luminanceColor, color, saturation);\n }\n\n vec3 applyContrast(vec3 color, vec3 contrast) {\n return (color - vec3(0.18)) * contrast + vec3(0.18);\n }\n\n vec3 applyGamma(vec3 color, vec3 gammaValue) {\n return pow(max(color, vec3(0.0)), vec3(1.0) / max(gammaValue, vec3(1e-4)));\n }\n\n vec3 applyGain(vec3 color, vec3 gainValue) {\n return color * gainValue;\n }\n\n vec3 applyOffset(vec3 color, vec3 offsetValue) {\n return color + offsetValue;\n }\n\n vec3 applyGrade(vec3 color, vec3 saturation, vec3 contrast, vec3 gammaValue, vec3 gainValue, vec3 offsetValue) {\n color = applySaturation(color, saturation);\n color = applyContrast(color, contrast);\n color = applyGamma(color, gammaValue);\n color = applyGain(color, gainValue);\n color = applyOffset(color, offsetValue);\n return max(color, vec3(0.0));\n }\n\n vec3 applyToneMappingMode(vec3 color) {\n if (toneMappingMode == 1) return LinearToneMapping(color);\n if (toneMappingMode == 2) return ReinhardToneMapping(color);\n if (toneMappingMode == 3) return CineonToneMapping(color);\n if (toneMappingMode == 4) return ACESFilmicToneMapping(color);\n if (toneMappingMode == 6) return AgXToneMapping(color);\n if (toneMappingMode == 7) return NeutralToneMapping(color);\n return color;\n }\n\n void main() {\n vec3 color = texture2D(tDiffuse, vUv).rgb;\n\n if (whiteBalanceEnabled) {\n color *= whiteBalanceScale;\n }\n\n if (colorTintEnabled) {\n color = mix(color, color * colorTint, clamp(colorTintIntensity, 0.0, 1.0));\n }\n\n if (colorGradingEnabled) {\n float shadowLimit = clamp(shadowsMax, 0.0, 0.98);\n float highlightLimit = clamp(max(highlightsMin, shadowLimit + 0.02), 0.02, 1.0);\n float luminance = clamp(dot(color, LUMA), 0.0, 1.0);\n\n float shadowTransition = max(0.02, min(0.25, shadowLimit + 0.05));\n float highlightTransition = max(0.02, min(0.25, (1.0 - highlightLimit) + 0.05));\n\n float shadowWeight = 1.0 - smoothstep(shadowLimit, min(1.0, shadowLimit + shadowTransition), luminance);\n float highlightWeight = smoothstep(max(0.0, highlightLimit - highlightTransition), highlightLimit, luminance);\n float midtoneWeight = clamp(1.0 - shadowWeight - highlightWeight, 0.0, 1.0);\n\n vec3 saturation = globalSaturation;\n vec3 contrast = globalContrast;\n vec3 gammaValue = globalGamma;\n vec3 gainValue = globalGain;\n vec3 offsetValue = globalOffset;\n\n saturation *= mix(vec3(1.0), shadowsSaturation, shadowWeight);\n saturation *= mix(vec3(1.0), midtonesSaturation, midtoneWeight);\n saturation *= mix(vec3(1.0), highlightsSaturation, highlightWeight);\n\n contrast *= mix(vec3(1.0), shadowsContrast, shadowWeight);\n contrast *= mix(vec3(1.0), midtonesContrast, midtoneWeight);\n contrast *= mix(vec3(1.0), highlightsContrast, highlightWeight);\n\n gammaValue *= mix(vec3(1.0), shadowsGamma, shadowWeight);\n gammaValue *= mix(vec3(1.0), midtonesGamma, midtoneWeight);\n gammaValue *= mix(vec3(1.0), highlightsGamma, highlightWeight);\n\n gainValue *= mix(vec3(1.0), shadowsGain, shadowWeight);\n gainValue *= mix(vec3(1.0), midtonesGain, midtoneWeight);\n gainValue *= mix(vec3(1.0), highlightsGain, highlightWeight);\n\n offsetValue += shadowsOffset * shadowWeight;\n offsetValue += midtonesOffset * midtoneWeight;\n offsetValue += highlightsOffset * highlightWeight;\n\n color = applyGrade(color, saturation, contrast, gammaValue, gainValue, offsetValue);\n }\n\n if (toneMappingEnabled) {\n color = applyToneMappingMode(color);\n }\n\n if (vignetteEnabled) {\n float d = distance(vUv, vec2(0.5));\n float offset = 0.2;\n float vignette = smoothstep(0.8, offset * 0.799, d * (vignetteIntensity + offset));\n color *= vignette;\n }\n\n gl_FragColor = vec4(color, 1.0);\n }\n "});const t=this.material;t.toneMapped=!1,t.depthWrite=!1,t.depthTest=!1}set vignetteEnabled(t){this.uniforms.vignetteEnabled.value=t}get vignetteEnabled(){return this.uniforms.vignetteEnabled.value}set whiteBalanceEnabled(t){this.uniforms.whiteBalanceEnabled.value=t}get whiteBalanceEnabled(){return this.uniforms.whiteBalanceEnabled.value}set whiteBalanceScale(t){this.setVec3Uniform("whiteBalanceScale",t)}get whiteBalanceScale(){return this.getVec3Uniform("whiteBalanceScale")}set vignetteIntensity(t){this.uniforms.vignetteIntensity.value=t}get vignetteIntensity(){return this.uniforms.vignetteIntensity.value}set colorTintEnabled(t){this.uniforms.colorTintEnabled.value=t}get colorTintEnabled(){return this.uniforms.colorTintEnabled.value}set colorTint(t){this.setVec3Uniform("colorTint",t)}get colorTint(){return(new t).setFromVector3(this.getVec3Uniform("colorTint"))}set colorTintIntensity(t){this.uniforms.colorTintIntensity.value=t}get colorTintIntensity(){return this.uniforms.colorTintIntensity.value}set colorGradingEnabled(t){this.uniforms.colorGradingEnabled.value=t}get colorGradingEnabled(){return this.uniforms.colorGradingEnabled.value}set toneMapping(t){this.uniforms.toneMappingMode.value=t??n}get toneMapping(){return this.uniforms.toneMappingMode.value}set toneMappingEnabled(t){this.uniforms.toneMappingEnabled.value=t}get toneMappingEnabled(){return this.uniforms.toneMappingEnabled.value}set toneMappingExposure(t){this.uniforms.toneMappingExposure.value=t}get toneMappingExposure(){return this.uniforms.toneMappingExposure.value}set globalSaturation(t){this.setVec3Uniform("globalSaturation",t)}get globalSaturation(){return this.getVec3Uniform("globalSaturation")}set globalContrast(t){this.setVec3Uniform("globalContrast",t)}get globalContrast(){return this.getVec3Uniform("globalContrast")}set globalGamma(t){this.setVec3Uniform("globalGamma",t)}get globalGamma(){return this.getVec3Uniform("globalGamma")}set globalGain(t){this.setVec3Uniform("globalGain",t)}get globalGain(){return this.getVec3Uniform("globalGain")}set globalOffset(t){this.setVec3Uniform("globalOffset",t)}get globalOffset(){return this.getVec3Uniform("globalOffset")}set shadowsSaturation(t){this.setVec3Uniform("shadowsSaturation",t)}get shadowsSaturation(){return this.getVec3Uniform("shadowsSaturation")}set shadowsContrast(t){this.setVec3Uniform("shadowsContrast",t)}get shadowsContrast(){return this.getVec3Uniform("shadowsContrast")}set shadowsGamma(t){this.setVec3Uniform("shadowsGamma",t)}get shadowsGamma(){return this.getVec3Uniform("shadowsGamma")}set shadowsGain(t){this.setVec3Uniform("shadowsGain",t)}get shadowsGain(){return this.getVec3Uniform("shadowsGain")}set shadowsOffset(t){this.setVec3Uniform("shadowsOffset",t)}get shadowsOffset(){return this.getVec3Uniform("shadowsOffset")}set shadowsMax(t){this.uniforms.shadowsMax.value=t}get shadowsMax(){return this.uniforms.shadowsMax.value}set midtonesSaturation(t){this.setVec3Uniform("midtonesSaturation",t)}get midtonesSaturation(){return this.getVec3Uniform("midtonesSaturation")}set midtonesContrast(t){this.setVec3Uniform("midtonesContrast",t)}get midtonesContrast(){return this.getVec3Uniform("midtonesContrast")}set midtonesGamma(t){this.setVec3Uniform("midtonesGamma",t)}get midtonesGamma(){return this.getVec3Uniform("midtonesGamma")}set midtonesGain(t){this.setVec3Uniform("midtonesGain",t)}get midtonesGain(){return this.getVec3Uniform("midtonesGain")}set midtonesOffset(t){this.setVec3Uniform("midtonesOffset",t)}get midtonesOffset(){return this.getVec3Uniform("midtonesOffset")}set highlightsSaturation(t){this.setVec3Uniform("highlightsSaturation",t)}get highlightsSaturation(){return this.getVec3Uniform("highlightsSaturation")}set highlightsContrast(t){this.setVec3Uniform("highlightsContrast",t)}get highlightsContrast(){return this.getVec3Uniform("highlightsContrast")}set highlightsGamma(t){this.setVec3Uniform("highlightsGamma",t)}get highlightsGamma(){return this.getVec3Uniform("highlightsGamma")}set highlightsGain(t){this.setVec3Uniform("highlightsGain",t)}get highlightsGain(){return this.getVec3Uniform("highlightsGain")}set highlightsOffset(t){this.setVec3Uniform("highlightsOffset",t)}get highlightsOffset(){return this.getVec3Uniform("highlightsOffset")}set highlightsMin(t){this.uniforms.highlightsMin.value=t}get highlightsMin(){return this.uniforms.highlightsMin.value}setVec3Uniform(n,e){const i=this.uniforms[n].value;e instanceof t?i.set(e.r,e.g,e.b):i.copy(e)}getVec3Uniform(t){return this.uniforms[t].value}}/*
|
|
1
|
+
import{Color as t,NoToneMapping as n,Vector3 as e}from"three";import{ShaderPass as i}from"three-stdlib";import{createPlaceholderTexture as a}from"../utils/three/placeholder-texture.js";export class ColorPass extends i{constructor(){super({uniforms:{tDiffuse:{value:a()},whiteBalanceEnabled:{value:!1},whiteBalanceScale:{value:new e(1,1,1)},vignetteEnabled:{value:!1},vignetteIntensity:{value:.5},colorTintEnabled:{value:!1},colorTint:{value:new e(1,1,1)},colorTintIntensity:{value:0},colorGradingEnabled:{value:!1},toneMappingMode:{value:n},toneMappingEnabled:{value:!1},toneMappingExposure:{value:1},globalSaturation:{value:new e(1,1,1)},globalContrast:{value:new e(1,1,1)},globalGamma:{value:new e(1,1,1)},globalGain:{value:new e(1,1,1)},globalOffset:{value:new e(0,0,0)},shadowsSaturation:{value:new e(1,1,1)},shadowsContrast:{value:new e(1,1,1)},shadowsGamma:{value:new e(1,1,1)},shadowsGain:{value:new e(1,1,1)},shadowsOffset:{value:new e(0,0,0)},shadowsMax:{value:.09},midtonesSaturation:{value:new e(1,1,1)},midtonesContrast:{value:new e(1,1,1)},midtonesGamma:{value:new e(1,1,1)},midtonesGain:{value:new e(1,1,1)},midtonesOffset:{value:new e(0,0,0)},highlightsSaturation:{value:new e(1,1,1)},highlightsContrast:{value:new e(1,1,1)},highlightsGamma:{value:new e(1,1,1)},highlightsGain:{value:new e(1,1,1)},highlightsOffset:{value:new e(0,0,0)},highlightsMin:{value:.5}},vertexShader:"\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ",fragmentShader:"\n uniform sampler2D tDiffuse;\n uniform bool whiteBalanceEnabled;\n uniform vec3 whiteBalanceScale;\n uniform bool vignetteEnabled;\n uniform float vignetteIntensity;\n uniform bool colorTintEnabled;\n uniform vec3 colorTint;\n uniform float colorTintIntensity;\n uniform bool colorGradingEnabled;\n uniform int toneMappingMode;\n uniform bool toneMappingEnabled;\n uniform vec3 globalSaturation;\n uniform vec3 globalContrast;\n uniform vec3 globalGamma;\n uniform vec3 globalGain;\n uniform vec3 globalOffset;\n uniform vec3 shadowsSaturation;\n uniform vec3 shadowsContrast;\n uniform vec3 shadowsGamma;\n uniform vec3 shadowsGain;\n uniform vec3 shadowsOffset;\n uniform float shadowsMax;\n uniform vec3 midtonesSaturation;\n uniform vec3 midtonesContrast;\n uniform vec3 midtonesGamma;\n uniform vec3 midtonesGain;\n uniform vec3 midtonesOffset;\n uniform vec3 highlightsSaturation;\n uniform vec3 highlightsContrast;\n uniform vec3 highlightsGamma;\n uniform vec3 highlightsGain;\n uniform vec3 highlightsOffset;\n uniform float highlightsMin;\n\n varying vec2 vUv;\n\n #include <tonemapping_pars_fragment>\n\n const vec3 LUMA = vec3(0.2126, 0.7152, 0.0722);\n\n vec3 applySaturation(vec3 color, vec3 saturation) {\n vec3 luminanceColor = vec3(dot(color, LUMA));\n return mix(luminanceColor, color, saturation);\n }\n\n vec3 applyContrast(vec3 color, vec3 contrast) {\n return (color - vec3(0.18)) * contrast + vec3(0.18);\n }\n\n vec3 applyGamma(vec3 color, vec3 gammaValue) {\n return pow(max(color, vec3(0.0)), vec3(1.0) / max(gammaValue, vec3(1e-4)));\n }\n\n vec3 applyGain(vec3 color, vec3 gainValue) {\n return color * gainValue;\n }\n\n vec3 applyOffset(vec3 color, vec3 offsetValue) {\n return color + offsetValue;\n }\n\n vec3 applyGrade(vec3 color, vec3 saturation, vec3 contrast, vec3 gammaValue, vec3 gainValue, vec3 offsetValue) {\n color = applySaturation(color, saturation);\n color = applyContrast(color, contrast);\n color = applyGamma(color, gammaValue);\n color = applyGain(color, gainValue);\n color = applyOffset(color, offsetValue);\n return max(color, vec3(0.0));\n }\n\n vec3 applyToneMappingMode(vec3 color) {\n if (toneMappingMode == 1) return LinearToneMapping(color);\n if (toneMappingMode == 2) return ReinhardToneMapping(color);\n if (toneMappingMode == 3) return CineonToneMapping(color);\n if (toneMappingMode == 4) return ACESFilmicToneMapping(color);\n if (toneMappingMode == 6) return AgXToneMapping(color);\n if (toneMappingMode == 7) return NeutralToneMapping(color);\n return color;\n }\n\n void main() {\n vec3 color = texture2D(tDiffuse, vUv).rgb;\n\n if (whiteBalanceEnabled) {\n color *= whiteBalanceScale;\n }\n\n if (colorTintEnabled) {\n color = mix(color, color * colorTint, clamp(colorTintIntensity, 0.0, 1.0));\n }\n\n if (colorGradingEnabled) {\n float shadowLimit = clamp(shadowsMax, 0.0, 0.98);\n float highlightLimit = clamp(max(highlightsMin, shadowLimit + 0.02), 0.02, 1.0);\n float luminance = clamp(dot(color, LUMA), 0.0, 1.0);\n\n float shadowTransition = max(0.02, min(0.25, shadowLimit + 0.05));\n float highlightTransition = max(0.02, min(0.25, (1.0 - highlightLimit) + 0.05));\n\n float shadowWeight = 1.0 - smoothstep(shadowLimit, min(1.0, shadowLimit + shadowTransition), luminance);\n float highlightWeight = smoothstep(max(0.0, highlightLimit - highlightTransition), highlightLimit, luminance);\n float midtoneWeight = clamp(1.0 - shadowWeight - highlightWeight, 0.0, 1.0);\n\n vec3 saturation = globalSaturation;\n vec3 contrast = globalContrast;\n vec3 gammaValue = globalGamma;\n vec3 gainValue = globalGain;\n vec3 offsetValue = globalOffset;\n\n saturation *= mix(vec3(1.0), shadowsSaturation, shadowWeight);\n saturation *= mix(vec3(1.0), midtonesSaturation, midtoneWeight);\n saturation *= mix(vec3(1.0), highlightsSaturation, highlightWeight);\n\n contrast *= mix(vec3(1.0), shadowsContrast, shadowWeight);\n contrast *= mix(vec3(1.0), midtonesContrast, midtoneWeight);\n contrast *= mix(vec3(1.0), highlightsContrast, highlightWeight);\n\n gammaValue *= mix(vec3(1.0), shadowsGamma, shadowWeight);\n gammaValue *= mix(vec3(1.0), midtonesGamma, midtoneWeight);\n gammaValue *= mix(vec3(1.0), highlightsGamma, highlightWeight);\n\n gainValue *= mix(vec3(1.0), shadowsGain, shadowWeight);\n gainValue *= mix(vec3(1.0), midtonesGain, midtoneWeight);\n gainValue *= mix(vec3(1.0), highlightsGain, highlightWeight);\n\n offsetValue += shadowsOffset * shadowWeight;\n offsetValue += midtonesOffset * midtoneWeight;\n offsetValue += highlightsOffset * highlightWeight;\n\n color = applyGrade(color, saturation, contrast, gammaValue, gainValue, offsetValue);\n }\n\n if (toneMappingEnabled) {\n color = applyToneMappingMode(color);\n }\n\n if (vignetteEnabled) {\n float d = distance(vUv, vec2(0.5));\n float offset = 0.2;\n float vignette = smoothstep(0.8, offset * 0.799, d * (vignetteIntensity + offset));\n color *= vignette;\n }\n\n gl_FragColor = vec4(color, 1.0);\n }\n "});const t=this.material;t.toneMapped=!1,t.depthWrite=!1,t.depthTest=!1}set vignetteEnabled(t){this.uniforms.vignetteEnabled.value=t}get vignetteEnabled(){return this.uniforms.vignetteEnabled.value}set whiteBalanceEnabled(t){this.uniforms.whiteBalanceEnabled.value=t}get whiteBalanceEnabled(){return this.uniforms.whiteBalanceEnabled.value}set whiteBalanceScale(t){this.setVec3Uniform("whiteBalanceScale",t)}get whiteBalanceScale(){return this.getVec3Uniform("whiteBalanceScale")}set vignetteIntensity(t){this.uniforms.vignetteIntensity.value=t}get vignetteIntensity(){return this.uniforms.vignetteIntensity.value}set colorTintEnabled(t){this.uniforms.colorTintEnabled.value=t}get colorTintEnabled(){return this.uniforms.colorTintEnabled.value}set colorTint(t){this.setVec3Uniform("colorTint",t)}get colorTint(){return(new t).setFromVector3(this.getVec3Uniform("colorTint"))}set colorTintIntensity(t){this.uniforms.colorTintIntensity.value=t}get colorTintIntensity(){return this.uniforms.colorTintIntensity.value}set colorGradingEnabled(t){this.uniforms.colorGradingEnabled.value=t}get colorGradingEnabled(){return this.uniforms.colorGradingEnabled.value}set toneMapping(t){this.uniforms.toneMappingMode.value=t??n}get toneMapping(){return this.uniforms.toneMappingMode.value}set toneMappingEnabled(t){this.uniforms.toneMappingEnabled.value=t}get toneMappingEnabled(){return this.uniforms.toneMappingEnabled.value}set toneMappingExposure(t){this.uniforms.toneMappingExposure.value=t}get toneMappingExposure(){return this.uniforms.toneMappingExposure.value}set globalSaturation(t){this.setVec3Uniform("globalSaturation",t)}get globalSaturation(){return this.getVec3Uniform("globalSaturation")}set globalContrast(t){this.setVec3Uniform("globalContrast",t)}get globalContrast(){return this.getVec3Uniform("globalContrast")}set globalGamma(t){this.setVec3Uniform("globalGamma",t)}get globalGamma(){return this.getVec3Uniform("globalGamma")}set globalGain(t){this.setVec3Uniform("globalGain",t)}get globalGain(){return this.getVec3Uniform("globalGain")}set globalOffset(t){this.setVec3Uniform("globalOffset",t)}get globalOffset(){return this.getVec3Uniform("globalOffset")}set shadowsSaturation(t){this.setVec3Uniform("shadowsSaturation",t)}get shadowsSaturation(){return this.getVec3Uniform("shadowsSaturation")}set shadowsContrast(t){this.setVec3Uniform("shadowsContrast",t)}get shadowsContrast(){return this.getVec3Uniform("shadowsContrast")}set shadowsGamma(t){this.setVec3Uniform("shadowsGamma",t)}get shadowsGamma(){return this.getVec3Uniform("shadowsGamma")}set shadowsGain(t){this.setVec3Uniform("shadowsGain",t)}get shadowsGain(){return this.getVec3Uniform("shadowsGain")}set shadowsOffset(t){this.setVec3Uniform("shadowsOffset",t)}get shadowsOffset(){return this.getVec3Uniform("shadowsOffset")}set shadowsMax(t){this.uniforms.shadowsMax.value=t}get shadowsMax(){return this.uniforms.shadowsMax.value}set midtonesSaturation(t){this.setVec3Uniform("midtonesSaturation",t)}get midtonesSaturation(){return this.getVec3Uniform("midtonesSaturation")}set midtonesContrast(t){this.setVec3Uniform("midtonesContrast",t)}get midtonesContrast(){return this.getVec3Uniform("midtonesContrast")}set midtonesGamma(t){this.setVec3Uniform("midtonesGamma",t)}get midtonesGamma(){return this.getVec3Uniform("midtonesGamma")}set midtonesGain(t){this.setVec3Uniform("midtonesGain",t)}get midtonesGain(){return this.getVec3Uniform("midtonesGain")}set midtonesOffset(t){this.setVec3Uniform("midtonesOffset",t)}get midtonesOffset(){return this.getVec3Uniform("midtonesOffset")}set highlightsSaturation(t){this.setVec3Uniform("highlightsSaturation",t)}get highlightsSaturation(){return this.getVec3Uniform("highlightsSaturation")}set highlightsContrast(t){this.setVec3Uniform("highlightsContrast",t)}get highlightsContrast(){return this.getVec3Uniform("highlightsContrast")}set highlightsGamma(t){this.setVec3Uniform("highlightsGamma",t)}get highlightsGamma(){return this.getVec3Uniform("highlightsGamma")}set highlightsGain(t){this.setVec3Uniform("highlightsGain",t)}get highlightsGain(){return this.getVec3Uniform("highlightsGain")}set highlightsOffset(t){this.setVec3Uniform("highlightsOffset",t)}get highlightsOffset(){return this.getVec3Uniform("highlightsOffset")}set highlightsMin(t){this.uniforms.highlightsMin.value=t}get highlightsMin(){return this.uniforms.highlightsMin.value}setVec3Uniform(n,e){const i=this.uniforms[n].value;e instanceof t?i.set(e.r,e.g,e.b):i.copy(e)}getVec3Uniform(t){return this.uniforms[t].value}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/rendering.d.ts
CHANGED
|
@@ -256,8 +256,10 @@ export declare class RenderingView {
|
|
|
256
256
|
loop(onFrame: (deltaTime: number) => any, showStats?: boolean): void;
|
|
257
257
|
private gBufferCachedMaterials;
|
|
258
258
|
private gBufferCachedVisibility;
|
|
259
|
+
private gBufferCachedOnBeforeRender;
|
|
259
260
|
private applyGBufferMaterials;
|
|
260
261
|
private unapplyGBufferMaterials;
|
|
262
|
+
private applyGBufferShadowUniformUpdater;
|
|
261
263
|
initTextures(scene?: THREE.Scene): void;
|
|
262
264
|
private _initiatedMaterialTextures;
|
|
263
265
|
private _initiatedTextures;
|