@mml-io/3d-web-client-core 0.6.1 → 0.8.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.
package/build/index.js CHANGED
@@ -1,15 +1,22 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
-
8
1
  // src/camera/CameraManager.ts
9
2
  import { PerspectiveCamera, Raycaster, Vector3 as Vector32 } from "three";
10
3
 
11
4
  // src/helpers/math-helpers.ts
12
- import { Vector3 } from "three";
5
+ import { Quaternion, Vector3, Vector4 } from "three";
6
+ var roundToDecimalPlaces = (value, decimalPlaces) => {
7
+ const mult = 10 ** decimalPlaces;
8
+ return Math.round(value * mult) / mult;
9
+ };
10
+ var toArray = (origin, precision = 3) => {
11
+ const array = [];
12
+ array[0] = roundToDecimalPlaces(origin.x, precision);
13
+ array[1] = roundToDecimalPlaces(origin.y, precision);
14
+ array[2] = roundToDecimalPlaces(origin.z, precision);
15
+ if (origin instanceof Vector4 || origin instanceof Quaternion) {
16
+ array[3] = roundToDecimalPlaces(origin.w, precision);
17
+ }
18
+ return array;
19
+ };
13
20
  var getSpawnPositionInsideCircle = (radius, positions, id, yPos = 0) => {
14
21
  if (id > 0)
15
22
  id += 3;
@@ -47,28 +54,27 @@ function getTweakpaneActive() {
47
54
  var CameraManager = class {
48
55
  constructor(collisionsManager) {
49
56
  this.collisionsManager = collisionsManager;
50
- __publicField(this, "camera");
51
- __publicField(this, "initialDistance", 3.3);
52
- __publicField(this, "minDistance", 0.1);
53
- __publicField(this, "maxDistance", 8);
54
- __publicField(this, "initialFOV", 60);
55
- __publicField(this, "fov", this.initialFOV);
56
- __publicField(this, "minFOV", 50);
57
- __publicField(this, "maxFOV", 70);
58
- __publicField(this, "targetFOV", this.initialFOV);
59
- __publicField(this, "minPolarAngle", Math.PI * 0.25);
60
- __publicField(this, "maxPolarAngle", Math.PI * 0.95);
61
- __publicField(this, "dampingFactor", 0.091);
62
- __publicField(this, "targetDistance", this.initialDistance);
63
- __publicField(this, "distance", this.initialDistance);
64
- __publicField(this, "targetPhi", Math.PI / 2);
65
- __publicField(this, "phi", Math.PI / 2);
66
- __publicField(this, "targetTheta", -Math.PI / 2);
67
- __publicField(this, "theta", -Math.PI / 2);
68
- __publicField(this, "dragging", false);
69
- __publicField(this, "target", new Vector32(0, 1.55, 0));
70
- __publicField(this, "hadTarget", false);
71
- __publicField(this, "rayCaster");
57
+ this.initialDistance = 3.3;
58
+ this.minDistance = 0.1;
59
+ this.maxDistance = 8;
60
+ this.initialFOV = 60;
61
+ this.fov = this.initialFOV;
62
+ this.minFOV = 50;
63
+ this.maxFOV = 70;
64
+ this.targetFOV = this.initialFOV;
65
+ this.minPolarAngle = Math.PI * 0.25;
66
+ this.maxPolarAngle = Math.PI * 0.95;
67
+ this.dampingFactor = 0.091;
68
+ this.targetDistance = this.initialDistance;
69
+ this.distance = this.initialDistance;
70
+ this.desiredDistance = this.initialDistance;
71
+ this.targetPhi = Math.PI / 2;
72
+ this.phi = Math.PI / 2;
73
+ this.targetTheta = -Math.PI / 2;
74
+ this.theta = -Math.PI / 2;
75
+ this.dragging = false;
76
+ this.target = new Vector32(0, 1.55, 0);
77
+ this.hadTarget = false;
72
78
  this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);
73
79
  this.camera.position.set(0, 1.4, -this.initialDistance);
74
80
  this.rayCaster = new Raycaster();
@@ -106,6 +112,7 @@ var CameraManager = class {
106
112
  this.minDistance,
107
113
  Math.min(this.maxDistance, this.targetDistance)
108
114
  );
115
+ this.desiredDistance = this.targetDistance;
109
116
  }
110
117
  setTarget(target) {
111
118
  this.target.copy(target);
@@ -137,6 +144,8 @@ var CameraManager = class {
137
144
  if (minimumDistance !== null && minimumDistance <= cameraToPlayerDistance) {
138
145
  this.targetDistance = cameraToPlayerDistance - minimumDistance;
139
146
  this.distance = this.targetDistance;
147
+ } else {
148
+ this.targetDistance += (this.desiredDistance - this.targetDistance) * this.dampingFactor * 4;
140
149
  }
141
150
  }
142
151
  update() {
@@ -168,7 +177,7 @@ var CameraManager = class {
168
177
  };
169
178
 
170
179
  // src/character/Character.ts
171
- import { Color as Color3, Vector3 as Vector34 } from "three";
180
+ import { Color as Color3, Vector3 as Vector35 } from "three";
172
181
 
173
182
  // src/character/CharacterModel.ts
174
183
  import {
@@ -272,38 +281,110 @@ ${before}
272
281
  );
273
282
  }
274
283
 
275
- // src/tweakpane/characterSettings.ts
284
+ // src/tweakpane/blades/characterFolder.ts
276
285
  var characterValues = {
277
- material: {
278
- transmission: 1,
279
- metalness: 0.8,
280
- roughness: 0.12,
281
- ior: 1.5,
282
- thickness: 0.1,
283
- specularColor: { r: 1, g: 1, b: 1 },
284
- specularIntensity: 0.1,
285
- emissive: { r: 1, g: 1, b: 1 },
286
- emissiveIntensity: 0.1,
287
- envMapIntensity: 1,
288
- sheenColor: { r: 1, g: 1, b: 1 },
289
- sheen: 0.5,
290
- clearcoat: 0,
291
- clearcoatRoughness: 0
292
- }
286
+ transmission: 0.01,
287
+ metalness: 0.8,
288
+ roughness: 0.05,
289
+ ior: 1,
290
+ thickness: 0.1,
291
+ specularColor: { r: 1, g: 1, b: 1 },
292
+ specularIntensity: 0.1,
293
+ emissive: { r: 1, g: 1, b: 1 },
294
+ emissiveIntensity: 0.1,
295
+ envMapIntensity: 0.8,
296
+ sheenColor: { r: 1, g: 1, b: 1 },
297
+ sheen: 0.5,
298
+ clearcoat: 0,
299
+ clearcoatRoughness: 0
293
300
  };
294
301
  var characterOptions = {
295
- material: {
296
- transmission: { min: 0.01, max: 3, step: 0.01 },
297
- metalness: { min: 0, max: 1, step: 0.01 },
298
- roughness: { min: 0, max: 1, step: 0.01 },
299
- ior: { min: 0, max: 5, step: 0.01 },
300
- thickness: { min: 0, max: 1, step: 0.01 },
301
- specularIntensity: { min: 0, max: 1, step: 0.01 },
302
- emissiveIntensity: { min: 0, max: 1, step: 0.01 },
303
- envMapIntensity: { min: 0, max: 1, step: 0.01 },
304
- sheen: { min: 0, max: 1, step: 0.01 },
305
- clearcoat: { min: 0, max: 1, step: 0.01 },
306
- clearcoatRoughness: { min: 0, max: 1, step: 0.01 }
302
+ transmission: { min: 0.01, max: 3, step: 0.01 },
303
+ metalness: { min: 0, max: 1, step: 0.01 },
304
+ roughness: { min: 0, max: 1, step: 0.01 },
305
+ ior: { min: 1, max: 5, step: 0.01 },
306
+ thickness: { min: 0, max: 1, step: 0.01 },
307
+ specularIntensity: { min: 0, max: 1, step: 0.01 },
308
+ emissiveIntensity: { min: 0, max: 1, step: 0.01 },
309
+ envMapIntensity: { min: 0, max: 1, step: 0.01 },
310
+ sheen: { min: 0, max: 1, step: 0.01 },
311
+ clearcoat: { min: 0, max: 1, step: 0.01 },
312
+ clearcoatRoughness: { min: 0, max: 1, step: 0.01 }
313
+ };
314
+ var CharacterFolder = class {
315
+ constructor(parentFolder, expand = false) {
316
+ this.folder = parentFolder.addFolder({ title: "characterMaterial", expanded: expand });
317
+ this.folder.addBinding(characterValues, "transmission", characterOptions.transmission);
318
+ this.folder.addBinding(characterValues, "metalness", characterOptions.metalness);
319
+ this.folder.addBinding(characterValues, "roughness", characterOptions.roughness);
320
+ this.folder.addBinding(characterValues, "ior", characterOptions.ior);
321
+ this.folder.addBinding(characterValues, "thickness", characterOptions.thickness);
322
+ this.folder.addBinding(characterValues, "specularColor", {
323
+ color: { type: "float" }
324
+ });
325
+ this.folder.addBinding(
326
+ characterValues,
327
+ "specularIntensity",
328
+ characterOptions.specularIntensity
329
+ );
330
+ this.folder.addBinding(characterValues, "emissive", {
331
+ color: { type: "float" }
332
+ });
333
+ this.folder.addBinding(
334
+ characterValues,
335
+ "emissiveIntensity",
336
+ characterOptions.emissiveIntensity
337
+ );
338
+ this.folder.addBinding(characterValues, "envMapIntensity", characterOptions.envMapIntensity);
339
+ this.folder.addBinding(characterValues, "sheenColor", {
340
+ color: { type: "float" }
341
+ });
342
+ this.folder.addBinding(characterValues, "sheen", characterOptions.sheen);
343
+ this.folder.addBinding(characterValues, "clearcoat", characterOptions.clearcoat);
344
+ this.folder.addBinding(
345
+ characterValues,
346
+ "clearcoatRoughness",
347
+ characterOptions.clearcoatRoughness
348
+ );
349
+ }
350
+ setupChangeEvent() {
351
+ this.folder.on("change", (e) => {
352
+ const target = e.target.key;
353
+ if (!target)
354
+ return;
355
+ switch (target) {
356
+ case "specularColor": {
357
+ const value = e.value;
358
+ characterValues.specularColor = {
359
+ r: value.r,
360
+ g: value.g,
361
+ b: value.b
362
+ };
363
+ break;
364
+ }
365
+ case "emissive": {
366
+ const value = e.value;
367
+ characterValues.emissive = {
368
+ r: value.r,
369
+ g: value.g,
370
+ b: value.b
371
+ };
372
+ break;
373
+ }
374
+ case "sheenColor": {
375
+ const value = e.value;
376
+ characterValues.sheenColor = {
377
+ r: value.r,
378
+ g: value.g,
379
+ b: value.b
380
+ };
381
+ break;
382
+ }
383
+ default: {
384
+ break;
385
+ }
386
+ }
387
+ });
307
388
  }
308
389
  };
309
390
 
@@ -311,35 +392,35 @@ var characterOptions = {
311
392
  var CharacterMaterial = class extends MeshPhysicalMaterial {
312
393
  constructor() {
313
394
  super();
314
- __publicField(this, "uniforms", {});
315
- __publicField(this, "colorsCube216", []);
395
+ this.uniforms = {};
396
+ this.colorsCube216 = [];
316
397
  this.color = new Color(16777215);
317
- this.transmission = characterValues.material.transmission;
318
- this.metalness = characterValues.material.metalness;
319
- this.roughness = characterValues.material.roughness;
320
- this.ior = characterValues.material.ior;
321
- this.thickness = characterValues.material.thickness;
398
+ this.transmission = characterValues.transmission;
399
+ this.metalness = characterValues.metalness;
400
+ this.roughness = characterValues.roughness;
401
+ this.ior = characterValues.ior;
402
+ this.thickness = characterValues.thickness;
322
403
  this.specularColor = new Color().setRGB(
323
- characterValues.material.specularColor.r,
324
- characterValues.material.specularColor.g,
325
- characterValues.material.specularColor.b
404
+ characterValues.specularColor.r,
405
+ characterValues.specularColor.g,
406
+ characterValues.specularColor.b
326
407
  );
327
- this.specularIntensity = characterValues.material.specularIntensity;
408
+ this.specularIntensity = characterValues.specularIntensity;
328
409
  this.emissive = new Color().setRGB(
329
- characterValues.material.emissive.r,
330
- characterValues.material.emissive.g,
331
- characterValues.material.emissive.b
410
+ characterValues.emissive.r,
411
+ characterValues.emissive.g,
412
+ characterValues.emissive.b
332
413
  );
333
- this.emissiveIntensity = characterValues.material.emissiveIntensity;
334
- this.envMapIntensity = characterValues.material.envMapIntensity;
414
+ this.emissiveIntensity = characterValues.emissiveIntensity;
415
+ this.envMapIntensity = characterValues.envMapIntensity;
335
416
  this.sheenColor = new Color().setRGB(
336
- characterValues.material.sheenColor.r,
337
- characterValues.material.sheenColor.g,
338
- characterValues.material.sheenColor.b
417
+ characterValues.sheenColor.r,
418
+ characterValues.sheenColor.g,
419
+ characterValues.sheenColor.b
339
420
  );
340
- this.sheen = characterValues.material.sheen;
341
- this.clearcoat = characterValues.material.clearcoat;
342
- this.clearcoatRoughness = characterValues.material.clearcoatRoughness;
421
+ this.sheen = characterValues.sheen;
422
+ this.clearcoat = characterValues.clearcoat;
423
+ this.clearcoatRoughness = characterValues.clearcoatRoughness;
343
424
  this.onBeforeCompile = (shader) => {
344
425
  this.uniforms = UniformsUtils.clone(shader.uniforms);
345
426
  this.uniforms.nearClip = { value: 0.01 };
@@ -439,32 +520,32 @@ var CharacterMaterial = class extends MeshPhysicalMaterial {
439
520
  }
440
521
  }
441
522
  update() {
442
- this.transmission = characterValues.material.transmission;
443
- this.metalness = characterValues.material.metalness;
444
- this.roughness = characterValues.material.roughness;
445
- this.ior = characterValues.material.ior;
446
- this.thickness = characterValues.material.thickness;
523
+ this.transmission = characterValues.transmission;
524
+ this.metalness = characterValues.metalness;
525
+ this.roughness = characterValues.roughness;
526
+ this.ior = characterValues.ior;
527
+ this.thickness = characterValues.thickness;
447
528
  this.specularColor = new Color().setRGB(
448
- characterValues.material.specularColor.r,
449
- characterValues.material.specularColor.g,
450
- characterValues.material.specularColor.b
529
+ characterValues.specularColor.r,
530
+ characterValues.specularColor.g,
531
+ characterValues.specularColor.b
451
532
  );
452
- this.specularIntensity = characterValues.material.specularIntensity;
533
+ this.specularIntensity = characterValues.specularIntensity;
453
534
  this.emissive = new Color().setRGB(
454
- characterValues.material.emissive.r,
455
- characterValues.material.emissive.g,
456
- characterValues.material.emissive.b
535
+ characterValues.emissive.r,
536
+ characterValues.emissive.g,
537
+ characterValues.emissive.b
457
538
  );
458
- this.emissiveIntensity = characterValues.material.emissiveIntensity;
459
- this.envMapIntensity = characterValues.material.envMapIntensity;
539
+ this.emissiveIntensity = characterValues.emissiveIntensity;
540
+ this.envMapIntensity = characterValues.envMapIntensity;
460
541
  this.sheenColor = new Color().setRGB(
461
- characterValues.material.sheenColor.r,
462
- characterValues.material.sheenColor.g,
463
- characterValues.material.sheenColor.b
542
+ characterValues.sheenColor.r,
543
+ characterValues.sheenColor.g,
544
+ characterValues.sheenColor.b
464
545
  );
465
- this.sheen = characterValues.material.sheen;
466
- this.clearcoat = characterValues.material.clearcoat;
467
- this.clearcoatRoughness = characterValues.material.clearcoatRoughness;
546
+ this.sheen = characterValues.sheen;
547
+ this.clearcoat = characterValues.clearcoat;
548
+ this.clearcoatRoughness = characterValues.clearcoatRoughness;
468
549
  }
469
550
  };
470
551
 
@@ -485,7 +566,6 @@ import { GLTFLoader as ThreeGLTFLoader } from "three/examples/jsm/loaders/GLTFLo
485
566
  var CachedGLTFLoader = class extends ThreeGLTFLoader {
486
567
  constructor(manager) {
487
568
  super(manager);
488
- __publicField(this, "blobCache");
489
569
  this.blobCache = /* @__PURE__ */ new Map();
490
570
  }
491
571
  setBlobUrl(originalUrl, blobUrl) {
@@ -506,8 +586,6 @@ var CachedGLTFLoader = class extends ThreeGLTFLoader {
506
586
  };
507
587
  var LRUCache = class {
508
588
  constructor(maxSize = 100) {
509
- __publicField(this, "maxSize");
510
- __publicField(this, "cache");
511
589
  this.maxSize = maxSize;
512
590
  this.cache = /* @__PURE__ */ new Map();
513
591
  }
@@ -527,12 +605,9 @@ var LRUCache = class {
527
605
  this.cache.set(key, value);
528
606
  }
529
607
  };
530
- var _ModelLoader = class {
608
+ var _ModelLoader = class _ModelLoader {
531
609
  constructor(maxCacheSize = 100) {
532
- __publicField(this, "loadingManager");
533
- __publicField(this, "gltfLoader");
534
- __publicField(this, "modelCache");
535
- __publicField(this, "ongoingLoads", /* @__PURE__ */ new Map());
610
+ this.ongoingLoads = /* @__PURE__ */ new Map();
536
611
  this.loadingManager = new LoadingManager();
537
612
  this.gltfLoader = new CachedGLTFLoader(this.loadingManager);
538
613
  this.modelCache = new LRUCache(maxCacheSize);
@@ -594,8 +669,8 @@ var _ModelLoader = class {
594
669
  }
595
670
  }
596
671
  };
672
+ _ModelLoader.instance = null;
597
673
  var ModelLoader = _ModelLoader;
598
- __publicField(ModelLoader, "instance", null);
599
674
  var MODEL_LOADER = ModelLoader.getInstance();
600
675
  var ModelLoader_default = MODEL_LOADER;
601
676
 
@@ -604,12 +679,13 @@ var CharacterModel = class {
604
679
  constructor(characterDescription) {
605
680
  this.characterDescription = characterDescription;
606
681
  /* TODO: pick between below eager instantiation or ModelLoader.getInstance() lazy one */
607
- __publicField(this, "modelLoader", ModelLoader_default);
608
- __publicField(this, "mesh", null);
609
- __publicField(this, "material", new CharacterMaterial());
610
- __publicField(this, "animations", {});
611
- __publicField(this, "animationMixer", null);
612
- __publicField(this, "currentAnimation", 0 /* idle */);
682
+ this.modelLoader = ModelLoader_default;
683
+ this.mesh = null;
684
+ this.material = new CharacterMaterial();
685
+ this.headBone = null;
686
+ this.animations = {};
687
+ this.animationMixer = null;
688
+ this.currentAnimation = 0 /* idle */;
613
689
  }
614
690
  async init() {
615
691
  await this.loadMainMesh();
@@ -632,15 +708,19 @@ var CharacterModel = class {
632
708
  this.applyMaterialToAllSkinnedMeshes(this.material);
633
709
  }
634
710
  updateAnimation(targetAnimation, deltaTime) {
711
+ var _a;
635
712
  if (this.currentAnimation !== targetAnimation) {
636
713
  this.transitionToAnimation(targetAnimation);
637
714
  }
638
- this.animationMixer?.update(deltaTime);
715
+ (_a = this.animationMixer) == null ? void 0 : _a.update(deltaTime);
639
716
  }
640
717
  hideMaterialByMeshName(meshName) {
641
718
  if (!this.mesh)
642
719
  return;
643
720
  this.mesh.traverse((child) => {
721
+ if (child.type === "Bone" && child.name === "mixamorigHeadTop_End") {
722
+ this.headBone = child;
723
+ }
644
724
  if (child.type === "SkinnedMesh" && child.name === meshName) {
645
725
  child.material = new MeshStandardMaterial({
646
726
  color: 16711680,
@@ -724,18 +804,110 @@ var CharacterModel = class {
724
804
  }
725
805
  };
726
806
 
807
+ // src/character/CharacterSpeakingIndicator.ts
808
+ import {
809
+ CircleGeometry,
810
+ GLSL3,
811
+ Mesh as Mesh2,
812
+ RawShaderMaterial
813
+ } from "three";
814
+ var CharacterSpeakingIndicator = class {
815
+ constructor(scene) {
816
+ this.scene = scene;
817
+ this.vertexShader = /* glsl */
818
+ `
819
+ in vec3 position;
820
+ in vec2 uv;
821
+ uniform mat4 modelViewMatrix;
822
+ uniform mat4 projectionMatrix;
823
+ out vec2 vUv;
824
+ void main() {
825
+ vUv = uv;
826
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
827
+ }`;
828
+ this.fragmentShader = /* glsl */
829
+ `
830
+ precision highp float;
831
+
832
+ uniform float time;
833
+ uniform float alpha;
834
+ in vec2 vUv;
835
+ out vec4 fragColor;
836
+
837
+ const float size = 1.7;
838
+ const float distribution = 0.03;
839
+ const float speed = 0.2;
840
+ const float overdraw = 3.5;
841
+ const float shapeK = 0.25;
842
+
843
+ float sdHyperbola(vec2 p, float k, float wi) {
844
+ p = abs(p);
845
+ float k2 = k * k;
846
+ float a = p.x + p.y;
847
+ float i = 0.5 * (a - k2 / a) > wi ? -1.0 : 1.0;
848
+ float x = clamp(0.5 * (a - k2 / a), 0.0, wi);
849
+ vec2 q = vec2(x, sqrt(x * x + k2));
850
+ float s = sign(p.x * p.x - p.y * p.y + k2);
851
+ return s * length(p - q);
852
+ }
853
+
854
+ void main(void) {
855
+ vec2 uv = (vUv * 2.0 - 1.0);
856
+ float r = -(uv.x * uv.x + uv.y * uv.y);
857
+ float z = 0.5 + 0.5 * sin((r + time * speed) / distribution);
858
+ float a = clamp(smoothstep(-0.1, 0.2, size - length(uv * 2.0)), 0.0, 0.5);
859
+ float h = clamp(sdHyperbola(uv, shapeK, 1.0), 0.0, 1.0) * overdraw;
860
+ float fragAlpha = clamp(a * h, 0.0, 0.7);
861
+ fragColor = vec4(z * fragAlpha) * alpha;
862
+ }`;
863
+ this.uniforms = {
864
+ time: { value: 0 },
865
+ alpha: { value: 0 }
866
+ };
867
+ this.geometry = new CircleGeometry(0.35, 21);
868
+ this.material = new RawShaderMaterial({
869
+ vertexShader: this.vertexShader,
870
+ fragmentShader: this.fragmentShader,
871
+ uniforms: this.uniforms,
872
+ transparent: true,
873
+ glslVersion: GLSL3
874
+ });
875
+ this.mesh = new Mesh2(this.geometry, this.material);
876
+ this.currentAlpha = 0;
877
+ this.targetAlpha = 0;
878
+ this.scene.add(this.mesh);
879
+ }
880
+ setBillboarding(position, camera) {
881
+ this.mesh.position.set(position.x, position.y - 0.15, position.z);
882
+ this.mesh.lookAt(camera.position);
883
+ }
884
+ setTime(value) {
885
+ this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.06);
886
+ this.uniforms.time.value = value;
887
+ this.uniforms.alpha.value = this.currentAlpha;
888
+ }
889
+ setSpeaking(value) {
890
+ this.targetAlpha = value === true ? 1 : 0;
891
+ }
892
+ dispose() {
893
+ this.scene.remove(this.mesh);
894
+ this.mesh.material.dispose();
895
+ this.mesh.geometry.dispose();
896
+ }
897
+ };
898
+
727
899
  // src/character/CharacterTooltip.ts
728
900
  import {
729
901
  Color as Color2,
730
902
  FrontSide,
731
903
  LinearFilter as LinearFilter2,
732
- Mesh as Mesh2,
904
+ Mesh as Mesh3,
733
905
  MeshBasicMaterial as MeshBasicMaterial2,
734
906
  PlaneGeometry
735
907
  } from "three";
736
908
 
737
909
  // src/character/CanvasText.ts
738
- import * as THREE from "three";
910
+ import { Texture, LinearFilter, RGBAFormat, MeshBasicMaterial } from "three";
739
911
  function getTextAlignOffset(textAlign, width) {
740
912
  switch (textAlign) {
741
913
  case "center":
@@ -836,10 +1008,10 @@ function CanvasText(message, options) {
836
1008
  }
837
1009
  function THREECanvasTextTexture(text, options) {
838
1010
  const canvas = CanvasText(text, options);
839
- const texture = new THREE.Texture(canvas);
840
- texture.minFilter = THREE.LinearFilter;
841
- texture.magFilter = THREE.LinearFilter;
842
- texture.format = THREE.RGBAFormat;
1011
+ const texture = new Texture(canvas);
1012
+ texture.minFilter = LinearFilter;
1013
+ texture.magFilter = LinearFilter;
1014
+ texture.format = RGBAFormat;
843
1015
  texture.needsUpdate = true;
844
1016
  return { texture, width: canvas.width, height: canvas.height };
845
1017
  }
@@ -856,14 +1028,11 @@ var defaultLabelHeight = 0.125;
856
1028
  var defaultLabelCastShadows = true;
857
1029
  var CharacterTooltip = class {
858
1030
  constructor(parentModel) {
859
- __publicField(this, "geometry");
860
- __publicField(this, "material");
861
- __publicField(this, "mesh");
862
- __publicField(this, "visibleOpacity", 0.85);
863
- __publicField(this, "targetOpacity", 0);
864
- __publicField(this, "fadingSpeed", 0.02);
865
- __publicField(this, "secondsToFadeOut", 15);
866
- __publicField(this, "props", {
1031
+ this.visibleOpacity = 0.85;
1032
+ this.targetOpacity = 0;
1033
+ this.fadingSpeed = 0.02;
1034
+ this.secondsToFadeOut = 15;
1035
+ this.props = {
867
1036
  content: "",
868
1037
  alignment: defaultLabelAlignment,
869
1038
  width: defaultLabelWidth,
@@ -873,7 +1042,7 @@ var CharacterTooltip = class {
873
1042
  color: defaultLabelColor,
874
1043
  fontColor: defaultFontColor,
875
1044
  castShadows: defaultLabelCastShadows
876
- });
1045
+ };
877
1046
  this.setText = this.setText.bind(this);
878
1047
  this.material = new MeshBasicMaterial2({
879
1048
  map: null,
@@ -882,7 +1051,7 @@ var CharacterTooltip = class {
882
1051
  });
883
1052
  this.material.side = FrontSide;
884
1053
  this.geometry = new PlaneGeometry(1, 1, 1, 1);
885
- this.mesh = new Mesh2(this.geometry, this.material);
1054
+ this.mesh = new Mesh3(this.geometry, this.material);
886
1055
  this.mesh.position.set(0, 1.6, 0);
887
1056
  this.mesh.visible = false;
888
1057
  parentModel.add(this.mesh);
@@ -965,7 +1134,7 @@ var CharacterTooltip = class {
965
1134
  };
966
1135
 
967
1136
  // src/character/LocalController.ts
968
- import { Box3, Line3, Matrix4, Quaternion, Raycaster as Raycaster2, Vector3 as Vector33 } from "three";
1137
+ import { Line3, Matrix4, Quaternion as Quaternion2, Raycaster as Raycaster2, Vector3 as Vector34 } from "three";
969
1138
  var LocalController = class {
970
1139
  constructor(model, id, collisionsManager, keyInputManager, cameraManager, timeManager) {
971
1140
  this.model = model;
@@ -974,45 +1143,35 @@ var LocalController = class {
974
1143
  this.keyInputManager = keyInputManager;
975
1144
  this.cameraManager = cameraManager;
976
1145
  this.timeManager = timeManager;
977
- __publicField(this, "collisionDetectionSteps", 15);
978
- __publicField(this, "capsuleInfo", {
1146
+ this.collisionDetectionSteps = 15;
1147
+ this.capsuleInfo = {
979
1148
  radius: 0.4,
980
- segment: new Line3(new Vector33(), new Vector33(0, 1.05, 0))
981
- });
982
- __publicField(this, "maxWalkSpeed", 6);
983
- __publicField(this, "maxRunSpeed", 8.5);
984
- __publicField(this, "gravity", -42);
985
- __publicField(this, "jumpForce", 16);
986
- __publicField(this, "coyoteTimeThreshold", 70);
987
- __publicField(this, "coyoteTime", false);
988
- __publicField(this, "canJump", true);
989
- __publicField(this, "characterOnGround", false);
990
- __publicField(this, "characterWasOnGround", false);
991
- __publicField(this, "characterAirborneSince", 0);
992
- __publicField(this, "currentHeight", 0);
993
- __publicField(this, "characterVelocity", new Vector33());
994
- __publicField(this, "vectorUp", new Vector33(0, 1, 0));
995
- __publicField(this, "vectorDown", new Vector33(0, -1, 0));
996
- __publicField(this, "rotationOffset", 0);
997
- __publicField(this, "azimuthalAngle", 0);
998
- __publicField(this, "tempBox", new Box3());
999
- __publicField(this, "tempMatrix", new Matrix4());
1000
- __publicField(this, "tempSegment", new Line3());
1001
- __publicField(this, "tempVector", new Vector33());
1002
- __publicField(this, "tempVector2", new Vector33());
1003
- __publicField(this, "rayCaster", new Raycaster2());
1004
- __publicField(this, "forward");
1005
- __publicField(this, "backward");
1006
- __publicField(this, "left");
1007
- __publicField(this, "right");
1008
- __publicField(this, "run");
1009
- __publicField(this, "jump");
1010
- __publicField(this, "anyDirection");
1011
- __publicField(this, "conflictingDirections");
1012
- __publicField(this, "thirdPersonCamera", null);
1013
- __publicField(this, "speed", 0);
1014
- __publicField(this, "targetSpeed", 0);
1015
- __publicField(this, "networkState");
1149
+ segment: new Line3(new Vector34(), new Vector34(0, 1.05, 0))
1150
+ };
1151
+ this.maxWalkSpeed = 6;
1152
+ this.maxRunSpeed = 8.5;
1153
+ this.gravity = -42;
1154
+ this.jumpForce = 16;
1155
+ this.coyoteTimeThreshold = 70;
1156
+ this.coyoteTime = false;
1157
+ this.canJump = true;
1158
+ this.characterOnGround = false;
1159
+ this.characterWasOnGround = false;
1160
+ this.characterAirborneSince = 0;
1161
+ this.currentHeight = 0;
1162
+ this.characterVelocity = new Vector34();
1163
+ this.vectorUp = new Vector34(0, 1, 0);
1164
+ this.vectorDown = new Vector34(0, -1, 0);
1165
+ this.rotationOffset = 0;
1166
+ this.azimuthalAngle = 0;
1167
+ this.tempMatrix = new Matrix4();
1168
+ this.tempSegment = new Line3();
1169
+ this.tempVector = new Vector34();
1170
+ this.tempVector2 = new Vector34();
1171
+ this.rayCaster = new Raycaster2();
1172
+ this.thirdPersonCamera = null;
1173
+ this.speed = 0;
1174
+ this.targetSpeed = 0;
1016
1175
  this.networkState = {
1017
1176
  id: this.id,
1018
1177
  position: { x: 0, y: 0, z: 0 },
@@ -1021,7 +1180,8 @@ var LocalController = class {
1021
1180
  };
1022
1181
  }
1023
1182
  update() {
1024
- if (!this.model?.mesh || !this.model?.animationMixer)
1183
+ var _a, _b;
1184
+ if (!((_a = this.model) == null ? void 0 : _a.mesh) || !((_b = this.model) == null ? void 0 : _b.animationMixer))
1025
1185
  return;
1026
1186
  if (!this.thirdPersonCamera)
1027
1187
  this.thirdPersonCamera = this.cameraManager.camera;
@@ -1089,12 +1249,13 @@ var LocalController = class {
1089
1249
  }
1090
1250
  }
1091
1251
  updateAzimuthalAngle() {
1092
- if (!this.thirdPersonCamera || !this.model?.mesh)
1252
+ var _a;
1253
+ if (!this.thirdPersonCamera || !((_a = this.model) == null ? void 0 : _a.mesh))
1093
1254
  return;
1094
1255
  const camToModelDistance = this.thirdPersonCamera.position.distanceTo(this.model.mesh.position);
1095
1256
  const isCameraFirstPerson = camToModelDistance < 2;
1096
1257
  if (isCameraFirstPerson) {
1097
- const cameraForward = new Vector33(0, 0, 1).applyQuaternion(this.thirdPersonCamera.quaternion);
1258
+ const cameraForward = new Vector34(0, 0, 1).applyQuaternion(this.thirdPersonCamera.quaternion);
1098
1259
  this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);
1099
1260
  } else {
1100
1261
  this.azimuthalAngle = Math.atan2(
@@ -1104,16 +1265,18 @@ var LocalController = class {
1104
1265
  }
1105
1266
  }
1106
1267
  computeAngularDifference(rotationQuaternion) {
1107
- if (!this.model?.mesh)
1268
+ var _a;
1269
+ if (!((_a = this.model) == null ? void 0 : _a.mesh))
1108
1270
  return 0;
1109
1271
  return 2 * Math.acos(Math.abs(this.model.mesh.quaternion.dot(rotationQuaternion)));
1110
1272
  }
1111
1273
  updateRotation() {
1112
- if (!this.thirdPersonCamera || !this.model?.mesh)
1274
+ var _a;
1275
+ if (!this.thirdPersonCamera || !((_a = this.model) == null ? void 0 : _a.mesh))
1113
1276
  return;
1114
1277
  this.updateRotationOffset();
1115
1278
  this.updateAzimuthalAngle();
1116
- const rotationQuaternion = new Quaternion();
1279
+ const rotationQuaternion = new Quaternion2();
1117
1280
  rotationQuaternion.setFromAxisAngle(this.vectorUp, this.azimuthalAngle + this.rotationOffset);
1118
1281
  const angularDifference = this.computeAngularDifference(rotationQuaternion);
1119
1282
  const desiredTime = 0.07;
@@ -1122,12 +1285,14 @@ var LocalController = class {
1122
1285
  this.model.mesh.quaternion.rotateTowards(rotationQuaternion, frameRotation);
1123
1286
  }
1124
1287
  addScaledVectorToCharacter(deltaTime) {
1125
- if (!this.model?.mesh)
1288
+ var _a;
1289
+ if (!((_a = this.model) == null ? void 0 : _a.mesh))
1126
1290
  return;
1127
1291
  this.model.mesh.position.addScaledVector(this.tempVector, this.speed * deltaTime);
1128
1292
  }
1129
1293
  updatePosition(deltaTime, _iter) {
1130
- if (!this.model?.mesh)
1294
+ var _a;
1295
+ if (!((_a = this.model) == null ? void 0 : _a.mesh))
1131
1296
  return;
1132
1297
  if (this.characterOnGround) {
1133
1298
  if (!this.jump)
@@ -1149,19 +1314,19 @@ var LocalController = class {
1149
1314
  this.model.mesh.position.addScaledVector(this.characterVelocity, deltaTime);
1150
1315
  this.tempVector.set(0, 0, 0);
1151
1316
  if (this.forward) {
1152
- const forward = new Vector33(0, 0, -1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1317
+ const forward = new Vector34(0, 0, -1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1153
1318
  this.tempVector.add(forward);
1154
1319
  }
1155
1320
  if (this.backward) {
1156
- const backward = new Vector33(0, 0, 1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1321
+ const backward = new Vector34(0, 0, 1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1157
1322
  this.tempVector.add(backward);
1158
1323
  }
1159
1324
  if (this.left) {
1160
- const left = new Vector33(-1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1325
+ const left = new Vector34(-1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1161
1326
  this.tempVector.add(left);
1162
1327
  }
1163
1328
  if (this.right) {
1164
- const right = new Vector33(1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1329
+ const right = new Vector34(1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
1165
1330
  this.tempVector.add(right);
1166
1331
  }
1167
1332
  if (this.tempVector.length() > 0) {
@@ -1169,15 +1334,10 @@ var LocalController = class {
1169
1334
  this.addScaledVectorToCharacter(deltaTime);
1170
1335
  }
1171
1336
  this.model.mesh.updateMatrixWorld();
1172
- this.tempBox.makeEmpty();
1173
1337
  this.tempSegment.copy(this.capsuleInfo.segment);
1174
1338
  this.tempSegment.start.applyMatrix4(this.model.mesh.matrixWorld).applyMatrix4(this.tempMatrix);
1175
1339
  this.tempSegment.end.applyMatrix4(this.model.mesh.matrixWorld).applyMatrix4(this.tempMatrix);
1176
- this.tempBox.expandByPoint(this.tempSegment.start);
1177
- this.tempBox.expandByPoint(this.tempSegment.end);
1178
- this.tempBox.min.subScalar(this.capsuleInfo.radius);
1179
- this.tempBox.max.addScalar(this.capsuleInfo.radius);
1180
- this.collisionsManager.applyColliders(this.tempSegment, this.capsuleInfo.radius, this.tempBox);
1340
+ this.collisionsManager.applyColliders(this.tempSegment, this.capsuleInfo.radius);
1181
1341
  const newPosition = this.tempVector;
1182
1342
  newPosition.copy(this.tempSegment.start);
1183
1343
  const deltaVector = this.tempVector2;
@@ -1199,16 +1359,17 @@ var LocalController = class {
1199
1359
  }
1200
1360
  }
1201
1361
  updateNetworkState() {
1202
- if (!this.model?.mesh) {
1362
+ var _a;
1363
+ if (!((_a = this.model) == null ? void 0 : _a.mesh)) {
1203
1364
  this.networkState = {
1204
1365
  id: this.id,
1205
- position: new Vector33(),
1366
+ position: new Vector34(),
1206
1367
  rotation: { quaternionY: 0, quaternionW: 1 },
1207
1368
  state: 0 /* idle */
1208
1369
  };
1209
1370
  } else {
1210
- const characterQuaternion = this.model.mesh.getWorldQuaternion(new Quaternion());
1211
- const positionUpdate = new Vector33(
1371
+ const characterQuaternion = this.model.mesh.getWorldQuaternion(new Quaternion2());
1372
+ const positionUpdate = new Vector34(
1212
1373
  this.model.mesh.position.x,
1213
1374
  this.model.mesh.position.y,
1214
1375
  this.model.mesh.position.z
@@ -1222,7 +1383,8 @@ var LocalController = class {
1222
1383
  }
1223
1384
  }
1224
1385
  resetPosition() {
1225
- if (!this.model?.mesh)
1386
+ var _a;
1387
+ if (!((_a = this.model) == null ? void 0 : _a.mesh))
1226
1388
  return;
1227
1389
  this.characterVelocity.y = 0;
1228
1390
  this.model.mesh.position.y = 3;
@@ -1232,7 +1394,7 @@ var LocalController = class {
1232
1394
 
1233
1395
  // src/character/Character.ts
1234
1396
  var Character = class {
1235
- constructor(characterDescription, id, isLocal, modelLoadedCallback, collisionsManager, keyInputManager, cameraManager, timeManager) {
1397
+ constructor(characterDescription, id, isLocal, modelLoadedCallback, collisionsManager, keyInputManager, cameraManager, timeManager, composer) {
1236
1398
  this.characterDescription = characterDescription;
1237
1399
  this.id = id;
1238
1400
  this.isLocal = isLocal;
@@ -1241,12 +1403,14 @@ var Character = class {
1241
1403
  this.keyInputManager = keyInputManager;
1242
1404
  this.cameraManager = cameraManager;
1243
1405
  this.timeManager = timeManager;
1244
- __publicField(this, "controller", null);
1245
- __publicField(this, "name", null);
1246
- __publicField(this, "model", null);
1247
- __publicField(this, "color", new Color3());
1248
- __publicField(this, "position", new Vector34());
1249
- __publicField(this, "tooltip", null);
1406
+ this.composer = composer;
1407
+ this.controller = null;
1408
+ this.name = null;
1409
+ this.model = null;
1410
+ this.color = new Color3();
1411
+ this.position = new Vector35();
1412
+ this.tooltip = null;
1413
+ this.speakingIndicator = null;
1250
1414
  this.load();
1251
1415
  }
1252
1416
  async load() {
@@ -1255,6 +1419,9 @@ var Character = class {
1255
1419
  if (this.tooltip === null) {
1256
1420
  this.tooltip = new CharacterTooltip(this.model.mesh);
1257
1421
  }
1422
+ if (this.speakingIndicator === null) {
1423
+ this.speakingIndicator = new CharacterSpeakingIndicator(this.composer.postPostScene);
1424
+ }
1258
1425
  this.color = this.model.material.colorsCube216[this.id];
1259
1426
  if (this.isLocal) {
1260
1427
  this.controller = new LocalController(
@@ -1269,11 +1436,21 @@ var Character = class {
1269
1436
  this.modelLoadedCallback();
1270
1437
  }
1271
1438
  update(time) {
1439
+ var _a;
1272
1440
  if (!this.model)
1273
1441
  return;
1274
1442
  if (this.tooltip) {
1275
1443
  this.tooltip.update(this.cameraManager.camera);
1276
1444
  }
1445
+ if (this.speakingIndicator) {
1446
+ this.speakingIndicator.setTime(time);
1447
+ if (this.model.mesh && this.model.headBone) {
1448
+ this.speakingIndicator.setBillboarding(
1449
+ (_a = this.model.headBone) == null ? void 0 : _a.getWorldPosition(new Vector35()),
1450
+ this.cameraManager.camera
1451
+ );
1452
+ }
1453
+ }
1277
1454
  this.model.mesh.getWorldPosition(this.position);
1278
1455
  if (typeof this.model.material.uniforms.time !== "undefined") {
1279
1456
  this.model.material.uniforms.time.value = time;
@@ -1284,25 +1461,24 @@ var Character = class {
1284
1461
  };
1285
1462
 
1286
1463
  // src/character/CharacterManager.ts
1287
- import { Group, Vector3 as Vector36 } from "three";
1464
+ import { Group, Vector3 as Vector37 } from "three";
1288
1465
 
1289
1466
  // src/character/RemoteController.ts
1290
1467
  import {
1291
1468
  AnimationMixer as AnimationMixer2,
1292
- Object3D as Object3D4,
1293
- Quaternion as Quaternion2,
1294
- Vector3 as Vector35
1469
+ Object3D as Object3D5,
1470
+ Quaternion as Quaternion3,
1471
+ Vector3 as Vector36
1295
1472
  } from "three";
1296
1473
  var RemoteController = class {
1297
1474
  constructor(character, id) {
1298
1475
  this.character = character;
1299
1476
  this.id = id;
1300
- __publicField(this, "modelLoader", ModelLoader_default);
1301
- __publicField(this, "characterModel", null);
1302
- __publicField(this, "animationMixer", new AnimationMixer2(new Object3D4()));
1303
- __publicField(this, "animations", /* @__PURE__ */ new Map());
1304
- __publicField(this, "currentAnimation", 0 /* idle */);
1305
- __publicField(this, "networkState");
1477
+ this.modelLoader = ModelLoader_default;
1478
+ this.characterModel = null;
1479
+ this.animationMixer = new AnimationMixer2(new Object3D5());
1480
+ this.animations = /* @__PURE__ */ new Map();
1481
+ this.currentAnimation = 0 /* idle */;
1306
1482
  this.characterModel = this.character.model.mesh;
1307
1483
  this.characterModel.updateMatrixWorld();
1308
1484
  this.animationMixer = new AnimationMixer2(this.characterModel);
@@ -1348,8 +1524,8 @@ var RemoteController = class {
1348
1524
  if (!this.characterModel)
1349
1525
  return;
1350
1526
  const { position, rotation, state } = clientUpdate;
1351
- this.characterModel.position.lerp(new Vector35(position.x, position.y, position.z), 0.15);
1352
- const rotationQuaternion = new Quaternion2(0, rotation.quaternionY, 0, rotation.quaternionW);
1527
+ this.characterModel.position.lerp(new Vector36(position.x, position.y, position.z), 0.15);
1528
+ const rotationQuaternion = new Quaternion3(0, rotation.quaternionY, 0, rotation.quaternionW);
1353
1529
  this.characterModel.quaternion.slerp(rotationQuaternion, 0.6);
1354
1530
  if (state !== this.currentAnimation) {
1355
1531
  this.transitionToAnimation(state);
@@ -1360,10 +1536,10 @@ var RemoteController = class {
1360
1536
  // src/character/CharacterManager.ts
1361
1537
  function encodeCharacterAndCamera(character, camera) {
1362
1538
  return [
1363
- ...character.position.toArray(),
1364
- ...character.quaternion.toArray(),
1365
- ...camera.position.toArray(),
1366
- ...camera.quaternion.toArray()
1539
+ ...toArray(character.position),
1540
+ ...toArray(character.quaternion),
1541
+ ...toArray(camera.position),
1542
+ ...toArray(camera.quaternion)
1367
1543
  ].join(",");
1368
1544
  }
1369
1545
  function decodeCharacterAndCamera(hash, character, camera) {
@@ -1374,7 +1550,8 @@ function decodeCharacterAndCamera(hash, character, camera) {
1374
1550
  camera.quaternion.fromArray(values.slice(10, 14));
1375
1551
  }
1376
1552
  var CharacterManager = class {
1377
- constructor(collisionsManager, cameraManager, timeManager, inputManager, clientStates, sendUpdate) {
1553
+ constructor(composer, collisionsManager, cameraManager, timeManager, inputManager, clientStates, sendUpdate) {
1554
+ this.composer = composer;
1378
1555
  this.collisionsManager = collisionsManager;
1379
1556
  this.cameraManager = cameraManager;
1380
1557
  this.timeManager = timeManager;
@@ -1386,15 +1563,16 @@ var CharacterManager = class {
1386
1563
  character was standing on a model and the page is reloaded the character falls into the model before it loads and
1387
1564
  can be trapped).
1388
1565
  */
1389
- __publicField(this, "updateLocationHash", false);
1390
- __publicField(this, "loadingCharacters", /* @__PURE__ */ new Map());
1391
- __publicField(this, "remoteCharacters", /* @__PURE__ */ new Map());
1392
- __publicField(this, "remoteCharacterControllers", /* @__PURE__ */ new Map());
1393
- __publicField(this, "characterDescription", null);
1394
- __publicField(this, "character", null);
1395
- __publicField(this, "cameraOffsetTarget", 0);
1396
- __publicField(this, "cameraOffset", 0);
1397
- __publicField(this, "group");
1566
+ this.updateLocationHash = false;
1567
+ this.id = 0;
1568
+ this.loadingCharacters = /* @__PURE__ */ new Map();
1569
+ this.remoteCharacters = /* @__PURE__ */ new Map();
1570
+ this.remoteCharacterControllers = /* @__PURE__ */ new Map();
1571
+ this.characterDescription = null;
1572
+ this.character = null;
1573
+ this.cameraOffsetTarget = 0;
1574
+ this.cameraOffset = 0;
1575
+ this.speakingCharacters = /* @__PURE__ */ new Map();
1398
1576
  this.group = new Group();
1399
1577
  }
1400
1578
  /* TODO:
@@ -1403,7 +1581,7 @@ var CharacterManager = class {
1403
1581
  the mesh loading async (would allow us to show a nameplate where a remote
1404
1582
  user is before the asset loads).
1405
1583
  */
1406
- spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector36()) {
1584
+ spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector37()) {
1407
1585
  this.characterDescription = characterDescription;
1408
1586
  const characterLoadingPromise = new Promise((resolve) => {
1409
1587
  const character = new Character(
@@ -1411,6 +1589,7 @@ var CharacterManager = class {
1411
1589
  id,
1412
1590
  isLocal,
1413
1591
  () => {
1592
+ var _a, _b, _c, _d, _e, _f, _g;
1414
1593
  if (window.location.hash && window.location.hash.length > 1) {
1415
1594
  decodeCharacterAndCamera(
1416
1595
  window.location.hash.substring(1),
@@ -1434,14 +1613,15 @@ var CharacterManager = class {
1434
1613
  }
1435
1614
  character.model.hideMaterialByMeshName("SK_Mannequin_2");
1436
1615
  if (!isLocal) {
1437
- character.model?.mesh?.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
1438
- character.model?.mesh?.updateMatrixWorld();
1616
+ (_b = (_a = character.model) == null ? void 0 : _a.mesh) == null ? void 0 : _b.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
1617
+ (_d = (_c = character.model) == null ? void 0 : _c.mesh) == null ? void 0 : _d.updateMatrixWorld();
1439
1618
  character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
1440
1619
  }
1441
1620
  this.group.add(character.model.mesh);
1442
1621
  if (isLocal) {
1622
+ this.id = id;
1443
1623
  this.character = character;
1444
- this.character.tooltip?.setText(`${id}`);
1624
+ (_e = this.character.tooltip) == null ? void 0 : _e.setText(`${id}`);
1445
1625
  } else {
1446
1626
  this.remoteCharacters.set(id, character);
1447
1627
  const remoteController = new RemoteController(character, id);
@@ -1461,20 +1641,21 @@ var CharacterManager = class {
1461
1641
  4 /* air */,
1462
1642
  characterDescription.airAnimationFileUrl
1463
1643
  );
1464
- remoteController.characterModel?.position.set(
1644
+ (_f = remoteController.characterModel) == null ? void 0 : _f.position.set(
1465
1645
  spawnPosition.x,
1466
1646
  spawnPosition.y,
1467
1647
  spawnPosition.z
1468
1648
  );
1469
1649
  this.remoteCharacterControllers.set(id, remoteController);
1470
- character.tooltip?.setText(`${id}`);
1650
+ (_g = character.tooltip) == null ? void 0 : _g.setText(`${id}`);
1471
1651
  }
1472
1652
  resolve(character);
1473
1653
  },
1474
1654
  this.collisionsManager,
1475
1655
  this.inputManager,
1476
1656
  this.cameraManager,
1477
- this.timeManager
1657
+ this.timeManager,
1658
+ this.composer
1478
1659
  );
1479
1660
  });
1480
1661
  this.loadingCharacters.set(id, characterLoadingPromise);
@@ -1504,13 +1685,20 @@ var CharacterManager = class {
1504
1685
  }
1505
1686
  this.loadingCharacters.clear();
1506
1687
  }
1688
+ setSpeakingCharacter(id, value) {
1689
+ this.speakingCharacters.set(id, value);
1690
+ }
1507
1691
  update() {
1692
+ var _a, _b, _c, _d;
1508
1693
  if (this.character) {
1509
1694
  this.character.update(this.timeManager.time);
1510
- if (this.character.model?.mesh) {
1511
- this.cameraOffsetTarget = this.cameraManager.targetDistance <= 0.4 ? 0.6 : 0;
1695
+ if (this.speakingCharacters.has(this.id)) {
1696
+ (_a = this.character.speakingIndicator) == null ? void 0 : _a.setSpeaking(this.speakingCharacters.get(this.id));
1697
+ }
1698
+ if ((_b = this.character.model) == null ? void 0 : _b.mesh) {
1699
+ this.cameraOffsetTarget = this.cameraManager.targetDistance <= 0.4 ? 0.13 : 0;
1512
1700
  this.cameraOffset += ease(this.cameraOffsetTarget, this.cameraOffset, 0.1);
1513
- const targetOffset = new Vector36(0, 1.3, this.cameraOffset);
1701
+ const targetOffset = new Vector37(0, 1.3, this.cameraOffset);
1514
1702
  targetOffset.applyQuaternion(this.character.model.mesh.quaternion);
1515
1703
  this.cameraManager.setTarget(this.character.position.add(targetOffset));
1516
1704
  }
@@ -1521,13 +1709,17 @@ var CharacterManager = class {
1521
1709
  }
1522
1710
  }
1523
1711
  for (const [id, update] of this.clientStates) {
1712
+ if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {
1713
+ const character = this.remoteCharacters.get(id);
1714
+ (_c = character == null ? void 0 : character.speakingIndicator) == null ? void 0 : _c.setSpeaking(this.speakingCharacters.get(id));
1715
+ }
1524
1716
  const { position } = update;
1525
1717
  if (!this.remoteCharacters.has(id) && !this.loadingCharacters.has(id)) {
1526
1718
  this.spawnCharacter(
1527
1719
  this.characterDescription,
1528
1720
  id,
1529
1721
  false,
1530
- new Vector36(position.x, position.y, position.z)
1722
+ new Vector37(position.x, position.y, position.z)
1531
1723
  ).then((_character) => {
1532
1724
  this.loadingCharacters.delete(id);
1533
1725
  });
@@ -1539,6 +1731,7 @@ var CharacterManager = class {
1539
1731
  }
1540
1732
  for (const [id, character] of this.remoteCharacters) {
1541
1733
  if (!this.clientStates.has(id)) {
1734
+ (_d = character.speakingIndicator) == null ? void 0 : _d.dispose();
1542
1735
  this.group.remove(character.model.mesh);
1543
1736
  this.remoteCharacters.delete(id);
1544
1737
  this.remoteCharacterControllers.delete(id);
@@ -1557,7 +1750,7 @@ var CharacterManager = class {
1557
1750
  // src/input/KeyInputManager.ts
1558
1751
  var KeyInputManager = class {
1559
1752
  constructor() {
1560
- __publicField(this, "keys", /* @__PURE__ */ new Map());
1753
+ this.keys = /* @__PURE__ */ new Map();
1561
1754
  document.addEventListener("keydown", this.onKeyDown.bind(this));
1562
1755
  document.addEventListener("keyup", this.onKeyUp.bind(this));
1563
1756
  window.addEventListener("blur", this.handleUnfocus.bind(this));
@@ -1625,12 +1818,7 @@ var MMLCompositionScene = class {
1625
1818
  this.audioListener = audioListener;
1626
1819
  this.collisionsManager = collisionsManager;
1627
1820
  this.getUserPositionAndRotation = getUserPositionAndRotation;
1628
- __publicField(this, "group");
1629
- __publicField(this, "debug", false);
1630
- __publicField(this, "mmlScene");
1631
- __publicField(this, "promptManager");
1632
- __publicField(this, "interactionListener");
1633
- __publicField(this, "clickTrigger");
1821
+ this.debug = false;
1634
1822
  this.group = new Group2();
1635
1823
  this.promptManager = PromptManager.init(document.body);
1636
1824
  const { interactionListener } = InteractionManager.init(document.body, this.camera, this.scene);
@@ -1679,22 +1867,23 @@ var MMLCompositionScene = class {
1679
1867
  };
1680
1868
 
1681
1869
  // src/rendering/composer.ts
1870
+ import { N8AOPostPass } from "n8ao";
1682
1871
  import {
1683
1872
  EffectComposer as EffectComposer2,
1684
1873
  RenderPass,
1685
1874
  EffectPass as EffectPass2,
1686
1875
  FXAAEffect,
1687
1876
  ShaderPass,
1688
- BloomEffect as BloomEffect2,
1877
+ BloomEffect,
1689
1878
  SSAOEffect as SSAOEffect2,
1690
- BlendFunction as BlendFunction3,
1879
+ BlendFunction as BlendFunction2,
1691
1880
  TextureEffect,
1692
- ToneMappingEffect as ToneMappingEffect2,
1881
+ ToneMappingEffect,
1693
1882
  SMAAEffect,
1694
1883
  SMAAPreset,
1695
1884
  EdgeDetectionMode,
1696
1885
  PredicationMode,
1697
- NormalPass
1886
+ NormalPass as NormalPass2
1698
1887
  } from "postprocessing";
1699
1888
  import {
1700
1889
  AmbientLight,
@@ -1704,22 +1893,23 @@ import {
1704
1893
  LinearSRGBColorSpace,
1705
1894
  LoadingManager as LoadingManager2,
1706
1895
  PMREMGenerator,
1896
+ Scene as Scene3,
1707
1897
  Vector2 as Vector22,
1708
- WebGLRenderer as WebGLRenderer3
1898
+ WebGLRenderer as WebGLRenderer2
1709
1899
  } from "three";
1710
1900
  import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
1711
1901
 
1712
1902
  // src/sun/Sun.ts
1713
- import { CameraHelper, Color as Color4, DirectionalLight, Group as Group3, OrthographicCamera, Vector3 as Vector37 } from "three";
1903
+ import { CameraHelper, Color as Color4, DirectionalLight, Group as Group3, OrthographicCamera, Vector3 as Vector38 } from "three";
1714
1904
 
1715
- // src/tweakpane/sunSettings.ts
1905
+ // src/tweakpane/blades/environmentFolder.ts
1716
1906
  var sunValues = {
1717
1907
  sunPosition: {
1718
1908
  sunAzimuthalAngle: 39,
1719
1909
  sunPolarAngle: 50
1720
1910
  },
1721
1911
  sunIntensity: 0.5,
1722
- sunColor: { r: 1, g: 1, b: 1 }
1912
+ sunColor: { r: 1, g: 0.74, b: 0.5 }
1723
1913
  };
1724
1914
  var sunOptions = {
1725
1915
  sunPosition: {
@@ -1728,23 +1918,159 @@ var sunOptions = {
1728
1918
  },
1729
1919
  sunIntensity: { min: 0, max: 1, step: 0.05 }
1730
1920
  };
1921
+ var envValues = {
1922
+ ambientLight: {
1923
+ ambientLightIntensity: 0,
1924
+ ambientLightColor: { r: 1, g: 1, b: 1 }
1925
+ },
1926
+ fog: {
1927
+ fogNear: 30,
1928
+ fogFar: 210,
1929
+ fogColor: { r: 0.42, g: 0.48, b: 0.59 }
1930
+ }
1931
+ };
1932
+ var envOptions = {
1933
+ ambientLight: {
1934
+ ambientLightIntensity: { min: 0, max: 1, step: 0.01 }
1935
+ },
1936
+ fog: {
1937
+ fogNear: { min: 0, max: 80, step: 1 },
1938
+ fogFar: { min: 81, max: 300, step: 1 }
1939
+ }
1940
+ };
1941
+ var EnvironmentFolder = class {
1942
+ constructor(parentFolder, expand = false) {
1943
+ this.folder = parentFolder.addFolder({ title: "environment", expanded: expand });
1944
+ this.sun = this.folder.addFolder({ title: "sun", expanded: true });
1945
+ this.ambient = this.folder.addFolder({ title: "ambient", expanded: true });
1946
+ this.sun.addBinding(
1947
+ sunValues.sunPosition,
1948
+ "sunAzimuthalAngle",
1949
+ sunOptions.sunPosition.sunAzimuthalAngle
1950
+ );
1951
+ this.sun.addBinding(
1952
+ sunValues.sunPosition,
1953
+ "sunPolarAngle",
1954
+ sunOptions.sunPosition.sunPolarAngle
1955
+ );
1956
+ this.sun.addBinding(sunValues, "sunIntensity", sunOptions.sunIntensity);
1957
+ this.sun.addBinding(sunValues, "sunColor", {
1958
+ color: { type: "float" }
1959
+ });
1960
+ this.sunButton = this.sun.addButton({ title: "Set HDRI" });
1961
+ this.ambient.addBinding(
1962
+ envValues.ambientLight,
1963
+ "ambientLightIntensity",
1964
+ envOptions.ambientLight.ambientLightIntensity
1965
+ );
1966
+ this.ambient.addBinding(envValues.ambientLight, "ambientLightColor", {
1967
+ color: { type: "float" }
1968
+ });
1969
+ this.ambient.addBinding(envValues.fog, "fogNear", envOptions.fog.fogNear);
1970
+ this.ambient.addBinding(envValues.fog, "fogFar", envOptions.fog.fogFar);
1971
+ this.ambient.addBinding(envValues.fog, "fogColor", {
1972
+ color: { type: "float" }
1973
+ });
1974
+ }
1975
+ setupChangeEvent(setHDR, setAmbientLight, setFog, sun) {
1976
+ this.sun.on("change", (e) => {
1977
+ const target = e.target.key;
1978
+ if (!target)
1979
+ return;
1980
+ switch (target) {
1981
+ case "sunAzimuthalAngle": {
1982
+ const value = e.value;
1983
+ sun == null ? void 0 : sun.setAzimuthalAngle(value * (Math.PI / 180));
1984
+ break;
1985
+ }
1986
+ case "sunPolarAngle": {
1987
+ const value = e.value;
1988
+ sun == null ? void 0 : sun.setPolarAngle(value * (Math.PI / 180));
1989
+ break;
1990
+ }
1991
+ case "sunIntensity": {
1992
+ const value = e.value;
1993
+ sun == null ? void 0 : sun.setIntensity(value);
1994
+ break;
1995
+ }
1996
+ case "sunColor": {
1997
+ const value = e.value;
1998
+ sunValues.sunColor = {
1999
+ r: value.r,
2000
+ g: value.g,
2001
+ b: value.b
2002
+ };
2003
+ sun == null ? void 0 : sun.setColor();
2004
+ break;
2005
+ }
2006
+ default:
2007
+ break;
2008
+ }
2009
+ });
2010
+ this.sunButton.on("click", () => {
2011
+ setHDR();
2012
+ });
2013
+ this.ambient.on("change", (e) => {
2014
+ const target = e.target.key;
2015
+ if (!target)
2016
+ return;
2017
+ switch (target) {
2018
+ case "ambientLightIntensity": {
2019
+ envValues.ambientLight.ambientLightIntensity = e.value;
2020
+ setAmbientLight();
2021
+ break;
2022
+ }
2023
+ case "ambientLightColor": {
2024
+ const value = e.value;
2025
+ envValues.ambientLight.ambientLightColor = {
2026
+ r: value.r,
2027
+ g: value.g,
2028
+ b: value.b
2029
+ };
2030
+ setAmbientLight();
2031
+ break;
2032
+ }
2033
+ case "fogNear": {
2034
+ envValues.fog.fogNear = e.value;
2035
+ setFog();
2036
+ break;
2037
+ }
2038
+ case "fogFar": {
2039
+ envValues.fog.fogFar = e.value;
2040
+ setFog();
2041
+ break;
2042
+ }
2043
+ case "fogColor": {
2044
+ const value = e.value;
2045
+ envValues.fog.fogColor = {
2046
+ r: value.r,
2047
+ g: value.g,
2048
+ b: value.b
2049
+ };
2050
+ setFog();
2051
+ break;
2052
+ }
2053
+ default:
2054
+ break;
2055
+ }
2056
+ });
2057
+ }
2058
+ };
1731
2059
 
1732
2060
  // src/sun/Sun.ts
1733
2061
  var Sun = class extends Group3 {
1734
2062
  constructor() {
1735
2063
  super();
1736
- __publicField(this, "debug", false);
1737
- __publicField(this, "sunOffset", new Vector37(
2064
+ this.debug = false;
2065
+ this.sunOffset = new Vector38(
1738
2066
  39 * (Math.PI / 180),
1739
2067
  50 * (Math.PI / 180),
1740
2068
  100
1741
- ));
1742
- __publicField(this, "shadowResolution", 8192);
1743
- __publicField(this, "shadowCamFrustum", 50);
1744
- __publicField(this, "camHelper", null);
1745
- __publicField(this, "shadowCamera");
1746
- __publicField(this, "directionalLight");
1747
- __publicField(this, "target", null);
2069
+ );
2070
+ this.shadowResolution = 8192;
2071
+ this.shadowCamFrustum = 50;
2072
+ this.camHelper = null;
2073
+ this.target = null;
1748
2074
  this.shadowCamera = new OrthographicCamera(
1749
2075
  -this.shadowCamFrustum,
1750
2076
  this.shadowCamFrustum,
@@ -1762,7 +2088,8 @@ var Sun = class extends Group3 {
1762
2088
  this.directionalLight.shadow.camera = this.shadowCamera;
1763
2089
  this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);
1764
2090
  this.directionalLight.castShadow = true;
1765
- this.updateCharacterPosition(new Vector37(0, 0, 0));
2091
+ this.setColor();
2092
+ this.updateCharacterPosition(new Vector38(0, 0, 0));
1766
2093
  this.add(this.directionalLight);
1767
2094
  if (this.debug === true && this.camHelper instanceof CameraHelper) {
1768
2095
  this.add(this.camHelper);
@@ -1800,7 +2127,7 @@ var Sun = class extends Group3 {
1800
2127
  if (!this.target)
1801
2128
  return;
1802
2129
  const distance = this.sunOffset.z;
1803
- const sphericalPosition = new Vector37(
2130
+ const sphericalPosition = new Vector38(
1804
2131
  distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),
1805
2132
  distance * Math.cos(polarAngle),
1806
2133
  distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle)
@@ -1812,80 +2139,13 @@ var Sun = class extends Group3 {
1812
2139
  }
1813
2140
  };
1814
2141
 
1815
- // src/tweakpane/composerSettings.ts
1816
- import { BlendFunction } from "postprocessing";
1817
- var composerValues = {
1818
- renderer: {
1819
- shadowMap: 2,
1820
- toneMapping: 5,
1821
- exposure: 1,
1822
- bgIntensity: 0.5,
1823
- bgBlurriness: 0
1824
- },
1825
- ssao: {
1826
- blendFunction: BlendFunction.MULTIPLY,
1827
- distanceScaling: true,
1828
- depthAwareUpsampling: true,
1829
- samples: 17,
1830
- rings: 7,
1831
- luminanceInfluence: 0.7,
1832
- radius: 0.03,
1833
- intensity: 2.5,
1834
- bias: 0.05,
1835
- fade: 0.03,
1836
- resolutionScale: 0.75,
1837
- color: { r: 0, g: 0, b: 0 },
1838
- worldDistanceThreshold: 30,
1839
- worldDistanceFalloff: 7,
1840
- worldProximityThreshold: 0.5,
1841
- worldProximityFalloff: 0.3
1842
- },
1843
- toneMapping: {
1844
- mode: 2,
1845
- resolution: 512,
1846
- whitePoint: 32,
1847
- middleGrey: 21,
1848
- minLuminance: 0.01,
1849
- averageLuminance: 0.01,
1850
- adaptationRate: 2
1851
- },
1852
- brightness: -0.03,
1853
- contrast: 1.21,
1854
- saturation: 0.91,
1855
- grain: 0.061,
1856
- bloom: 0.25
2142
+ // src/tweakpane/blades/bcsFolder.ts
2143
+ var bcsValues = {
2144
+ brightness: 0,
2145
+ contrast: 1.25,
2146
+ saturation: 1
1857
2147
  };
1858
- var composerOptions = {
1859
- renderer: {
1860
- shadowMap: { min: 0, max: 2, step: 1 },
1861
- toneMapping: { min: 0, max: 5, step: 1 },
1862
- exposure: { min: 0, max: 3, step: 0.01 },
1863
- bgIntensity: { min: 0, max: 1.3, step: 0.01 },
1864
- bgBlurriness: { min: 0, max: 0.1, step: 1e-3 }
1865
- },
1866
- ssao: {
1867
- samples: { min: 1, max: 50, step: 1 },
1868
- rings: { min: 1, max: 50, step: 1 },
1869
- luminanceInfluence: { min: 0, max: 1, step: 0.01 },
1870
- radius: { min: 0, max: 0.1, step: 1e-3 },
1871
- intensity: { min: 0, max: 5, step: 0.1 },
1872
- bias: { min: 0, max: 0.1, step: 1e-3 },
1873
- fade: { min: 0, max: 0.1, step: 1e-3 },
1874
- resolutionScale: { min: 0.25, max: 2, step: 0.25 },
1875
- worldDistanceThreshold: { min: 0, max: 200, step: 1 },
1876
- worldDistanceFalloff: { min: 0, max: 200, step: 1 },
1877
- worldProximityThreshold: { min: 0, max: 2, step: 0.01 },
1878
- worldProximityFalloff: { min: 0, max: 2, step: 0.01 }
1879
- },
1880
- toneMapping: {
1881
- mode: { min: 0, max: 4, step: 1 },
1882
- resolution: { min: 64, max: 512, step: 64 },
1883
- whitePoint: { min: 0, max: 32, step: 0.01 },
1884
- middleGrey: { min: 0, max: 32, step: 0.01 },
1885
- minLuminance: { min: 0, max: 32, step: 1e-3 },
1886
- averageLuminance: { min: 1e-3, max: 0.2, step: 1e-3 },
1887
- adaptationRate: { min: 0.1, max: 2, step: 0.1 }
1888
- },
2148
+ var bcsOptions = {
1889
2149
  brightness: {
1890
2150
  amount: { min: -1, max: 1, step: 0.01 }
1891
2151
  },
@@ -1894,7 +2154,44 @@ var composerOptions = {
1894
2154
  },
1895
2155
  saturation: {
1896
2156
  amount: { min: 0, max: 2, step: 0.01 }
1897
- },
2157
+ }
2158
+ };
2159
+ var BrightnessContrastSaturationFolder = class {
2160
+ constructor(parentFolder, expand = false) {
2161
+ this.folder = parentFolder.addFolder({
2162
+ title: "brightness / contrast / sat",
2163
+ expanded: expand
2164
+ });
2165
+ this.folder.addBinding(bcsValues, "brightness", bcsOptions.brightness.amount);
2166
+ this.folder.addBinding(bcsValues, "contrast", bcsOptions.contrast.amount);
2167
+ this.folder.addBinding(bcsValues, "saturation", bcsOptions.saturation.amount);
2168
+ }
2169
+ setupChangeEvent(brightnessContrastSaturation) {
2170
+ this.folder.on("change", (e) => {
2171
+ const target = e.target.key;
2172
+ if (!target)
2173
+ return;
2174
+ switch (target) {
2175
+ case "brightness":
2176
+ brightnessContrastSaturation.uniforms.brightness.value = e.value;
2177
+ break;
2178
+ case "contrast":
2179
+ brightnessContrastSaturation.uniforms.contrast.value = e.value;
2180
+ break;
2181
+ case "saturation":
2182
+ brightnessContrastSaturation.uniforms.saturation.value = e.value;
2183
+ break;
2184
+ }
2185
+ });
2186
+ }
2187
+ };
2188
+
2189
+ // src/tweakpane/blades/postExtrasFolder.ts
2190
+ var extrasValues = {
2191
+ grain: 0.055,
2192
+ bloom: 0.25
2193
+ };
2194
+ var extrasOptions = {
1898
2195
  grain: {
1899
2196
  amount: { min: 0, max: 0.2, step: 2e-3 }
1900
2197
  },
@@ -1902,12 +2199,52 @@ var composerOptions = {
1902
2199
  amount: { min: 0, max: 2, step: 0.05 }
1903
2200
  }
1904
2201
  };
2202
+ var PostExtrasFolder = class {
2203
+ constructor(parentFolder, expand = false) {
2204
+ this.folder = parentFolder.addFolder({ title: "bloom / grain", expanded: expand });
2205
+ this.folder.addBinding(extrasValues, "bloom", extrasOptions.bloom.amount);
2206
+ this.folder.addBinding(extrasValues, "grain", extrasOptions.grain.amount);
2207
+ }
2208
+ setupChangeEvent(bloomEffect, gaussGrainEffect) {
2209
+ this.folder.on("change", (e) => {
2210
+ const target = e.target.key;
2211
+ if (!target)
2212
+ return;
2213
+ switch (target) {
2214
+ case "bloom":
2215
+ bloomEffect.intensity = e.value;
2216
+ break;
2217
+ case "grain":
2218
+ gaussGrainEffect.uniforms.amount.value = e.value;
2219
+ break;
2220
+ default:
2221
+ break;
2222
+ }
2223
+ });
2224
+ }
2225
+ };
2226
+
2227
+ // src/tweakpane/blades/rendererFolder.ts
2228
+ var rendererValues = {
2229
+ shadowMap: 2,
2230
+ toneMapping: 5,
2231
+ exposure: 1,
2232
+ bgIntensity: 0.45,
2233
+ bgBlurriness: 0
2234
+ };
2235
+ var rendererOptions = {
2236
+ shadowMap: { min: 0, max: 2, step: 1 },
2237
+ toneMapping: { min: 0, max: 5, step: 1 },
2238
+ exposure: { min: 0, max: 3, step: 0.01 },
2239
+ bgIntensity: { min: 0, max: 1.3, step: 0.01 },
2240
+ bgBlurriness: { min: 0, max: 0.1, step: 1e-3 }
2241
+ };
1905
2242
  var shadowMapTypes = {
1906
2243
  0: "BasicShadowMap",
1907
2244
  1: "PCFShadowMap",
1908
2245
  2: "PCFSoftShadowMap"
1909
2246
  };
1910
- var rendererToneMappingTypes = {
2247
+ var toneMappingTypes = {
1911
2248
  0: "NoToneMapping",
1912
2249
  1: "LinearToneMapping",
1913
2250
  2: "ReinhardToneMapping",
@@ -1915,28 +2252,120 @@ var rendererToneMappingTypes = {
1915
2252
  4: "ACESFilmicToneMapping",
1916
2253
  5: "CustomToneMapping"
1917
2254
  };
1918
- var customToneMappingTypes = {
1919
- 0: "REINHARD",
1920
- 1: "REINHARD2",
1921
- 2: "REINHARD2_ADAPTIVE",
1922
- 3: "OPTIMIZED_CINEON",
1923
- 4: "ACES_FILMIC"
1924
- };
1925
- var rendererBlades = {
1926
- shadowMapType: shadowMapTypes[composerValues.renderer.shadowMap],
1927
- toneMappingType: rendererToneMappingTypes[composerValues.renderer.toneMapping]
2255
+ var monitoredValues = {
2256
+ shadowMapType: shadowMapTypes[rendererValues.shadowMap],
2257
+ toneMappingType: toneMappingTypes[rendererValues.toneMapping]
1928
2258
  };
1929
2259
  var setShadowMapType = (value) => {
1930
- rendererBlades.shadowMapType = shadowMapTypes[value];
2260
+ monitoredValues.shadowMapType = shadowMapTypes[value];
1931
2261
  };
1932
2262
  var setToneMappingType = (value) => {
1933
- rendererBlades.toneMappingType = rendererToneMappingTypes[value];
2263
+ monitoredValues.toneMappingType = toneMappingTypes[value];
1934
2264
  };
1935
- var customToneMappingBlade = {
1936
- customToneMappingType: customToneMappingTypes[composerValues.toneMapping.mode]
2265
+ var RendererFolder = class {
2266
+ constructor(parentFolder, expand = false) {
2267
+ this.folder = parentFolder.addFolder({
2268
+ title: "rendererOptions",
2269
+ expanded: expand
2270
+ });
2271
+ this.folder.addBinding(rendererValues, "shadowMap", rendererOptions.shadowMap);
2272
+ this.folder.addBinding(monitoredValues, "shadowMapType", { readonly: true });
2273
+ this.folder.addBinding(rendererValues, "toneMapping", rendererOptions.toneMapping);
2274
+ this.folder.addBinding(monitoredValues, "toneMappingType", { readonly: true });
2275
+ this.folder.addBinding(rendererValues, "exposure", rendererOptions.exposure);
2276
+ this.folder.addBinding(rendererValues, "bgIntensity", rendererOptions.bgIntensity);
2277
+ this.folder.addBinding(rendererValues, "bgBlurriness", rendererOptions.bgBlurriness);
2278
+ }
2279
+ setupChangeEvent(scene, renderer, toneMappingFolder, toneMappingPass) {
2280
+ this.folder.on("change", (e) => {
2281
+ const target = e.target.key;
2282
+ if (!target)
2283
+ return;
2284
+ switch (target) {
2285
+ case "shadowMap": {
2286
+ const value = e.value;
2287
+ renderer.shadowMap.type = value;
2288
+ setShadowMapType(value);
2289
+ break;
2290
+ }
2291
+ case "toneMapping":
2292
+ renderer.toneMapping = e.value;
2293
+ toneMappingFolder.hidden = e.value !== 5;
2294
+ toneMappingPass.enabled = e.value === 5 ? true : false;
2295
+ setToneMappingType(e.value);
2296
+ break;
2297
+ case "exposure":
2298
+ renderer.toneMappingExposure = e.value;
2299
+ break;
2300
+ case "bgIntensity":
2301
+ scene.backgroundIntensity = e.value;
2302
+ break;
2303
+ case "bgBlurriness":
2304
+ scene.backgroundBlurriness = e.value;
2305
+ break;
2306
+ default:
2307
+ break;
2308
+ }
2309
+ });
2310
+ }
1937
2311
  };
1938
- var setCustomToneMappingType = (value) => {
1939
- customToneMappingBlade.customToneMappingType = customToneMappingTypes[value];
2312
+
2313
+ // src/tweakpane/blades/ssaoFolder.ts
2314
+ import { BlendFunction } from "postprocessing";
2315
+ import { Color as Color5 } from "three";
2316
+ var ppssaoValues = {
2317
+ enabled: false,
2318
+ blendFunction: BlendFunction.MULTIPLY,
2319
+ distanceScaling: true,
2320
+ depthAwareUpsampling: true,
2321
+ samples: 30,
2322
+ rings: 11,
2323
+ luminanceInfluence: 0.7,
2324
+ radius: 0.03,
2325
+ intensity: 2.5,
2326
+ bias: 0.05,
2327
+ fade: 0.03,
2328
+ resolutionScale: 0.5,
2329
+ color: { r: 0, g: 0, b: 0 },
2330
+ worldDistanceThreshold: 30,
2331
+ worldDistanceFalloff: 7,
2332
+ worldProximityThreshold: 0.5,
2333
+ worldProximityFalloff: 0.3
2334
+ };
2335
+ var ppssaoOptions = {
2336
+ samples: { min: 1, max: 50, step: 1 },
2337
+ rings: { min: 1, max: 50, step: 1 },
2338
+ luminanceInfluence: { min: 0, max: 1, step: 0.01 },
2339
+ radius: { min: 0, max: 0.1, step: 1e-3 },
2340
+ intensity: { min: 0, max: 5, step: 0.1 },
2341
+ bias: { min: 0, max: 0.1, step: 1e-3 },
2342
+ fade: { min: 0, max: 0.1, step: 1e-3 },
2343
+ resolutionScale: { min: 0.25, max: 2, step: 0.25 },
2344
+ worldDistanceThreshold: { min: 0, max: 200, step: 1 },
2345
+ worldDistanceFalloff: { min: 0, max: 200, step: 1 },
2346
+ worldProximityThreshold: { min: 0, max: 2, step: 0.01 },
2347
+ worldProximityFalloff: { min: 0, max: 2, step: 0.01 }
2348
+ };
2349
+ var n8ssaoValues = {
2350
+ enabled: true,
2351
+ halfRes: false,
2352
+ aoRadius: 5,
2353
+ distanceFalloff: 3,
2354
+ intensity: 1,
2355
+ color: { r: 0, g: 0, b: 0 },
2356
+ aoSamples: 16,
2357
+ denoiseSamples: 4,
2358
+ denoiseRadius: 12,
2359
+ viewMode: "Combined"
2360
+ };
2361
+ var n8ssaoOptions = {
2362
+ radius: { min: 0.1, max: 6, step: 0.1 },
2363
+ distanceFalloff: { min: 1, max: 6, step: 0.1 },
2364
+ intensity: { min: 0.1, max: 5, step: 0.1 },
2365
+ aoSamples: [2, 4, 8, 16, 32, 64],
2366
+ denoiseSamples: [2, 4, 8, 16, 32, 64],
2367
+ denoiseRadius: [3, 6, 12],
2368
+ viewMode: ["Combined", "AO", "Split", "No AO"]
1940
2369
  };
1941
2370
  var ssaoMaterialParams = [
1942
2371
  "fade",
@@ -1947,72 +2376,336 @@ var ssaoMaterialParams = [
1947
2376
  "worldProximityThreshold",
1948
2377
  "worldProximityFalloff"
1949
2378
  ];
1950
- var statsData = {
1951
- triangles: "0",
1952
- geometries: "0",
1953
- textures: "0",
1954
- shaders: "0",
1955
- postPasses: "0",
1956
- drawCalls: "0",
1957
- rawDeltaTime: "0",
1958
- deltaTime: "0",
1959
- FPS: "0"
2379
+ var SSAOFolder = class {
2380
+ constructor(parentFolder, expand = false) {
2381
+ this.postProcessingSSAOIndex = 1;
2382
+ this.folder = parentFolder.addFolder({ title: "ambientOcclusion", expanded: expand });
2383
+ this.n8ssao = this.folder.addFolder({
2384
+ title: "N8 ambientOcclusion",
2385
+ expanded: n8ssaoValues.enabled
2386
+ });
2387
+ this.ppssao = this.folder.addFolder({
2388
+ title: "PP ambientOcclusion",
2389
+ expanded: ppssaoValues.enabled
2390
+ });
2391
+ {
2392
+ this.ppssao.addBinding({ enabled: ppssaoValues.enabled }, "enabled");
2393
+ this.ppssao.addBinding({ showEffectOnly: false }, "showEffectOnly");
2394
+ this.ppssao.addBinding(ppssaoValues, "samples", ppssaoOptions.samples);
2395
+ this.ppssao.addBinding(ppssaoValues, "rings", ppssaoOptions.rings);
2396
+ this.ppssao.addBinding(ppssaoValues, "luminanceInfluence", ppssaoOptions.luminanceInfluence);
2397
+ this.ppssao.addBinding(ppssaoValues, "radius", ppssaoOptions.radius);
2398
+ this.ppssao.addBinding(ppssaoValues, "intensity", ppssaoOptions.intensity);
2399
+ this.ppssao.addBinding(ppssaoValues, "bias", ppssaoOptions.bias);
2400
+ this.ppssao.addBinding(ppssaoValues, "fade", ppssaoOptions.fade);
2401
+ this.ppssao.addBinding(ppssaoValues, "resolutionScale", ppssaoOptions.resolutionScale);
2402
+ this.ppssao.addBinding(
2403
+ ppssaoValues,
2404
+ "worldDistanceThreshold",
2405
+ ppssaoOptions.worldDistanceThreshold
2406
+ );
2407
+ this.ppssao.addBinding(
2408
+ ppssaoValues,
2409
+ "worldDistanceFalloff",
2410
+ ppssaoOptions.worldDistanceFalloff
2411
+ );
2412
+ this.ppssao.addBinding(
2413
+ ppssaoValues,
2414
+ "worldProximityThreshold",
2415
+ ppssaoOptions.worldProximityThreshold
2416
+ );
2417
+ this.ppssao.addBinding(
2418
+ ppssaoValues,
2419
+ "worldProximityFalloff",
2420
+ ppssaoOptions.worldProximityFalloff
2421
+ );
2422
+ this.ppssao.addBinding(ppssaoValues, "color", { color: { alpha: false, type: "float" } });
2423
+ }
2424
+ {
2425
+ this.n8ssao.addBinding({ enabled: n8ssaoValues.enabled }, "enabled");
2426
+ this.n8ssao.addBinding({ halfRes: n8ssaoValues.halfRes }, "halfRes");
2427
+ this.n8ssao.addBinding(n8ssaoValues, "aoRadius", n8ssaoOptions.radius);
2428
+ this.n8ssao.addBinding(n8ssaoValues, "distanceFalloff", n8ssaoOptions.distanceFalloff);
2429
+ this.n8ssao.addBinding(n8ssaoValues, "intensity", n8ssaoOptions.intensity);
2430
+ this.n8ssao.addBinding(n8ssaoValues, "color", { color: { alpha: false, type: "float" } });
2431
+ this.aoSamples = this.n8ssao.addBinding(n8ssaoValues, "aoSamples", {
2432
+ view: "radiogrid",
2433
+ groupName: "aoSamples",
2434
+ size: [3, 2],
2435
+ cells: (x, y) => ({
2436
+ title: `${n8ssaoOptions.aoSamples[y * 3 + x]}`,
2437
+ value: n8ssaoOptions.aoSamples[y * 3 + x]
2438
+ }),
2439
+ label: "aoSamples"
2440
+ });
2441
+ this.denoiseSamples = this.n8ssao.addBinding(n8ssaoValues, "denoiseSamples", {
2442
+ view: "radiogrid",
2443
+ groupName: "denoiseSamples",
2444
+ size: [3, 2],
2445
+ cells: (x, y) => ({
2446
+ title: `${n8ssaoOptions.denoiseSamples[y * 3 + x]}`,
2447
+ value: n8ssaoOptions.denoiseSamples[y * 3 + x]
2448
+ }),
2449
+ label: "denoiseSamples"
2450
+ });
2451
+ this.denoiseRadius = this.n8ssao.addBinding(n8ssaoValues, "denoiseRadius", {
2452
+ view: "radiogrid",
2453
+ groupName: "denoiseRadius",
2454
+ size: [3, 1],
2455
+ cells: (x, y) => ({
2456
+ title: `${n8ssaoOptions.denoiseRadius[y * 3 + x]}`,
2457
+ value: n8ssaoOptions.denoiseRadius[y * 3 + x]
2458
+ }),
2459
+ label: "denoiseRadius"
2460
+ });
2461
+ this.aoDisplay = this.n8ssao.addBinding(n8ssaoValues, "viewMode", {
2462
+ view: "radiogrid",
2463
+ groupName: "viewMode",
2464
+ size: [2, 2],
2465
+ cells: (x, y) => ({
2466
+ title: `${n8ssaoOptions.viewMode[y * 2 + x]}`,
2467
+ value: `${n8ssaoOptions.viewMode[y * 2 + x]}`
2468
+ }),
2469
+ label: "viewMode"
2470
+ });
2471
+ }
2472
+ this.folder.addBlade({ view: "separator" });
2473
+ }
2474
+ setupChangeEvent(composer, normalPass, ppssaoEffect, ppssaoPass, n8aopass) {
2475
+ this.ppssao.on("change", (e) => {
2476
+ const target = e.target.key;
2477
+ if (!target)
2478
+ return;
2479
+ switch (target) {
2480
+ case "enabled": {
2481
+ const value = e.value;
2482
+ if (e.value === true) {
2483
+ composer.addPass(normalPass, this.postProcessingSSAOIndex);
2484
+ composer.addPass(ppssaoPass, this.postProcessingSSAOIndex + 1);
2485
+ } else {
2486
+ composer.removePass(ppssaoPass);
2487
+ composer.removePass(normalPass);
2488
+ }
2489
+ ppssaoValues.enabled = value;
2490
+ normalPass.enabled = value;
2491
+ ppssaoPass.enabled = value;
2492
+ break;
2493
+ }
2494
+ case "showEffectOnly": {
2495
+ const value = e.value;
2496
+ const blend = value === true ? BlendFunction.NORMAL : BlendFunction.MULTIPLY;
2497
+ ppssaoEffect.blendMode.blendFunction = blend;
2498
+ break;
2499
+ }
2500
+ case "resolutionScale": {
2501
+ const value = e.value;
2502
+ ppssaoEffect.resolution.scale = value;
2503
+ break;
2504
+ }
2505
+ case "color": {
2506
+ const value = e.value;
2507
+ ppssaoEffect.color = new Color5().setRGB(value.r, value.g, value.b);
2508
+ break;
2509
+ }
2510
+ default: {
2511
+ break;
2512
+ }
2513
+ }
2514
+ if (ssaoMaterialParams.includes(target)) {
2515
+ ppssaoEffect.ssaoMaterial[target] = e.value;
2516
+ return;
2517
+ }
2518
+ ppssaoEffect[target] = e.value;
2519
+ });
2520
+ this.n8ssao.on("change", (e) => {
2521
+ const target = e.target.key;
2522
+ if (!target)
2523
+ return;
2524
+ switch (target) {
2525
+ case "enabled":
2526
+ if (e.value === true) {
2527
+ composer.addPass(n8aopass, this.postProcessingSSAOIndex + 2);
2528
+ } else {
2529
+ composer.removePass(n8aopass);
2530
+ }
2531
+ n8aopass.enabled = e.value;
2532
+ break;
2533
+ case "halfRes":
2534
+ n8aopass.configuration.halfRes = e.value;
2535
+ break;
2536
+ case "aoRadius":
2537
+ n8aopass.configuration.aoRadius = e.value;
2538
+ break;
2539
+ case "distanceFalloff":
2540
+ n8aopass.configuration.distanceFalloff = e.value;
2541
+ break;
2542
+ case "intensity":
2543
+ n8aopass.configuration.intensity = e.value;
2544
+ break;
2545
+ case "color":
2546
+ const value = e.value;
2547
+ n8aopass.configuration.color = new Color5().setRGB(value.r, value.g, value.b);
2548
+ break;
2549
+ default:
2550
+ break;
2551
+ }
2552
+ });
2553
+ this.aoSamples.on("change", (e) => {
2554
+ n8aopass.configuration.aoSamples = e.value;
2555
+ });
2556
+ this.denoiseSamples.on("change", (e) => {
2557
+ n8aopass.configuration.denoiseSamples = e.value;
2558
+ });
2559
+ this.denoiseRadius.on("change", (e) => {
2560
+ n8aopass.configuration.denoiseRadius = e.value;
2561
+ });
2562
+ this.aoDisplay.on("change", (e) => {
2563
+ n8aopass.setDisplayMode(e.value);
2564
+ });
2565
+ }
1960
2566
  };
1961
2567
 
1962
- // src/tweakpane/envSettings.ts
1963
- var envValues = {
1964
- ambientLight: {
1965
- ambientLightIntensity: 0,
1966
- ambientLightColor: { r: 1, g: 1, b: 1 }
1967
- },
1968
- fog: {
1969
- fogNear: 30,
1970
- fogFar: 210,
1971
- fogColor: { r: 0.42, g: 0.48, b: 0.59 }
1972
- }
2568
+ // src/tweakpane/blades/toneMappingFolder.ts
2569
+ var toneMappingValues = {
2570
+ mode: 2,
2571
+ resolution: 512,
2572
+ whitePoint: 32,
2573
+ middleGrey: 21,
2574
+ minLuminance: 0.01,
2575
+ averageLuminance: 0.01,
2576
+ adaptationRate: 2
1973
2577
  };
1974
- var envOptions = {
1975
- ambientLight: {
1976
- ambientLightIntensity: { min: 0, max: 1, step: 0.01 }
1977
- },
1978
- fog: {
1979
- fogNear: { min: 0, max: 80, step: 1 },
1980
- fogFar: { min: 81, max: 300, step: 1 }
2578
+ var toneMappingOptions = {
2579
+ mode: { min: 0, max: 4, step: 1 },
2580
+ resolution: { min: 64, max: 512, step: 64 },
2581
+ whitePoint: { min: 0, max: 32, step: 0.01 },
2582
+ middleGrey: { min: 0, max: 32, step: 0.01 },
2583
+ minLuminance: { min: 0, max: 32, step: 1e-3 },
2584
+ averageLuminance: { min: 1e-3, max: 0.2, step: 1e-3 },
2585
+ adaptationRate: { min: 0.1, max: 2, step: 0.1 }
2586
+ };
2587
+ var customToneMappingTypes = {
2588
+ 0: "REINHARD",
2589
+ 1: "REINHARD2",
2590
+ 2: "REINHARD2_ADAPTIVE",
2591
+ 3: "OPTIMIZED_CINEON",
2592
+ 4: "ACES_FILMIC"
2593
+ };
2594
+ var customToneMappingBlade = {
2595
+ customToneMappingType: customToneMappingTypes[toneMappingValues.mode]
2596
+ };
2597
+ var setCustomToneMappingType = (value) => {
2598
+ customToneMappingBlade.customToneMappingType = customToneMappingTypes[value];
2599
+ };
2600
+ var ToneMappingFolder = class {
2601
+ constructor(parentFolder, expand = false) {
2602
+ this.folder = parentFolder.addFolder({
2603
+ title: "customToneMapping",
2604
+ expanded: expand
2605
+ });
2606
+ this.folder.addBinding(toneMappingValues, "mode", toneMappingOptions.mode);
2607
+ this.folder.addBinding(customToneMappingBlade, "customToneMappingType", { readonly: true });
2608
+ this.folder.addBinding(toneMappingValues, "whitePoint", toneMappingOptions.whitePoint);
2609
+ this.folder.addBinding(toneMappingValues, "middleGrey", toneMappingOptions.middleGrey);
2610
+ this.minLuminance = this.folder.addBinding(
2611
+ toneMappingValues,
2612
+ "minLuminance",
2613
+ toneMappingOptions.minLuminance
2614
+ );
2615
+ this.minLuminance.hidden = toneMappingValues.mode === 2 ? true : false;
2616
+ this.avgLuminance = this.folder.addBinding(
2617
+ toneMappingValues,
2618
+ "averageLuminance",
2619
+ toneMappingOptions.averageLuminance
2620
+ );
2621
+ this.avgLuminance.hidden = toneMappingValues.mode === 2 ? true : false;
2622
+ this.folder.addBinding(toneMappingValues, "adaptationRate", toneMappingOptions.adaptationRate);
2623
+ }
2624
+ setupChangeEvent(toneMappingEffect) {
2625
+ this.folder.on("change", (e) => {
2626
+ const target = e.target.key;
2627
+ if (!target)
2628
+ return;
2629
+ if (target === "mode") {
2630
+ this.minLuminance.hidden = toneMappingValues.mode === 2 ? true : false;
2631
+ this.avgLuminance.hidden = toneMappingValues.mode === 2 ? true : false;
2632
+ setCustomToneMappingType(e.value);
2633
+ }
2634
+ toneMappingEffect[target] = e.value;
2635
+ return;
2636
+ });
1981
2637
  }
1982
2638
  };
1983
2639
 
1984
2640
  // src/tweakpane/TweakPane.ts
1985
- import {
1986
- BlendFunction as BlendFunction2
1987
- } from "postprocessing";
1988
- import { Color as Color5 } from "three";
2641
+ import * as EssentialsPlugin from "@tweakpane/plugin-essentials";
1989
2642
  import { Pane } from "tweakpane";
1990
- var TweakPane = class {
1991
- constructor(renderer, scene, composer) {
1992
- __publicField(this, "renderer");
1993
- __publicField(this, "scene");
1994
- __publicField(this, "composer");
1995
- __publicField(this, "guiStyle", `
2643
+
2644
+ // src/tweakpane/blades/rendererStatsFolder.ts
2645
+ var RendererStatsFolder = class {
2646
+ constructor(parentFolder, expanded = true) {
2647
+ this.statsData = {
2648
+ triangles: "0",
2649
+ geometries: "0",
2650
+ textures: "0",
2651
+ shaders: "0",
2652
+ postPasses: "0",
2653
+ drawCalls: "0",
2654
+ rawDeltaTime: "0",
2655
+ deltaTime: "0",
2656
+ FPS: "0"
2657
+ };
2658
+ this.folder = parentFolder.addFolder({ title: "renderStats", expanded });
2659
+ this.performance = this.folder.addFolder({ title: "performance", expanded: true });
2660
+ this.defails = this.folder.addFolder({ title: "pipeline details", expanded: false });
2661
+ this.folder.addBlade({ view: "separator" });
2662
+ this.performance.addBinding(this.statsData, "FPS", { readonly: true });
2663
+ this.performance.addBinding(this.statsData, "deltaTime", { readonly: true });
2664
+ this.performance.addBinding(this.statsData, "rawDeltaTime", { readonly: true });
2665
+ this.defails.addBinding(this.statsData, "triangles", { readonly: true });
2666
+ this.defails.addBinding(this.statsData, "geometries", { readonly: true });
2667
+ this.defails.addBinding(this.statsData, "textures", { readonly: true });
2668
+ this.defails.addBinding(this.statsData, "shaders", { readonly: true });
2669
+ this.defails.addBinding(this.statsData, "postPasses", { readonly: true });
2670
+ this.defails.addBinding(this.statsData, "drawCalls", { readonly: true });
2671
+ }
2672
+ update(renderer, composer, timeManager) {
2673
+ const { geometries, textures } = renderer.info.memory;
2674
+ const { triangles, calls } = renderer.info.render;
2675
+ this.statsData.triangles = triangles.toString();
2676
+ this.statsData.geometries = geometries.toString();
2677
+ this.statsData.textures = textures.toString();
2678
+ this.statsData.shaders = renderer.info.programs.length.toString();
2679
+ this.statsData.postPasses = composer.passes.length.toString();
2680
+ this.statsData.drawCalls = calls.toString();
2681
+ this.statsData.rawDeltaTime = (Math.round(timeManager.rawDeltaTime * 1e5) / 1e5).toString();
2682
+ this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 1e5) / 1e5).toString();
2683
+ this.statsData.FPS = timeManager.fps.toString();
2684
+ }
2685
+ };
2686
+
2687
+ // src/tweakpane/tweakPaneStyle.ts
2688
+ var tweakPaneStyle = `
1996
2689
  :root {
1997
- --tp-base-background-color: hsla(0, 0%, 10%, 0.8);
2690
+ --tp-base-background-color: rgba(0, 0, 0, 0.6);
1998
2691
  --tp-base-shadow-color: hsla(0, 0%, 0%, 0.2);
1999
2692
  --tp-button-background-color: hsla(0, 0%, 80%, 1);
2000
2693
  --tp-button-background-color-active: hsla(0, 0%, 100%, 1);
2001
2694
  --tp-button-background-color-focus: hsla(0, 0%, 95%, 1);
2002
2695
  --tp-button-background-color-hover: hsla(0, 0%, 85%, 1);
2003
- --tp-button-foreground-color: hsla(0, 0%, 0%, 0.8);
2696
+ --tp-button-foreground-color: hsla(0, 0%, 0%, 0.7);
2004
2697
  --tp-container-background-color: hsla(0, 0%, 0%, 0.3);
2005
2698
  --tp-container-background-color-active: hsla(0, 0%, 0%, 0.6);
2006
2699
  --tp-container-background-color-focus: hsla(0, 0%, 0%, 0.5);
2007
2700
  --tp-container-background-color-hover: hsla(0, 0%, 0%, 0.4);
2008
- --tp-container-foreground-color: hsla(0, 0%, 100%, 0.5);
2701
+ --tp-container-foreground-color: hsla(0, 0%, 90%, 0.6);
2009
2702
  --tp-groove-foreground-color: hsla(0, 0%, 0%, 0.2);
2010
- --tp-input-background-color: hsla(0, 0%, 0%, 0.3);
2703
+ --tp-input-background-color: hsla(0, 0%, 30%, 0.3);
2011
2704
  --tp-input-background-color-active: hsla(0, 0%, 0%, 0.6);
2012
2705
  --tp-input-background-color-focus: hsla(0, 0%, 0%, 0.5);
2013
2706
  --tp-input-background-color-hover: hsla(0, 0%, 0%, 0.4);
2014
- --tp-input-foreground-color: hsla(0, 0%, 100%, 0.5);
2015
- --tp-label-foreground-color: hsla(0, 0%, 100%, 0.5);
2707
+ --tp-input-foreground-color: hsla(0, 0%, 100%, 0.6);
2708
+ --tp-label-foreground-color: hsla(0, 0%, 100%, 0.6);
2016
2709
  --tp-monitor-background-color: hsla(0, 0%, 0%, 0.3);
2017
2710
  --tp-monitor-foreground-color: hsla(0, 0%, 100%, 0.3);
2018
2711
  }
@@ -2024,31 +2717,50 @@ var TweakPane = class {
2024
2717
  }
2025
2718
 
2026
2719
  .tp-dfwv {
2027
- width: 333px !important;
2720
+ color: white;
2721
+ backdrop-filter: blur(12px);
2722
+ width: 360px !important;
2028
2723
  display: none;
2724
+ -webkit-user-select: none;
2725
+ -ms-user-select: none;
2726
+ user-select: none;
2727
+ }
2728
+
2729
+ .tp-fldv_t {
2730
+ font-size: 11px;
2731
+ background-color: rgba(0, 0, 0, 0.1);
2029
2732
  }
2030
2733
 
2031
2734
  .tp-lblv_l {
2032
- font-size: 10px;
2735
+ font-size: 11px;
2033
2736
  padding-left: 0px !important;
2034
2737
  padding-right: 0px !important;
2035
2738
  }
2036
- `);
2037
- __publicField(this, "gui", new Pane());
2038
- __publicField(this, "render");
2039
- __publicField(this, "stats");
2040
- __publicField(this, "renderOptions");
2041
- __publicField(this, "ssao");
2042
- __publicField(this, "toneMapping");
2043
- __publicField(this, "post");
2044
- __publicField(this, "export");
2045
- __publicField(this, "characterMaterial");
2046
- __publicField(this, "environment");
2047
- __publicField(this, "sun");
2048
- __publicField(this, "sunButton");
2049
- __publicField(this, "ambient");
2050
- __publicField(this, "saveVisibilityInLocalStorage", true);
2051
- __publicField(this, "guiVisible", false);
2739
+
2740
+ .tp-lblv_v {
2741
+ width: 180px;
2742
+ }
2743
+
2744
+ .tp-sldtxtv_t {
2745
+ max-width: 50px;
2746
+ }
2747
+
2748
+ .tp-sglv_i {
2749
+ font-size: 11px;
2750
+ color: rgba(255, 255, 255, 0.7);
2751
+ }
2752
+ `;
2753
+
2754
+ // src/tweakpane/TweakPane.ts
2755
+ var TweakPane = class {
2756
+ constructor(renderer, scene, composer) {
2757
+ this.renderer = renderer;
2758
+ this.scene = scene;
2759
+ this.composer = composer;
2760
+ this.gui = new Pane();
2761
+ this.saveVisibilityInLocalStorage = true;
2762
+ this.guiVisible = false;
2763
+ this.gui.registerPlugin(EssentialsPlugin);
2052
2764
  if (this.saveVisibilityInLocalStorage) {
2053
2765
  const localStorageGuiVisible = localStorage.getItem("guiVisible");
2054
2766
  if (localStorageGuiVisible !== null) {
@@ -2059,120 +2771,20 @@ var TweakPane = class {
2059
2771
  }
2060
2772
  }
2061
2773
  }
2062
- this.renderer = renderer;
2063
- this.scene = scene;
2064
- this.composer = composer;
2065
2774
  const styleElement = document.createElement("style");
2066
2775
  styleElement.type = "text/css";
2067
- styleElement.appendChild(document.createTextNode(this.guiStyle));
2776
+ styleElement.appendChild(document.createTextNode(tweakPaneStyle));
2068
2777
  document.head.appendChild(styleElement);
2069
- this.render = this.gui.addFolder({ title: "rendering", expanded: true });
2070
- this.stats = this.render.addFolder({ title: "stats", expanded: true });
2071
- this.renderOptions = this.render.addFolder({ title: "renderOptions", expanded: false });
2072
- this.toneMapping = this.render.addFolder({ title: "customToneMapping", expanded: false });
2073
- this.ssao = this.render.addFolder({ title: "ambientOcclusion", expanded: false });
2074
- this.post = this.render.addFolder({ title: "post", expanded: false });
2075
- this.toneMapping.hidden = composerValues.renderer.toneMapping === 5 ? false : true;
2076
- {
2077
- this.characterMaterial = this.gui.addFolder({ title: "characterMaterial", expanded: false });
2078
- this.characterMaterial.addInput(
2079
- characterValues.material,
2080
- "transmission",
2081
- characterOptions.material.transmission
2082
- );
2083
- this.characterMaterial.addInput(
2084
- characterValues.material,
2085
- "metalness",
2086
- characterOptions.material.metalness
2087
- );
2088
- this.characterMaterial.addInput(
2089
- characterValues.material,
2090
- "roughness",
2091
- characterOptions.material.roughness
2092
- );
2093
- this.characterMaterial.addInput(
2094
- characterValues.material,
2095
- "ior",
2096
- characterOptions.material.ior
2097
- );
2098
- this.characterMaterial.addInput(
2099
- characterValues.material,
2100
- "thickness",
2101
- characterOptions.material.thickness
2102
- );
2103
- this.characterMaterial.addInput(characterValues.material, "specularColor", {
2104
- color: { type: "float" }
2105
- });
2106
- this.characterMaterial.addInput(
2107
- characterValues.material,
2108
- "specularIntensity",
2109
- characterOptions.material.specularIntensity
2110
- );
2111
- this.characterMaterial.addInput(characterValues.material, "emissive", {
2112
- color: { type: "float" }
2113
- });
2114
- this.characterMaterial.addInput(
2115
- characterValues.material,
2116
- "emissiveIntensity",
2117
- characterOptions.material.emissiveIntensity
2118
- );
2119
- this.characterMaterial.addInput(
2120
- characterValues.material,
2121
- "envMapIntensity",
2122
- characterOptions.material.envMapIntensity
2123
- );
2124
- this.characterMaterial.addInput(characterValues.material, "sheenColor", {
2125
- color: { type: "float" }
2126
- });
2127
- this.characterMaterial.addInput(
2128
- characterValues.material,
2129
- "sheen",
2130
- characterOptions.material.sheen
2131
- );
2132
- this.characterMaterial.addInput(
2133
- characterValues.material,
2134
- "clearcoat",
2135
- characterOptions.material.clearcoat
2136
- );
2137
- this.characterMaterial.addInput(
2138
- characterValues.material,
2139
- "clearcoatRoughness",
2140
- characterOptions.material.clearcoatRoughness
2141
- );
2142
- this.characterMaterial.on("change", (e) => {
2143
- if (!e.presetKey) {
2144
- return;
2145
- }
2146
- if (e.presetKey === "specularColor") {
2147
- characterValues.material.specularColor = {
2148
- r: e.value.r,
2149
- g: e.value.g,
2150
- b: e.value.b
2151
- };
2152
- return;
2153
- }
2154
- if (e.presetKey === "emissive") {
2155
- characterValues.material.emissive = {
2156
- r: e.value.r,
2157
- g: e.value.g,
2158
- b: e.value.b
2159
- };
2160
- return;
2161
- }
2162
- if (e.presetKey === "sheenColor") {
2163
- characterValues.material.sheenColor = {
2164
- r: e.value.r,
2165
- g: e.value.g,
2166
- b: e.value.b
2167
- };
2168
- return;
2169
- }
2170
- });
2171
- }
2172
- this.environment = this.gui.addFolder({ title: "environment", expanded: false });
2173
- this.sun = this.environment.addFolder({ title: "sun", expanded: true });
2174
- this.ambient = this.environment.addFolder({ title: "ambient", expanded: true });
2175
- this.export = this.gui.addFolder({ title: "import/export", expanded: false });
2778
+ this.renderStatsFolder = new RendererStatsFolder(this.gui, true);
2779
+ this.rendererFolder = new RendererFolder(this.gui, false);
2780
+ this.toneMappingFolder = new ToneMappingFolder(this.gui, false);
2781
+ this.ssaoFolder = new SSAOFolder(this.gui, false);
2782
+ this.bcsFolder = new BrightnessContrastSaturationFolder(this.gui, false);
2783
+ this.postExtrasFolder = new PostExtrasFolder(this.gui, false);
2784
+ this.character = new CharacterFolder(this.gui, false);
2785
+ this.environment = new EnvironmentFolder(this.gui, false);
2786
+ this.toneMappingFolder.folder.hidden = rendererValues.toneMapping === 5 ? false : true;
2787
+ this.export = this.gui.addFolder({ title: "import / export", expanded: false });
2176
2788
  window.addEventListener("keydown", this.processKey.bind(this));
2177
2789
  this.setupGUIListeners.bind(this)();
2178
2790
  this.setupRenderPane = this.setupRenderPane.bind(this);
@@ -2189,319 +2801,33 @@ var TweakPane = class {
2189
2801
  this.gui.element.addEventListener("mouseup", () => setTweakpaneActive(false));
2190
2802
  this.gui.element.addEventListener("mouseleave", () => setTweakpaneActive(false));
2191
2803
  }
2192
- setupRenderPane(ssaoEffect, toneMappingEffect, toneMappingPass, brightnessContrastSaturation, bloomEffect, gaussGrainEffect, hasLighting, sun, setHDR, setAmbientLight, setFog) {
2193
- {
2194
- this.stats.addMonitor(statsData, "triangles");
2195
- this.stats.addMonitor(statsData, "geometries");
2196
- this.stats.addMonitor(statsData, "textures");
2197
- this.stats.addMonitor(statsData, "shaders");
2198
- this.stats.addMonitor(statsData, "postPasses");
2199
- this.stats.addMonitor(statsData, "drawCalls");
2200
- this.stats.addMonitor(statsData, "rawDeltaTime");
2201
- this.stats.addMonitor(statsData, "deltaTime");
2202
- this.stats.addMonitor(statsData, "FPS");
2203
- }
2204
- {
2205
- this.renderOptions.addInput(
2206
- composerValues.renderer,
2207
- "shadowMap",
2208
- composerOptions.renderer.shadowMap
2209
- );
2210
- this.renderOptions.addMonitor(rendererBlades, "shadowMapType");
2211
- this.renderOptions.addInput(
2212
- composerValues.renderer,
2213
- "toneMapping",
2214
- composerOptions.renderer.toneMapping
2215
- );
2216
- this.renderOptions.addMonitor(rendererBlades, "toneMappingType");
2217
- this.renderOptions.addInput(
2218
- composerValues.renderer,
2219
- "exposure",
2220
- composerOptions.renderer.exposure
2221
- );
2222
- this.renderOptions.addInput(
2223
- composerValues.renderer,
2224
- "bgIntensity",
2225
- composerOptions.renderer.bgIntensity
2226
- );
2227
- this.renderOptions.addInput(
2228
- composerValues.renderer,
2229
- "bgBlurriness",
2230
- composerOptions.renderer.bgBlurriness
2231
- );
2232
- this.renderOptions.on("change", (e) => {
2233
- const target = e.target;
2234
- switch (target.label) {
2235
- case "shadowMap":
2236
- this.renderer.shadowMap.type = e.value;
2237
- setShadowMapType(e.value);
2238
- break;
2239
- case "toneMapping":
2240
- this.renderer.toneMapping = e.value;
2241
- this.toneMapping.hidden = e.value !== 5;
2242
- toneMappingPass.enabled = e.value === 5 ? true : false;
2243
- setToneMappingType(e.value);
2244
- break;
2245
- case "exposure":
2246
- this.renderer.toneMappingExposure = e.value;
2247
- break;
2248
- case "bgIntensity":
2249
- this.scene.backgroundIntensity = e.value;
2250
- break;
2251
- case "bgBlurriness":
2252
- this.scene.backgroundBlurriness = e.value;
2253
- break;
2254
- default:
2255
- break;
2256
- }
2257
- });
2258
- }
2259
- {
2260
- this.ssao.addInput({ showEffectOnly: false }, "showEffectOnly");
2261
- this.ssao.addInput(composerValues.ssao, "samples", composerOptions.ssao.samples);
2262
- this.ssao.addInput(composerValues.ssao, "rings", composerOptions.ssao.rings);
2263
- this.ssao.addInput(
2264
- composerValues.ssao,
2265
- "luminanceInfluence",
2266
- composerOptions.ssao.luminanceInfluence
2267
- );
2268
- this.ssao.addInput(composerValues.ssao, "radius", composerOptions.ssao.radius);
2269
- this.ssao.addInput(composerValues.ssao, "intensity", composerOptions.ssao.intensity);
2270
- this.ssao.addInput(composerValues.ssao, "bias", composerOptions.ssao.bias);
2271
- this.ssao.addInput(composerValues.ssao, "fade", composerOptions.ssao.fade);
2272
- this.ssao.addInput(
2273
- composerValues.ssao,
2274
- "resolutionScale",
2275
- composerOptions.ssao.resolutionScale
2276
- );
2277
- this.ssao.addInput(
2278
- composerValues.ssao,
2279
- "worldDistanceThreshold",
2280
- composerOptions.ssao.worldDistanceThreshold
2281
- );
2282
- this.ssao.addInput(
2283
- composerValues.ssao,
2284
- "worldDistanceFalloff",
2285
- composerOptions.ssao.worldDistanceFalloff
2286
- );
2287
- this.ssao.addInput(
2288
- composerValues.ssao,
2289
- "worldProximityThreshold",
2290
- composerOptions.ssao.worldProximityThreshold
2291
- );
2292
- this.ssao.addInput(
2293
- composerValues.ssao,
2294
- "worldProximityFalloff",
2295
- composerOptions.ssao.worldProximityFalloff
2296
- );
2297
- this.ssao.addInput(composerValues.ssao, "color", {
2298
- color: { alpha: false, type: "float" }
2299
- });
2300
- this.ssao.on("change", (e) => {
2301
- if (!e.presetKey) {
2302
- return;
2303
- }
2304
- const preset = e.presetKey;
2305
- if (preset === "showEffectOnly") {
2306
- ssaoEffect.blendMode.blendFunction = e.value === true ? BlendFunction2.NORMAL : BlendFunction2.MULTIPLY;
2307
- return;
2308
- }
2309
- if (preset === "resolutionScale") {
2310
- ssaoEffect.resolution.scale = e.value;
2311
- return;
2312
- }
2313
- if (ssaoMaterialParams.includes(e.presetKey)) {
2314
- ssaoEffect.ssaoMaterial[preset] = e.value;
2315
- return;
2316
- }
2317
- if (e.presetKey === "color") {
2318
- ssaoEffect.color = new Color5().setRGB(e.value.r, e.value.g, e.value.b);
2319
- return;
2320
- }
2321
- ssaoEffect[preset] = e.value;
2322
- });
2323
- }
2324
- {
2325
- this.toneMapping.addInput(
2326
- composerValues.toneMapping,
2327
- "mode",
2328
- composerOptions.toneMapping.mode
2329
- );
2330
- this.toneMapping.addMonitor(customToneMappingBlade, "customToneMappingType");
2331
- this.toneMapping.addInput(
2332
- composerValues.toneMapping,
2333
- "whitePoint",
2334
- composerOptions.toneMapping.whitePoint
2335
- );
2336
- this.toneMapping.addInput(
2337
- composerValues.toneMapping,
2338
- "middleGrey",
2339
- composerOptions.toneMapping.middleGrey
2340
- );
2341
- const minLuminance = this.toneMapping.addInput(
2342
- composerValues.toneMapping,
2343
- "minLuminance",
2344
- composerOptions.toneMapping.minLuminance
2345
- );
2346
- minLuminance.hidden = composerValues.toneMapping.mode === 2 ? true : false;
2347
- const averageLuminance = this.toneMapping.addInput(
2348
- composerValues.toneMapping,
2349
- "averageLuminance",
2350
- composerOptions.toneMapping.averageLuminance
2351
- );
2352
- averageLuminance.hidden = composerValues.toneMapping.mode === 2 ? true : false;
2353
- this.toneMapping.addInput(
2354
- composerValues.toneMapping,
2355
- "adaptationRate",
2356
- composerOptions.toneMapping.adaptationRate
2357
- );
2358
- this.toneMapping.on("change", (e) => {
2359
- if (!e.presetKey) {
2360
- return;
2361
- }
2362
- const preset = e.presetKey;
2363
- if (preset === "mode") {
2364
- minLuminance.hidden = composerValues.toneMapping.mode === 2 ? true : false;
2365
- averageLuminance.hidden = composerValues.toneMapping.mode === 2 ? true : false;
2366
- setCustomToneMappingType(e.value);
2367
- }
2368
- toneMappingEffect[preset] = e.value;
2369
- return;
2370
- });
2371
- }
2372
- {
2373
- this.post.addInput(composerValues, "brightness", composerOptions.brightness.amount);
2374
- this.post.addInput(composerValues, "contrast", composerOptions.contrast.amount);
2375
- this.post.addInput(composerValues, "saturation", composerOptions.saturation.amount);
2376
- this.post.addInput(composerValues, "bloom", composerOptions.bloom.amount);
2377
- this.post.addInput(composerValues, "grain", composerOptions.grain.amount);
2378
- this.post.on("change", (e) => {
2379
- const target = e.presetKey;
2380
- switch (target) {
2381
- case "brightness":
2382
- brightnessContrastSaturation.uniforms.brightness.value = e.value;
2383
- break;
2384
- case "contrast":
2385
- brightnessContrastSaturation.uniforms.contrast.value = e.value;
2386
- break;
2387
- case "saturation":
2388
- brightnessContrastSaturation.uniforms.saturation.value = e.value;
2389
- break;
2390
- case "bloom":
2391
- bloomEffect.intensity = e.value;
2392
- break;
2393
- case "grain":
2394
- gaussGrainEffect.uniforms.amount.value = e.value;
2395
- break;
2396
- default:
2397
- break;
2398
- }
2399
- });
2400
- }
2401
- {
2402
- this.environment.hidden = hasLighting === false || sun === null;
2403
- this.sun.addInput(
2404
- sunValues.sunPosition,
2405
- "sunAzimuthalAngle",
2406
- sunOptions.sunPosition.sunAzimuthalAngle
2407
- );
2408
- this.sun.addInput(
2409
- sunValues.sunPosition,
2410
- "sunPolarAngle",
2411
- sunOptions.sunPosition.sunPolarAngle
2412
- );
2413
- this.sun.addInput(sunValues, "sunIntensity", sunOptions.sunIntensity);
2414
- this.sun.addInput(sunValues, "sunColor", {
2415
- color: { type: "float" }
2416
- });
2417
- this.sunButton = this.sun.addButton({ title: "Set HDRI" });
2418
- this.sunButton.on("click", () => {
2419
- setHDR();
2420
- });
2421
- this.sun.on("change", (e) => {
2422
- const target = e.presetKey;
2423
- switch (target) {
2424
- case "sunAzimuthalAngle":
2425
- sun?.setAzimuthalAngle(e.value * (Math.PI / 180));
2426
- break;
2427
- case "sunPolarAngle":
2428
- sun?.setPolarAngle(e.value * (Math.PI / 180));
2429
- break;
2430
- case "sunIntensity":
2431
- sun?.setIntensity(e.value);
2432
- break;
2433
- case "sunColor":
2434
- sunValues.sunColor = {
2435
- r: e.value.r,
2436
- g: e.value.g,
2437
- b: e.value.b
2438
- };
2439
- sun?.setColor();
2440
- break;
2441
- default:
2442
- break;
2443
- }
2444
- });
2445
- this.ambient.addInput(
2446
- envValues.ambientLight,
2447
- "ambientLightIntensity",
2448
- envOptions.ambientLight.ambientLightIntensity
2449
- );
2450
- this.ambient.addInput(envValues.ambientLight, "ambientLightColor", {
2451
- color: { type: "float" }
2452
- });
2453
- this.ambient.addInput(envValues.fog, "fogNear", envOptions.fog.fogNear);
2454
- this.ambient.addInput(envValues.fog, "fogFar", envOptions.fog.fogFar);
2455
- this.ambient.addInput(envValues.fog, "fogColor", {
2456
- color: { type: "float" }
2457
- });
2458
- this.ambient.on("change", (e) => {
2459
- const target = e.presetKey;
2460
- switch (target) {
2461
- case "ambientLightIntensity":
2462
- envValues.ambientLight.ambientLightIntensity = e.value;
2463
- setAmbientLight();
2464
- break;
2465
- case "ambientLightColor":
2466
- envValues.ambientLight.ambientLightColor = {
2467
- r: e.value.r,
2468
- g: e.value.g,
2469
- b: e.value.b
2470
- };
2471
- setAmbientLight();
2472
- break;
2473
- case "fogNear":
2474
- envValues.fog.fogNear = e.value;
2475
- setFog();
2476
- break;
2477
- case "fogFar":
2478
- envValues.fog.fogFar = e.value;
2479
- setFog();
2480
- break;
2481
- case "fogColor":
2482
- envValues.fog.fogColor = {
2483
- r: e.value.r,
2484
- g: e.value.g,
2485
- b: e.value.b
2486
- };
2487
- setFog();
2488
- break;
2489
- default:
2490
- break;
2491
- }
2492
- });
2493
- }
2804
+ setupRenderPane(composer, normalPass, ppssaoEffect, ppssaoPass, n8aopass, toneMappingEffect, toneMappingPass, brightnessContrastSaturation, bloomEffect, gaussGrainEffect, hasLighting, sun, setHDR, setAmbientLight, setFog) {
2805
+ this.rendererFolder.setupChangeEvent(
2806
+ this.scene,
2807
+ this.renderer,
2808
+ this.toneMappingFolder.folder,
2809
+ toneMappingPass
2810
+ );
2811
+ this.toneMappingFolder.setupChangeEvent(toneMappingEffect);
2812
+ this.ssaoFolder.setupChangeEvent(composer, normalPass, ppssaoEffect, ppssaoPass, n8aopass);
2813
+ this.bcsFolder.setupChangeEvent(brightnessContrastSaturation);
2814
+ this.postExtrasFolder.setupChangeEvent(bloomEffect, gaussGrainEffect);
2815
+ this.environment.setupChangeEvent(setHDR, setAmbientLight, setFog, sun);
2816
+ this.environment.folder.hidden = hasLighting === false || sun === null;
2494
2817
  const exportButton = this.export.addButton({ title: "export" });
2495
2818
  exportButton.on("click", () => {
2496
- this.downloadSettingsAsJSON(this.gui.exportPreset());
2819
+ this.downloadSettingsAsJSON(this.gui.exportState());
2497
2820
  });
2498
2821
  const importButton = this.export.addButton({ title: "import" });
2499
2822
  importButton.on("click", () => {
2500
2823
  this.importSettingsFromJSON((settings) => {
2501
- this.gui.importPreset(settings);
2824
+ this.gui.importState(settings);
2502
2825
  });
2503
2826
  });
2504
2827
  }
2828
+ updateStats(timeManager) {
2829
+ this.renderStatsFolder.update(this.renderer, this.composer, timeManager);
2830
+ }
2505
2831
  formatDateForFilename() {
2506
2832
  const date = /* @__PURE__ */ new Date();
2507
2833
  const year = date.getFullYear();
@@ -2527,12 +2853,14 @@ var TweakPane = class {
2527
2853
  input.type = "file";
2528
2854
  input.accept = ".json";
2529
2855
  input.addEventListener("change", (event) => {
2530
- const file = event.target.files?.[0];
2856
+ var _a;
2857
+ const file = (_a = event.target.files) == null ? void 0 : _a[0];
2531
2858
  if (file) {
2532
2859
  const reader = new FileReader();
2533
2860
  reader.onload = (loadEvent) => {
2861
+ var _a2;
2534
2862
  try {
2535
- const settings = JSON.parse(loadEvent.target?.result);
2863
+ const settings = JSON.parse((_a2 = loadEvent.target) == null ? void 0 : _a2.result);
2536
2864
  callback(settings);
2537
2865
  } catch (err) {
2538
2866
  console.error("Error parsing JSON:", err);
@@ -2543,19 +2871,6 @@ var TweakPane = class {
2543
2871
  });
2544
2872
  input.click();
2545
2873
  }
2546
- updateStats(timeManager) {
2547
- const { geometries, textures } = this.renderer.info.memory;
2548
- const { triangles, calls } = this.renderer.info.render;
2549
- statsData.triangles = triangles.toString();
2550
- statsData.geometries = geometries.toString();
2551
- statsData.textures = textures.toString();
2552
- statsData.shaders = this.renderer.info.programs.length.toString();
2553
- statsData.postPasses = this.composer.passes.length.toString();
2554
- statsData.drawCalls = calls.toString();
2555
- statsData.rawDeltaTime = (Math.round(timeManager.rawDeltaTime * 1e5) / 1e5).toString();
2556
- statsData.deltaTime = (Math.round(timeManager.deltaTime * 1e5) / 1e5).toString();
2557
- statsData.FPS = timeManager.fps.toString();
2558
- }
2559
2874
  toggleGUI() {
2560
2875
  const gui = this.gui;
2561
2876
  const paneElement = gui.containerElem_;
@@ -2714,39 +3029,19 @@ var GaussGrainEffect = new ShaderMaterial2({
2714
3029
  // src/rendering/composer.ts
2715
3030
  var Composer = class {
2716
3031
  constructor(scene, camera, spawnSun = false) {
2717
- __publicField(this, "width", window.innerWidth);
2718
- __publicField(this, "height", window.innerHeight);
2719
- __publicField(this, "resolution", new Vector22(this.width, this.height));
2720
- __publicField(this, "isEnvHDRI", false);
2721
- __publicField(this, "scene");
2722
- __publicField(this, "camera");
2723
- __publicField(this, "renderer");
2724
- __publicField(this, "composer");
2725
- __publicField(this, "renderPass");
2726
- __publicField(this, "fxaaEffect");
2727
- __publicField(this, "fxaaPass");
2728
- __publicField(this, "bloomEffect");
2729
- __publicField(this, "bloomPass");
2730
- __publicField(this, "toneMappingEffect");
2731
- __publicField(this, "smaaEffect");
2732
- __publicField(this, "normalPass");
2733
- __publicField(this, "normalTextureEffect");
2734
- __publicField(this, "ssaoEffect");
2735
- __publicField(this, "ssaoPass");
2736
- __publicField(this, "toneMappingPass");
2737
- __publicField(this, "smaaPass");
2738
- __publicField(this, "bcs", BrightnessContrastSaturation);
2739
- __publicField(this, "bcsPass");
2740
- __publicField(this, "gaussGrainEffect", GaussGrainEffect);
2741
- __publicField(this, "gaussGrainPass");
2742
- __publicField(this, "ambientLight", null);
2743
- __publicField(this, "sun", null);
2744
- __publicField(this, "spawnSun");
2745
- __publicField(this, "tweakPane");
3032
+ this.width = window.innerWidth;
3033
+ this.height = window.innerHeight;
3034
+ this.resolution = new Vector22(this.width, this.height);
3035
+ this.isEnvHDRI = false;
3036
+ this.bcs = BrightnessContrastSaturation;
3037
+ this.gaussGrainEffect = GaussGrainEffect;
3038
+ this.ambientLight = null;
3039
+ this.sun = null;
2746
3040
  this.scene = scene;
3041
+ this.postPostScene = new Scene3();
2747
3042
  this.camera = camera;
2748
3043
  this.spawnSun = spawnSun;
2749
- this.renderer = new WebGLRenderer3({
3044
+ this.renderer = new WebGLRenderer2({
2750
3045
  powerPreference: "high-performance",
2751
3046
  antialias: false,
2752
3047
  stencil: false,
@@ -2755,9 +3050,9 @@ var Composer = class {
2755
3050
  this.renderer.info.autoReset = false;
2756
3051
  this.renderer.setSize(this.width, this.height);
2757
3052
  this.renderer.shadowMap.enabled = true;
2758
- this.renderer.shadowMap.type = composerValues.renderer.shadowMap;
2759
- this.renderer.toneMapping = composerValues.renderer.toneMapping;
2760
- this.renderer.toneMappingExposure = composerValues.renderer.exposure;
3053
+ this.renderer.shadowMap.type = rendererValues.shadowMap;
3054
+ this.renderer.toneMapping = rendererValues.toneMapping;
3055
+ this.renderer.toneMappingExposure = rendererValues.exposure;
2761
3056
  this.setAmbientLight();
2762
3057
  this.setFog();
2763
3058
  document.body.appendChild(this.renderer.domElement);
@@ -2766,44 +3061,59 @@ var Composer = class {
2766
3061
  });
2767
3062
  this.tweakPane = new TweakPane(this.renderer, this.scene, this.composer);
2768
3063
  this.renderPass = new RenderPass(this.scene, this.camera);
2769
- this.normalPass = new NormalPass(this.scene, this.camera);
3064
+ this.normalPass = new NormalPass2(this.scene, this.camera);
3065
+ this.normalPass.enabled = ppssaoValues.enabled;
2770
3066
  this.normalTextureEffect = new TextureEffect({
2771
- blendFunction: BlendFunction3.SKIP,
3067
+ blendFunction: BlendFunction2.SKIP,
2772
3068
  texture: this.normalPass.texture
2773
3069
  });
2774
- this.fxaaEffect = new FXAAEffect();
2775
- this.bloomEffect = new BloomEffect2({
2776
- intensity: composerValues.bloom
3070
+ this.ppssaoEffect = new SSAOEffect2(this.camera, this.normalPass.texture, {
3071
+ blendFunction: ppssaoValues.blendFunction,
3072
+ distanceScaling: ppssaoValues.distanceScaling,
3073
+ depthAwareUpsampling: ppssaoValues.depthAwareUpsampling,
3074
+ samples: ppssaoValues.samples,
3075
+ rings: ppssaoValues.rings,
3076
+ luminanceInfluence: ppssaoValues.luminanceInfluence,
3077
+ radius: ppssaoValues.radius,
3078
+ intensity: ppssaoValues.intensity,
3079
+ bias: ppssaoValues.bias,
3080
+ fade: ppssaoValues.fade,
3081
+ resolutionScale: ppssaoValues.resolutionScale,
3082
+ color: new Color6().setRGB(ppssaoValues.color.r, ppssaoValues.color.g, ppssaoValues.color.b),
3083
+ worldDistanceThreshold: ppssaoValues.worldDistanceThreshold,
3084
+ worldDistanceFalloff: ppssaoValues.worldDistanceFalloff,
3085
+ worldProximityThreshold: ppssaoValues.worldProximityThreshold,
3086
+ worldProximityFalloff: ppssaoValues.worldProximityFalloff
2777
3087
  });
2778
- this.ssaoEffect = new SSAOEffect2(this.camera, this.normalPass.texture, {
2779
- blendFunction: composerValues.ssao.blendFunction,
2780
- distanceScaling: composerValues.ssao.distanceScaling,
2781
- depthAwareUpsampling: composerValues.ssao.depthAwareUpsampling,
2782
- samples: composerValues.ssao.samples,
2783
- rings: composerValues.ssao.rings,
2784
- luminanceInfluence: composerValues.ssao.luminanceInfluence,
2785
- radius: composerValues.ssao.radius,
2786
- intensity: composerValues.ssao.intensity,
2787
- bias: composerValues.ssao.bias,
2788
- fade: composerValues.ssao.fade,
2789
- resolutionScale: composerValues.ssao.resolutionScale,
2790
- color: new Color6().setRGB(composerValues.ssao.color.r, composerValues.ssao.color.g, composerValues.ssao.color.b),
2791
- worldDistanceThreshold: composerValues.ssao.worldDistanceThreshold,
2792
- worldDistanceFalloff: composerValues.ssao.worldDistanceFalloff,
2793
- worldProximityThreshold: composerValues.ssao.worldProximityThreshold,
2794
- worldProximityFalloff: composerValues.ssao.worldProximityFalloff
3088
+ this.ppssaoPass = new EffectPass2(this.camera, this.ppssaoEffect, this.normalTextureEffect);
3089
+ this.ppssaoPass.enabled = ppssaoValues.enabled;
3090
+ this.fxaaEffect = new FXAAEffect();
3091
+ this.bloomEffect = new BloomEffect({
3092
+ intensity: extrasValues.bloom
2795
3093
  });
3094
+ this.n8aopass = new N8AOPostPass(this.scene, this.camera, this.width, this.height);
3095
+ this.n8aopass.configuration.aoRadius = n8ssaoValues.aoRadius;
3096
+ this.n8aopass.configuration.distanceFalloff = n8ssaoValues.distanceFalloff;
3097
+ this.n8aopass.configuration.intensity = n8ssaoValues.intensity;
3098
+ this.n8aopass.configuration.color = new Color6().setRGB(
3099
+ n8ssaoValues.color.r,
3100
+ n8ssaoValues.color.g,
3101
+ n8ssaoValues.color.b
3102
+ );
3103
+ this.n8aopass.configuration.aoSamples = n8ssaoValues.aoSamples;
3104
+ this.n8aopass.configuration.denoiseSamples = n8ssaoValues.denoiseSamples;
3105
+ this.n8aopass.configuration.denoiseRadius = n8ssaoValues.denoiseRadius;
3106
+ this.n8aopass.enabled = n8ssaoValues.enabled;
2796
3107
  this.fxaaPass = new EffectPass2(this.camera, this.fxaaEffect);
2797
3108
  this.bloomPass = new EffectPass2(this.camera, this.bloomEffect);
2798
- this.ssaoPass = new EffectPass2(this.camera, this.ssaoEffect, this.normalTextureEffect);
2799
- this.toneMappingEffect = new ToneMappingEffect2({
2800
- mode: composerValues.toneMapping.mode,
2801
- resolution: composerValues.toneMapping.resolution,
2802
- whitePoint: composerValues.toneMapping.whitePoint,
2803
- middleGrey: composerValues.toneMapping.middleGrey,
2804
- minLuminance: composerValues.toneMapping.minLuminance,
2805
- averageLuminance: composerValues.toneMapping.averageLuminance,
2806
- adaptationRate: composerValues.toneMapping.adaptationRate
3109
+ this.toneMappingEffect = new ToneMappingEffect({
3110
+ mode: toneMappingValues.mode,
3111
+ resolution: toneMappingValues.resolution,
3112
+ whitePoint: toneMappingValues.whitePoint,
3113
+ middleGrey: toneMappingValues.middleGrey,
3114
+ minLuminance: toneMappingValues.minLuminance,
3115
+ averageLuminance: toneMappingValues.averageLuminance,
3116
+ adaptationRate: toneMappingValues.adaptationRate
2807
3117
  });
2808
3118
  this.smaaEffect = new SMAAEffect({
2809
3119
  preset: SMAAPreset.ULTRA,
@@ -2811,16 +3121,21 @@ var Composer = class {
2811
3121
  predicationMode: PredicationMode.DEPTH
2812
3122
  });
2813
3123
  this.toneMappingPass = new EffectPass2(this.camera, this.toneMappingEffect);
2814
- this.toneMappingPass.enabled = composerValues.renderer.toneMapping === 5 || composerValues.renderer.toneMapping === 0 ? true : false;
3124
+ this.toneMappingPass.enabled = rendererValues.toneMapping === 5 || rendererValues.toneMapping === 0 ? true : false;
2815
3125
  this.bcsPass = new ShaderPass(this.bcs, "tDiffuse");
2816
- this.bcs.uniforms.brightness.value = composerValues.brightness;
2817
- this.bcs.uniforms.contrast.value = composerValues.contrast;
2818
- this.bcs.uniforms.saturation.value = composerValues.saturation;
3126
+ this.bcs.uniforms.brightness.value = bcsValues.brightness;
3127
+ this.bcs.uniforms.contrast.value = bcsValues.contrast;
3128
+ this.bcs.uniforms.saturation.value = bcsValues.saturation;
2819
3129
  this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, "tDiffuse");
2820
3130
  this.smaaPass = new EffectPass2(this.camera, this.smaaEffect);
2821
3131
  this.composer.addPass(this.renderPass);
2822
- this.composer.addPass(this.normalPass);
2823
- this.composer.addPass(this.ssaoPass);
3132
+ if (ppssaoValues.enabled) {
3133
+ this.composer.addPass(this.normalPass);
3134
+ this.composer.addPass(this.ppssaoPass);
3135
+ }
3136
+ if (n8ssaoValues.enabled) {
3137
+ this.composer.addPass(this.n8aopass);
3138
+ }
2824
3139
  this.composer.addPass(this.fxaaPass);
2825
3140
  this.composer.addPass(this.smaaPass);
2826
3141
  this.composer.addPass(this.bloomPass);
@@ -2832,7 +3147,11 @@ var Composer = class {
2832
3147
  this.scene.add(this.sun);
2833
3148
  }
2834
3149
  this.tweakPane.setupRenderPane(
2835
- this.ssaoEffect,
3150
+ this.composer,
3151
+ this.normalPass,
3152
+ this.ppssaoEffect,
3153
+ this.ppssaoPass,
3154
+ this.n8aopass,
2836
3155
  this.toneMappingEffect,
2837
3156
  this.toneMappingPass,
2838
3157
  this.bcs,
@@ -2853,8 +3172,14 @@ var Composer = class {
2853
3172
  this.resolution = new Vector22(this.width, this.height);
2854
3173
  this.composer.setSize(this.width, this.height);
2855
3174
  this.renderPass.setSize(this.width, this.height);
2856
- this.normalPass.setSize(this.width, this.height);
2857
- this.ssaoPass.setSize(this.width, this.height);
3175
+ if (ppssaoValues.enabled) {
3176
+ this.normalPass.setSize(this.width, this.height);
3177
+ this.normalTextureEffect.setSize(this.width, this.height);
3178
+ this.ppssaoPass.setSize(this.width, this.height);
3179
+ }
3180
+ if (n8ssaoValues.enabled) {
3181
+ this.n8aopass.setSize(this.width, this.height);
3182
+ }
2858
3183
  this.fxaaPass.setSize(this.width, this.height);
2859
3184
  this.smaaPass.setSize(this.width, this.height);
2860
3185
  this.bloomPass.setSize(this.width, this.height);
@@ -2872,6 +3197,7 @@ var Composer = class {
2872
3197
  this.gaussGrainEffect.uniforms.time.value = timeManager.time;
2873
3198
  this.gaussGrainEffect.uniforms.alpha.value = 1;
2874
3199
  this.composer.render();
3200
+ this.renderer.render(this.postPostScene, this.camera);
2875
3201
  if (this.tweakPane.guiVisible) {
2876
3202
  this.tweakPane.updateStats(timeManager);
2877
3203
  }
@@ -2889,7 +3215,7 @@ var Composer = class {
2889
3215
  envMap.needsUpdate = true;
2890
3216
  this.scene.environment = envMap;
2891
3217
  this.scene.background = envMap;
2892
- this.scene.backgroundIntensity = composerValues.renderer.bgIntensity;
3218
+ this.scene.backgroundIntensity = rendererValues.bgIntensity;
2893
3219
  this.isEnvHDRI = true;
2894
3220
  texture.dispose();
2895
3221
  pmremGenerator.dispose();
@@ -2909,7 +3235,8 @@ var Composer = class {
2909
3235
  fileInput.type = "file";
2910
3236
  fileInput.accept = ".hdr";
2911
3237
  fileInput.addEventListener("change", () => {
2912
- const file = fileInput.files?.[0];
3238
+ var _a;
3239
+ const file = (_a = fileInput.files) == null ? void 0 : _a[0];
2913
3240
  if (!file) {
2914
3241
  console.log("no file");
2915
3242
  return;
@@ -2954,21 +3281,21 @@ var Composer = class {
2954
3281
  import { Clock } from "three";
2955
3282
  var TimeManager = class {
2956
3283
  constructor() {
2957
- __publicField(this, "clock", new Clock());
2958
- __publicField(this, "roundMagnitude", 2e5);
2959
- __publicField(this, "maxAverageFrames", 150);
2960
- __publicField(this, "deltaTimes", []);
2961
- __publicField(this, "targetAverageDeltaTime", 0);
2962
- __publicField(this, "lerpedAverageMagDelta", 0);
2963
- __publicField(this, "fpsUpdateTime", 0);
2964
- __publicField(this, "framesSinceLastFPSUpdate", 0);
2965
- __publicField(this, "time", 0);
2966
- __publicField(this, "deltaTime", 0);
2967
- __publicField(this, "rawDeltaTime", 0);
2968
- __publicField(this, "smoothDeltaTime", 0);
2969
- __publicField(this, "frame", 0);
2970
- __publicField(this, "fps", 0);
2971
- __publicField(this, "averageFPS", 0);
3284
+ this.clock = new Clock();
3285
+ this.roundMagnitude = 2e5;
3286
+ this.maxAverageFrames = 150;
3287
+ this.deltaTimes = [];
3288
+ this.targetAverageDeltaTime = 0;
3289
+ this.lerpedAverageMagDelta = 0;
3290
+ this.fpsUpdateTime = 0;
3291
+ this.framesSinceLastFPSUpdate = 0;
3292
+ this.time = 0;
3293
+ this.deltaTime = 0;
3294
+ this.rawDeltaTime = 0;
3295
+ this.smoothDeltaTime = 0;
3296
+ this.frame = 0;
3297
+ this.fps = 0;
3298
+ this.averageFPS = 0;
2972
3299
  }
2973
3300
  update() {
2974
3301
  this.rawDeltaTime = this.clock.getDelta();
@@ -2998,52 +3325,73 @@ var TimeManager = class {
2998
3325
 
2999
3326
  // src/collisions/CollisionsManager.ts
3000
3327
  import {
3001
- MMLCollisionTrigger,
3002
- getRelativePositionAndRotationRelativeToObject
3328
+ getRelativePositionAndRotationRelativeToObject,
3329
+ MMLCollisionTrigger
3003
3330
  } from "mml-web";
3004
3331
  import {
3332
+ Box3,
3005
3333
  Color as Color7,
3006
3334
  DoubleSide,
3007
3335
  Euler,
3008
- FrontSide as FrontSide2,
3009
- Mesh as Mesh3,
3010
- MeshStandardMaterial as MeshStandardMaterial2,
3011
- Vector3 as Vector38
3336
+ Group as Group4,
3337
+ Line3 as Line32,
3338
+ Matrix4 as Matrix42,
3339
+ Mesh as Mesh4,
3340
+ MeshBasicMaterial as MeshBasicMaterial3,
3341
+ Ray,
3342
+ Vector3 as Vector39
3012
3343
  } from "three";
3344
+ import { VertexNormalsHelper } from "three/examples/jsm/helpers/VertexNormalsHelper.js";
3013
3345
  import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
3014
3346
  import { MeshBVH, MeshBVHVisualizer } from "three-mesh-bvh";
3015
3347
  var CollisionsManager = class {
3016
3348
  constructor(scene) {
3017
- __publicField(this, "debug", false);
3018
- __publicField(this, "scene");
3019
- __publicField(this, "tempVector", new Vector38());
3020
- __publicField(this, "tempVector2", new Vector38());
3021
- __publicField(this, "collisionMeshState", /* @__PURE__ */ new Map());
3022
- __publicField(this, "collisionTrigger");
3349
+ this.debug = false;
3350
+ this.tempVector = new Vector39();
3351
+ this.tempVector2 = new Vector39();
3352
+ this.tempVector3 = new Vector39();
3353
+ this.tempRay = new Ray();
3354
+ this.tempMatrix = new Matrix42();
3355
+ this.tempMatrix2 = new Matrix42();
3356
+ this.tempBox = new Box3();
3357
+ this.tempEuler = new Euler();
3358
+ this.tempSegment = new Line32();
3359
+ this.tempSegment2 = new Line32();
3360
+ this.collisionMeshState = /* @__PURE__ */ new Map();
3023
3361
  this.scene = scene;
3024
3362
  this.collisionTrigger = MMLCollisionTrigger.init();
3025
3363
  }
3026
3364
  raycastFirstDistance(ray) {
3027
3365
  let minimumDistance = null;
3028
3366
  for (const [, value] of this.collisionMeshState) {
3029
- const hit = value.meshBVH.raycastFirst(ray, DoubleSide);
3367
+ this.tempRay.copy(ray).applyMatrix4(this.tempMatrix.copy(value.matrix).invert());
3368
+ const hit = value.meshBVH.raycastFirst(this.tempRay, DoubleSide);
3030
3369
  if (hit) {
3031
- if (minimumDistance === null || hit.distance < minimumDistance) {
3032
- minimumDistance = hit.distance;
3370
+ this.tempSegment.start.copy(this.tempRay.origin);
3371
+ this.tempSegment.end.copy(hit.point);
3372
+ this.tempSegment.applyMatrix4(value.matrix);
3373
+ const dist = this.tempSegment.distance();
3374
+ if (minimumDistance === null || dist < minimumDistance) {
3375
+ minimumDistance = dist;
3033
3376
  }
3034
3377
  }
3035
3378
  }
3036
3379
  return minimumDistance;
3037
3380
  }
3038
- createCollisionMeshState(group) {
3381
+ createCollisionMeshState(group, trackCollisions) {
3039
3382
  const geometries = [];
3383
+ group.updateWorldMatrix(true, false);
3384
+ const invertedRootMatrix = this.tempMatrix.copy(group.matrixWorld).invert();
3040
3385
  group.traverse((child) => {
3041
3386
  if (child.type === "Mesh") {
3042
3387
  const mesh = child;
3043
- mesh.localToWorld(new Vector38());
3044
- mesh.updateMatrixWorld();
3045
3388
  const clonedGeometry = mesh.geometry.clone();
3046
- clonedGeometry.applyMatrix4(mesh.matrixWorld);
3389
+ if (child !== group) {
3390
+ mesh.updateWorldMatrix(true, false);
3391
+ clonedGeometry.applyMatrix4(
3392
+ this.tempMatrix2.multiplyMatrices(invertedRootMatrix, mesh.matrixWorld)
3393
+ );
3394
+ }
3047
3395
  for (const key in clonedGeometry.attributes) {
3048
3396
  if (key !== "position") {
3049
3397
  clonedGeometry.deleteAttribute(key);
@@ -3056,85 +3404,134 @@ var CollisionsManager = class {
3056
3404
  }
3057
3405
  }
3058
3406
  });
3059
- const newBufferGeometry = BufferGeometryUtils.mergeGeometries(geometries);
3407
+ const newBufferGeometry = BufferGeometryUtils.mergeGeometries(geometries, false);
3408
+ newBufferGeometry.computeVertexNormals();
3060
3409
  const meshBVH = new MeshBVH(newBufferGeometry);
3061
- if (!this.debug) {
3062
- return { source: group, visualizer: null, meshBVH };
3063
- }
3064
- const mergedMesh = new Mesh3(
3065
- newBufferGeometry,
3066
- new MeshStandardMaterial2({ color: 16711680, side: FrontSide2, wireframe: true })
3067
- );
3068
- mergedMesh.geometry.boundsTree = meshBVH;
3069
- const visualizer = new MeshBVHVisualizer(mergedMesh, 3);
3070
- visualizer.edgeMaterial.color = new Color7(255);
3071
- visualizer.update();
3072
- return { source: group, visualizer, meshBVH };
3410
+ const meshState = {
3411
+ source: group,
3412
+ meshBVH,
3413
+ matrix: group.matrixWorld.clone(),
3414
+ trackCollisions
3415
+ };
3416
+ if (this.debug) {
3417
+ newBufferGeometry.boundsTree = meshBVH;
3418
+ const wireframeMesh = new Mesh4(newBufferGeometry, new MeshBasicMaterial3({ wireframe: true }));
3419
+ const normalsHelper = new VertexNormalsHelper(wireframeMesh, 0.25, 65280);
3420
+ const visualizer = new MeshBVHVisualizer(wireframeMesh, 4);
3421
+ visualizer.edgeMaterial.color = new Color7("blue");
3422
+ const debugGroup = new Group4();
3423
+ debugGroup.add(wireframeMesh, normalsHelper, visualizer);
3424
+ group.matrixWorld.decompose(debugGroup.position, debugGroup.quaternion, debugGroup.scale);
3425
+ visualizer.update();
3426
+ meshState.debugGroup = debugGroup;
3427
+ }
3428
+ return meshState;
3073
3429
  }
3074
3430
  addMeshesGroup(group, mElement) {
3075
3431
  if (mElement) {
3076
3432
  this.collisionTrigger.addCollider(group, mElement);
3077
3433
  }
3078
- const meshState = this.createCollisionMeshState(group);
3079
- if (meshState.visualizer) {
3080
- this.scene.add(meshState.visualizer);
3434
+ const meshState = this.createCollisionMeshState(group, mElement !== void 0);
3435
+ if (meshState.debugGroup) {
3436
+ this.scene.add(meshState.debugGroup);
3081
3437
  }
3082
3438
  this.collisionMeshState.set(group, meshState);
3083
3439
  }
3084
3440
  updateMeshesGroup(group) {
3085
3441
  const meshState = this.collisionMeshState.get(group);
3086
3442
  if (meshState) {
3087
- const newMeshState = this.createCollisionMeshState(group);
3088
- if (meshState.visualizer) {
3089
- this.scene.remove(meshState.visualizer);
3090
- }
3091
- if (newMeshState.visualizer) {
3092
- this.scene.add(newMeshState.visualizer);
3443
+ group.updateWorldMatrix(true, false);
3444
+ meshState.matrix.copy(group.matrixWorld);
3445
+ if (meshState.debugGroup) {
3446
+ group.matrixWorld.decompose(
3447
+ meshState.debugGroup.position,
3448
+ meshState.debugGroup.quaternion,
3449
+ meshState.debugGroup.scale
3450
+ );
3093
3451
  }
3094
- this.collisionMeshState.set(group, newMeshState);
3095
3452
  }
3096
3453
  }
3097
3454
  removeMeshesGroup(group) {
3098
3455
  this.collisionTrigger.removeCollider(group);
3099
3456
  const meshState = this.collisionMeshState.get(group);
3100
3457
  if (meshState) {
3101
- if (meshState.visualizer) {
3102
- this.scene.remove(meshState.visualizer);
3458
+ if (meshState.debugGroup) {
3459
+ this.scene.remove(meshState.debugGroup);
3103
3460
  }
3104
3461
  this.collisionMeshState.delete(group);
3105
3462
  }
3106
3463
  }
3107
- applyCollider(tempSegment, radius, boundingBox, meshState) {
3464
+ applyCollider(worldBasedCapsuleSegment, capsuleRadius, meshState) {
3465
+ const meshMatrix = this.tempMatrix.copy(meshState.matrix).invert();
3466
+ const meshRelativeCapsuleBoundingBox = this.tempBox;
3467
+ meshRelativeCapsuleBoundingBox.makeEmpty();
3468
+ meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.start);
3469
+ meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.end);
3470
+ meshRelativeCapsuleBoundingBox.min.subScalar(capsuleRadius);
3471
+ meshRelativeCapsuleBoundingBox.max.addScalar(capsuleRadius);
3472
+ meshRelativeCapsuleBoundingBox.applyMatrix4(meshMatrix);
3473
+ const meshRelativeCapsuleSegment = this.tempSegment;
3474
+ meshRelativeCapsuleSegment.start.copy(worldBasedCapsuleSegment.start);
3475
+ meshRelativeCapsuleSegment.end.copy(worldBasedCapsuleSegment.end);
3476
+ meshRelativeCapsuleSegment.applyMatrix4(meshMatrix);
3477
+ const initialMeshRelativeCapsuleSegmentStart = this.tempVector3.copy(
3478
+ meshRelativeCapsuleSegment.start
3479
+ );
3108
3480
  let collisionPosition = null;
3109
3481
  meshState.meshBVH.shapecast({
3110
- intersectsBounds: (box) => box.intersectsBox(boundingBox),
3111
- intersectsTriangle: (tri) => {
3112
- const triPoint = this.tempVector;
3113
- const capsulePoint = this.tempVector2;
3114
- const distance = tri.closestPointToSegment(tempSegment, triPoint, capsulePoint);
3115
- if (distance < radius) {
3116
- const depth = radius - distance;
3117
- collisionPosition = new Vector38().copy(capsulePoint);
3118
- const direction = capsulePoint.sub(triPoint).normalize();
3119
- tempSegment.start.addScaledVector(direction, depth);
3120
- tempSegment.end.addScaledVector(direction, depth);
3482
+ intersectsBounds: (meshBox) => {
3483
+ return meshBox.intersectsBox(meshRelativeCapsuleBoundingBox);
3484
+ },
3485
+ intersectsTriangle: (meshTriangle) => {
3486
+ const closestPointOnTriangle = this.tempVector;
3487
+ const closestPointOnSegment = this.tempVector2;
3488
+ meshTriangle.closestPointToSegment(
3489
+ meshRelativeCapsuleSegment,
3490
+ closestPointOnTriangle,
3491
+ closestPointOnSegment
3492
+ );
3493
+ const intersectionSegment = this.tempSegment2;
3494
+ intersectionSegment.start.copy(closestPointOnTriangle);
3495
+ intersectionSegment.end.copy(closestPointOnSegment);
3496
+ const modelReferenceDistance = intersectionSegment.distance();
3497
+ intersectionSegment.applyMatrix4(meshState.matrix);
3498
+ const realDistance = intersectionSegment.distance();
3499
+ if (realDistance < capsuleRadius) {
3500
+ if (!collisionPosition) {
3501
+ collisionPosition = new Vector39().copy(closestPointOnSegment).applyMatrix4(meshState.matrix);
3502
+ }
3503
+ const ratio = realDistance / modelReferenceDistance;
3504
+ const realDepth = capsuleRadius - realDistance;
3505
+ const modelDepth = realDepth / ratio;
3506
+ const direction = closestPointOnSegment.sub(closestPointOnTriangle).normalize();
3507
+ meshRelativeCapsuleSegment.start.addScaledVector(direction, modelDepth);
3508
+ meshRelativeCapsuleSegment.end.addScaledVector(direction, modelDepth);
3121
3509
  }
3122
3510
  }
3123
3511
  });
3512
+ if (collisionPosition) {
3513
+ const delta = this.tempVector.copy(meshRelativeCapsuleSegment.start).sub(initialMeshRelativeCapsuleSegmentStart);
3514
+ this.tempMatrix.copy(meshState.matrix).setPosition(0, 0, 0);
3515
+ delta.applyMatrix4(this.tempMatrix);
3516
+ if (!(isNaN(delta.x) && isNaN(delta.y) && isNaN(delta.z))) {
3517
+ worldBasedCapsuleSegment.start.add(delta);
3518
+ worldBasedCapsuleSegment.end.add(delta);
3519
+ }
3520
+ }
3124
3521
  return collisionPosition;
3125
3522
  }
3126
- applyColliders(tempSegment, radius, boundingBox) {
3523
+ applyColliders(tempSegment, radius) {
3127
3524
  let collidedElements = null;
3128
3525
  for (const meshState of this.collisionMeshState.values()) {
3129
- const collisionPosition = this.applyCollider(tempSegment, radius, boundingBox, meshState);
3130
- if (collisionPosition) {
3526
+ const collisionPosition = this.applyCollider(tempSegment, radius, meshState);
3527
+ if (collisionPosition && meshState.trackCollisions) {
3131
3528
  if (collidedElements === null) {
3132
3529
  collidedElements = /* @__PURE__ */ new Map();
3133
3530
  }
3134
3531
  const relativePosition = getRelativePositionAndRotationRelativeToObject(
3135
3532
  {
3136
3533
  position: collisionPosition,
3137
- rotation: new Euler()
3534
+ rotation: this.tempEuler.set(0, 0, 0)
3138
3535
  },
3139
3536
  meshState.source
3140
3537
  );