@mml-io/3d-web-client-core 0.7.0 → 0.9.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/camera/CameraManager.d.ts +5 -3
- package/build/character/Character.d.ts +7 -1
- package/build/character/CharacterManager.d.ts +10 -3
- package/build/character/CharacterModel.d.ts +5 -3
- package/build/character/{ModelLoader.d.ts → CharacterModelLoader.d.ts} +3 -3
- package/build/character/CharacterSpeakingIndicator.d.ts +17 -0
- package/build/character/RemoteController.d.ts +3 -2
- package/build/helpers/math-helpers.d.ts +3 -1
- package/build/index.d.ts +2 -0
- package/build/index.js +718 -503
- package/build/index.js.map +4 -4
- package/build/input/EventHandlerCollection.d.ts +9 -0
- package/build/input/KeyInputManager.d.ts +3 -1
- package/build/mml/MMLCompositionScene.d.ts +5 -4
- package/build/rendering/composer.d.ts +8 -4
- package/build/tweakpane/TweakPane.d.ts +1 -1
- package/package.json +3 -3
package/build/index.js
CHANGED
@@ -2,7 +2,21 @@
|
|
2
2
|
import { PerspectiveCamera, Raycaster, Vector3 as Vector32 } from "three";
|
3
3
|
|
4
4
|
// src/helpers/math-helpers.ts
|
5
|
-
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
|
+
};
|
6
20
|
var getSpawnPositionInsideCircle = (radius, positions, id, yPos = 0) => {
|
7
21
|
if (id > 0)
|
8
22
|
id += 3;
|
@@ -27,6 +41,47 @@ var remap = (value, minValue, maxValue, minScaledValue, maxScaledValue) => {
|
|
27
41
|
return minScaledValue + (maxScaledValue - minScaledValue) * (value - minValue) / (maxValue - minValue);
|
28
42
|
};
|
29
43
|
|
44
|
+
// src/input/EventHandlerCollection.ts
|
45
|
+
var EventHandlerCollection = class _EventHandlerCollection {
|
46
|
+
constructor() {
|
47
|
+
this.eventsByTarget = /* @__PURE__ */ new Map();
|
48
|
+
}
|
49
|
+
add(target, key, listener, options) {
|
50
|
+
target.addEventListener(key, listener, options);
|
51
|
+
let existingTarget = this.eventsByTarget.get(target);
|
52
|
+
if (existingTarget === void 0) {
|
53
|
+
existingTarget = /* @__PURE__ */ new Map();
|
54
|
+
this.eventsByTarget.set(target, existingTarget);
|
55
|
+
}
|
56
|
+
let existingKey = existingTarget.get(key);
|
57
|
+
if (existingKey === void 0) {
|
58
|
+
existingKey = /* @__PURE__ */ new Set();
|
59
|
+
existingTarget.set(key, existingKey);
|
60
|
+
}
|
61
|
+
existingKey.add(listener);
|
62
|
+
return this;
|
63
|
+
}
|
64
|
+
clear() {
|
65
|
+
this.eventsByTarget.forEach((keyMap, target) => {
|
66
|
+
keyMap.forEach((listenerSet, key) => {
|
67
|
+
listenerSet.forEach((listenerFunc) => {
|
68
|
+
target.removeEventListener(key, listenerFunc);
|
69
|
+
});
|
70
|
+
});
|
71
|
+
});
|
72
|
+
this.eventsByTarget.clear();
|
73
|
+
}
|
74
|
+
static create(initial) {
|
75
|
+
const instance = new _EventHandlerCollection();
|
76
|
+
if (initial !== void 0) {
|
77
|
+
initial.forEach(([target, key, listenerFunc, options]) => {
|
78
|
+
instance.add(target, key, listenerFunc, options);
|
79
|
+
});
|
80
|
+
}
|
81
|
+
return instance;
|
82
|
+
}
|
83
|
+
};
|
84
|
+
|
30
85
|
// src/tweakpane/tweakPaneActivity.ts
|
31
86
|
var isTweakpaneActive = false;
|
32
87
|
function setTweakpaneActive(status) {
|
@@ -38,7 +93,7 @@ function getTweakpaneActive() {
|
|
38
93
|
|
39
94
|
// src/camera/CameraManager.ts
|
40
95
|
var CameraManager = class {
|
41
|
-
constructor(collisionsManager) {
|
96
|
+
constructor(targetElement, collisionsManager, initialPhi = Math.PI / 2, initialTheta = -Math.PI / 2) {
|
42
97
|
this.collisionsManager = collisionsManager;
|
43
98
|
this.initialDistance = 3.3;
|
44
99
|
this.minDistance = 0.1;
|
@@ -53,42 +108,39 @@ var CameraManager = class {
|
|
53
108
|
this.dampingFactor = 0.091;
|
54
109
|
this.targetDistance = this.initialDistance;
|
55
110
|
this.distance = this.initialDistance;
|
56
|
-
this.
|
57
|
-
this.phi = Math.PI / 2;
|
58
|
-
this.targetTheta = -Math.PI / 2;
|
59
|
-
this.theta = -Math.PI / 2;
|
111
|
+
this.desiredDistance = this.initialDistance;
|
60
112
|
this.dragging = false;
|
61
113
|
this.target = new Vector32(0, 1.55, 0);
|
62
114
|
this.hadTarget = false;
|
115
|
+
this.phi = initialPhi;
|
116
|
+
this.targetPhi = initialPhi;
|
117
|
+
this.theta = initialTheta;
|
118
|
+
this.targetTheta = initialTheta;
|
63
119
|
this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);
|
64
120
|
this.camera.position.set(0, 1.4, -this.initialDistance);
|
65
121
|
this.rayCaster = new Raycaster();
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
const height = window.innerHeight;
|
75
|
-
this.camera.aspect = width / height;
|
76
|
-
this.camera.updateProjectionMatrix();
|
77
|
-
}
|
78
|
-
onMouseDown(_event) {
|
122
|
+
this.eventHandlerCollection = EventHandlerCollection.create([
|
123
|
+
[targetElement, "mousedown", this.onMouseDown.bind(this)],
|
124
|
+
[document, "mouseup", this.onMouseUp.bind(this)],
|
125
|
+
[document, "mousemove", this.onMouseMove.bind(this)],
|
126
|
+
[targetElement, "wheel", this.onMouseWheel.bind(this)]
|
127
|
+
]);
|
128
|
+
}
|
129
|
+
onMouseDown() {
|
79
130
|
this.dragging = true;
|
80
131
|
}
|
81
132
|
onMouseUp(_event) {
|
82
133
|
this.dragging = false;
|
83
134
|
}
|
84
135
|
onMouseMove(event) {
|
85
|
-
if (!this.dragging || getTweakpaneActive()
|
136
|
+
if (!this.dragging || getTweakpaneActive())
|
86
137
|
return;
|
87
138
|
if (this.targetTheta === null || this.targetPhi === null)
|
88
139
|
return;
|
89
140
|
this.targetTheta += event.movementX * 0.01;
|
90
141
|
this.targetPhi -= event.movementY * 0.01;
|
91
142
|
this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));
|
143
|
+
event.preventDefault();
|
92
144
|
}
|
93
145
|
onMouseWheel(event) {
|
94
146
|
const scrollAmount = event.deltaY * 1e-3;
|
@@ -97,6 +149,8 @@ var CameraManager = class {
|
|
97
149
|
this.minDistance,
|
98
150
|
Math.min(this.maxDistance, this.targetDistance)
|
99
151
|
);
|
152
|
+
this.desiredDistance = this.targetDistance;
|
153
|
+
event.preventDefault();
|
100
154
|
}
|
101
155
|
setTarget(target) {
|
102
156
|
this.target.copy(target);
|
@@ -128,8 +182,13 @@ var CameraManager = class {
|
|
128
182
|
if (minimumDistance !== null && minimumDistance <= cameraToPlayerDistance) {
|
129
183
|
this.targetDistance = cameraToPlayerDistance - minimumDistance;
|
130
184
|
this.distance = this.targetDistance;
|
185
|
+
} else {
|
186
|
+
this.targetDistance += (this.desiredDistance - this.targetDistance) * this.dampingFactor * 4;
|
131
187
|
}
|
132
188
|
}
|
189
|
+
dispose() {
|
190
|
+
this.eventHandlerCollection.clear();
|
191
|
+
}
|
133
192
|
update() {
|
134
193
|
if (this.target === null)
|
135
194
|
return;
|
@@ -159,15 +218,15 @@ var CameraManager = class {
|
|
159
218
|
};
|
160
219
|
|
161
220
|
// src/character/Character.ts
|
162
|
-
import { Color as Color3, Vector3 as
|
221
|
+
import { Color as Color3, Vector3 as Vector35 } from "three";
|
163
222
|
|
164
223
|
// src/character/CharacterModel.ts
|
165
224
|
import {
|
166
|
-
AnimationClip
|
225
|
+
AnimationClip,
|
167
226
|
AnimationMixer,
|
168
227
|
LoopRepeat,
|
169
228
|
MeshStandardMaterial,
|
170
|
-
Object3D
|
229
|
+
Object3D
|
171
230
|
} from "three";
|
172
231
|
|
173
232
|
// src/character/CharacterMaterial.ts
|
@@ -542,128 +601,14 @@ var AnimationState = /* @__PURE__ */ ((AnimationState2) => {
|
|
542
601
|
return AnimationState2;
|
543
602
|
})(AnimationState || {});
|
544
603
|
|
545
|
-
// src/character/ModelLoader.ts
|
546
|
-
import { LoadingManager } from "three";
|
547
|
-
import { GLTFLoader as ThreeGLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
548
|
-
var CachedGLTFLoader = class extends ThreeGLTFLoader {
|
549
|
-
constructor(manager) {
|
550
|
-
super(manager);
|
551
|
-
this.blobCache = /* @__PURE__ */ new Map();
|
552
|
-
}
|
553
|
-
setBlobUrl(originalUrl, blobUrl) {
|
554
|
-
this.blobCache.set(originalUrl, blobUrl);
|
555
|
-
}
|
556
|
-
getBlobUrl(originalUrl) {
|
557
|
-
return this.blobCache.get(originalUrl);
|
558
|
-
}
|
559
|
-
load(url, onLoad, onProgress, onError) {
|
560
|
-
const blobUrl = this.getBlobUrl(url);
|
561
|
-
if (blobUrl) {
|
562
|
-
console.log(`Loading cached ${url.split("/").pop()}`);
|
563
|
-
super.load(blobUrl, onLoad, onProgress, onError);
|
564
|
-
} else {
|
565
|
-
super.load(url, onLoad, onProgress, onError);
|
566
|
-
}
|
567
|
-
}
|
568
|
-
};
|
569
|
-
var LRUCache = class {
|
570
|
-
constructor(maxSize = 100) {
|
571
|
-
this.maxSize = maxSize;
|
572
|
-
this.cache = /* @__PURE__ */ new Map();
|
573
|
-
}
|
574
|
-
get(key) {
|
575
|
-
const item = this.cache.get(key);
|
576
|
-
if (item) {
|
577
|
-
this.cache.delete(key);
|
578
|
-
this.cache.set(key, item);
|
579
|
-
}
|
580
|
-
return item;
|
581
|
-
}
|
582
|
-
set(key, value) {
|
583
|
-
if (this.cache.size >= this.maxSize) {
|
584
|
-
const oldestKey = this.cache.keys().next().value;
|
585
|
-
this.cache.delete(oldestKey);
|
586
|
-
}
|
587
|
-
this.cache.set(key, value);
|
588
|
-
}
|
589
|
-
};
|
590
|
-
var _ModelLoader = class _ModelLoader {
|
591
|
-
constructor(maxCacheSize = 100) {
|
592
|
-
this.ongoingLoads = /* @__PURE__ */ new Map();
|
593
|
-
this.loadingManager = new LoadingManager();
|
594
|
-
this.gltfLoader = new CachedGLTFLoader(this.loadingManager);
|
595
|
-
this.modelCache = new LRUCache(maxCacheSize);
|
596
|
-
}
|
597
|
-
/* TODO: decide between below lazy initialization or eager on this file's bottom export */
|
598
|
-
static getInstance() {
|
599
|
-
if (!_ModelLoader.instance) {
|
600
|
-
_ModelLoader.instance = new _ModelLoader();
|
601
|
-
}
|
602
|
-
return _ModelLoader.instance;
|
603
|
-
}
|
604
|
-
async load(fileUrl, fileType) {
|
605
|
-
const cachedModel = this.modelCache.get(fileUrl);
|
606
|
-
if (cachedModel) {
|
607
|
-
const blobURL = URL.createObjectURL(cachedModel.blob);
|
608
|
-
this.gltfLoader.setBlobUrl(fileUrl, blobURL);
|
609
|
-
return this.loadFromUrl(fileUrl, fileType, cachedModel.originalExtension);
|
610
|
-
} else {
|
611
|
-
console.log(`Loading ${fileUrl} from server`);
|
612
|
-
const ongoingLoad = this.ongoingLoads.get(fileUrl);
|
613
|
-
if (ongoingLoad)
|
614
|
-
return ongoingLoad;
|
615
|
-
const loadPromise = fetch(fileUrl).then((response) => response.blob()).then((blob) => {
|
616
|
-
const originalExtension = fileUrl.split(".").pop() || "";
|
617
|
-
this.modelCache.set(fileUrl, { blob, originalExtension });
|
618
|
-
const blobURL = URL.createObjectURL(blob);
|
619
|
-
this.ongoingLoads.delete(fileUrl);
|
620
|
-
return this.loadFromUrl(blobURL, fileType, originalExtension);
|
621
|
-
});
|
622
|
-
this.ongoingLoads.set(fileUrl, loadPromise);
|
623
|
-
return loadPromise;
|
624
|
-
}
|
625
|
-
}
|
626
|
-
async loadFromUrl(url, fileType, extension) {
|
627
|
-
if (["gltf", "glb"].includes(extension)) {
|
628
|
-
return new Promise((resolve, reject) => {
|
629
|
-
this.gltfLoader.load(
|
630
|
-
url,
|
631
|
-
(object) => {
|
632
|
-
if (fileType === "model") {
|
633
|
-
resolve(object.scene);
|
634
|
-
} else if (fileType === "animation") {
|
635
|
-
resolve(object.animations[0]);
|
636
|
-
} else {
|
637
|
-
const error = `Trying to load unknown ${fileType} type of element from file ${url}`;
|
638
|
-
console.error(error);
|
639
|
-
reject(error);
|
640
|
-
}
|
641
|
-
},
|
642
|
-
void 0,
|
643
|
-
(error) => {
|
644
|
-
console.error(`Error loading GL(B|TF) from ${url}: ${error}`);
|
645
|
-
reject(error);
|
646
|
-
}
|
647
|
-
);
|
648
|
-
});
|
649
|
-
} else {
|
650
|
-
console.error(`Error: can't recognize ${url} extension: ${extension}`);
|
651
|
-
}
|
652
|
-
}
|
653
|
-
};
|
654
|
-
_ModelLoader.instance = null;
|
655
|
-
var ModelLoader = _ModelLoader;
|
656
|
-
var MODEL_LOADER = ModelLoader.getInstance();
|
657
|
-
var ModelLoader_default = MODEL_LOADER;
|
658
|
-
|
659
604
|
// src/character/CharacterModel.ts
|
660
605
|
var CharacterModel = class {
|
661
|
-
constructor(characterDescription) {
|
606
|
+
constructor(characterDescription, characterModelLoader) {
|
662
607
|
this.characterDescription = characterDescription;
|
663
|
-
|
664
|
-
this.modelLoader = ModelLoader_default;
|
608
|
+
this.characterModelLoader = characterModelLoader;
|
665
609
|
this.mesh = null;
|
666
610
|
this.material = new CharacterMaterial();
|
611
|
+
this.headBone = null;
|
667
612
|
this.animations = {};
|
668
613
|
this.animationMixer = null;
|
669
614
|
this.currentAnimation = 0 /* idle */;
|
@@ -699,6 +644,9 @@ var CharacterModel = class {
|
|
699
644
|
if (!this.mesh)
|
700
645
|
return;
|
701
646
|
this.mesh.traverse((child) => {
|
647
|
+
if (child.type === "Bone" && child.name === "mixamorigHeadTop_End") {
|
648
|
+
this.headBone = child;
|
649
|
+
}
|
702
650
|
if (child.type === "SkinnedMesh" && child.name === meshName) {
|
703
651
|
child.material = new MeshStandardMaterial({
|
704
652
|
color: 16711680,
|
@@ -735,9 +683,9 @@ var CharacterModel = class {
|
|
735
683
|
const scale = this.characterDescription.modelScale;
|
736
684
|
const extension = mainMeshUrl.split(".").pop();
|
737
685
|
const name = mainMeshUrl.split("/").pop().replace(`.${extension}`, "");
|
738
|
-
const mainMesh = await this.
|
686
|
+
const mainMesh = await this.characterModelLoader.load(mainMeshUrl, "model");
|
739
687
|
if (typeof mainMesh !== "undefined") {
|
740
|
-
this.mesh = new
|
688
|
+
this.mesh = new Object3D();
|
741
689
|
const model = mainMesh;
|
742
690
|
model.position.set(0, -0.4, 0);
|
743
691
|
this.mesh.add(model);
|
@@ -749,8 +697,8 @@ var CharacterModel = class {
|
|
749
697
|
async setAnimationFromFile(animationFileUrl, animationType) {
|
750
698
|
return new Promise(async (resolve, reject) => {
|
751
699
|
this.initAnimationMixer();
|
752
|
-
const animation = await this.
|
753
|
-
if (typeof animation !== "undefined" && animation instanceof
|
700
|
+
const animation = await this.characterModelLoader.load(animationFileUrl, "animation");
|
701
|
+
if (typeof animation !== "undefined" && animation instanceof AnimationClip) {
|
754
702
|
this.animations[animationType] = this.animationMixer.clipAction(animation);
|
755
703
|
this.animations[animationType].stop();
|
756
704
|
if (animationType === 0 /* idle */) {
|
@@ -782,12 +730,104 @@ var CharacterModel = class {
|
|
782
730
|
}
|
783
731
|
};
|
784
732
|
|
733
|
+
// src/character/CharacterSpeakingIndicator.ts
|
734
|
+
import {
|
735
|
+
CircleGeometry,
|
736
|
+
GLSL3,
|
737
|
+
Mesh as Mesh2,
|
738
|
+
RawShaderMaterial
|
739
|
+
} from "three";
|
740
|
+
var CharacterSpeakingIndicator = class {
|
741
|
+
constructor(scene) {
|
742
|
+
this.scene = scene;
|
743
|
+
this.vertexShader = /* glsl */
|
744
|
+
`
|
745
|
+
in vec3 position;
|
746
|
+
in vec2 uv;
|
747
|
+
uniform mat4 modelViewMatrix;
|
748
|
+
uniform mat4 projectionMatrix;
|
749
|
+
out vec2 vUv;
|
750
|
+
void main() {
|
751
|
+
vUv = uv;
|
752
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
753
|
+
}`;
|
754
|
+
this.fragmentShader = /* glsl */
|
755
|
+
`
|
756
|
+
precision highp float;
|
757
|
+
|
758
|
+
uniform float time;
|
759
|
+
uniform float alpha;
|
760
|
+
in vec2 vUv;
|
761
|
+
out vec4 fragColor;
|
762
|
+
|
763
|
+
const float size = 1.7;
|
764
|
+
const float distribution = 0.03;
|
765
|
+
const float speed = 0.2;
|
766
|
+
const float overdraw = 3.5;
|
767
|
+
const float shapeK = 0.25;
|
768
|
+
|
769
|
+
float sdHyperbola(vec2 p, float k, float wi) {
|
770
|
+
p = abs(p);
|
771
|
+
float k2 = k * k;
|
772
|
+
float a = p.x + p.y;
|
773
|
+
float i = 0.5 * (a - k2 / a) > wi ? -1.0 : 1.0;
|
774
|
+
float x = clamp(0.5 * (a - k2 / a), 0.0, wi);
|
775
|
+
vec2 q = vec2(x, sqrt(x * x + k2));
|
776
|
+
float s = sign(p.x * p.x - p.y * p.y + k2);
|
777
|
+
return s * length(p - q);
|
778
|
+
}
|
779
|
+
|
780
|
+
void main(void) {
|
781
|
+
vec2 uv = (vUv * 2.0 - 1.0);
|
782
|
+
float r = -(uv.x * uv.x + uv.y * uv.y);
|
783
|
+
float z = 0.5 + 0.5 * sin((r + time * speed) / distribution);
|
784
|
+
float a = clamp(smoothstep(-0.1, 0.2, size - length(uv * 2.0)), 0.0, 0.5);
|
785
|
+
float h = clamp(sdHyperbola(uv, shapeK, 1.0), 0.0, 1.0) * overdraw;
|
786
|
+
float fragAlpha = clamp(a * h, 0.0, 0.7);
|
787
|
+
fragColor = vec4(z * fragAlpha) * alpha;
|
788
|
+
}`;
|
789
|
+
this.uniforms = {
|
790
|
+
time: { value: 0 },
|
791
|
+
alpha: { value: 0 }
|
792
|
+
};
|
793
|
+
this.geometry = new CircleGeometry(0.35, 21);
|
794
|
+
this.material = new RawShaderMaterial({
|
795
|
+
vertexShader: this.vertexShader,
|
796
|
+
fragmentShader: this.fragmentShader,
|
797
|
+
uniforms: this.uniforms,
|
798
|
+
transparent: true,
|
799
|
+
glslVersion: GLSL3
|
800
|
+
});
|
801
|
+
this.mesh = new Mesh2(this.geometry, this.material);
|
802
|
+
this.currentAlpha = 0;
|
803
|
+
this.targetAlpha = 0;
|
804
|
+
this.scene.add(this.mesh);
|
805
|
+
}
|
806
|
+
setBillboarding(position, camera) {
|
807
|
+
this.mesh.position.set(position.x, position.y - 0.15, position.z);
|
808
|
+
this.mesh.lookAt(camera.position);
|
809
|
+
}
|
810
|
+
setTime(value) {
|
811
|
+
this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.06);
|
812
|
+
this.uniforms.time.value = value;
|
813
|
+
this.uniforms.alpha.value = this.currentAlpha;
|
814
|
+
}
|
815
|
+
setSpeaking(value) {
|
816
|
+
this.targetAlpha = value === true ? 1 : 0;
|
817
|
+
}
|
818
|
+
dispose() {
|
819
|
+
this.scene.remove(this.mesh);
|
820
|
+
this.mesh.material.dispose();
|
821
|
+
this.mesh.geometry.dispose();
|
822
|
+
}
|
823
|
+
};
|
824
|
+
|
785
825
|
// src/character/CharacterTooltip.ts
|
786
826
|
import {
|
787
827
|
Color as Color2,
|
788
828
|
FrontSide,
|
789
829
|
LinearFilter as LinearFilter2,
|
790
|
-
Mesh as
|
830
|
+
Mesh as Mesh3,
|
791
831
|
MeshBasicMaterial as MeshBasicMaterial2,
|
792
832
|
PlaneGeometry
|
793
833
|
} from "three";
|
@@ -937,7 +977,7 @@ var CharacterTooltip = class {
|
|
937
977
|
});
|
938
978
|
this.material.side = FrontSide;
|
939
979
|
this.geometry = new PlaneGeometry(1, 1, 1, 1);
|
940
|
-
this.mesh = new
|
980
|
+
this.mesh = new Mesh3(this.geometry, this.material);
|
941
981
|
this.mesh.position.set(0, 1.6, 0);
|
942
982
|
this.mesh.visible = false;
|
943
983
|
parentModel.add(this.mesh);
|
@@ -1020,7 +1060,7 @@ var CharacterTooltip = class {
|
|
1020
1060
|
};
|
1021
1061
|
|
1022
1062
|
// src/character/LocalController.ts
|
1023
|
-
import { Line3, Matrix4, Quaternion, Raycaster as Raycaster2, Vector3 as
|
1063
|
+
import { Line3, Matrix4, Quaternion as Quaternion2, Raycaster as Raycaster2, Vector3 as Vector34 } from "three";
|
1024
1064
|
var LocalController = class {
|
1025
1065
|
constructor(model, id, collisionsManager, keyInputManager, cameraManager, timeManager) {
|
1026
1066
|
this.model = model;
|
@@ -1032,7 +1072,7 @@ var LocalController = class {
|
|
1032
1072
|
this.collisionDetectionSteps = 15;
|
1033
1073
|
this.capsuleInfo = {
|
1034
1074
|
radius: 0.4,
|
1035
|
-
segment: new Line3(new
|
1075
|
+
segment: new Line3(new Vector34(), new Vector34(0, 1.05, 0))
|
1036
1076
|
};
|
1037
1077
|
this.maxWalkSpeed = 6;
|
1038
1078
|
this.maxRunSpeed = 8.5;
|
@@ -1045,15 +1085,15 @@ var LocalController = class {
|
|
1045
1085
|
this.characterWasOnGround = false;
|
1046
1086
|
this.characterAirborneSince = 0;
|
1047
1087
|
this.currentHeight = 0;
|
1048
|
-
this.characterVelocity = new
|
1049
|
-
this.vectorUp = new
|
1050
|
-
this.vectorDown = new
|
1088
|
+
this.characterVelocity = new Vector34();
|
1089
|
+
this.vectorUp = new Vector34(0, 1, 0);
|
1090
|
+
this.vectorDown = new Vector34(0, -1, 0);
|
1051
1091
|
this.rotationOffset = 0;
|
1052
1092
|
this.azimuthalAngle = 0;
|
1053
1093
|
this.tempMatrix = new Matrix4();
|
1054
1094
|
this.tempSegment = new Line3();
|
1055
|
-
this.tempVector = new
|
1056
|
-
this.tempVector2 = new
|
1095
|
+
this.tempVector = new Vector34();
|
1096
|
+
this.tempVector2 = new Vector34();
|
1057
1097
|
this.rayCaster = new Raycaster2();
|
1058
1098
|
this.thirdPersonCamera = null;
|
1059
1099
|
this.speed = 0;
|
@@ -1141,7 +1181,7 @@ var LocalController = class {
|
|
1141
1181
|
const camToModelDistance = this.thirdPersonCamera.position.distanceTo(this.model.mesh.position);
|
1142
1182
|
const isCameraFirstPerson = camToModelDistance < 2;
|
1143
1183
|
if (isCameraFirstPerson) {
|
1144
|
-
const cameraForward = new
|
1184
|
+
const cameraForward = new Vector34(0, 0, 1).applyQuaternion(this.thirdPersonCamera.quaternion);
|
1145
1185
|
this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);
|
1146
1186
|
} else {
|
1147
1187
|
this.azimuthalAngle = Math.atan2(
|
@@ -1162,7 +1202,7 @@ var LocalController = class {
|
|
1162
1202
|
return;
|
1163
1203
|
this.updateRotationOffset();
|
1164
1204
|
this.updateAzimuthalAngle();
|
1165
|
-
const rotationQuaternion = new
|
1205
|
+
const rotationQuaternion = new Quaternion2();
|
1166
1206
|
rotationQuaternion.setFromAxisAngle(this.vectorUp, this.azimuthalAngle + this.rotationOffset);
|
1167
1207
|
const angularDifference = this.computeAngularDifference(rotationQuaternion);
|
1168
1208
|
const desiredTime = 0.07;
|
@@ -1190,7 +1230,6 @@ var LocalController = class {
|
|
1190
1230
|
this.characterVelocity.y = deltaTime * this.gravity;
|
1191
1231
|
}
|
1192
1232
|
} else if (this.jump && this.coyoteTime) {
|
1193
|
-
console.log("coyoteJump");
|
1194
1233
|
this.characterVelocity.y = this.jumpForce;
|
1195
1234
|
this.canJump = false;
|
1196
1235
|
} else {
|
@@ -1200,19 +1239,19 @@ var LocalController = class {
|
|
1200
1239
|
this.model.mesh.position.addScaledVector(this.characterVelocity, deltaTime);
|
1201
1240
|
this.tempVector.set(0, 0, 0);
|
1202
1241
|
if (this.forward) {
|
1203
|
-
const forward = new
|
1242
|
+
const forward = new Vector34(0, 0, -1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1204
1243
|
this.tempVector.add(forward);
|
1205
1244
|
}
|
1206
1245
|
if (this.backward) {
|
1207
|
-
const backward = new
|
1246
|
+
const backward = new Vector34(0, 0, 1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1208
1247
|
this.tempVector.add(backward);
|
1209
1248
|
}
|
1210
1249
|
if (this.left) {
|
1211
|
-
const left = new
|
1250
|
+
const left = new Vector34(-1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1212
1251
|
this.tempVector.add(left);
|
1213
1252
|
}
|
1214
1253
|
if (this.right) {
|
1215
|
-
const right = new
|
1254
|
+
const right = new Vector34(1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1216
1255
|
this.tempVector.add(right);
|
1217
1256
|
}
|
1218
1257
|
if (this.tempVector.length() > 0) {
|
@@ -1249,13 +1288,13 @@ var LocalController = class {
|
|
1249
1288
|
if (!((_a = this.model) == null ? void 0 : _a.mesh)) {
|
1250
1289
|
this.networkState = {
|
1251
1290
|
id: this.id,
|
1252
|
-
position: new
|
1291
|
+
position: new Vector34(),
|
1253
1292
|
rotation: { quaternionY: 0, quaternionW: 1 },
|
1254
1293
|
state: 0 /* idle */
|
1255
1294
|
};
|
1256
1295
|
} else {
|
1257
|
-
const characterQuaternion = this.model.mesh.getWorldQuaternion(new
|
1258
|
-
const positionUpdate = new
|
1296
|
+
const characterQuaternion = this.model.mesh.getWorldQuaternion(new Quaternion2());
|
1297
|
+
const positionUpdate = new Vector34(
|
1259
1298
|
this.model.mesh.position.x,
|
1260
1299
|
this.model.mesh.position.y,
|
1261
1300
|
this.model.mesh.position.z
|
@@ -1280,8 +1319,9 @@ var LocalController = class {
|
|
1280
1319
|
|
1281
1320
|
// src/character/Character.ts
|
1282
1321
|
var Character = class {
|
1283
|
-
constructor(characterDescription, id, isLocal, modelLoadedCallback, collisionsManager, keyInputManager, cameraManager, timeManager) {
|
1322
|
+
constructor(characterDescription, characterModelLoader, id, isLocal, modelLoadedCallback, collisionsManager, keyInputManager, cameraManager, timeManager, composer) {
|
1284
1323
|
this.characterDescription = characterDescription;
|
1324
|
+
this.characterModelLoader = characterModelLoader;
|
1285
1325
|
this.id = id;
|
1286
1326
|
this.isLocal = isLocal;
|
1287
1327
|
this.modelLoadedCallback = modelLoadedCallback;
|
@@ -1289,20 +1329,25 @@ var Character = class {
|
|
1289
1329
|
this.keyInputManager = keyInputManager;
|
1290
1330
|
this.cameraManager = cameraManager;
|
1291
1331
|
this.timeManager = timeManager;
|
1332
|
+
this.composer = composer;
|
1292
1333
|
this.controller = null;
|
1293
1334
|
this.name = null;
|
1294
1335
|
this.model = null;
|
1295
1336
|
this.color = new Color3();
|
1296
|
-
this.position = new
|
1337
|
+
this.position = new Vector35();
|
1297
1338
|
this.tooltip = null;
|
1339
|
+
this.speakingIndicator = null;
|
1298
1340
|
this.load();
|
1299
1341
|
}
|
1300
1342
|
async load() {
|
1301
|
-
this.model = new CharacterModel(this.characterDescription);
|
1343
|
+
this.model = new CharacterModel(this.characterDescription, this.characterModelLoader);
|
1302
1344
|
await this.model.init();
|
1303
1345
|
if (this.tooltip === null) {
|
1304
1346
|
this.tooltip = new CharacterTooltip(this.model.mesh);
|
1305
1347
|
}
|
1348
|
+
if (this.speakingIndicator === null) {
|
1349
|
+
this.speakingIndicator = new CharacterSpeakingIndicator(this.composer.postPostScene);
|
1350
|
+
}
|
1306
1351
|
this.color = this.model.material.colorsCube216[this.id];
|
1307
1352
|
if (this.isLocal) {
|
1308
1353
|
this.controller = new LocalController(
|
@@ -1317,11 +1362,21 @@ var Character = class {
|
|
1317
1362
|
this.modelLoadedCallback();
|
1318
1363
|
}
|
1319
1364
|
update(time) {
|
1365
|
+
var _a;
|
1320
1366
|
if (!this.model)
|
1321
1367
|
return;
|
1322
1368
|
if (this.tooltip) {
|
1323
1369
|
this.tooltip.update(this.cameraManager.camera);
|
1324
1370
|
}
|
1371
|
+
if (this.speakingIndicator) {
|
1372
|
+
this.speakingIndicator.setTime(time);
|
1373
|
+
if (this.model.mesh && this.model.headBone) {
|
1374
|
+
this.speakingIndicator.setBillboarding(
|
1375
|
+
(_a = this.model.headBone) == null ? void 0 : _a.getWorldPosition(new Vector35()),
|
1376
|
+
this.cameraManager.camera
|
1377
|
+
);
|
1378
|
+
}
|
1379
|
+
}
|
1325
1380
|
this.model.mesh.getWorldPosition(this.position);
|
1326
1381
|
if (typeof this.model.material.uniforms.time !== "undefined") {
|
1327
1382
|
this.model.material.uniforms.time.value = time;
|
@@ -1332,20 +1387,20 @@ var Character = class {
|
|
1332
1387
|
};
|
1333
1388
|
|
1334
1389
|
// src/character/CharacterManager.ts
|
1335
|
-
import { Group, Vector3 as
|
1390
|
+
import { Euler, Group, Quaternion as Quaternion4, Vector3 as Vector37 } from "three";
|
1336
1391
|
|
1337
1392
|
// src/character/RemoteController.ts
|
1338
1393
|
import {
|
1339
1394
|
AnimationMixer as AnimationMixer2,
|
1340
1395
|
Object3D as Object3D4,
|
1341
|
-
Quaternion as
|
1342
|
-
Vector3 as
|
1396
|
+
Quaternion as Quaternion3,
|
1397
|
+
Vector3 as Vector36
|
1343
1398
|
} from "three";
|
1344
1399
|
var RemoteController = class {
|
1345
|
-
constructor(character, id) {
|
1400
|
+
constructor(character, characterModelLoader, id) {
|
1346
1401
|
this.character = character;
|
1402
|
+
this.characterModelLoader = characterModelLoader;
|
1347
1403
|
this.id = id;
|
1348
|
-
this.modelLoader = ModelLoader_default;
|
1349
1404
|
this.characterModel = null;
|
1350
1405
|
this.animationMixer = new AnimationMixer2(new Object3D4());
|
1351
1406
|
this.animations = /* @__PURE__ */ new Map();
|
@@ -1368,7 +1423,7 @@ var RemoteController = class {
|
|
1368
1423
|
this.animationMixer.update(deltaTime);
|
1369
1424
|
}
|
1370
1425
|
async setAnimationFromFile(animationType, fileName) {
|
1371
|
-
const animation = await this.
|
1426
|
+
const animation = await this.characterModelLoader.load(fileName, "animation");
|
1372
1427
|
const animationAction = this.animationMixer.clipAction(animation);
|
1373
1428
|
this.animations.set(animationType, animationAction);
|
1374
1429
|
if (animationType === 0 /* idle */) {
|
@@ -1395,8 +1450,8 @@ var RemoteController = class {
|
|
1395
1450
|
if (!this.characterModel)
|
1396
1451
|
return;
|
1397
1452
|
const { position, rotation, state } = clientUpdate;
|
1398
|
-
this.characterModel.position.lerp(new
|
1399
|
-
const rotationQuaternion = new
|
1453
|
+
this.characterModel.position.lerp(new Vector36(position.x, position.y, position.z), 0.15);
|
1454
|
+
const rotationQuaternion = new Quaternion3(0, rotation.quaternionY, 0, rotation.quaternionW);
|
1400
1455
|
this.characterModel.quaternion.slerp(rotationQuaternion, 0.6);
|
1401
1456
|
if (state !== this.currentAnimation) {
|
1402
1457
|
this.transitionToAnimation(state);
|
@@ -1407,10 +1462,10 @@ var RemoteController = class {
|
|
1407
1462
|
// src/character/CharacterManager.ts
|
1408
1463
|
function encodeCharacterAndCamera(character, camera) {
|
1409
1464
|
return [
|
1410
|
-
...character.position
|
1411
|
-
...character.quaternion
|
1412
|
-
...camera.position
|
1413
|
-
...camera.quaternion
|
1465
|
+
...toArray(character.position),
|
1466
|
+
...toArray(character.quaternion),
|
1467
|
+
...toArray(camera.position),
|
1468
|
+
...toArray(camera.quaternion)
|
1414
1469
|
].join(",");
|
1415
1470
|
}
|
1416
1471
|
function decodeCharacterAndCamera(hash, character, camera) {
|
@@ -1421,7 +1476,9 @@ function decodeCharacterAndCamera(hash, character, camera) {
|
|
1421
1476
|
camera.quaternion.fromArray(values.slice(10, 14));
|
1422
1477
|
}
|
1423
1478
|
var CharacterManager = class {
|
1424
|
-
constructor(collisionsManager, cameraManager, timeManager, inputManager, clientStates, sendUpdate) {
|
1479
|
+
constructor(composer, characterModelLoader, collisionsManager, cameraManager, timeManager, inputManager, clientStates, sendUpdate) {
|
1480
|
+
this.composer = composer;
|
1481
|
+
this.characterModelLoader = characterModelLoader;
|
1425
1482
|
this.collisionsManager = collisionsManager;
|
1426
1483
|
this.cameraManager = cameraManager;
|
1427
1484
|
this.timeManager = timeManager;
|
@@ -1434,6 +1491,7 @@ var CharacterManager = class {
|
|
1434
1491
|
can be trapped).
|
1435
1492
|
*/
|
1436
1493
|
this.updateLocationHash = false;
|
1494
|
+
this.id = 0;
|
1437
1495
|
this.loadingCharacters = /* @__PURE__ */ new Map();
|
1438
1496
|
this.remoteCharacters = /* @__PURE__ */ new Map();
|
1439
1497
|
this.remoteCharacterControllers = /* @__PURE__ */ new Map();
|
@@ -1441,6 +1499,7 @@ var CharacterManager = class {
|
|
1441
1499
|
this.character = null;
|
1442
1500
|
this.cameraOffsetTarget = 0;
|
1443
1501
|
this.cameraOffset = 0;
|
1502
|
+
this.speakingCharacters = /* @__PURE__ */ new Map();
|
1444
1503
|
this.group = new Group();
|
1445
1504
|
}
|
1446
1505
|
/* TODO:
|
@@ -1449,11 +1508,12 @@ var CharacterManager = class {
|
|
1449
1508
|
the mesh loading async (would allow us to show a nameplate where a remote
|
1450
1509
|
user is before the asset loads).
|
1451
1510
|
*/
|
1452
|
-
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new
|
1511
|
+
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector37(), spawnRotation = new Euler()) {
|
1453
1512
|
this.characterDescription = characterDescription;
|
1454
1513
|
const characterLoadingPromise = new Promise((resolve) => {
|
1455
1514
|
const character = new Character(
|
1456
1515
|
characterDescription,
|
1516
|
+
this.characterModelLoader,
|
1457
1517
|
id,
|
1458
1518
|
isLocal,
|
1459
1519
|
() => {
|
@@ -1465,9 +1525,12 @@ var CharacterManager = class {
|
|
1465
1525
|
this.cameraManager.camera
|
1466
1526
|
);
|
1467
1527
|
} else {
|
1468
|
-
spawnPosition = getSpawnPositionInsideCircle(3, 30, id, 0.4);
|
1528
|
+
spawnPosition = spawnPosition || getSpawnPositionInsideCircle(3, 30, id, 0.4);
|
1469
1529
|
character.model.mesh.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1530
|
+
character.model.mesh.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);
|
1531
|
+
character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1470
1532
|
character.model.mesh.updateMatrixWorld();
|
1533
|
+
const quaternion = new Quaternion4().setFromEuler(character.model.mesh.rotation);
|
1471
1534
|
this.sendUpdate({
|
1472
1535
|
id,
|
1473
1536
|
position: {
|
@@ -1475,7 +1538,7 @@ var CharacterManager = class {
|
|
1475
1538
|
y: spawnPosition.y,
|
1476
1539
|
z: spawnPosition.z
|
1477
1540
|
},
|
1478
|
-
rotation: { quaternionY:
|
1541
|
+
rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },
|
1479
1542
|
state: 0 /* idle */
|
1480
1543
|
});
|
1481
1544
|
}
|
@@ -1487,11 +1550,12 @@ var CharacterManager = class {
|
|
1487
1550
|
}
|
1488
1551
|
this.group.add(character.model.mesh);
|
1489
1552
|
if (isLocal) {
|
1553
|
+
this.id = id;
|
1490
1554
|
this.character = character;
|
1491
1555
|
(_e = this.character.tooltip) == null ? void 0 : _e.setText(`${id}`);
|
1492
1556
|
} else {
|
1493
1557
|
this.remoteCharacters.set(id, character);
|
1494
|
-
const remoteController = new RemoteController(character, id);
|
1558
|
+
const remoteController = new RemoteController(character, this.characterModelLoader, id);
|
1495
1559
|
remoteController.setAnimationFromFile(
|
1496
1560
|
0 /* idle */,
|
1497
1561
|
characterDescription.idleAnimationFileUrl
|
@@ -1521,7 +1585,8 @@ var CharacterManager = class {
|
|
1521
1585
|
this.collisionsManager,
|
1522
1586
|
this.inputManager,
|
1523
1587
|
this.cameraManager,
|
1524
|
-
this.timeManager
|
1588
|
+
this.timeManager,
|
1589
|
+
this.composer
|
1525
1590
|
);
|
1526
1591
|
});
|
1527
1592
|
this.loadingCharacters.set(id, characterLoadingPromise);
|
@@ -1551,14 +1616,20 @@ var CharacterManager = class {
|
|
1551
1616
|
}
|
1552
1617
|
this.loadingCharacters.clear();
|
1553
1618
|
}
|
1619
|
+
setSpeakingCharacter(id, value) {
|
1620
|
+
this.speakingCharacters.set(id, value);
|
1621
|
+
}
|
1554
1622
|
update() {
|
1555
|
-
var _a;
|
1623
|
+
var _a, _b, _c, _d;
|
1556
1624
|
if (this.character) {
|
1557
1625
|
this.character.update(this.timeManager.time);
|
1558
|
-
if (
|
1559
|
-
|
1626
|
+
if (this.speakingCharacters.has(this.id)) {
|
1627
|
+
(_a = this.character.speakingIndicator) == null ? void 0 : _a.setSpeaking(this.speakingCharacters.get(this.id));
|
1628
|
+
}
|
1629
|
+
if ((_b = this.character.model) == null ? void 0 : _b.mesh) {
|
1630
|
+
this.cameraOffsetTarget = this.cameraManager.targetDistance <= 0.4 ? 0.13 : 0;
|
1560
1631
|
this.cameraOffset += ease(this.cameraOffsetTarget, this.cameraOffset, 0.1);
|
1561
|
-
const targetOffset = new
|
1632
|
+
const targetOffset = new Vector37(0, 1.3, this.cameraOffset);
|
1562
1633
|
targetOffset.applyQuaternion(this.character.model.mesh.quaternion);
|
1563
1634
|
this.cameraManager.setTarget(this.character.position.add(targetOffset));
|
1564
1635
|
}
|
@@ -1569,13 +1640,17 @@ var CharacterManager = class {
|
|
1569
1640
|
}
|
1570
1641
|
}
|
1571
1642
|
for (const [id, update] of this.clientStates) {
|
1643
|
+
if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {
|
1644
|
+
const character = this.remoteCharacters.get(id);
|
1645
|
+
(_c = character == null ? void 0 : character.speakingIndicator) == null ? void 0 : _c.setSpeaking(this.speakingCharacters.get(id));
|
1646
|
+
}
|
1572
1647
|
const { position } = update;
|
1573
1648
|
if (!this.remoteCharacters.has(id) && !this.loadingCharacters.has(id)) {
|
1574
1649
|
this.spawnCharacter(
|
1575
1650
|
this.characterDescription,
|
1576
1651
|
id,
|
1577
1652
|
false,
|
1578
|
-
new
|
1653
|
+
new Vector37(position.x, position.y, position.z)
|
1579
1654
|
).then((_character) => {
|
1580
1655
|
this.loadingCharacters.delete(id);
|
1581
1656
|
});
|
@@ -1587,6 +1662,7 @@ var CharacterManager = class {
|
|
1587
1662
|
}
|
1588
1663
|
for (const [id, character] of this.remoteCharacters) {
|
1589
1664
|
if (!this.clientStates.has(id)) {
|
1665
|
+
(_d = character.speakingIndicator) == null ? void 0 : _d.dispose();
|
1590
1666
|
this.group.remove(character.model.mesh);
|
1591
1667
|
this.remoteCharacters.delete(id);
|
1592
1668
|
this.remoteCharacterControllers.delete(id);
|
@@ -1602,57 +1678,179 @@ var CharacterManager = class {
|
|
1602
1678
|
}
|
1603
1679
|
};
|
1604
1680
|
|
1605
|
-
// src/
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
}
|
1613
|
-
handleUnfocus(_event) {
|
1614
|
-
this.keys.clear();
|
1615
|
-
}
|
1616
|
-
onKeyDown(event) {
|
1617
|
-
this.keys.set(event.key.toLowerCase(), true);
|
1618
|
-
}
|
1619
|
-
onKeyUp(event) {
|
1620
|
-
this.keys.set(event.key.toLowerCase(), false);
|
1621
|
-
}
|
1622
|
-
isKeyPressed(key) {
|
1623
|
-
return this.keys.get(key) || false;
|
1681
|
+
// src/character/CharacterModelLoader.ts
|
1682
|
+
import { LoadingManager } from "three";
|
1683
|
+
import { GLTFLoader as ThreeGLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
1684
|
+
var CachedGLTFLoader = class extends ThreeGLTFLoader {
|
1685
|
+
constructor(manager) {
|
1686
|
+
super(manager);
|
1687
|
+
this.blobCache = /* @__PURE__ */ new Map();
|
1624
1688
|
}
|
1625
|
-
|
1626
|
-
|
1689
|
+
setBlobUrl(originalUrl, blobUrl) {
|
1690
|
+
this.blobCache.set(originalUrl, blobUrl);
|
1627
1691
|
}
|
1628
|
-
|
1629
|
-
return this.
|
1692
|
+
getBlobUrl(originalUrl) {
|
1693
|
+
return this.blobCache.get(originalUrl);
|
1630
1694
|
}
|
1631
|
-
|
1632
|
-
|
1695
|
+
load(url, onLoad, onProgress, onError) {
|
1696
|
+
const blobUrl = this.getBlobUrl(url);
|
1697
|
+
if (blobUrl) {
|
1698
|
+
console.log(`Loading cached ${url.split("/").pop()}`);
|
1699
|
+
super.load(blobUrl, onLoad, onProgress, onError);
|
1700
|
+
} else {
|
1701
|
+
super.load(url, onLoad, onProgress, onError);
|
1702
|
+
}
|
1633
1703
|
}
|
1634
|
-
|
1635
|
-
|
1704
|
+
};
|
1705
|
+
var LRUCache = class {
|
1706
|
+
constructor(maxSize = 100) {
|
1707
|
+
this.maxSize = maxSize;
|
1708
|
+
this.cache = /* @__PURE__ */ new Map();
|
1636
1709
|
}
|
1637
|
-
get
|
1638
|
-
|
1710
|
+
get(key) {
|
1711
|
+
const item = this.cache.get(key);
|
1712
|
+
if (item) {
|
1713
|
+
this.cache.delete(key);
|
1714
|
+
this.cache.set(key, item);
|
1715
|
+
}
|
1716
|
+
return item;
|
1639
1717
|
}
|
1640
|
-
|
1641
|
-
|
1718
|
+
set(key, value) {
|
1719
|
+
if (this.cache.size >= this.maxSize) {
|
1720
|
+
const oldestKey = this.cache.keys().next().value;
|
1721
|
+
this.cache.delete(oldestKey);
|
1722
|
+
}
|
1723
|
+
this.cache.set(key, value);
|
1642
1724
|
}
|
1643
|
-
|
1644
|
-
|
1725
|
+
};
|
1726
|
+
var _CharacterModelLoader = class _CharacterModelLoader {
|
1727
|
+
constructor(maxCacheSize = 100) {
|
1728
|
+
this.ongoingLoads = /* @__PURE__ */ new Map();
|
1729
|
+
this.loadingManager = new LoadingManager();
|
1730
|
+
this.gltfLoader = new CachedGLTFLoader(this.loadingManager);
|
1731
|
+
this.modelCache = new LRUCache(maxCacheSize);
|
1645
1732
|
}
|
1646
|
-
|
1647
|
-
|
1733
|
+
/* TODO: decide between below lazy initialization or eager on this file's bottom export */
|
1734
|
+
static getInstance() {
|
1735
|
+
if (!_CharacterModelLoader.instance) {
|
1736
|
+
_CharacterModelLoader.instance = new _CharacterModelLoader();
|
1737
|
+
}
|
1738
|
+
return _CharacterModelLoader.instance;
|
1648
1739
|
}
|
1649
|
-
|
1650
|
-
|
1740
|
+
async load(fileUrl, fileType) {
|
1741
|
+
const cachedModel = this.modelCache.get(fileUrl);
|
1742
|
+
if (cachedModel) {
|
1743
|
+
const blobURL = URL.createObjectURL(cachedModel.blob);
|
1744
|
+
this.gltfLoader.setBlobUrl(fileUrl, blobURL);
|
1745
|
+
return this.loadFromUrl(fileUrl, fileType, cachedModel.originalExtension);
|
1746
|
+
} else {
|
1747
|
+
console.log(`Loading ${fileUrl} from server`);
|
1748
|
+
const ongoingLoad = this.ongoingLoads.get(fileUrl);
|
1749
|
+
if (ongoingLoad)
|
1750
|
+
return ongoingLoad;
|
1751
|
+
const loadPromise = fetch(fileUrl).then((response) => response.blob()).then((blob) => {
|
1752
|
+
const originalExtension = fileUrl.split(".").pop() || "";
|
1753
|
+
this.modelCache.set(fileUrl, { blob, originalExtension });
|
1754
|
+
const blobURL = URL.createObjectURL(blob);
|
1755
|
+
this.ongoingLoads.delete(fileUrl);
|
1756
|
+
return this.loadFromUrl(blobURL, fileType, originalExtension);
|
1757
|
+
});
|
1758
|
+
this.ongoingLoads.set(fileUrl, loadPromise);
|
1759
|
+
return loadPromise;
|
1760
|
+
}
|
1761
|
+
}
|
1762
|
+
async loadFromUrl(url, fileType, extension) {
|
1763
|
+
if (["gltf", "glb"].includes(extension)) {
|
1764
|
+
return new Promise((resolve, reject) => {
|
1765
|
+
this.gltfLoader.load(
|
1766
|
+
url,
|
1767
|
+
(object) => {
|
1768
|
+
if (fileType === "model") {
|
1769
|
+
resolve(object.scene);
|
1770
|
+
} else if (fileType === "animation") {
|
1771
|
+
resolve(object.animations[0]);
|
1772
|
+
} else {
|
1773
|
+
const error = `Trying to load unknown ${fileType} type of element from file ${url}`;
|
1774
|
+
console.error(error);
|
1775
|
+
reject(error);
|
1776
|
+
}
|
1777
|
+
},
|
1778
|
+
void 0,
|
1779
|
+
(error) => {
|
1780
|
+
console.error(`Error loading GL(B|TF) from ${url}: ${error}`);
|
1781
|
+
reject(error);
|
1782
|
+
}
|
1783
|
+
);
|
1784
|
+
});
|
1785
|
+
} else {
|
1786
|
+
console.error(`Error: can't recognize ${url} extension: ${extension}`);
|
1787
|
+
}
|
1788
|
+
}
|
1789
|
+
};
|
1790
|
+
_CharacterModelLoader.instance = null;
|
1791
|
+
var CharacterModelLoader = _CharacterModelLoader;
|
1792
|
+
var MODEL_LOADER = CharacterModelLoader.getInstance();
|
1793
|
+
|
1794
|
+
// src/input/KeyInputManager.ts
|
1795
|
+
var KeyInputManager = class {
|
1796
|
+
constructor(shouldCaptureKeyPress = () => true) {
|
1797
|
+
this.shouldCaptureKeyPress = shouldCaptureKeyPress;
|
1798
|
+
this.keys = /* @__PURE__ */ new Map();
|
1799
|
+
this.eventHandlerCollection = new EventHandlerCollection();
|
1800
|
+
this.eventHandlerCollection.add(document, "keydown", this.onKeyDown.bind(this));
|
1801
|
+
this.eventHandlerCollection.add(document, "keyup", this.onKeyUp.bind(this));
|
1802
|
+
this.eventHandlerCollection.add(window, "blur", this.handleUnfocus.bind(this));
|
1803
|
+
}
|
1804
|
+
handleUnfocus(_event) {
|
1805
|
+
this.keys.clear();
|
1806
|
+
}
|
1807
|
+
onKeyDown(event) {
|
1808
|
+
if (this.shouldCaptureKeyPress()) {
|
1809
|
+
if (event.key.length === 2 && event.key[0] === "F") {
|
1810
|
+
return;
|
1811
|
+
}
|
1812
|
+
if (event.metaKey) {
|
1813
|
+
return;
|
1814
|
+
}
|
1815
|
+
this.keys.set(event.key.toLowerCase(), true);
|
1816
|
+
event.preventDefault();
|
1817
|
+
}
|
1818
|
+
}
|
1819
|
+
onKeyUp(event) {
|
1820
|
+
this.keys.set(event.key.toLowerCase(), false);
|
1821
|
+
}
|
1822
|
+
isKeyPressed(key) {
|
1823
|
+
return this.keys.get(key) || false;
|
1824
|
+
}
|
1825
|
+
isMovementKeyPressed() {
|
1826
|
+
return ["w" /* W */, "a" /* A */, "s" /* S */, "d" /* D */].some((key) => this.isKeyPressed(key));
|
1827
|
+
}
|
1828
|
+
get forward() {
|
1829
|
+
return this.isKeyPressed("w" /* W */);
|
1830
|
+
}
|
1831
|
+
get backward() {
|
1832
|
+
return this.isKeyPressed("s" /* S */);
|
1833
|
+
}
|
1834
|
+
get left() {
|
1835
|
+
return this.isKeyPressed("a" /* A */);
|
1836
|
+
}
|
1837
|
+
get right() {
|
1838
|
+
return this.isKeyPressed("d" /* D */);
|
1839
|
+
}
|
1840
|
+
get run() {
|
1841
|
+
return this.isKeyPressed("shift" /* SHIFT */);
|
1842
|
+
}
|
1843
|
+
get jump() {
|
1844
|
+
return this.isKeyPressed(" " /* SPACE */);
|
1845
|
+
}
|
1846
|
+
get anyDirection() {
|
1847
|
+
return this.isMovementKeyPressed();
|
1848
|
+
}
|
1849
|
+
get conflictingDirection() {
|
1850
|
+
return this.isKeyPressed("w" /* W */) && this.isKeyPressed("s" /* S */) || this.isKeyPressed("a" /* A */) && this.isKeyPressed("d" /* D */);
|
1651
1851
|
}
|
1652
1852
|
dispose() {
|
1653
|
-
|
1654
|
-
document.removeEventListener("keyup", this.onKeyDown.bind(this));
|
1655
|
-
window.removeEventListener("blur", this.handleUnfocus.bind(this));
|
1853
|
+
this.eventHandlerCollection.clear();
|
1656
1854
|
}
|
1657
1855
|
};
|
1658
1856
|
|
@@ -1660,23 +1858,25 @@ var KeyInputManager = class {
|
|
1660
1858
|
import {
|
1661
1859
|
InteractionManager,
|
1662
1860
|
MMLClickTrigger,
|
1663
|
-
PromptManager
|
1664
|
-
registerCustomElementsToWindow,
|
1665
|
-
setGlobalMScene
|
1861
|
+
PromptManager
|
1666
1862
|
} from "mml-web";
|
1667
1863
|
import { Group as Group2 } from "three";
|
1668
1864
|
var MMLCompositionScene = class {
|
1669
|
-
constructor(renderer, scene, camera, audioListener, collisionsManager, getUserPositionAndRotation
|
1865
|
+
constructor(targetElement, renderer, scene, camera, audioListener, collisionsManager, getUserPositionAndRotation) {
|
1670
1866
|
this.renderer = renderer;
|
1671
1867
|
this.scene = scene;
|
1672
1868
|
this.camera = camera;
|
1673
1869
|
this.audioListener = audioListener;
|
1674
1870
|
this.collisionsManager = collisionsManager;
|
1675
1871
|
this.getUserPositionAndRotation = getUserPositionAndRotation;
|
1676
|
-
this.debug = false;
|
1677
1872
|
this.group = new Group2();
|
1678
|
-
this.promptManager = PromptManager.init(
|
1679
|
-
const { interactionListener } = InteractionManager.init(
|
1873
|
+
this.promptManager = PromptManager.init(targetElement);
|
1874
|
+
const { interactionListener, interactionManager } = InteractionManager.init(
|
1875
|
+
targetElement,
|
1876
|
+
this.camera,
|
1877
|
+
this.scene
|
1878
|
+
);
|
1879
|
+
this.interactionManager = interactionManager;
|
1680
1880
|
this.interactionListener = interactionListener;
|
1681
1881
|
this.mmlScene = {
|
1682
1882
|
getAudioListener: () => this.audioListener,
|
@@ -1707,54 +1907,65 @@ var MMLCompositionScene = class {
|
|
1707
1907
|
this.promptManager.prompt(promptProps, callback);
|
1708
1908
|
}
|
1709
1909
|
};
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
for (const address of documentAddresses) {
|
1717
|
-
const frameElement = document.createElement("m-frame");
|
1718
|
-
frameElement.setAttribute("src", address);
|
1719
|
-
document.body.appendChild(frameElement);
|
1720
|
-
}
|
1910
|
+
this.clickTrigger = MMLClickTrigger.init(targetElement, this.mmlScene);
|
1911
|
+
}
|
1912
|
+
dispose() {
|
1913
|
+
this.promptManager.dispose();
|
1914
|
+
this.clickTrigger.dispose();
|
1915
|
+
this.interactionManager.dispose();
|
1721
1916
|
}
|
1722
1917
|
};
|
1723
1918
|
|
1724
|
-
// src/
|
1725
|
-
import
|
1726
|
-
import {
|
1727
|
-
EffectComposer as EffectComposer2,
|
1728
|
-
RenderPass,
|
1729
|
-
EffectPass as EffectPass2,
|
1730
|
-
FXAAEffect,
|
1731
|
-
ShaderPass,
|
1732
|
-
BloomEffect,
|
1733
|
-
SSAOEffect as SSAOEffect2,
|
1734
|
-
BlendFunction as BlendFunction2,
|
1735
|
-
TextureEffect,
|
1736
|
-
ToneMappingEffect,
|
1737
|
-
SMAAEffect,
|
1738
|
-
SMAAPreset,
|
1739
|
-
EdgeDetectionMode,
|
1740
|
-
PredicationMode,
|
1741
|
-
NormalPass as NormalPass2
|
1742
|
-
} from "postprocessing";
|
1743
|
-
import {
|
1744
|
-
AmbientLight,
|
1745
|
-
Color as Color6,
|
1746
|
-
Fog,
|
1747
|
-
HalfFloatType,
|
1748
|
-
LinearSRGBColorSpace,
|
1749
|
-
LoadingManager as LoadingManager2,
|
1750
|
-
PMREMGenerator,
|
1751
|
-
Vector2 as Vector22,
|
1752
|
-
WebGLRenderer as WebGLRenderer2
|
1753
|
-
} from "three";
|
1754
|
-
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
|
1919
|
+
// src/tweakpane/TweakPane.ts
|
1920
|
+
import * as EssentialsPlugin from "@tweakpane/plugin-essentials";
|
1921
|
+
import { Pane } from "tweakpane";
|
1755
1922
|
|
1756
|
-
// src/
|
1757
|
-
|
1923
|
+
// src/tweakpane/blades/bcsFolder.ts
|
1924
|
+
var bcsValues = {
|
1925
|
+
brightness: 0,
|
1926
|
+
contrast: 1.25,
|
1927
|
+
saturation: 1
|
1928
|
+
};
|
1929
|
+
var bcsOptions = {
|
1930
|
+
brightness: {
|
1931
|
+
amount: { min: -1, max: 1, step: 0.01 }
|
1932
|
+
},
|
1933
|
+
contrast: {
|
1934
|
+
amount: { min: 0, max: 2, step: 0.01 }
|
1935
|
+
},
|
1936
|
+
saturation: {
|
1937
|
+
amount: { min: 0, max: 2, step: 0.01 }
|
1938
|
+
}
|
1939
|
+
};
|
1940
|
+
var BrightnessContrastSaturationFolder = class {
|
1941
|
+
constructor(parentFolder, expand = false) {
|
1942
|
+
this.folder = parentFolder.addFolder({
|
1943
|
+
title: "brightness / contrast / sat",
|
1944
|
+
expanded: expand
|
1945
|
+
});
|
1946
|
+
this.folder.addBinding(bcsValues, "brightness", bcsOptions.brightness.amount);
|
1947
|
+
this.folder.addBinding(bcsValues, "contrast", bcsOptions.contrast.amount);
|
1948
|
+
this.folder.addBinding(bcsValues, "saturation", bcsOptions.saturation.amount);
|
1949
|
+
}
|
1950
|
+
setupChangeEvent(brightnessContrastSaturation) {
|
1951
|
+
this.folder.on("change", (e) => {
|
1952
|
+
const target = e.target.key;
|
1953
|
+
if (!target)
|
1954
|
+
return;
|
1955
|
+
switch (target) {
|
1956
|
+
case "brightness":
|
1957
|
+
brightnessContrastSaturation.uniforms.brightness.value = e.value;
|
1958
|
+
break;
|
1959
|
+
case "contrast":
|
1960
|
+
brightnessContrastSaturation.uniforms.contrast.value = e.value;
|
1961
|
+
break;
|
1962
|
+
case "saturation":
|
1963
|
+
brightnessContrastSaturation.uniforms.saturation.value = e.value;
|
1964
|
+
break;
|
1965
|
+
}
|
1966
|
+
});
|
1967
|
+
}
|
1968
|
+
};
|
1758
1969
|
|
1759
1970
|
// src/tweakpane/blades/environmentFolder.ts
|
1760
1971
|
var sunValues = {
|
@@ -1911,135 +2122,6 @@ var EnvironmentFolder = class {
|
|
1911
2122
|
}
|
1912
2123
|
};
|
1913
2124
|
|
1914
|
-
// src/sun/Sun.ts
|
1915
|
-
var Sun = class extends Group3 {
|
1916
|
-
constructor() {
|
1917
|
-
super();
|
1918
|
-
this.debug = false;
|
1919
|
-
this.sunOffset = new Vector37(
|
1920
|
-
39 * (Math.PI / 180),
|
1921
|
-
50 * (Math.PI / 180),
|
1922
|
-
100
|
1923
|
-
);
|
1924
|
-
this.shadowResolution = 8192;
|
1925
|
-
this.shadowCamFrustum = 50;
|
1926
|
-
this.camHelper = null;
|
1927
|
-
this.target = null;
|
1928
|
-
this.shadowCamera = new OrthographicCamera(
|
1929
|
-
-this.shadowCamFrustum,
|
1930
|
-
this.shadowCamFrustum,
|
1931
|
-
this.shadowCamFrustum,
|
1932
|
-
-this.shadowCamFrustum,
|
1933
|
-
0.1,
|
1934
|
-
200
|
1935
|
-
);
|
1936
|
-
if (this.debug === true) {
|
1937
|
-
this.camHelper = new CameraHelper(this.shadowCamera);
|
1938
|
-
}
|
1939
|
-
this.directionalLight = new DirectionalLight(16777215, 0.5);
|
1940
|
-
this.directionalLight.shadow.normalBias = 0.05;
|
1941
|
-
this.directionalLight.shadow.radius = 1.5;
|
1942
|
-
this.directionalLight.shadow.camera = this.shadowCamera;
|
1943
|
-
this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);
|
1944
|
-
this.directionalLight.castShadow = true;
|
1945
|
-
this.setColor();
|
1946
|
-
this.updateCharacterPosition(new Vector37(0, 0, 0));
|
1947
|
-
this.add(this.directionalLight);
|
1948
|
-
if (this.debug === true && this.camHelper instanceof CameraHelper) {
|
1949
|
-
this.add(this.camHelper);
|
1950
|
-
}
|
1951
|
-
}
|
1952
|
-
updateCharacterPosition(position) {
|
1953
|
-
if (!position)
|
1954
|
-
return;
|
1955
|
-
this.target = position;
|
1956
|
-
this.setSunPosition(this.sunOffset.x, this.sunOffset.y);
|
1957
|
-
}
|
1958
|
-
setAzimuthalAngle(angle) {
|
1959
|
-
if (this.sunOffset)
|
1960
|
-
this.sunOffset.x = angle;
|
1961
|
-
if (this.target)
|
1962
|
-
this.updateCharacterPosition(this.target);
|
1963
|
-
}
|
1964
|
-
setPolarAngle(angle) {
|
1965
|
-
if (this.sunOffset)
|
1966
|
-
this.sunOffset.y = angle;
|
1967
|
-
if (this.target)
|
1968
|
-
this.updateCharacterPosition(this.target);
|
1969
|
-
}
|
1970
|
-
setIntensity(intensity) {
|
1971
|
-
this.directionalLight.intensity = intensity;
|
1972
|
-
}
|
1973
|
-
setColor() {
|
1974
|
-
this.directionalLight.color = new Color4().setRGB(
|
1975
|
-
sunValues.sunColor.r,
|
1976
|
-
sunValues.sunColor.g,
|
1977
|
-
sunValues.sunColor.b
|
1978
|
-
);
|
1979
|
-
}
|
1980
|
-
setSunPosition(azimuthalAngle, polarAngle) {
|
1981
|
-
if (!this.target)
|
1982
|
-
return;
|
1983
|
-
const distance = this.sunOffset.z;
|
1984
|
-
const sphericalPosition = new Vector37(
|
1985
|
-
distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),
|
1986
|
-
distance * Math.cos(polarAngle),
|
1987
|
-
distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle)
|
1988
|
-
);
|
1989
|
-
const newSunPosition = this.target.clone().add(sphericalPosition);
|
1990
|
-
this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);
|
1991
|
-
this.directionalLight.target.position.copy(this.target.clone());
|
1992
|
-
this.directionalLight.target.updateMatrixWorld();
|
1993
|
-
}
|
1994
|
-
};
|
1995
|
-
|
1996
|
-
// src/tweakpane/blades/bcsFolder.ts
|
1997
|
-
var bcsValues = {
|
1998
|
-
brightness: 0,
|
1999
|
-
contrast: 1.25,
|
2000
|
-
saturation: 1
|
2001
|
-
};
|
2002
|
-
var bcsOptions = {
|
2003
|
-
brightness: {
|
2004
|
-
amount: { min: -1, max: 1, step: 0.01 }
|
2005
|
-
},
|
2006
|
-
contrast: {
|
2007
|
-
amount: { min: 0, max: 2, step: 0.01 }
|
2008
|
-
},
|
2009
|
-
saturation: {
|
2010
|
-
amount: { min: 0, max: 2, step: 0.01 }
|
2011
|
-
}
|
2012
|
-
};
|
2013
|
-
var BrightnessContrastSaturationFolder = class {
|
2014
|
-
constructor(parentFolder, expand = false) {
|
2015
|
-
this.folder = parentFolder.addFolder({
|
2016
|
-
title: "brightness / contrast / sat",
|
2017
|
-
expanded: expand
|
2018
|
-
});
|
2019
|
-
this.folder.addBinding(bcsValues, "brightness", bcsOptions.brightness.amount);
|
2020
|
-
this.folder.addBinding(bcsValues, "contrast", bcsOptions.contrast.amount);
|
2021
|
-
this.folder.addBinding(bcsValues, "saturation", bcsOptions.saturation.amount);
|
2022
|
-
}
|
2023
|
-
setupChangeEvent(brightnessContrastSaturation) {
|
2024
|
-
this.folder.on("change", (e) => {
|
2025
|
-
const target = e.target.key;
|
2026
|
-
if (!target)
|
2027
|
-
return;
|
2028
|
-
switch (target) {
|
2029
|
-
case "brightness":
|
2030
|
-
brightnessContrastSaturation.uniforms.brightness.value = e.value;
|
2031
|
-
break;
|
2032
|
-
case "contrast":
|
2033
|
-
brightnessContrastSaturation.uniforms.contrast.value = e.value;
|
2034
|
-
break;
|
2035
|
-
case "saturation":
|
2036
|
-
brightnessContrastSaturation.uniforms.saturation.value = e.value;
|
2037
|
-
break;
|
2038
|
-
}
|
2039
|
-
});
|
2040
|
-
}
|
2041
|
-
};
|
2042
|
-
|
2043
2125
|
// src/tweakpane/blades/postExtrasFolder.ts
|
2044
2126
|
var extrasValues = {
|
2045
2127
|
grain: 0.055,
|
@@ -2164,9 +2246,52 @@ var RendererFolder = class {
|
|
2164
2246
|
}
|
2165
2247
|
};
|
2166
2248
|
|
2249
|
+
// src/tweakpane/blades/rendererStatsFolder.ts
|
2250
|
+
var RendererStatsFolder = class {
|
2251
|
+
constructor(parentFolder, expanded = true) {
|
2252
|
+
this.statsData = {
|
2253
|
+
triangles: "0",
|
2254
|
+
geometries: "0",
|
2255
|
+
textures: "0",
|
2256
|
+
shaders: "0",
|
2257
|
+
postPasses: "0",
|
2258
|
+
drawCalls: "0",
|
2259
|
+
rawDeltaTime: "0",
|
2260
|
+
deltaTime: "0",
|
2261
|
+
FPS: "0"
|
2262
|
+
};
|
2263
|
+
this.folder = parentFolder.addFolder({ title: "renderStats", expanded });
|
2264
|
+
this.performance = this.folder.addFolder({ title: "performance", expanded: true });
|
2265
|
+
this.defails = this.folder.addFolder({ title: "pipeline details", expanded: false });
|
2266
|
+
this.folder.addBlade({ view: "separator" });
|
2267
|
+
this.performance.addBinding(this.statsData, "FPS", { readonly: true });
|
2268
|
+
this.performance.addBinding(this.statsData, "deltaTime", { readonly: true });
|
2269
|
+
this.performance.addBinding(this.statsData, "rawDeltaTime", { readonly: true });
|
2270
|
+
this.defails.addBinding(this.statsData, "triangles", { readonly: true });
|
2271
|
+
this.defails.addBinding(this.statsData, "geometries", { readonly: true });
|
2272
|
+
this.defails.addBinding(this.statsData, "textures", { readonly: true });
|
2273
|
+
this.defails.addBinding(this.statsData, "shaders", { readonly: true });
|
2274
|
+
this.defails.addBinding(this.statsData, "postPasses", { readonly: true });
|
2275
|
+
this.defails.addBinding(this.statsData, "drawCalls", { readonly: true });
|
2276
|
+
}
|
2277
|
+
update(renderer, composer, timeManager) {
|
2278
|
+
const { geometries, textures } = renderer.info.memory;
|
2279
|
+
const { triangles, calls } = renderer.info.render;
|
2280
|
+
this.statsData.triangles = triangles.toString();
|
2281
|
+
this.statsData.geometries = geometries.toString();
|
2282
|
+
this.statsData.textures = textures.toString();
|
2283
|
+
this.statsData.shaders = renderer.info.programs.length.toString();
|
2284
|
+
this.statsData.postPasses = composer.passes.length.toString();
|
2285
|
+
this.statsData.drawCalls = calls.toString();
|
2286
|
+
this.statsData.rawDeltaTime = (Math.round(timeManager.rawDeltaTime * 1e5) / 1e5).toString();
|
2287
|
+
this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 1e5) / 1e5).toString();
|
2288
|
+
this.statsData.FPS = timeManager.fps.toString();
|
2289
|
+
}
|
2290
|
+
};
|
2291
|
+
|
2167
2292
|
// src/tweakpane/blades/ssaoFolder.ts
|
2168
2293
|
import { BlendFunction } from "postprocessing";
|
2169
|
-
import { Color as
|
2294
|
+
import { Color as Color4 } from "three";
|
2170
2295
|
var ppssaoValues = {
|
2171
2296
|
enabled: false,
|
2172
2297
|
blendFunction: BlendFunction.MULTIPLY,
|
@@ -2358,7 +2483,7 @@ var SSAOFolder = class {
|
|
2358
2483
|
}
|
2359
2484
|
case "color": {
|
2360
2485
|
const value = e.value;
|
2361
|
-
ppssaoEffect.color = new
|
2486
|
+
ppssaoEffect.color = new Color4().setRGB(value.r, value.g, value.b);
|
2362
2487
|
break;
|
2363
2488
|
}
|
2364
2489
|
default: {
|
@@ -2398,7 +2523,7 @@ var SSAOFolder = class {
|
|
2398
2523
|
break;
|
2399
2524
|
case "color":
|
2400
2525
|
const value = e.value;
|
2401
|
-
n8aopass.configuration.color = new
|
2526
|
+
n8aopass.configuration.color = new Color4().setRGB(value.r, value.g, value.b);
|
2402
2527
|
break;
|
2403
2528
|
default:
|
2404
2529
|
break;
|
@@ -2491,53 +2616,6 @@ var ToneMappingFolder = class {
|
|
2491
2616
|
}
|
2492
2617
|
};
|
2493
2618
|
|
2494
|
-
// src/tweakpane/TweakPane.ts
|
2495
|
-
import * as EssentialsPlugin from "@tweakpane/plugin-essentials";
|
2496
|
-
import { Pane } from "tweakpane";
|
2497
|
-
|
2498
|
-
// src/tweakpane/blades/rendererStatsFolder.ts
|
2499
|
-
var RendererStatsFolder = class {
|
2500
|
-
constructor(parentFolder, expanded = true) {
|
2501
|
-
this.statsData = {
|
2502
|
-
triangles: "0",
|
2503
|
-
geometries: "0",
|
2504
|
-
textures: "0",
|
2505
|
-
shaders: "0",
|
2506
|
-
postPasses: "0",
|
2507
|
-
drawCalls: "0",
|
2508
|
-
rawDeltaTime: "0",
|
2509
|
-
deltaTime: "0",
|
2510
|
-
FPS: "0"
|
2511
|
-
};
|
2512
|
-
this.folder = parentFolder.addFolder({ title: "renderStats", expanded });
|
2513
|
-
this.performance = this.folder.addFolder({ title: "performance", expanded: true });
|
2514
|
-
this.defails = this.folder.addFolder({ title: "pipeline details", expanded: false });
|
2515
|
-
this.folder.addBlade({ view: "separator" });
|
2516
|
-
this.performance.addBinding(this.statsData, "FPS", { readonly: true });
|
2517
|
-
this.performance.addBinding(this.statsData, "deltaTime", { readonly: true });
|
2518
|
-
this.performance.addBinding(this.statsData, "rawDeltaTime", { readonly: true });
|
2519
|
-
this.defails.addBinding(this.statsData, "triangles", { readonly: true });
|
2520
|
-
this.defails.addBinding(this.statsData, "geometries", { readonly: true });
|
2521
|
-
this.defails.addBinding(this.statsData, "textures", { readonly: true });
|
2522
|
-
this.defails.addBinding(this.statsData, "shaders", { readonly: true });
|
2523
|
-
this.defails.addBinding(this.statsData, "postPasses", { readonly: true });
|
2524
|
-
this.defails.addBinding(this.statsData, "drawCalls", { readonly: true });
|
2525
|
-
}
|
2526
|
-
update(renderer, composer, timeManager) {
|
2527
|
-
const { geometries, textures } = renderer.info.memory;
|
2528
|
-
const { triangles, calls } = renderer.info.render;
|
2529
|
-
this.statsData.triangles = triangles.toString();
|
2530
|
-
this.statsData.geometries = geometries.toString();
|
2531
|
-
this.statsData.textures = textures.toString();
|
2532
|
-
this.statsData.shaders = renderer.info.programs.length.toString();
|
2533
|
-
this.statsData.postPasses = composer.passes.length.toString();
|
2534
|
-
this.statsData.drawCalls = calls.toString();
|
2535
|
-
this.statsData.rawDeltaTime = (Math.round(timeManager.rawDeltaTime * 1e5) / 1e5).toString();
|
2536
|
-
this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 1e5) / 1e5).toString();
|
2537
|
-
this.statsData.FPS = timeManager.fps.toString();
|
2538
|
-
}
|
2539
|
-
};
|
2540
|
-
|
2541
2619
|
// src/tweakpane/tweakPaneStyle.ts
|
2542
2620
|
var tweakPaneStyle = `
|
2543
2621
|
:root {
|
@@ -2736,6 +2814,122 @@ var TweakPane = class {
|
|
2736
2814
|
}
|
2737
2815
|
};
|
2738
2816
|
|
2817
|
+
// src/rendering/composer.ts
|
2818
|
+
import { N8AOPostPass } from "n8ao";
|
2819
|
+
import {
|
2820
|
+
EffectComposer as EffectComposer2,
|
2821
|
+
RenderPass,
|
2822
|
+
EffectPass as EffectPass2,
|
2823
|
+
FXAAEffect,
|
2824
|
+
ShaderPass,
|
2825
|
+
BloomEffect,
|
2826
|
+
SSAOEffect as SSAOEffect2,
|
2827
|
+
BlendFunction as BlendFunction2,
|
2828
|
+
TextureEffect,
|
2829
|
+
ToneMappingEffect,
|
2830
|
+
SMAAEffect,
|
2831
|
+
SMAAPreset,
|
2832
|
+
EdgeDetectionMode,
|
2833
|
+
PredicationMode,
|
2834
|
+
NormalPass as NormalPass2
|
2835
|
+
} from "postprocessing";
|
2836
|
+
import {
|
2837
|
+
AmbientLight,
|
2838
|
+
Color as Color6,
|
2839
|
+
Fog,
|
2840
|
+
HalfFloatType,
|
2841
|
+
LinearSRGBColorSpace,
|
2842
|
+
LoadingManager as LoadingManager2,
|
2843
|
+
PMREMGenerator,
|
2844
|
+
Scene as Scene3,
|
2845
|
+
Vector2 as Vector22,
|
2846
|
+
WebGLRenderer as WebGLRenderer2
|
2847
|
+
} from "three";
|
2848
|
+
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
|
2849
|
+
|
2850
|
+
// src/sun/Sun.ts
|
2851
|
+
import { CameraHelper, Color as Color5, DirectionalLight, Group as Group3, OrthographicCamera, Vector3 as Vector38 } from "three";
|
2852
|
+
var Sun = class extends Group3 {
|
2853
|
+
constructor() {
|
2854
|
+
super();
|
2855
|
+
this.debug = false;
|
2856
|
+
this.sunOffset = new Vector38(
|
2857
|
+
39 * (Math.PI / 180),
|
2858
|
+
50 * (Math.PI / 180),
|
2859
|
+
100
|
2860
|
+
);
|
2861
|
+
this.shadowResolution = 8192;
|
2862
|
+
this.shadowCamFrustum = 50;
|
2863
|
+
this.camHelper = null;
|
2864
|
+
this.target = null;
|
2865
|
+
this.shadowCamera = new OrthographicCamera(
|
2866
|
+
-this.shadowCamFrustum,
|
2867
|
+
this.shadowCamFrustum,
|
2868
|
+
this.shadowCamFrustum,
|
2869
|
+
-this.shadowCamFrustum,
|
2870
|
+
0.1,
|
2871
|
+
200
|
2872
|
+
);
|
2873
|
+
if (this.debug === true) {
|
2874
|
+
this.camHelper = new CameraHelper(this.shadowCamera);
|
2875
|
+
}
|
2876
|
+
this.directionalLight = new DirectionalLight(16777215, 0.5);
|
2877
|
+
this.directionalLight.shadow.normalBias = 0.05;
|
2878
|
+
this.directionalLight.shadow.radius = 1.5;
|
2879
|
+
this.directionalLight.shadow.camera = this.shadowCamera;
|
2880
|
+
this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);
|
2881
|
+
this.directionalLight.castShadow = true;
|
2882
|
+
this.setColor();
|
2883
|
+
this.updateCharacterPosition(new Vector38(0, 0, 0));
|
2884
|
+
this.add(this.directionalLight);
|
2885
|
+
if (this.debug === true && this.camHelper instanceof CameraHelper) {
|
2886
|
+
this.add(this.camHelper);
|
2887
|
+
}
|
2888
|
+
}
|
2889
|
+
updateCharacterPosition(position) {
|
2890
|
+
if (!position)
|
2891
|
+
return;
|
2892
|
+
this.target = position;
|
2893
|
+
this.setSunPosition(this.sunOffset.x, this.sunOffset.y);
|
2894
|
+
}
|
2895
|
+
setAzimuthalAngle(angle) {
|
2896
|
+
if (this.sunOffset)
|
2897
|
+
this.sunOffset.x = angle;
|
2898
|
+
if (this.target)
|
2899
|
+
this.updateCharacterPosition(this.target);
|
2900
|
+
}
|
2901
|
+
setPolarAngle(angle) {
|
2902
|
+
if (this.sunOffset)
|
2903
|
+
this.sunOffset.y = angle;
|
2904
|
+
if (this.target)
|
2905
|
+
this.updateCharacterPosition(this.target);
|
2906
|
+
}
|
2907
|
+
setIntensity(intensity) {
|
2908
|
+
this.directionalLight.intensity = intensity;
|
2909
|
+
}
|
2910
|
+
setColor() {
|
2911
|
+
this.directionalLight.color = new Color5().setRGB(
|
2912
|
+
sunValues.sunColor.r,
|
2913
|
+
sunValues.sunColor.g,
|
2914
|
+
sunValues.sunColor.b
|
2915
|
+
);
|
2916
|
+
}
|
2917
|
+
setSunPosition(azimuthalAngle, polarAngle) {
|
2918
|
+
if (!this.target)
|
2919
|
+
return;
|
2920
|
+
const distance = this.sunOffset.z;
|
2921
|
+
const sphericalPosition = new Vector38(
|
2922
|
+
distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),
|
2923
|
+
distance * Math.cos(polarAngle),
|
2924
|
+
distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle)
|
2925
|
+
);
|
2926
|
+
const newSunPosition = this.target.clone().add(sphericalPosition);
|
2927
|
+
this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);
|
2928
|
+
this.directionalLight.target.position.copy(this.target.clone());
|
2929
|
+
this.directionalLight.target.updateMatrixWorld();
|
2930
|
+
}
|
2931
|
+
};
|
2932
|
+
|
2739
2933
|
// src/rendering/post-effects/bright-contrast-sat.ts
|
2740
2934
|
import { ShaderMaterial, Uniform } from "three";
|
2741
2935
|
|
@@ -2883,8 +3077,8 @@ var GaussGrainEffect = new ShaderMaterial2({
|
|
2883
3077
|
// src/rendering/composer.ts
|
2884
3078
|
var Composer = class {
|
2885
3079
|
constructor(scene, camera, spawnSun = false) {
|
2886
|
-
this.width =
|
2887
|
-
this.height =
|
3080
|
+
this.width = 1;
|
3081
|
+
this.height = 1;
|
2888
3082
|
this.resolution = new Vector22(this.width, this.height);
|
2889
3083
|
this.isEnvHDRI = false;
|
2890
3084
|
this.bcs = BrightnessContrastSaturation;
|
@@ -2892,6 +3086,7 @@ var Composer = class {
|
|
2892
3086
|
this.ambientLight = null;
|
2893
3087
|
this.sun = null;
|
2894
3088
|
this.scene = scene;
|
3089
|
+
this.postPostScene = new Scene3();
|
2895
3090
|
this.camera = camera;
|
2896
3091
|
this.spawnSun = spawnSun;
|
2897
3092
|
this.renderer = new WebGLRenderer2({
|
@@ -2908,11 +3103,9 @@ var Composer = class {
|
|
2908
3103
|
this.renderer.toneMappingExposure = rendererValues.exposure;
|
2909
3104
|
this.setAmbientLight();
|
2910
3105
|
this.setFog();
|
2911
|
-
|
2912
|
-
this.composer = new EffectComposer2(this.renderer, {
|
3106
|
+
this.effectComposer = new EffectComposer2(this.renderer, {
|
2913
3107
|
frameBufferType: HalfFloatType
|
2914
3108
|
});
|
2915
|
-
this.tweakPane = new TweakPane(this.renderer, this.scene, this.composer);
|
2916
3109
|
this.renderPass = new RenderPass(this.scene, this.camera);
|
2917
3110
|
this.normalPass = new NormalPass2(this.scene, this.camera);
|
2918
3111
|
this.normalPass.enabled = ppssaoValues.enabled;
|
@@ -2981,26 +3174,33 @@ var Composer = class {
|
|
2981
3174
|
this.bcs.uniforms.saturation.value = bcsValues.saturation;
|
2982
3175
|
this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, "tDiffuse");
|
2983
3176
|
this.smaaPass = new EffectPass2(this.camera, this.smaaEffect);
|
2984
|
-
this.
|
3177
|
+
this.effectComposer.addPass(this.renderPass);
|
2985
3178
|
if (ppssaoValues.enabled) {
|
2986
|
-
this.
|
2987
|
-
this.
|
3179
|
+
this.effectComposer.addPass(this.normalPass);
|
3180
|
+
this.effectComposer.addPass(this.ppssaoPass);
|
2988
3181
|
}
|
2989
3182
|
if (n8ssaoValues.enabled) {
|
2990
|
-
this.
|
2991
|
-
}
|
2992
|
-
this.
|
2993
|
-
this.
|
2994
|
-
this.
|
2995
|
-
this.
|
2996
|
-
this.
|
2997
|
-
this.
|
3183
|
+
this.effectComposer.addPass(this.n8aopass);
|
3184
|
+
}
|
3185
|
+
this.effectComposer.addPass(this.fxaaPass);
|
3186
|
+
this.effectComposer.addPass(this.smaaPass);
|
3187
|
+
this.effectComposer.addPass(this.bloomPass);
|
3188
|
+
this.effectComposer.addPass(this.toneMappingPass);
|
3189
|
+
this.effectComposer.addPass(this.bcsPass);
|
3190
|
+
this.effectComposer.addPass(this.gaussGrainPass);
|
2998
3191
|
if (this.spawnSun === true) {
|
2999
3192
|
this.sun = new Sun();
|
3000
3193
|
this.scene.add(this.sun);
|
3001
3194
|
}
|
3002
|
-
this.
|
3003
|
-
this.
|
3195
|
+
this.resizeListener = () => {
|
3196
|
+
this.fitContainer();
|
3197
|
+
};
|
3198
|
+
window.addEventListener("resize", this.resizeListener, false);
|
3199
|
+
this.fitContainer();
|
3200
|
+
}
|
3201
|
+
setupTweakPane(tweakPane) {
|
3202
|
+
tweakPane.setupRenderPane(
|
3203
|
+
this.effectComposer,
|
3004
3204
|
this.normalPass,
|
3005
3205
|
this.ppssaoEffect,
|
3006
3206
|
this.ppssaoPass,
|
@@ -3016,14 +3216,32 @@ var Composer = class {
|
|
3016
3216
|
this.setAmbientLight.bind(this),
|
3017
3217
|
this.setFog.bind(this)
|
3018
3218
|
);
|
3019
|
-
window.addEventListener("resize", () => this.updateProjection());
|
3020
|
-
this.updateProjection();
|
3021
3219
|
}
|
3022
|
-
|
3023
|
-
|
3024
|
-
|
3025
|
-
|
3026
|
-
|
3220
|
+
dispose() {
|
3221
|
+
window.removeEventListener("resize", this.resizeListener);
|
3222
|
+
}
|
3223
|
+
fitContainer() {
|
3224
|
+
if (!this) {
|
3225
|
+
console.error("Composer not initialized");
|
3226
|
+
return;
|
3227
|
+
}
|
3228
|
+
const parentElement = this.renderer.domElement.parentNode;
|
3229
|
+
if (!parentElement) {
|
3230
|
+
return;
|
3231
|
+
}
|
3232
|
+
this.width = parentElement.clientWidth;
|
3233
|
+
this.height = parentElement.clientHeight;
|
3234
|
+
this.camera.aspect = this.width / this.height;
|
3235
|
+
this.camera.updateProjectionMatrix();
|
3236
|
+
this.renderer.setPixelRatio(window.devicePixelRatio);
|
3237
|
+
this.resolution.set(
|
3238
|
+
this.width * window.devicePixelRatio,
|
3239
|
+
this.height * window.devicePixelRatio
|
3240
|
+
);
|
3241
|
+
this.effectComposer.setSize(
|
3242
|
+
this.width / window.devicePixelRatio,
|
3243
|
+
this.height / window.devicePixelRatio
|
3244
|
+
);
|
3027
3245
|
this.renderPass.setSize(this.width, this.height);
|
3028
3246
|
if (ppssaoValues.enabled) {
|
3029
3247
|
this.normalPass.setSize(this.width, this.height);
|
@@ -3040,19 +3258,14 @@ var Composer = class {
|
|
3040
3258
|
this.gaussGrainPass.setSize(this.width, this.height);
|
3041
3259
|
this.renderer.setSize(this.width, this.height);
|
3042
3260
|
}
|
3043
|
-
isTweakPaneVisible() {
|
3044
|
-
return this.tweakPane.guiVisible;
|
3045
|
-
}
|
3046
3261
|
render(timeManager) {
|
3047
3262
|
this.renderer.info.reset();
|
3048
3263
|
this.normalPass.texture.needsUpdate = true;
|
3049
3264
|
this.gaussGrainEffect.uniforms.resolution.value = this.resolution;
|
3050
3265
|
this.gaussGrainEffect.uniforms.time.value = timeManager.time;
|
3051
3266
|
this.gaussGrainEffect.uniforms.alpha.value = 1;
|
3052
|
-
this.
|
3053
|
-
|
3054
|
-
this.tweakPane.updateStats(timeManager);
|
3055
|
-
}
|
3267
|
+
this.effectComposer.render();
|
3268
|
+
this.renderer.render(this.postPostScene, this.camera);
|
3056
3269
|
}
|
3057
3270
|
useHDRI(url, fromFile = false) {
|
3058
3271
|
if (this.isEnvHDRI && fromFile === false || !this.renderer)
|
@@ -3181,17 +3394,17 @@ import {
|
|
3181
3394
|
MMLCollisionTrigger
|
3182
3395
|
} from "mml-web";
|
3183
3396
|
import {
|
3184
|
-
Box3
|
3397
|
+
Box3,
|
3185
3398
|
Color as Color7,
|
3186
3399
|
DoubleSide,
|
3187
|
-
Euler,
|
3400
|
+
Euler as Euler2,
|
3188
3401
|
Group as Group4,
|
3189
3402
|
Line3 as Line32,
|
3190
3403
|
Matrix4 as Matrix42,
|
3191
|
-
Mesh as
|
3404
|
+
Mesh as Mesh4,
|
3192
3405
|
MeshBasicMaterial as MeshBasicMaterial3,
|
3193
3406
|
Ray,
|
3194
|
-
Vector3 as
|
3407
|
+
Vector3 as Vector39
|
3195
3408
|
} from "three";
|
3196
3409
|
import { VertexNormalsHelper } from "three/examples/jsm/helpers/VertexNormalsHelper.js";
|
3197
3410
|
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
@@ -3199,14 +3412,14 @@ import { MeshBVH, MeshBVHVisualizer } from "three-mesh-bvh";
|
|
3199
3412
|
var CollisionsManager = class {
|
3200
3413
|
constructor(scene) {
|
3201
3414
|
this.debug = false;
|
3202
|
-
this.tempVector = new
|
3203
|
-
this.tempVector2 = new
|
3204
|
-
this.tempVector3 = new
|
3415
|
+
this.tempVector = new Vector39();
|
3416
|
+
this.tempVector2 = new Vector39();
|
3417
|
+
this.tempVector3 = new Vector39();
|
3205
3418
|
this.tempRay = new Ray();
|
3206
3419
|
this.tempMatrix = new Matrix42();
|
3207
3420
|
this.tempMatrix2 = new Matrix42();
|
3208
|
-
this.tempBox = new
|
3209
|
-
this.tempEuler = new
|
3421
|
+
this.tempBox = new Box3();
|
3422
|
+
this.tempEuler = new Euler2();
|
3210
3423
|
this.tempSegment = new Line32();
|
3211
3424
|
this.tempSegment2 = new Line32();
|
3212
3425
|
this.collisionMeshState = /* @__PURE__ */ new Map();
|
@@ -3267,7 +3480,7 @@ var CollisionsManager = class {
|
|
3267
3480
|
};
|
3268
3481
|
if (this.debug) {
|
3269
3482
|
newBufferGeometry.boundsTree = meshBVH;
|
3270
|
-
const wireframeMesh = new
|
3483
|
+
const wireframeMesh = new Mesh4(newBufferGeometry, new MeshBasicMaterial3({ wireframe: true }));
|
3271
3484
|
const normalsHelper = new VertexNormalsHelper(wireframeMesh, 0.25, 65280);
|
3272
3485
|
const visualizer = new MeshBVHVisualizer(wireframeMesh, 4);
|
3273
3486
|
visualizer.edgeMaterial.color = new Color7("blue");
|
@@ -3350,7 +3563,7 @@ var CollisionsManager = class {
|
|
3350
3563
|
const realDistance = intersectionSegment.distance();
|
3351
3564
|
if (realDistance < capsuleRadius) {
|
3352
3565
|
if (!collisionPosition) {
|
3353
|
-
collisionPosition = new
|
3566
|
+
collisionPosition = new Vector39().copy(closestPointOnSegment).applyMatrix4(meshState.matrix);
|
3354
3567
|
}
|
3355
3568
|
const ratio = realDistance / modelReferenceDistance;
|
3356
3569
|
const realDepth = capsuleRadius - realDistance;
|
@@ -3399,11 +3612,13 @@ export {
|
|
3399
3612
|
AnimationState,
|
3400
3613
|
CameraManager,
|
3401
3614
|
CharacterManager,
|
3615
|
+
CharacterModelLoader,
|
3402
3616
|
CollisionsManager,
|
3403
3617
|
Composer,
|
3404
3618
|
KeyInputManager,
|
3405
3619
|
MMLCompositionScene,
|
3406
3620
|
Sun,
|
3407
|
-
TimeManager
|
3621
|
+
TimeManager,
|
3622
|
+
TweakPane
|
3408
3623
|
};
|
3409
3624
|
//# sourceMappingURL=index.js.map
|