@mml-io/3d-web-client-core 0.0.0-experimental-19bc481-20241121 → 0.0.0-experimental-16d1b9c-20241218

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.
@@ -5,6 +5,9 @@ export declare class CameraManager {
5
5
  private targetElement;
6
6
  private collisionsManager;
7
7
  readonly camera: PerspectiveCamera;
8
+ private flyCamera;
9
+ private orbitControls;
10
+ private isMainCameraActive;
8
11
  initialDistance: number;
9
12
  minDistance: number;
10
13
  maxDistance: number;
@@ -37,6 +40,8 @@ export declare class CameraManager {
37
40
  private lerpDuration;
38
41
  private activePointers;
39
42
  constructor(targetElement: HTMLElement, collisionsManager: CollisionsManager, initialPhi?: number, initialTheta?: number);
43
+ private createEventHandlers;
44
+ private disposeEventHandlers;
40
45
  private preventDefaultAndStopPropagation;
41
46
  setupTweakPane(tweakPane: TweakPane): void;
42
47
  private onPointerDown;
@@ -54,6 +59,8 @@ export declare class CameraManager {
54
59
  private easeOutExpo;
55
60
  updateAspect(aspect: number): void;
56
61
  recomputeFoV(immediately?: boolean): void;
62
+ toggleFlyCamera(): void;
63
+ get activeCamera(): PerspectiveCamera;
57
64
  update(): void;
58
65
  hasActiveInput(): boolean;
59
66
  }
package/build/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export * from "./character/url-position";
5
5
  export * from "./helpers/math-helpers";
6
6
  export { CharacterModelLoader } from "./character/CharacterModelLoader";
7
7
  export { CharacterState, AnimationState } from "./character/CharacterState";
8
- export { KeyInputManager } from "./input/KeyInputManager";
8
+ export { Key, KeyInputManager } from "./input/KeyInputManager";
9
9
  export { VirtualJoystick } from "./input/VirtualJoystick";
10
10
  export { MMLCompositionScene } from "./mml/MMLCompositionScene";
11
11
  export { TweakPane } from "./tweakpane/TweakPane";
package/build/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/camera/CameraManager.ts
2
2
  import { PerspectiveCamera, Raycaster, Vector3 as Vector32 } from "three";
3
+ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
3
4
 
4
5
  // src/helpers/math-helpers.ts
5
6
  import { Quaternion, Vector3, Vector4 } from "three";
@@ -218,6 +219,7 @@ var CameraManager = class {
218
219
  constructor(targetElement, collisionsManager, initialPhi = Math.PI / 2, initialTheta = -Math.PI / 2) {
219
220
  this.targetElement = targetElement;
220
221
  this.collisionsManager = collisionsManager;
222
+ this.isMainCameraActive = true;
221
223
  this.initialDistance = camValues.initialDistance;
222
224
  this.minDistance = camValues.minDistance;
223
225
  this.maxDistance = camValues.maxDistance;
@@ -248,19 +250,36 @@ var CameraManager = class {
248
250
  this.targetPhi = this.phi;
249
251
  this.theta = initialTheta;
250
252
  this.targetTheta = this.theta;
251
- this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);
253
+ const aspect = window.innerWidth / window.innerHeight;
254
+ this.camera = new PerspectiveCamera(this.fov, aspect, 0.1, 400);
252
255
  this.camera.position.set(0, 1.4, -this.initialDistance);
256
+ this.camera.name = "MainCamera";
257
+ this.flyCamera = new PerspectiveCamera(this.initialFOV, aspect, 0.1, 400);
258
+ this.flyCamera.name = "FlyCamera";
259
+ this.flyCamera.position.copy(this.camera.position);
260
+ this.flyCamera.name = "FlyCamera";
261
+ this.orbitControls = new OrbitControls(this.flyCamera, this.targetElement);
262
+ this.orbitControls.enableDamping = true;
263
+ this.orbitControls.dampingFactor = 0.05;
264
+ this.orbitControls.enablePan = true;
265
+ this.orbitControls.enabled = false;
253
266
  this.rayCaster = new Raycaster();
267
+ this.createEventHandlers();
268
+ }
269
+ createEventHandlers() {
254
270
  this.eventHandlerCollection = EventHandlerCollection.create([
255
- [targetElement, "pointerdown", this.onPointerDown.bind(this)],
256
- [targetElement, "gesturestart", this.preventDefaultAndStopPropagation.bind(this)],
271
+ [this.targetElement, "pointerdown", this.onPointerDown.bind(this)],
272
+ [this.targetElement, "gesturestart", this.preventDefaultAndStopPropagation.bind(this)],
273
+ [this.targetElement, "wheel", this.onMouseWheel.bind(this)],
274
+ [this.targetElement, "contextmenu", this.onContextMenu.bind(this)],
257
275
  [document, "pointerup", this.onPointerUp.bind(this)],
258
276
  [document, "pointercancel", this.onPointerUp.bind(this)],
259
- [document, "pointermove", this.onPointerMove.bind(this)],
260
- [targetElement, "wheel", this.onMouseWheel.bind(this)],
261
- [targetElement, "contextmenu", this.onContextMenu.bind(this)]
277
+ [document, "pointermove", this.onPointerMove.bind(this)]
262
278
  ]);
263
279
  }
280
+ disposeEventHandlers() {
281
+ this.eventHandlerCollection.clear();
282
+ }
264
283
  preventDefaultAndStopPropagation(evt) {
265
284
  evt.preventDefault();
266
285
  evt.stopPropagation();
@@ -391,7 +410,8 @@ var CameraManager = class {
391
410
  }
392
411
  }
393
412
  dispose() {
394
- this.eventHandlerCollection.clear();
413
+ this.disposeEventHandlers();
414
+ this.orbitControls.dispose();
395
415
  document.body.style.cursor = "";
396
416
  }
397
417
  easeOutExpo(x) {
@@ -399,6 +419,7 @@ var CameraManager = class {
399
419
  }
400
420
  updateAspect(aspect) {
401
421
  this.camera.aspect = aspect;
422
+ this.flyCamera.aspect = aspect;
402
423
  }
403
424
  recomputeFoV(immediately = false) {
404
425
  this.targetFOV = remap(
@@ -412,7 +433,31 @@ var CameraManager = class {
412
433
  this.fov = this.targetFOV;
413
434
  }
414
435
  }
436
+ toggleFlyCamera() {
437
+ this.isMainCameraActive = !this.isMainCameraActive;
438
+ this.orbitControls.enabled = !this.isMainCameraActive;
439
+ if (!this.isMainCameraActive) {
440
+ this.updateAspect(window.innerWidth / window.innerHeight);
441
+ this.flyCamera.position.copy(this.camera.position);
442
+ this.flyCamera.rotation.copy(this.camera.rotation);
443
+ const target = new Vector32();
444
+ this.camera.getWorldDirection(target);
445
+ target.multiplyScalar(this.targetDistance).add(this.camera.position);
446
+ this.orbitControls.target.copy(target);
447
+ this.orbitControls.update();
448
+ this.disposeEventHandlers();
449
+ } else {
450
+ this.createEventHandlers();
451
+ }
452
+ }
453
+ get activeCamera() {
454
+ return this.isMainCameraActive ? this.camera : this.flyCamera;
455
+ }
415
456
  update() {
457
+ if (!this.isMainCameraActive) {
458
+ this.orbitControls.update();
459
+ return;
460
+ }
416
461
  if (this.isLerping && this.lerpFactor < 1) {
417
462
  this.lerpFactor += 0.01 / this.lerpDuration;
418
463
  this.lerpFactor = Math.min(1, this.lerpFactor);
@@ -1666,17 +1711,17 @@ var LocalController = class {
1666
1711
  }
1667
1712
  }
1668
1713
  updateAzimuthalAngle() {
1669
- const camToModelDistance = this.config.cameraManager.camera.position.distanceTo(
1714
+ const camToModelDistance = this.config.cameraManager.activeCamera.position.distanceTo(
1670
1715
  this.config.character.position
1671
1716
  );
1672
1717
  const isCameraFirstPerson = camToModelDistance < 2;
1673
1718
  if (isCameraFirstPerson) {
1674
- const cameraForward = this.tempVector.set(0, 0, 1).applyQuaternion(this.config.cameraManager.camera.quaternion);
1719
+ const cameraForward = this.tempVector.set(0, 0, 1).applyQuaternion(this.config.cameraManager.activeCamera.quaternion);
1675
1720
  this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);
1676
1721
  } else {
1677
1722
  this.azimuthalAngle = Math.atan2(
1678
- this.config.cameraManager.camera.position.x - this.config.character.position.x,
1679
- this.config.cameraManager.camera.position.z - this.config.character.position.z
1723
+ this.config.cameraManager.activeCamera.position.x - this.config.character.position.x,
1724
+ this.config.cameraManager.activeCamera.position.z - this.config.character.position.z
1680
1725
  );
1681
1726
  }
1682
1727
  }
@@ -2221,11 +2266,22 @@ var CharacterModelLoader = class {
2221
2266
  };
2222
2267
 
2223
2268
  // src/input/KeyInputManager.ts
2269
+ var Key = /* @__PURE__ */ ((Key2) => {
2270
+ Key2["W"] = "w";
2271
+ Key2["A"] = "a";
2272
+ Key2["S"] = "s";
2273
+ Key2["D"] = "d";
2274
+ Key2["SHIFT"] = "shift";
2275
+ Key2["SPACE"] = " ";
2276
+ Key2["C"] = "c";
2277
+ return Key2;
2278
+ })(Key || {});
2224
2279
  var KeyInputManager = class {
2225
2280
  constructor(shouldCaptureKeyPress = () => true) {
2226
2281
  this.shouldCaptureKeyPress = shouldCaptureKeyPress;
2227
2282
  this.keys = /* @__PURE__ */ new Map();
2228
2283
  this.eventHandlerCollection = new EventHandlerCollection();
2284
+ this.bindings = /* @__PURE__ */ new Map();
2229
2285
  this.eventHandlerCollection.add(document, "keydown", this.onKeyDown.bind(this));
2230
2286
  this.eventHandlerCollection.add(document, "keyup", this.onKeyUp.bind(this));
2231
2287
  this.eventHandlerCollection.add(window, "blur", this.handleUnfocus.bind(this));
@@ -2247,10 +2303,16 @@ var KeyInputManager = class {
2247
2303
  }
2248
2304
  onKeyUp(event) {
2249
2305
  this.keys.set(event.key.toLowerCase(), false);
2306
+ if (this.bindings.has(event.key.toLowerCase())) {
2307
+ this.bindings.get(event.key.toLowerCase())();
2308
+ }
2250
2309
  }
2251
2310
  isKeyPressed(key) {
2252
2311
  return this.keys.get(key) || false;
2253
2312
  }
2313
+ createKeyBinding(key, callback) {
2314
+ this.bindings.set(key, callback);
2315
+ }
2254
2316
  isMovementKeyPressed() {
2255
2317
  return ["w" /* W */, "a" /* A */, "s" /* S */, "d" /* D */].some((key) => this.isKeyPressed(key));
2256
2318
  }
@@ -2287,6 +2349,7 @@ var KeyInputManager = class {
2287
2349
  }
2288
2350
  dispose() {
2289
2351
  this.eventHandlerCollection.clear();
2352
+ this.bindings.clear();
2290
2353
  }
2291
2354
  };
2292
2355
 
@@ -5152,7 +5215,7 @@ var N8SSAOPass = class extends Pass {
5152
5215
  var Composer = class {
5153
5216
  constructor({
5154
5217
  scene,
5155
- camera,
5218
+ cameraManager,
5156
5219
  spawnSun = false,
5157
5220
  environmentConfiguration
5158
5221
  }) {
@@ -5166,8 +5229,8 @@ var Composer = class {
5166
5229
  this.sun = null;
5167
5230
  var _a, _b;
5168
5231
  this.scene = scene;
5232
+ this.cameraManager = cameraManager;
5169
5233
  this.postPostScene = new Scene4();
5170
- this.camera = camera;
5171
5234
  this.spawnSun = spawnSun;
5172
5235
  this.renderer = new WebGLRenderer4({
5173
5236
  powerPreference: "high-performance",
@@ -5187,14 +5250,14 @@ var Composer = class {
5187
5250
  this.effectComposer = new EffectComposer2(this.renderer, {
5188
5251
  frameBufferType: HalfFloatType2
5189
5252
  });
5190
- this.renderPass = new RenderPass(this.scene, this.camera);
5191
- this.normalPass = new NormalPass2(this.scene, this.camera);
5253
+ this.renderPass = new RenderPass(this.scene, this.cameraManager.activeCamera);
5254
+ this.normalPass = new NormalPass2(this.scene, this.cameraManager.activeCamera);
5192
5255
  this.normalPass.enabled = ppssaoValues.enabled;
5193
5256
  this.normalTextureEffect = new TextureEffect({
5194
5257
  blendFunction: BlendFunction2.SKIP,
5195
5258
  texture: this.normalPass.texture
5196
5259
  });
5197
- this.ppssaoEffect = new SSAOEffect2(this.camera, this.normalPass.texture, {
5260
+ this.ppssaoEffect = new SSAOEffect2(this.cameraManager.activeCamera, this.normalPass.texture, {
5198
5261
  blendFunction: ppssaoValues.blendFunction,
5199
5262
  distanceScaling: ppssaoValues.distanceScaling,
5200
5263
  depthAwareUpsampling: ppssaoValues.depthAwareUpsampling,
@@ -5212,7 +5275,11 @@ var Composer = class {
5212
5275
  worldProximityThreshold: ppssaoValues.worldProximityThreshold,
5213
5276
  worldProximityFalloff: ppssaoValues.worldProximityFalloff
5214
5277
  });
5215
- this.ppssaoPass = new EffectPass2(this.camera, this.ppssaoEffect, this.normalTextureEffect);
5278
+ this.ppssaoPass = new EffectPass2(
5279
+ this.cameraManager.activeCamera,
5280
+ this.ppssaoEffect,
5281
+ this.normalTextureEffect
5282
+ );
5216
5283
  this.ppssaoPass.enabled = ppssaoValues.enabled;
5217
5284
  this.fxaaEffect = new FXAAEffect();
5218
5285
  if ((_a = environmentConfiguration == null ? void 0 : environmentConfiguration.postProcessing) == null ? void 0 : _a.bloomIntensity) {
@@ -5221,7 +5288,12 @@ var Composer = class {
5221
5288
  this.bloomEffect = new BloomEffect({
5222
5289
  intensity: extrasValues.bloom
5223
5290
  });
5224
- this.n8aopass = new N8SSAOPass(this.scene, this.camera, this.width, this.height);
5291
+ this.n8aopass = new N8SSAOPass(
5292
+ this.scene,
5293
+ this.cameraManager.activeCamera,
5294
+ this.width,
5295
+ this.height
5296
+ );
5225
5297
  this.n8aopass.configuration.aoRadius = n8ssaoValues.aoRadius;
5226
5298
  this.n8aopass.configuration.distanceFalloff = n8ssaoValues.distanceFalloff;
5227
5299
  this.n8aopass.configuration.intensity = n8ssaoValues.intensity;
@@ -5234,8 +5306,8 @@ var Composer = class {
5234
5306
  this.n8aopass.configuration.denoiseSamples = n8ssaoValues.denoiseSamples;
5235
5307
  this.n8aopass.configuration.denoiseRadius = n8ssaoValues.denoiseRadius;
5236
5308
  this.n8aopass.enabled = n8ssaoValues.enabled;
5237
- this.fxaaPass = new EffectPass2(this.camera, this.fxaaEffect);
5238
- this.bloomPass = new EffectPass2(this.camera, this.bloomEffect);
5309
+ this.fxaaPass = new EffectPass2(this.cameraManager.activeCamera, this.fxaaEffect);
5310
+ this.bloomPass = new EffectPass2(this.cameraManager.activeCamera, this.bloomEffect);
5239
5311
  this.toneMappingEffect = new ToneMappingEffect({
5240
5312
  mode: toneMappingValues.mode,
5241
5313
  resolution: toneMappingValues.resolution,
@@ -5250,7 +5322,7 @@ var Composer = class {
5250
5322
  edgeDetectionMode: EdgeDetectionMode.COLOR,
5251
5323
  predicationMode: PredicationMode.DEPTH
5252
5324
  });
5253
- this.toneMappingPass = new EffectPass2(this.camera, this.toneMappingEffect);
5325
+ this.toneMappingPass = new EffectPass2(this.cameraManager.activeCamera, this.toneMappingEffect);
5254
5326
  this.toneMappingPass.enabled = rendererValues.toneMapping === 5 || rendererValues.toneMapping === 0 ? true : false;
5255
5327
  this.bcsPass = new ShaderPass(this.bcs, "tDiffuse");
5256
5328
  this.bcs.uniforms.brightness.value = bcsValues.brightness;
@@ -5259,7 +5331,7 @@ var Composer = class {
5259
5331
  this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, "tDiffuse");
5260
5332
  this.gaussGrainEffect.uniforms.amount.value = extrasValues.grain;
5261
5333
  this.gaussGrainEffect.uniforms.alpha.value = 1;
5262
- this.smaaPass = new EffectPass2(this.camera, this.smaaEffect);
5334
+ this.smaaPass = new EffectPass2(this.cameraManager.activeCamera, this.smaaEffect);
5263
5335
  this.effectComposer.addPass(this.renderPass);
5264
5336
  if (ppssaoValues.enabled) {
5265
5337
  this.effectComposer.addPass(this.normalPass);
@@ -5346,8 +5418,8 @@ var Composer = class {
5346
5418
  }
5347
5419
  this.width = parentElement.clientWidth;
5348
5420
  this.height = parentElement.clientHeight;
5349
- this.camera.aspect = this.width / this.height;
5350
- this.camera.updateProjectionMatrix();
5421
+ this.cameraManager.activeCamera.aspect = this.width / this.height;
5422
+ this.cameraManager.activeCamera.updateProjectionMatrix();
5351
5423
  this.renderer.setPixelRatio(window.devicePixelRatio);
5352
5424
  this.resolution.set(
5353
5425
  this.width * window.devicePixelRatio,
@@ -5376,11 +5448,12 @@ var Composer = class {
5376
5448
  }
5377
5449
  render(timeManager) {
5378
5450
  this.renderer.info.reset();
5451
+ this.renderPass.mainCamera = this.cameraManager.activeCamera;
5379
5452
  this.normalPass.texture.needsUpdate = true;
5380
5453
  this.gaussGrainEffect.uniforms.time.value = timeManager.time;
5381
5454
  this.effectComposer.render();
5382
5455
  this.renderer.clearDepth();
5383
- this.renderer.render(this.postPostScene, this.camera);
5456
+ this.renderer.render(this.postPostScene, this.cameraManager.activeCamera);
5384
5457
  }
5385
5458
  updateSkyboxRotation() {
5386
5459
  this.scene.backgroundRotation = new Euler3(
@@ -6196,6 +6269,7 @@ export {
6196
6269
  Composer,
6197
6270
  ErrorScreen,
6198
6271
  GroundPlane,
6272
+ Key,
6199
6273
  KeyInputManager,
6200
6274
  LoadingScreen,
6201
6275
  MMLCompositionScene,