@mml-io/3d-web-client-core 0.21.5 → 0.22.0

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.
@@ -59,6 +59,7 @@ export declare class CameraManager {
59
59
  private easeOutExpo;
60
60
  updateAspect(aspect: number): void;
61
61
  recomputeFoV(immediately?: boolean): void;
62
+ isFlyCameraOn(): boolean;
62
63
  toggleFlyCamera(): void;
63
64
  get activeCamera(): PerspectiveCamera;
64
65
  update(): void;
@@ -12,6 +12,38 @@ import { CharacterModelLoader } from "./CharacterModelLoader";
12
12
  import { CharacterState } from "./CharacterState";
13
13
  import { LocalController } from "./LocalController";
14
14
  import { RemoteController } from "./RemoteController";
15
+ type SpawnPosition = {
16
+ x: number;
17
+ y: number;
18
+ z: number;
19
+ };
20
+ type SpawnPositionVariance = {
21
+ x: number;
22
+ y: number;
23
+ z: number;
24
+ };
25
+ type RespawnTrigger = {
26
+ minX: number;
27
+ maxX: number;
28
+ minY: number;
29
+ maxY: number;
30
+ minZ: number;
31
+ maxZ: number;
32
+ };
33
+ export type SpawnConfiguration = {
34
+ spawnPosition?: Partial<SpawnPosition>;
35
+ spawnPositionVariance?: Partial<SpawnPositionVariance>;
36
+ spawnYRotation?: number;
37
+ respawnTrigger?: Partial<RespawnTrigger>;
38
+ enableRespawnButton?: boolean;
39
+ };
40
+ export type SpawnConfigurationState = {
41
+ spawnPosition: SpawnPosition;
42
+ spawnPositionVariance: SpawnPositionVariance;
43
+ spawnYRotation: number;
44
+ respawnTrigger: RespawnTrigger;
45
+ enableRespawnButton: boolean;
46
+ };
15
47
  export type CharacterManagerConfig = {
16
48
  composer: Composer;
17
49
  characterModelLoader: CharacterModelLoader;
@@ -23,6 +55,7 @@ export type CharacterManagerConfig = {
23
55
  remoteUserStates: Map<number, CharacterState>;
24
56
  sendUpdate: (update: CharacterState) => void;
25
57
  animationConfig: AnimationConfig;
58
+ spawnConfiguration: SpawnConfigurationState;
26
59
  characterResolve: (clientId: number) => {
27
60
  username: string;
28
61
  characterDescription: CharacterDescription;
@@ -43,6 +76,7 @@ export declare class CharacterManager {
43
76
  private lastUpdateSentTime;
44
77
  constructor(config: CharacterManagerConfig);
45
78
  spawnLocalCharacter(id: number, username: string, characterDescription: CharacterDescription, spawnPosition?: Vector3, spawnRotation?: Euler): void;
79
+ createRespawnButton(): HTMLDivElement;
46
80
  setupTweakPane(tweakPane: TweakPane): void;
47
81
  spawnRemoteCharacter(id: number, username: string, characterDescription: CharacterDescription, spawnPosition?: Vector3, spawnRotation?: Euler): void;
48
82
  getLocalCharacterPositionAndRotation(): PositionAndRotation;
@@ -53,3 +87,4 @@ export declare class CharacterManager {
53
87
  respawnIfPresent(id: number): void;
54
88
  update(): void;
55
89
  }
90
+ export {};
@@ -5,6 +5,7 @@ import { KeyInputManager } from "../input/KeyInputManager";
5
5
  import { VirtualJoystick } from "../input/VirtualJoystick";
6
6
  import { TimeManager } from "../time/TimeManager";
7
7
  import { Character } from "./Character";
8
+ import { SpawnConfigurationState } from "./CharacterManager";
8
9
  import { CharacterState } from "./CharacterState";
9
10
  export type LocalControllerConfig = {
10
11
  id: number;
@@ -14,6 +15,7 @@ export type LocalControllerConfig = {
14
15
  virtualJoystick?: VirtualJoystick;
15
16
  cameraManager: CameraManager;
16
17
  timeManager: TimeManager;
18
+ spawnConfiguration: SpawnConfigurationState;
17
19
  };
18
20
  export declare class LocalController {
19
21
  private config;
@@ -50,7 +52,6 @@ export declare class LocalController {
50
52
  private vectorDown;
51
53
  private rotationOffset;
52
54
  private azimuthalAngle;
53
- private tempMatrix;
54
55
  private tempSegment;
55
56
  private tempQuaternion;
56
57
  private tempEuler;
@@ -71,7 +72,14 @@ export declare class LocalController {
71
72
  jumpReleased: boolean;
72
73
  networkState: CharacterState;
73
74
  private controlState;
75
+ private minimumX;
76
+ private maximumX;
77
+ private minimumY;
78
+ private maximumY;
79
+ private minimumZ;
80
+ private maximumZ;
74
81
  constructor(config: LocalControllerConfig);
82
+ updateSpawnConfig(spawnConfig: SpawnConfigurationState): void;
75
83
  update(): void;
76
84
  private getTargetAnimation;
77
85
  private updateRotationOffset;
@@ -86,5 +94,5 @@ export declare class LocalController {
86
94
  position: Vector3;
87
95
  } | null;
88
96
  private updateNetworkState;
89
- private resetPosition;
97
+ resetPosition(): void;
90
98
  }
@@ -26,7 +26,7 @@ export declare class CollisionsManager {
26
26
  private collisionTrigger;
27
27
  private previouslyCollidingElements;
28
28
  constructor(scene: Scene);
29
- raycastFirst(ray: Ray): [number, Vector3, CollisionMeshState] | null;
29
+ raycastFirst(ray: Ray, maximumDistance?: number | null): [number, Vector3, CollisionMeshState, Vector3] | null;
30
30
  private createCollisionMeshState;
31
31
  addMeshesGroup(group: Group, mElement?: MElement): void;
32
32
  updateMeshesGroup(group: Group): void;
package/build/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { CameraManager } from "./camera/CameraManager";
2
2
  export { CharacterDescription, AnimationConfig } from "./character/Character";
3
- export { CharacterManager } from "./character/CharacterManager";
3
+ export { CharacterManager, SpawnConfiguration, SpawnConfigurationState, } from "./character/CharacterManager";
4
4
  export * from "./character/url-position";
5
5
  export * from "./helpers/math-helpers";
6
6
  export { CharacterModelLoader } from "./character/CharacterModelLoader";
package/build/index.js CHANGED
@@ -431,6 +431,9 @@ var CameraManager = class {
431
431
  this.fov = this.targetFOV;
432
432
  }
433
433
  }
434
+ isFlyCameraOn() {
435
+ return this.isMainCameraActive === false && this.orbitControls.enabled === true;
436
+ }
434
437
  toggleFlyCamera() {
435
438
  this.isMainCameraActive = !this.isMainCameraActive;
436
439
  this.orbitControls.enabled = !this.isMainCameraActive;
@@ -1530,10 +1533,11 @@ var Character = class extends Group {
1530
1533
  };
1531
1534
 
1532
1535
  // src/character/CharacterManager.ts
1536
+ import { radToDeg } from "@mml-io/mml-web";
1533
1537
  import { Euler as Euler2, Group as Group2, Quaternion as Quaternion5, Vector3 as Vector39 } from "three";
1534
1538
 
1535
1539
  // src/character/LocalController.ts
1536
- import { Euler, Line3, Matrix4, Quaternion as Quaternion2, Ray, Raycaster as Raycaster2, Vector3 as Vector36 } from "three";
1540
+ import { Euler, Line3, Quaternion as Quaternion2, Ray, Raycaster as Raycaster2, Vector3 as Vector36 } from "three";
1537
1541
 
1538
1542
  // src/tweakpane/blades/characterControlsFolder.ts
1539
1543
  var characterControllerValues = {
@@ -1752,7 +1756,6 @@ var LocalController = class {
1752
1756
  this.vectorDown = new Vector36(0, -1, 0);
1753
1757
  this.rotationOffset = 0;
1754
1758
  this.azimuthalAngle = 0;
1755
- this.tempMatrix = new Matrix4();
1756
1759
  this.tempSegment = new Line3();
1757
1760
  this.tempQuaternion = new Quaternion2();
1758
1761
  this.tempEuler = new Euler();
@@ -1779,6 +1782,45 @@ var LocalController = class {
1779
1782
  rotation: { quaternionY: 0, quaternionW: 1 },
1780
1783
  state: 0 /* idle */
1781
1784
  };
1785
+ this.minimumX = this.config.spawnConfiguration.respawnTrigger.minX;
1786
+ this.maximumX = this.config.spawnConfiguration.respawnTrigger.maxX;
1787
+ this.minimumY = this.config.spawnConfiguration.respawnTrigger.minY;
1788
+ this.maximumY = this.config.spawnConfiguration.respawnTrigger.maxY;
1789
+ this.minimumZ = this.config.spawnConfiguration.respawnTrigger.minZ;
1790
+ this.maximumZ = this.config.spawnConfiguration.respawnTrigger.maxZ;
1791
+ const maxAbsSpawnX = Math.abs(this.config.spawnConfiguration.spawnPosition.x) + Math.abs(this.config.spawnConfiguration.spawnPositionVariance.x);
1792
+ const maxAbsSpawnY = Math.abs(this.config.spawnConfiguration.spawnPosition.y) + Math.abs(this.config.spawnConfiguration.spawnPositionVariance.y);
1793
+ const maxAbsSpawnZ = Math.abs(this.config.spawnConfiguration.spawnPosition.z) + Math.abs(this.config.spawnConfiguration.spawnPositionVariance.z);
1794
+ if (Math.abs(this.minimumX) < maxAbsSpawnX || Math.abs(this.maximumX) < maxAbsSpawnX) {
1795
+ this.minimumX = -maxAbsSpawnX - 1;
1796
+ this.maximumX = maxAbsSpawnX + 1;
1797
+ console.warn(
1798
+ "The respawnTrigger X values are out of the bounds of the spawnPosition + spawnPositionVariance. Please check your respawnTrigger config."
1799
+ );
1800
+ }
1801
+ if (Math.abs(this.minimumY) < maxAbsSpawnY || Math.abs(this.maximumY) < maxAbsSpawnY) {
1802
+ this.minimumY = -maxAbsSpawnY - 1;
1803
+ this.maximumY = maxAbsSpawnY + 1;
1804
+ console.warn(
1805
+ "The respawnTrigger Y values are out of the bounds of the spawnPosition + spawnPositionVariance. Please check your respawnTrigger config."
1806
+ );
1807
+ }
1808
+ if (Math.abs(this.minimumZ) < maxAbsSpawnZ) {
1809
+ this.minimumZ = -maxAbsSpawnZ - 1;
1810
+ this.maximumZ = maxAbsSpawnZ + 1;
1811
+ console.warn(
1812
+ "The respawnTrigger Z values are out of the bounds of the spawnPosition + spawnPositionVariance. Please check your respawnTrigger config."
1813
+ );
1814
+ }
1815
+ }
1816
+ updateSpawnConfig(spawnConfig) {
1817
+ this.config.spawnConfiguration = spawnConfig;
1818
+ this.minimumX = spawnConfig.respawnTrigger.minX;
1819
+ this.maximumX = spawnConfig.respawnTrigger.maxX;
1820
+ this.minimumY = spawnConfig.respawnTrigger.minY;
1821
+ this.maximumY = spawnConfig.respawnTrigger.maxY;
1822
+ this.minimumZ = spawnConfig.respawnTrigger.minZ;
1823
+ this.maximumZ = spawnConfig.respawnTrigger.maxZ;
1782
1824
  }
1783
1825
  update() {
1784
1826
  var _a, _b;
@@ -1805,7 +1847,13 @@ var LocalController = class {
1805
1847
  i
1806
1848
  );
1807
1849
  }
1808
- if (this.config.character.position.y < -100) {
1850
+ const outOfBounds = this.config.character.position.x < this.minimumX || // left
1851
+ this.config.character.position.x > this.maximumX || // right
1852
+ this.config.character.position.z < this.minimumZ || // back
1853
+ this.config.character.position.z > this.maximumZ || // front
1854
+ this.config.character.position.y < this.minimumY || // down
1855
+ this.config.character.position.y > this.maximumY;
1856
+ if (outOfBounds) {
1809
1857
  this.resetPosition();
1810
1858
  }
1811
1859
  this.updateNetworkState();
@@ -1949,13 +1997,25 @@ var LocalController = class {
1949
1997
  this.config.character.rotation.setFromQuaternion(asQuaternion);
1950
1998
  }
1951
1999
  }
1952
- this.config.character.updateMatrixWorld();
1953
2000
  const avatarSegment = this.tempSegment;
1954
2001
  avatarSegment.copy(this.capsuleInfo.segment);
1955
- avatarSegment.start.applyMatrix4(this.config.character.matrixWorld).applyMatrix4(this.tempMatrix);
1956
- avatarSegment.end.applyMatrix4(this.config.character.matrixWorld).applyMatrix4(this.tempMatrix);
2002
+ avatarSegment.start.add(this.config.character.position);
2003
+ avatarSegment.end.add(this.config.character.position);
1957
2004
  const positionBeforeCollisions = this.tempVector.copy(avatarSegment.start);
1958
2005
  this.config.collisionsManager.applyColliders(avatarSegment, this.capsuleInfo.radius);
2006
+ const capsuleLength = this.capsuleInfo.segment.end.y - this.capsuleInfo.segment.start.y + this.capsuleInfo.radius * 2;
2007
+ this.rayCaster.set(avatarSegment.start, this.vectorDown);
2008
+ const endIgnoreLength = 0.1;
2009
+ this.rayCaster.ray.origin.y += -this.capsuleInfo.radius + capsuleLength - endIgnoreLength;
2010
+ const withinCapsuleRayHit = this.config.collisionsManager.raycastFirst(
2011
+ this.rayCaster.ray,
2012
+ capsuleLength - endIgnoreLength * 2
2013
+ );
2014
+ if (withinCapsuleRayHit !== null) {
2015
+ const rayHitPosition = withinCapsuleRayHit[3];
2016
+ avatarSegment.start.copy(rayHitPosition);
2017
+ avatarSegment.start.y += this.capsuleInfo.radius;
2018
+ }
1959
2019
  this.config.character.position.copy(avatarSegment.start);
1960
2020
  const deltaCollisionPosition = avatarSegment.start.sub(positionBeforeCollisions);
1961
2021
  this.characterOnGround = deltaCollisionPosition.y > 0;
@@ -2052,8 +2112,34 @@ var LocalController = class {
2052
2112
  };
2053
2113
  }
2054
2114
  resetPosition() {
2115
+ const randomWithVariance = (value, variance) => {
2116
+ const min = value - variance;
2117
+ const max = value + variance;
2118
+ return Math.random() * (max - min) + min;
2119
+ };
2120
+ this.characterVelocity.x = 0;
2055
2121
  this.characterVelocity.y = 0;
2056
- this.config.character.position.y = 3;
2122
+ this.characterVelocity.z = 0;
2123
+ this.config.character.position.set(
2124
+ randomWithVariance(
2125
+ this.config.spawnConfiguration.spawnPosition.x,
2126
+ this.config.spawnConfiguration.spawnPositionVariance.x
2127
+ ),
2128
+ randomWithVariance(
2129
+ this.config.spawnConfiguration.spawnPosition.y,
2130
+ this.config.spawnConfiguration.spawnPositionVariance.y
2131
+ ),
2132
+ randomWithVariance(
2133
+ this.config.spawnConfiguration.spawnPosition.z,
2134
+ this.config.spawnConfiguration.spawnPositionVariance.z
2135
+ )
2136
+ );
2137
+ const respawnRotation = new Euler(
2138
+ 0,
2139
+ -this.config.spawnConfiguration.spawnYRotation * (Math.PI / 180),
2140
+ 0
2141
+ );
2142
+ this.config.character.rotation.set(respawnRotation.x, respawnRotation.y, respawnRotation.z);
2057
2143
  this.characterOnGround = false;
2058
2144
  this.doubleJumpUsed = false;
2059
2145
  this.jumpReleased = true;
@@ -2091,8 +2177,13 @@ var RemoteController = class {
2091
2177
  }
2092
2178
  updateFromNetwork(clientUpdate) {
2093
2179
  const { position, rotation, state } = clientUpdate;
2094
- this.config.character.position.lerp(new Vector37(position.x, position.y, position.z), 0.15);
2095
- const rotationQuaternion = new Quaternion3(0, rotation.quaternionY, 0, rotation.quaternionW);
2180
+ const distanceSquared = this.config.character.position.distanceToSquared(position);
2181
+ if (distanceSquared > 5 * 5) {
2182
+ this.config.character.position.copy(position);
2183
+ } else {
2184
+ this.config.character.position.lerp(new Vector37(position.x, position.y, position.z), 0.15);
2185
+ }
2186
+ const rotationQuaternion = tempQuaternion.set(0, rotation.quaternionY, 0, rotation.quaternionW);
2096
2187
  this.config.character.quaternion.slerp(rotationQuaternion, 0.6);
2097
2188
  if (state !== this.currentAnimation) {
2098
2189
  this.currentAnimation = state;
@@ -2172,13 +2263,40 @@ var CharacterManager = class {
2172
2263
  keyInputManager: this.config.keyInputManager,
2173
2264
  virtualJoystick: this.config.virtualJoystick,
2174
2265
  cameraManager: this.config.cameraManager,
2175
- timeManager: this.config.timeManager
2266
+ timeManager: this.config.timeManager,
2267
+ spawnConfiguration: this.config.spawnConfiguration
2176
2268
  });
2177
2269
  this.localCharacter.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
2178
2270
  this.localCharacter.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);
2179
2271
  this.group.add(character);
2180
2272
  this.localCharacterSpawned = true;
2181
2273
  }
2274
+ createRespawnButton() {
2275
+ const respawnButton = document.createElement("div");
2276
+ respawnButton.className = "respawn-button";
2277
+ respawnButton.textContent = "RESPAWN";
2278
+ respawnButton.addEventListener("click", () => {
2279
+ this.localController.resetPosition();
2280
+ });
2281
+ respawnButton.style.position = "absolute";
2282
+ respawnButton.style.top = "14px";
2283
+ respawnButton.style.left = "8px";
2284
+ respawnButton.style.zIndex = "102";
2285
+ respawnButton.style.backgroundColor = "rgba(0, 0, 0, 0.7)";
2286
+ respawnButton.style.color = "#ffffff";
2287
+ respawnButton.style.borderRadius = "8px";
2288
+ respawnButton.style.border = "1px solid rgba(255, 255, 255, 0.21)";
2289
+ respawnButton.style.height = "22px";
2290
+ respawnButton.style.padding = "8px";
2291
+ respawnButton.style.cursor = "pointer";
2292
+ respawnButton.style.fontSize = "12px";
2293
+ respawnButton.style.fontFamily = "Helvetica, sans-serif";
2294
+ respawnButton.style.userSelect = "none";
2295
+ respawnButton.style.display = "flex";
2296
+ respawnButton.style.alignItems = "center";
2297
+ respawnButton.style.justifyContent = "center";
2298
+ return respawnButton;
2299
+ }
2182
2300
  setupTweakPane(tweakPane) {
2183
2301
  tweakPane.setupCharacterController(this.localController);
2184
2302
  }
@@ -2204,9 +2322,14 @@ var CharacterManager = class {
2204
2322
  }
2205
2323
  getLocalCharacterPositionAndRotation() {
2206
2324
  if (this.localCharacter && this.localCharacter && this.localCharacter) {
2325
+ const rotation = this.localCharacter.rotation;
2207
2326
  return {
2208
2327
  position: this.localCharacter.position,
2209
- rotation: this.localCharacter.rotation
2328
+ rotation: {
2329
+ x: radToDeg(rotation.x),
2330
+ y: radToDeg(rotation.y),
2331
+ z: radToDeg(rotation.z)
2332
+ }
2210
2333
  };
2211
2334
  }
2212
2335
  return {
@@ -2442,8 +2565,17 @@ var KeyInputManager = class {
2442
2565
  return this.keys.get(key) || false;
2443
2566
  }
2444
2567
  createKeyBinding(key, callback) {
2568
+ if (this.bindings.has(key)) {
2569
+ return;
2570
+ }
2445
2571
  this.bindings.set(key, callback);
2446
2572
  }
2573
+ removeKeyBinding(key) {
2574
+ if (!this.bindings.has(key)) {
2575
+ return;
2576
+ }
2577
+ this.bindings.delete(key);
2578
+ }
2447
2579
  isMovementKeyPressed() {
2448
2580
  return ["w" /* W */, "a" /* A */, "s" /* S */, "d" /* D */].some((key) => this.isKeyPressed(key));
2449
2581
  }
@@ -5395,9 +5527,6 @@ var Composer = class {
5395
5527
  this.renderer.toneMapping = rendererValues.toneMapping;
5396
5528
  this.renderer.toneMappingExposure = rendererValues.exposure;
5397
5529
  this.environmentConfiguration = environmentConfiguration;
5398
- this.updateSkyboxAndEnvValues();
5399
- this.updateAmbientLightValues();
5400
- this.setFog();
5401
5530
  this.effectComposer = new EffectComposer2(this.renderer, {
5402
5531
  frameBufferType: HalfFloatType2
5403
5532
  });
@@ -5436,6 +5565,9 @@ var Composer = class {
5436
5565
  if ((_a = environmentConfiguration == null ? void 0 : environmentConfiguration.postProcessing) == null ? void 0 : _a.bloomIntensity) {
5437
5566
  extrasValues.bloom = environmentConfiguration.postProcessing.bloomIntensity;
5438
5567
  }
5568
+ this.updateSkyboxAndEnvValues();
5569
+ this.updateAmbientLightValues();
5570
+ this.updateFogValues();
5439
5571
  this.bloomEffect = new BloomEffect({
5440
5572
  intensity: extrasValues.bloom
5441
5573
  });
@@ -5525,7 +5657,9 @@ var Composer = class {
5525
5657
  }
5526
5658
  this.updateSkyboxAndEnvValues();
5527
5659
  this.updateAmbientLightValues();
5660
+ this.updateBloomValues();
5528
5661
  this.updateSunValues();
5662
+ this.updateFogValues();
5529
5663
  }
5530
5664
  setupTweakPane(tweakPane) {
5531
5665
  tweakPane.setupRenderPane(
@@ -5758,6 +5892,21 @@ var Composer = class {
5758
5892
  (_i = this.sun) == null ? void 0 : _i.setPolarAngle(this.environmentConfiguration.sun.polarAngle * (Math.PI / 180));
5759
5893
  }
5760
5894
  }
5895
+ updateFogValues() {
5896
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
5897
+ if (typeof ((_b = (_a = this.environmentConfiguration) == null ? void 0 : _a.fog) == null ? void 0 : _b.fogNear) === "number") {
5898
+ envValues.fog.fogNear = this.environmentConfiguration.fog.fogNear;
5899
+ }
5900
+ if (typeof ((_d = (_c = this.environmentConfiguration) == null ? void 0 : _c.fog) == null ? void 0 : _d.fogFar) === "number") {
5901
+ envValues.fog.fogFar = this.environmentConfiguration.fog.fogFar;
5902
+ }
5903
+ if (typeof ((_g = (_f = (_e = this.environmentConfiguration) == null ? void 0 : _e.fog) == null ? void 0 : _f.fogColor) == null ? void 0 : _g.r) === "number" && typeof ((_j = (_i = (_h = this.environmentConfiguration) == null ? void 0 : _h.fog) == null ? void 0 : _i.fogColor) == null ? void 0 : _j.g) === "number" && typeof ((_m = (_l = (_k = this.environmentConfiguration) == null ? void 0 : _k.fog) == null ? void 0 : _l.fogColor) == null ? void 0 : _m.b) === "number") {
5904
+ envValues.fog.fogColor.r = this.environmentConfiguration.fog.fogColor.r;
5905
+ envValues.fog.fogColor.g = this.environmentConfiguration.fog.fogColor.g;
5906
+ envValues.fog.fogColor.b = this.environmentConfiguration.fog.fogColor.b;
5907
+ }
5908
+ this.setFog();
5909
+ }
5761
5910
  updateSkyboxAndEnvValues() {
5762
5911
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
5763
5912
  if (typeof ((_b = (_a = this.environmentConfiguration) == null ? void 0 : _a.envMap) == null ? void 0 : _b.intensity) === "number") {
@@ -5781,6 +5930,13 @@ var Composer = class {
5781
5930
  this.updateSkyboxRotation();
5782
5931
  }
5783
5932
  }
5933
+ updateBloomValues() {
5934
+ var _a, _b;
5935
+ if (typeof ((_b = (_a = this.environmentConfiguration) == null ? void 0 : _a.postProcessing) == null ? void 0 : _b.bloomIntensity) === "number") {
5936
+ extrasValues.bloom = this.environmentConfiguration.postProcessing.bloomIntensity;
5937
+ }
5938
+ this.bloomEffect.intensity = extrasValues.bloom;
5939
+ }
5784
5940
  updateAmbientLightValues() {
5785
5941
  var _a, _b;
5786
5942
  if (typeof ((_b = (_a = this.environmentConfiguration) == null ? void 0 : _a.ambientLight) == null ? void 0 : _b.intensity) === "number") {
@@ -5809,7 +5965,7 @@ var Composer = class {
5809
5965
 
5810
5966
  // src/time/TimeManager.ts
5811
5967
  import { Clock } from "three";
5812
- var TimeManager = class {
5968
+ var _TimeManager = class _TimeManager {
5813
5969
  constructor() {
5814
5970
  this.clock = new Clock();
5815
5971
  this.roundMagnitude = 2e5;
@@ -5827,8 +5983,12 @@ var TimeManager = class {
5827
5983
  this.fps = 0;
5828
5984
  this.averageFPS = 0;
5829
5985
  }
5986
+ // 100ms
5830
5987
  update() {
5831
5988
  this.rawDeltaTime = this.clock.getDelta();
5989
+ if (this.rawDeltaTime > _TimeManager.maxDeltaTime) {
5990
+ this.rawDeltaTime = _TimeManager.maxDeltaTime;
5991
+ }
5832
5992
  this.frame++;
5833
5993
  this.time += this.rawDeltaTime;
5834
5994
  this.deltaTimes.push(this.rawDeltaTime);
@@ -5851,6 +6011,8 @@ var TimeManager = class {
5851
6011
  }
5852
6012
  }
5853
6013
  };
6014
+ _TimeManager.maxDeltaTime = 0.1;
6015
+ var TimeManager = _TimeManager;
5854
6016
 
5855
6017
  // src/collisions/CollisionsManager.ts
5856
6018
  import { MMLCollisionTrigger } from "@mml-io/mml-web";
@@ -5927,10 +6089,11 @@ var CollisionsManager = class {
5927
6089
  this.scene = scene;
5928
6090
  this.collisionTrigger = MMLCollisionTrigger.init();
5929
6091
  }
5930
- raycastFirst(ray) {
6092
+ raycastFirst(ray, maximumDistance = null) {
5931
6093
  let minimumDistance = null;
5932
6094
  let minimumHit = null;
5933
- let minimumNormal = new Vector316();
6095
+ let minimumNormal = null;
6096
+ let minimumPoint = null;
5934
6097
  for (const [, collisionMeshState] of this.collisionMeshState) {
5935
6098
  this.tempRay.copy(ray).applyMatrix4(this.tempMatrix.copy(collisionMeshState.matrix).invert());
5936
6099
  const hit = collisionMeshState.meshBVH.raycastFirst(this.tempRay, DoubleSide);
@@ -5939,17 +6102,24 @@ var CollisionsManager = class {
5939
6102
  this.tempSegment.end.copy(hit.point);
5940
6103
  this.tempSegment.applyMatrix4(collisionMeshState.matrix);
5941
6104
  const dist = this.tempSegment.distance();
5942
- if (minimumDistance === null || dist < minimumDistance) {
6105
+ if ((maximumDistance === null || dist < maximumDistance) && (minimumDistance === null || dist < minimumDistance)) {
5943
6106
  minimumDistance = dist;
5944
6107
  minimumHit = collisionMeshState;
6108
+ if (minimumNormal === null) {
6109
+ minimumNormal = new Vector316();
6110
+ }
6111
+ if (minimumPoint === null) {
6112
+ minimumPoint = new Vector316();
6113
+ }
5945
6114
  minimumNormal = (hit.normal ? minimumNormal.copy(hit.normal) : minimumNormal).applyQuaternion(this.tempQuaternion.setFromRotationMatrix(collisionMeshState.matrix)).normalize();
6115
+ minimumPoint = minimumPoint.copy(hit.point).applyMatrix4(collisionMeshState.matrix);
5946
6116
  }
5947
6117
  }
5948
6118
  }
5949
- if (minimumDistance === null || minimumNormal === null || minimumHit === null) {
6119
+ if (minimumDistance === null || minimumNormal === null || minimumHit === null || minimumPoint === null) {
5950
6120
  return null;
5951
6121
  }
5952
- return [minimumDistance, minimumNormal, minimumHit];
6122
+ return [minimumDistance, minimumNormal, minimumHit, minimumPoint];
5953
6123
  }
5954
6124
  createCollisionMeshState(group, trackCollisions) {
5955
6125
  const geometries = [];