@mml-io/3d-web-client-core 0.8.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 +4 -3
- package/build/character/Character.d.ts +3 -1
- package/build/character/CharacterManager.d.ts +5 -3
- package/build/character/CharacterModel.d.ts +3 -2
- package/build/character/{ModelLoader.d.ts → CharacterModelLoader.d.ts} +3 -3
- package/build/character/RemoteController.d.ts +3 -2
- package/build/index.d.ts +2 -0
- package/build/index.js +505 -438
- 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 +7 -4
- package/build/tweakpane/TweakPane.d.ts +1 -1
- package/package.json +3 -3
package/build/index.js
CHANGED
@@ -41,6 +41,47 @@ var remap = (value, minValue, maxValue, minScaledValue, maxScaledValue) => {
|
|
41
41
|
return minScaledValue + (maxScaledValue - minScaledValue) * (value - minValue) / (maxValue - minValue);
|
42
42
|
};
|
43
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
|
+
|
44
85
|
// src/tweakpane/tweakPaneActivity.ts
|
45
86
|
var isTweakpaneActive = false;
|
46
87
|
function setTweakpaneActive(status) {
|
@@ -52,7 +93,7 @@ function getTweakpaneActive() {
|
|
52
93
|
|
53
94
|
// src/camera/CameraManager.ts
|
54
95
|
var CameraManager = class {
|
55
|
-
constructor(collisionsManager) {
|
96
|
+
constructor(targetElement, collisionsManager, initialPhi = Math.PI / 2, initialTheta = -Math.PI / 2) {
|
56
97
|
this.collisionsManager = collisionsManager;
|
57
98
|
this.initialDistance = 3.3;
|
58
99
|
this.minDistance = 0.1;
|
@@ -68,42 +109,38 @@ var CameraManager = class {
|
|
68
109
|
this.targetDistance = this.initialDistance;
|
69
110
|
this.distance = this.initialDistance;
|
70
111
|
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
112
|
this.dragging = false;
|
76
113
|
this.target = new Vector32(0, 1.55, 0);
|
77
114
|
this.hadTarget = false;
|
115
|
+
this.phi = initialPhi;
|
116
|
+
this.targetPhi = initialPhi;
|
117
|
+
this.theta = initialTheta;
|
118
|
+
this.targetTheta = initialTheta;
|
78
119
|
this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);
|
79
120
|
this.camera.position.set(0, 1.4, -this.initialDistance);
|
80
121
|
this.rayCaster = new Raycaster();
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
const height = window.innerHeight;
|
90
|
-
this.camera.aspect = width / height;
|
91
|
-
this.camera.updateProjectionMatrix();
|
92
|
-
}
|
93
|
-
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() {
|
94
130
|
this.dragging = true;
|
95
131
|
}
|
96
132
|
onMouseUp(_event) {
|
97
133
|
this.dragging = false;
|
98
134
|
}
|
99
135
|
onMouseMove(event) {
|
100
|
-
if (!this.dragging || getTweakpaneActive()
|
136
|
+
if (!this.dragging || getTweakpaneActive())
|
101
137
|
return;
|
102
138
|
if (this.targetTheta === null || this.targetPhi === null)
|
103
139
|
return;
|
104
140
|
this.targetTheta += event.movementX * 0.01;
|
105
141
|
this.targetPhi -= event.movementY * 0.01;
|
106
142
|
this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));
|
143
|
+
event.preventDefault();
|
107
144
|
}
|
108
145
|
onMouseWheel(event) {
|
109
146
|
const scrollAmount = event.deltaY * 1e-3;
|
@@ -113,6 +150,7 @@ var CameraManager = class {
|
|
113
150
|
Math.min(this.maxDistance, this.targetDistance)
|
114
151
|
);
|
115
152
|
this.desiredDistance = this.targetDistance;
|
153
|
+
event.preventDefault();
|
116
154
|
}
|
117
155
|
setTarget(target) {
|
118
156
|
this.target.copy(target);
|
@@ -148,6 +186,9 @@ var CameraManager = class {
|
|
148
186
|
this.targetDistance += (this.desiredDistance - this.targetDistance) * this.dampingFactor * 4;
|
149
187
|
}
|
150
188
|
}
|
189
|
+
dispose() {
|
190
|
+
this.eventHandlerCollection.clear();
|
191
|
+
}
|
151
192
|
update() {
|
152
193
|
if (this.target === null)
|
153
194
|
return;
|
@@ -181,11 +222,11 @@ import { Color as Color3, Vector3 as Vector35 } from "three";
|
|
181
222
|
|
182
223
|
// src/character/CharacterModel.ts
|
183
224
|
import {
|
184
|
-
AnimationClip
|
225
|
+
AnimationClip,
|
185
226
|
AnimationMixer,
|
186
227
|
LoopRepeat,
|
187
228
|
MeshStandardMaterial,
|
188
|
-
Object3D
|
229
|
+
Object3D
|
189
230
|
} from "three";
|
190
231
|
|
191
232
|
// src/character/CharacterMaterial.ts
|
@@ -560,126 +601,11 @@ var AnimationState = /* @__PURE__ */ ((AnimationState2) => {
|
|
560
601
|
return AnimationState2;
|
561
602
|
})(AnimationState || {});
|
562
603
|
|
563
|
-
// src/character/ModelLoader.ts
|
564
|
-
import { LoadingManager } from "three";
|
565
|
-
import { GLTFLoader as ThreeGLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
566
|
-
var CachedGLTFLoader = class extends ThreeGLTFLoader {
|
567
|
-
constructor(manager) {
|
568
|
-
super(manager);
|
569
|
-
this.blobCache = /* @__PURE__ */ new Map();
|
570
|
-
}
|
571
|
-
setBlobUrl(originalUrl, blobUrl) {
|
572
|
-
this.blobCache.set(originalUrl, blobUrl);
|
573
|
-
}
|
574
|
-
getBlobUrl(originalUrl) {
|
575
|
-
return this.blobCache.get(originalUrl);
|
576
|
-
}
|
577
|
-
load(url, onLoad, onProgress, onError) {
|
578
|
-
const blobUrl = this.getBlobUrl(url);
|
579
|
-
if (blobUrl) {
|
580
|
-
console.log(`Loading cached ${url.split("/").pop()}`);
|
581
|
-
super.load(blobUrl, onLoad, onProgress, onError);
|
582
|
-
} else {
|
583
|
-
super.load(url, onLoad, onProgress, onError);
|
584
|
-
}
|
585
|
-
}
|
586
|
-
};
|
587
|
-
var LRUCache = class {
|
588
|
-
constructor(maxSize = 100) {
|
589
|
-
this.maxSize = maxSize;
|
590
|
-
this.cache = /* @__PURE__ */ new Map();
|
591
|
-
}
|
592
|
-
get(key) {
|
593
|
-
const item = this.cache.get(key);
|
594
|
-
if (item) {
|
595
|
-
this.cache.delete(key);
|
596
|
-
this.cache.set(key, item);
|
597
|
-
}
|
598
|
-
return item;
|
599
|
-
}
|
600
|
-
set(key, value) {
|
601
|
-
if (this.cache.size >= this.maxSize) {
|
602
|
-
const oldestKey = this.cache.keys().next().value;
|
603
|
-
this.cache.delete(oldestKey);
|
604
|
-
}
|
605
|
-
this.cache.set(key, value);
|
606
|
-
}
|
607
|
-
};
|
608
|
-
var _ModelLoader = class _ModelLoader {
|
609
|
-
constructor(maxCacheSize = 100) {
|
610
|
-
this.ongoingLoads = /* @__PURE__ */ new Map();
|
611
|
-
this.loadingManager = new LoadingManager();
|
612
|
-
this.gltfLoader = new CachedGLTFLoader(this.loadingManager);
|
613
|
-
this.modelCache = new LRUCache(maxCacheSize);
|
614
|
-
}
|
615
|
-
/* TODO: decide between below lazy initialization or eager on this file's bottom export */
|
616
|
-
static getInstance() {
|
617
|
-
if (!_ModelLoader.instance) {
|
618
|
-
_ModelLoader.instance = new _ModelLoader();
|
619
|
-
}
|
620
|
-
return _ModelLoader.instance;
|
621
|
-
}
|
622
|
-
async load(fileUrl, fileType) {
|
623
|
-
const cachedModel = this.modelCache.get(fileUrl);
|
624
|
-
if (cachedModel) {
|
625
|
-
const blobURL = URL.createObjectURL(cachedModel.blob);
|
626
|
-
this.gltfLoader.setBlobUrl(fileUrl, blobURL);
|
627
|
-
return this.loadFromUrl(fileUrl, fileType, cachedModel.originalExtension);
|
628
|
-
} else {
|
629
|
-
console.log(`Loading ${fileUrl} from server`);
|
630
|
-
const ongoingLoad = this.ongoingLoads.get(fileUrl);
|
631
|
-
if (ongoingLoad)
|
632
|
-
return ongoingLoad;
|
633
|
-
const loadPromise = fetch(fileUrl).then((response) => response.blob()).then((blob) => {
|
634
|
-
const originalExtension = fileUrl.split(".").pop() || "";
|
635
|
-
this.modelCache.set(fileUrl, { blob, originalExtension });
|
636
|
-
const blobURL = URL.createObjectURL(blob);
|
637
|
-
this.ongoingLoads.delete(fileUrl);
|
638
|
-
return this.loadFromUrl(blobURL, fileType, originalExtension);
|
639
|
-
});
|
640
|
-
this.ongoingLoads.set(fileUrl, loadPromise);
|
641
|
-
return loadPromise;
|
642
|
-
}
|
643
|
-
}
|
644
|
-
async loadFromUrl(url, fileType, extension) {
|
645
|
-
if (["gltf", "glb"].includes(extension)) {
|
646
|
-
return new Promise((resolve, reject) => {
|
647
|
-
this.gltfLoader.load(
|
648
|
-
url,
|
649
|
-
(object) => {
|
650
|
-
if (fileType === "model") {
|
651
|
-
resolve(object.scene);
|
652
|
-
} else if (fileType === "animation") {
|
653
|
-
resolve(object.animations[0]);
|
654
|
-
} else {
|
655
|
-
const error = `Trying to load unknown ${fileType} type of element from file ${url}`;
|
656
|
-
console.error(error);
|
657
|
-
reject(error);
|
658
|
-
}
|
659
|
-
},
|
660
|
-
void 0,
|
661
|
-
(error) => {
|
662
|
-
console.error(`Error loading GL(B|TF) from ${url}: ${error}`);
|
663
|
-
reject(error);
|
664
|
-
}
|
665
|
-
);
|
666
|
-
});
|
667
|
-
} else {
|
668
|
-
console.error(`Error: can't recognize ${url} extension: ${extension}`);
|
669
|
-
}
|
670
|
-
}
|
671
|
-
};
|
672
|
-
_ModelLoader.instance = null;
|
673
|
-
var ModelLoader = _ModelLoader;
|
674
|
-
var MODEL_LOADER = ModelLoader.getInstance();
|
675
|
-
var ModelLoader_default = MODEL_LOADER;
|
676
|
-
|
677
604
|
// src/character/CharacterModel.ts
|
678
605
|
var CharacterModel = class {
|
679
|
-
constructor(characterDescription) {
|
606
|
+
constructor(characterDescription, characterModelLoader) {
|
680
607
|
this.characterDescription = characterDescription;
|
681
|
-
|
682
|
-
this.modelLoader = ModelLoader_default;
|
608
|
+
this.characterModelLoader = characterModelLoader;
|
683
609
|
this.mesh = null;
|
684
610
|
this.material = new CharacterMaterial();
|
685
611
|
this.headBone = null;
|
@@ -757,9 +683,9 @@ var CharacterModel = class {
|
|
757
683
|
const scale = this.characterDescription.modelScale;
|
758
684
|
const extension = mainMeshUrl.split(".").pop();
|
759
685
|
const name = mainMeshUrl.split("/").pop().replace(`.${extension}`, "");
|
760
|
-
const mainMesh = await this.
|
686
|
+
const mainMesh = await this.characterModelLoader.load(mainMeshUrl, "model");
|
761
687
|
if (typeof mainMesh !== "undefined") {
|
762
|
-
this.mesh = new
|
688
|
+
this.mesh = new Object3D();
|
763
689
|
const model = mainMesh;
|
764
690
|
model.position.set(0, -0.4, 0);
|
765
691
|
this.mesh.add(model);
|
@@ -771,8 +697,8 @@ var CharacterModel = class {
|
|
771
697
|
async setAnimationFromFile(animationFileUrl, animationType) {
|
772
698
|
return new Promise(async (resolve, reject) => {
|
773
699
|
this.initAnimationMixer();
|
774
|
-
const animation = await this.
|
775
|
-
if (typeof animation !== "undefined" && animation instanceof
|
700
|
+
const animation = await this.characterModelLoader.load(animationFileUrl, "animation");
|
701
|
+
if (typeof animation !== "undefined" && animation instanceof AnimationClip) {
|
776
702
|
this.animations[animationType] = this.animationMixer.clipAction(animation);
|
777
703
|
this.animations[animationType].stop();
|
778
704
|
if (animationType === 0 /* idle */) {
|
@@ -1304,7 +1230,6 @@ var LocalController = class {
|
|
1304
1230
|
this.characterVelocity.y = deltaTime * this.gravity;
|
1305
1231
|
}
|
1306
1232
|
} else if (this.jump && this.coyoteTime) {
|
1307
|
-
console.log("coyoteJump");
|
1308
1233
|
this.characterVelocity.y = this.jumpForce;
|
1309
1234
|
this.canJump = false;
|
1310
1235
|
} else {
|
@@ -1394,8 +1319,9 @@ var LocalController = class {
|
|
1394
1319
|
|
1395
1320
|
// src/character/Character.ts
|
1396
1321
|
var Character = class {
|
1397
|
-
constructor(characterDescription, id, isLocal, modelLoadedCallback, collisionsManager, keyInputManager, cameraManager, timeManager, composer) {
|
1322
|
+
constructor(characterDescription, characterModelLoader, id, isLocal, modelLoadedCallback, collisionsManager, keyInputManager, cameraManager, timeManager, composer) {
|
1398
1323
|
this.characterDescription = characterDescription;
|
1324
|
+
this.characterModelLoader = characterModelLoader;
|
1399
1325
|
this.id = id;
|
1400
1326
|
this.isLocal = isLocal;
|
1401
1327
|
this.modelLoadedCallback = modelLoadedCallback;
|
@@ -1414,7 +1340,7 @@ var Character = class {
|
|
1414
1340
|
this.load();
|
1415
1341
|
}
|
1416
1342
|
async load() {
|
1417
|
-
this.model = new CharacterModel(this.characterDescription);
|
1343
|
+
this.model = new CharacterModel(this.characterDescription, this.characterModelLoader);
|
1418
1344
|
await this.model.init();
|
1419
1345
|
if (this.tooltip === null) {
|
1420
1346
|
this.tooltip = new CharacterTooltip(this.model.mesh);
|
@@ -1461,22 +1387,22 @@ var Character = class {
|
|
1461
1387
|
};
|
1462
1388
|
|
1463
1389
|
// src/character/CharacterManager.ts
|
1464
|
-
import { Group, Vector3 as Vector37 } from "three";
|
1390
|
+
import { Euler, Group, Quaternion as Quaternion4, Vector3 as Vector37 } from "three";
|
1465
1391
|
|
1466
1392
|
// src/character/RemoteController.ts
|
1467
1393
|
import {
|
1468
1394
|
AnimationMixer as AnimationMixer2,
|
1469
|
-
Object3D as
|
1395
|
+
Object3D as Object3D4,
|
1470
1396
|
Quaternion as Quaternion3,
|
1471
1397
|
Vector3 as Vector36
|
1472
1398
|
} from "three";
|
1473
1399
|
var RemoteController = class {
|
1474
|
-
constructor(character, id) {
|
1400
|
+
constructor(character, characterModelLoader, id) {
|
1475
1401
|
this.character = character;
|
1402
|
+
this.characterModelLoader = characterModelLoader;
|
1476
1403
|
this.id = id;
|
1477
|
-
this.modelLoader = ModelLoader_default;
|
1478
1404
|
this.characterModel = null;
|
1479
|
-
this.animationMixer = new AnimationMixer2(new
|
1405
|
+
this.animationMixer = new AnimationMixer2(new Object3D4());
|
1480
1406
|
this.animations = /* @__PURE__ */ new Map();
|
1481
1407
|
this.currentAnimation = 0 /* idle */;
|
1482
1408
|
this.characterModel = this.character.model.mesh;
|
@@ -1497,7 +1423,7 @@ var RemoteController = class {
|
|
1497
1423
|
this.animationMixer.update(deltaTime);
|
1498
1424
|
}
|
1499
1425
|
async setAnimationFromFile(animationType, fileName) {
|
1500
|
-
const animation = await this.
|
1426
|
+
const animation = await this.characterModelLoader.load(fileName, "animation");
|
1501
1427
|
const animationAction = this.animationMixer.clipAction(animation);
|
1502
1428
|
this.animations.set(animationType, animationAction);
|
1503
1429
|
if (animationType === 0 /* idle */) {
|
@@ -1550,8 +1476,9 @@ function decodeCharacterAndCamera(hash, character, camera) {
|
|
1550
1476
|
camera.quaternion.fromArray(values.slice(10, 14));
|
1551
1477
|
}
|
1552
1478
|
var CharacterManager = class {
|
1553
|
-
constructor(composer, collisionsManager, cameraManager, timeManager, inputManager, clientStates, sendUpdate) {
|
1479
|
+
constructor(composer, characterModelLoader, collisionsManager, cameraManager, timeManager, inputManager, clientStates, sendUpdate) {
|
1554
1480
|
this.composer = composer;
|
1481
|
+
this.characterModelLoader = characterModelLoader;
|
1555
1482
|
this.collisionsManager = collisionsManager;
|
1556
1483
|
this.cameraManager = cameraManager;
|
1557
1484
|
this.timeManager = timeManager;
|
@@ -1581,11 +1508,12 @@ var CharacterManager = class {
|
|
1581
1508
|
the mesh loading async (would allow us to show a nameplate where a remote
|
1582
1509
|
user is before the asset loads).
|
1583
1510
|
*/
|
1584
|
-
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector37()) {
|
1511
|
+
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector37(), spawnRotation = new Euler()) {
|
1585
1512
|
this.characterDescription = characterDescription;
|
1586
1513
|
const characterLoadingPromise = new Promise((resolve) => {
|
1587
1514
|
const character = new Character(
|
1588
1515
|
characterDescription,
|
1516
|
+
this.characterModelLoader,
|
1589
1517
|
id,
|
1590
1518
|
isLocal,
|
1591
1519
|
() => {
|
@@ -1597,9 +1525,12 @@ var CharacterManager = class {
|
|
1597
1525
|
this.cameraManager.camera
|
1598
1526
|
);
|
1599
1527
|
} else {
|
1600
|
-
spawnPosition = getSpawnPositionInsideCircle(3, 30, id, 0.4);
|
1528
|
+
spawnPosition = spawnPosition || getSpawnPositionInsideCircle(3, 30, id, 0.4);
|
1601
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);
|
1602
1532
|
character.model.mesh.updateMatrixWorld();
|
1533
|
+
const quaternion = new Quaternion4().setFromEuler(character.model.mesh.rotation);
|
1603
1534
|
this.sendUpdate({
|
1604
1535
|
id,
|
1605
1536
|
position: {
|
@@ -1607,7 +1538,7 @@ var CharacterManager = class {
|
|
1607
1538
|
y: spawnPosition.y,
|
1608
1539
|
z: spawnPosition.z
|
1609
1540
|
},
|
1610
|
-
rotation: { quaternionY:
|
1541
|
+
rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },
|
1611
1542
|
state: 0 /* idle */
|
1612
1543
|
});
|
1613
1544
|
}
|
@@ -1624,7 +1555,7 @@ var CharacterManager = class {
|
|
1624
1555
|
(_e = this.character.tooltip) == null ? void 0 : _e.setText(`${id}`);
|
1625
1556
|
} else {
|
1626
1557
|
this.remoteCharacters.set(id, character);
|
1627
|
-
const remoteController = new RemoteController(character, id);
|
1558
|
+
const remoteController = new RemoteController(character, this.characterModelLoader, id);
|
1628
1559
|
remoteController.setAnimationFromFile(
|
1629
1560
|
0 /* idle */,
|
1630
1561
|
characterDescription.idleAnimationFileUrl
|
@@ -1747,19 +1678,143 @@ var CharacterManager = class {
|
|
1747
1678
|
}
|
1748
1679
|
};
|
1749
1680
|
|
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();
|
1688
|
+
}
|
1689
|
+
setBlobUrl(originalUrl, blobUrl) {
|
1690
|
+
this.blobCache.set(originalUrl, blobUrl);
|
1691
|
+
}
|
1692
|
+
getBlobUrl(originalUrl) {
|
1693
|
+
return this.blobCache.get(originalUrl);
|
1694
|
+
}
|
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
|
+
}
|
1703
|
+
}
|
1704
|
+
};
|
1705
|
+
var LRUCache = class {
|
1706
|
+
constructor(maxSize = 100) {
|
1707
|
+
this.maxSize = maxSize;
|
1708
|
+
this.cache = /* @__PURE__ */ new Map();
|
1709
|
+
}
|
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;
|
1717
|
+
}
|
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);
|
1724
|
+
}
|
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);
|
1732
|
+
}
|
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;
|
1739
|
+
}
|
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
|
+
|
1750
1794
|
// src/input/KeyInputManager.ts
|
1751
1795
|
var KeyInputManager = class {
|
1752
|
-
constructor() {
|
1796
|
+
constructor(shouldCaptureKeyPress = () => true) {
|
1797
|
+
this.shouldCaptureKeyPress = shouldCaptureKeyPress;
|
1753
1798
|
this.keys = /* @__PURE__ */ new Map();
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
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));
|
1757
1803
|
}
|
1758
1804
|
handleUnfocus(_event) {
|
1759
1805
|
this.keys.clear();
|
1760
1806
|
}
|
1761
1807
|
onKeyDown(event) {
|
1762
|
-
this.
|
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
|
+
}
|
1763
1818
|
}
|
1764
1819
|
onKeyUp(event) {
|
1765
1820
|
this.keys.set(event.key.toLowerCase(), false);
|
@@ -1768,36 +1823,34 @@ var KeyInputManager = class {
|
|
1768
1823
|
return this.keys.get(key) || false;
|
1769
1824
|
}
|
1770
1825
|
isMovementKeyPressed() {
|
1771
|
-
return ["w"
|
1826
|
+
return ["w" /* W */, "a" /* A */, "s" /* S */, "d" /* D */].some((key) => this.isKeyPressed(key));
|
1772
1827
|
}
|
1773
1828
|
get forward() {
|
1774
|
-
return this.isKeyPressed("w");
|
1829
|
+
return this.isKeyPressed("w" /* W */);
|
1775
1830
|
}
|
1776
1831
|
get backward() {
|
1777
|
-
return this.isKeyPressed("s");
|
1832
|
+
return this.isKeyPressed("s" /* S */);
|
1778
1833
|
}
|
1779
1834
|
get left() {
|
1780
|
-
return this.isKeyPressed("a");
|
1835
|
+
return this.isKeyPressed("a" /* A */);
|
1781
1836
|
}
|
1782
1837
|
get right() {
|
1783
|
-
return this.isKeyPressed("d");
|
1838
|
+
return this.isKeyPressed("d" /* D */);
|
1784
1839
|
}
|
1785
1840
|
get run() {
|
1786
|
-
return this.isKeyPressed("shift");
|
1841
|
+
return this.isKeyPressed("shift" /* SHIFT */);
|
1787
1842
|
}
|
1788
1843
|
get jump() {
|
1789
|
-
return this.isKeyPressed(" ");
|
1844
|
+
return this.isKeyPressed(" " /* SPACE */);
|
1790
1845
|
}
|
1791
1846
|
get anyDirection() {
|
1792
1847
|
return this.isMovementKeyPressed();
|
1793
1848
|
}
|
1794
1849
|
get conflictingDirection() {
|
1795
|
-
return this.isKeyPressed("w") && this.isKeyPressed("s") || this.isKeyPressed("a") && this.isKeyPressed("d");
|
1850
|
+
return this.isKeyPressed("w" /* W */) && this.isKeyPressed("s" /* S */) || this.isKeyPressed("a" /* A */) && this.isKeyPressed("d" /* D */);
|
1796
1851
|
}
|
1797
1852
|
dispose() {
|
1798
|
-
|
1799
|
-
document.removeEventListener("keyup", this.onKeyDown.bind(this));
|
1800
|
-
window.removeEventListener("blur", this.handleUnfocus.bind(this));
|
1853
|
+
this.eventHandlerCollection.clear();
|
1801
1854
|
}
|
1802
1855
|
};
|
1803
1856
|
|
@@ -1805,23 +1858,25 @@ var KeyInputManager = class {
|
|
1805
1858
|
import {
|
1806
1859
|
InteractionManager,
|
1807
1860
|
MMLClickTrigger,
|
1808
|
-
PromptManager
|
1809
|
-
registerCustomElementsToWindow,
|
1810
|
-
setGlobalMScene
|
1861
|
+
PromptManager
|
1811
1862
|
} from "mml-web";
|
1812
1863
|
import { Group as Group2 } from "three";
|
1813
1864
|
var MMLCompositionScene = class {
|
1814
|
-
constructor(renderer, scene, camera, audioListener, collisionsManager, getUserPositionAndRotation
|
1865
|
+
constructor(targetElement, renderer, scene, camera, audioListener, collisionsManager, getUserPositionAndRotation) {
|
1815
1866
|
this.renderer = renderer;
|
1816
1867
|
this.scene = scene;
|
1817
1868
|
this.camera = camera;
|
1818
1869
|
this.audioListener = audioListener;
|
1819
1870
|
this.collisionsManager = collisionsManager;
|
1820
1871
|
this.getUserPositionAndRotation = getUserPositionAndRotation;
|
1821
|
-
this.debug = false;
|
1822
1872
|
this.group = new Group2();
|
1823
|
-
this.promptManager = PromptManager.init(
|
1824
|
-
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;
|
1825
1880
|
this.interactionListener = interactionListener;
|
1826
1881
|
this.mmlScene = {
|
1827
1882
|
getAudioListener: () => this.audioListener,
|
@@ -1852,55 +1907,65 @@ var MMLCompositionScene = class {
|
|
1852
1907
|
this.promptManager.prompt(promptProps, callback);
|
1853
1908
|
}
|
1854
1909
|
};
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
for (const address of documentAddresses) {
|
1862
|
-
const frameElement = document.createElement("m-frame");
|
1863
|
-
frameElement.setAttribute("src", address);
|
1864
|
-
document.body.appendChild(frameElement);
|
1865
|
-
}
|
1910
|
+
this.clickTrigger = MMLClickTrigger.init(targetElement, this.mmlScene);
|
1911
|
+
}
|
1912
|
+
dispose() {
|
1913
|
+
this.promptManager.dispose();
|
1914
|
+
this.clickTrigger.dispose();
|
1915
|
+
this.interactionManager.dispose();
|
1866
1916
|
}
|
1867
1917
|
};
|
1868
1918
|
|
1869
|
-
// src/
|
1870
|
-
import
|
1871
|
-
import {
|
1872
|
-
EffectComposer as EffectComposer2,
|
1873
|
-
RenderPass,
|
1874
|
-
EffectPass as EffectPass2,
|
1875
|
-
FXAAEffect,
|
1876
|
-
ShaderPass,
|
1877
|
-
BloomEffect,
|
1878
|
-
SSAOEffect as SSAOEffect2,
|
1879
|
-
BlendFunction as BlendFunction2,
|
1880
|
-
TextureEffect,
|
1881
|
-
ToneMappingEffect,
|
1882
|
-
SMAAEffect,
|
1883
|
-
SMAAPreset,
|
1884
|
-
EdgeDetectionMode,
|
1885
|
-
PredicationMode,
|
1886
|
-
NormalPass as NormalPass2
|
1887
|
-
} from "postprocessing";
|
1888
|
-
import {
|
1889
|
-
AmbientLight,
|
1890
|
-
Color as Color6,
|
1891
|
-
Fog,
|
1892
|
-
HalfFloatType,
|
1893
|
-
LinearSRGBColorSpace,
|
1894
|
-
LoadingManager as LoadingManager2,
|
1895
|
-
PMREMGenerator,
|
1896
|
-
Scene as Scene3,
|
1897
|
-
Vector2 as Vector22,
|
1898
|
-
WebGLRenderer as WebGLRenderer2
|
1899
|
-
} from "three";
|
1900
|
-
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";
|
1901
1922
|
|
1902
|
-
// src/
|
1903
|
-
|
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
|
+
};
|
1904
1969
|
|
1905
1970
|
// src/tweakpane/blades/environmentFolder.ts
|
1906
1971
|
var sunValues = {
|
@@ -2057,135 +2122,6 @@ var EnvironmentFolder = class {
|
|
2057
2122
|
}
|
2058
2123
|
};
|
2059
2124
|
|
2060
|
-
// src/sun/Sun.ts
|
2061
|
-
var Sun = class extends Group3 {
|
2062
|
-
constructor() {
|
2063
|
-
super();
|
2064
|
-
this.debug = false;
|
2065
|
-
this.sunOffset = new Vector38(
|
2066
|
-
39 * (Math.PI / 180),
|
2067
|
-
50 * (Math.PI / 180),
|
2068
|
-
100
|
2069
|
-
);
|
2070
|
-
this.shadowResolution = 8192;
|
2071
|
-
this.shadowCamFrustum = 50;
|
2072
|
-
this.camHelper = null;
|
2073
|
-
this.target = null;
|
2074
|
-
this.shadowCamera = new OrthographicCamera(
|
2075
|
-
-this.shadowCamFrustum,
|
2076
|
-
this.shadowCamFrustum,
|
2077
|
-
this.shadowCamFrustum,
|
2078
|
-
-this.shadowCamFrustum,
|
2079
|
-
0.1,
|
2080
|
-
200
|
2081
|
-
);
|
2082
|
-
if (this.debug === true) {
|
2083
|
-
this.camHelper = new CameraHelper(this.shadowCamera);
|
2084
|
-
}
|
2085
|
-
this.directionalLight = new DirectionalLight(16777215, 0.5);
|
2086
|
-
this.directionalLight.shadow.normalBias = 0.05;
|
2087
|
-
this.directionalLight.shadow.radius = 1.5;
|
2088
|
-
this.directionalLight.shadow.camera = this.shadowCamera;
|
2089
|
-
this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);
|
2090
|
-
this.directionalLight.castShadow = true;
|
2091
|
-
this.setColor();
|
2092
|
-
this.updateCharacterPosition(new Vector38(0, 0, 0));
|
2093
|
-
this.add(this.directionalLight);
|
2094
|
-
if (this.debug === true && this.camHelper instanceof CameraHelper) {
|
2095
|
-
this.add(this.camHelper);
|
2096
|
-
}
|
2097
|
-
}
|
2098
|
-
updateCharacterPosition(position) {
|
2099
|
-
if (!position)
|
2100
|
-
return;
|
2101
|
-
this.target = position;
|
2102
|
-
this.setSunPosition(this.sunOffset.x, this.sunOffset.y);
|
2103
|
-
}
|
2104
|
-
setAzimuthalAngle(angle) {
|
2105
|
-
if (this.sunOffset)
|
2106
|
-
this.sunOffset.x = angle;
|
2107
|
-
if (this.target)
|
2108
|
-
this.updateCharacterPosition(this.target);
|
2109
|
-
}
|
2110
|
-
setPolarAngle(angle) {
|
2111
|
-
if (this.sunOffset)
|
2112
|
-
this.sunOffset.y = angle;
|
2113
|
-
if (this.target)
|
2114
|
-
this.updateCharacterPosition(this.target);
|
2115
|
-
}
|
2116
|
-
setIntensity(intensity) {
|
2117
|
-
this.directionalLight.intensity = intensity;
|
2118
|
-
}
|
2119
|
-
setColor() {
|
2120
|
-
this.directionalLight.color = new Color4().setRGB(
|
2121
|
-
sunValues.sunColor.r,
|
2122
|
-
sunValues.sunColor.g,
|
2123
|
-
sunValues.sunColor.b
|
2124
|
-
);
|
2125
|
-
}
|
2126
|
-
setSunPosition(azimuthalAngle, polarAngle) {
|
2127
|
-
if (!this.target)
|
2128
|
-
return;
|
2129
|
-
const distance = this.sunOffset.z;
|
2130
|
-
const sphericalPosition = new Vector38(
|
2131
|
-
distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),
|
2132
|
-
distance * Math.cos(polarAngle),
|
2133
|
-
distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle)
|
2134
|
-
);
|
2135
|
-
const newSunPosition = this.target.clone().add(sphericalPosition);
|
2136
|
-
this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);
|
2137
|
-
this.directionalLight.target.position.copy(this.target.clone());
|
2138
|
-
this.directionalLight.target.updateMatrixWorld();
|
2139
|
-
}
|
2140
|
-
};
|
2141
|
-
|
2142
|
-
// src/tweakpane/blades/bcsFolder.ts
|
2143
|
-
var bcsValues = {
|
2144
|
-
brightness: 0,
|
2145
|
-
contrast: 1.25,
|
2146
|
-
saturation: 1
|
2147
|
-
};
|
2148
|
-
var bcsOptions = {
|
2149
|
-
brightness: {
|
2150
|
-
amount: { min: -1, max: 1, step: 0.01 }
|
2151
|
-
},
|
2152
|
-
contrast: {
|
2153
|
-
amount: { min: 0, max: 2, step: 0.01 }
|
2154
|
-
},
|
2155
|
-
saturation: {
|
2156
|
-
amount: { min: 0, max: 2, step: 0.01 }
|
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
2125
|
// src/tweakpane/blades/postExtrasFolder.ts
|
2190
2126
|
var extrasValues = {
|
2191
2127
|
grain: 0.055,
|
@@ -2310,9 +2246,52 @@ var RendererFolder = class {
|
|
2310
2246
|
}
|
2311
2247
|
};
|
2312
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
|
+
|
2313
2292
|
// src/tweakpane/blades/ssaoFolder.ts
|
2314
2293
|
import { BlendFunction } from "postprocessing";
|
2315
|
-
import { Color as
|
2294
|
+
import { Color as Color4 } from "three";
|
2316
2295
|
var ppssaoValues = {
|
2317
2296
|
enabled: false,
|
2318
2297
|
blendFunction: BlendFunction.MULTIPLY,
|
@@ -2504,7 +2483,7 @@ var SSAOFolder = class {
|
|
2504
2483
|
}
|
2505
2484
|
case "color": {
|
2506
2485
|
const value = e.value;
|
2507
|
-
ppssaoEffect.color = new
|
2486
|
+
ppssaoEffect.color = new Color4().setRGB(value.r, value.g, value.b);
|
2508
2487
|
break;
|
2509
2488
|
}
|
2510
2489
|
default: {
|
@@ -2544,7 +2523,7 @@ var SSAOFolder = class {
|
|
2544
2523
|
break;
|
2545
2524
|
case "color":
|
2546
2525
|
const value = e.value;
|
2547
|
-
n8aopass.configuration.color = new
|
2526
|
+
n8aopass.configuration.color = new Color4().setRGB(value.r, value.g, value.b);
|
2548
2527
|
break;
|
2549
2528
|
default:
|
2550
2529
|
break;
|
@@ -2637,53 +2616,6 @@ var ToneMappingFolder = class {
|
|
2637
2616
|
}
|
2638
2617
|
};
|
2639
2618
|
|
2640
|
-
// src/tweakpane/TweakPane.ts
|
2641
|
-
import * as EssentialsPlugin from "@tweakpane/plugin-essentials";
|
2642
|
-
import { Pane } from "tweakpane";
|
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
2619
|
// src/tweakpane/tweakPaneStyle.ts
|
2688
2620
|
var tweakPaneStyle = `
|
2689
2621
|
:root {
|
@@ -2882,6 +2814,122 @@ var TweakPane = class {
|
|
2882
2814
|
}
|
2883
2815
|
};
|
2884
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
|
+
|
2885
2933
|
// src/rendering/post-effects/bright-contrast-sat.ts
|
2886
2934
|
import { ShaderMaterial, Uniform } from "three";
|
2887
2935
|
|
@@ -3029,8 +3077,8 @@ var GaussGrainEffect = new ShaderMaterial2({
|
|
3029
3077
|
// src/rendering/composer.ts
|
3030
3078
|
var Composer = class {
|
3031
3079
|
constructor(scene, camera, spawnSun = false) {
|
3032
|
-
this.width =
|
3033
|
-
this.height =
|
3080
|
+
this.width = 1;
|
3081
|
+
this.height = 1;
|
3034
3082
|
this.resolution = new Vector22(this.width, this.height);
|
3035
3083
|
this.isEnvHDRI = false;
|
3036
3084
|
this.bcs = BrightnessContrastSaturation;
|
@@ -3055,11 +3103,9 @@ var Composer = class {
|
|
3055
3103
|
this.renderer.toneMappingExposure = rendererValues.exposure;
|
3056
3104
|
this.setAmbientLight();
|
3057
3105
|
this.setFog();
|
3058
|
-
|
3059
|
-
this.composer = new EffectComposer2(this.renderer, {
|
3106
|
+
this.effectComposer = new EffectComposer2(this.renderer, {
|
3060
3107
|
frameBufferType: HalfFloatType
|
3061
3108
|
});
|
3062
|
-
this.tweakPane = new TweakPane(this.renderer, this.scene, this.composer);
|
3063
3109
|
this.renderPass = new RenderPass(this.scene, this.camera);
|
3064
3110
|
this.normalPass = new NormalPass2(this.scene, this.camera);
|
3065
3111
|
this.normalPass.enabled = ppssaoValues.enabled;
|
@@ -3128,26 +3174,33 @@ var Composer = class {
|
|
3128
3174
|
this.bcs.uniforms.saturation.value = bcsValues.saturation;
|
3129
3175
|
this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, "tDiffuse");
|
3130
3176
|
this.smaaPass = new EffectPass2(this.camera, this.smaaEffect);
|
3131
|
-
this.
|
3177
|
+
this.effectComposer.addPass(this.renderPass);
|
3132
3178
|
if (ppssaoValues.enabled) {
|
3133
|
-
this.
|
3134
|
-
this.
|
3179
|
+
this.effectComposer.addPass(this.normalPass);
|
3180
|
+
this.effectComposer.addPass(this.ppssaoPass);
|
3135
3181
|
}
|
3136
3182
|
if (n8ssaoValues.enabled) {
|
3137
|
-
this.
|
3138
|
-
}
|
3139
|
-
this.
|
3140
|
-
this.
|
3141
|
-
this.
|
3142
|
-
this.
|
3143
|
-
this.
|
3144
|
-
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);
|
3145
3191
|
if (this.spawnSun === true) {
|
3146
3192
|
this.sun = new Sun();
|
3147
3193
|
this.scene.add(this.sun);
|
3148
3194
|
}
|
3149
|
-
this.
|
3150
|
-
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,
|
3151
3204
|
this.normalPass,
|
3152
3205
|
this.ppssaoEffect,
|
3153
3206
|
this.ppssaoPass,
|
@@ -3163,14 +3216,32 @@ var Composer = class {
|
|
3163
3216
|
this.setAmbientLight.bind(this),
|
3164
3217
|
this.setFog.bind(this)
|
3165
3218
|
);
|
3166
|
-
window.addEventListener("resize", () => this.updateProjection());
|
3167
|
-
this.updateProjection();
|
3168
3219
|
}
|
3169
|
-
|
3170
|
-
|
3171
|
-
|
3172
|
-
|
3173
|
-
|
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
|
+
);
|
3174
3245
|
this.renderPass.setSize(this.width, this.height);
|
3175
3246
|
if (ppssaoValues.enabled) {
|
3176
3247
|
this.normalPass.setSize(this.width, this.height);
|
@@ -3187,20 +3258,14 @@ var Composer = class {
|
|
3187
3258
|
this.gaussGrainPass.setSize(this.width, this.height);
|
3188
3259
|
this.renderer.setSize(this.width, this.height);
|
3189
3260
|
}
|
3190
|
-
isTweakPaneVisible() {
|
3191
|
-
return this.tweakPane.guiVisible;
|
3192
|
-
}
|
3193
3261
|
render(timeManager) {
|
3194
3262
|
this.renderer.info.reset();
|
3195
3263
|
this.normalPass.texture.needsUpdate = true;
|
3196
3264
|
this.gaussGrainEffect.uniforms.resolution.value = this.resolution;
|
3197
3265
|
this.gaussGrainEffect.uniforms.time.value = timeManager.time;
|
3198
3266
|
this.gaussGrainEffect.uniforms.alpha.value = 1;
|
3199
|
-
this.
|
3267
|
+
this.effectComposer.render();
|
3200
3268
|
this.renderer.render(this.postPostScene, this.camera);
|
3201
|
-
if (this.tweakPane.guiVisible) {
|
3202
|
-
this.tweakPane.updateStats(timeManager);
|
3203
|
-
}
|
3204
3269
|
}
|
3205
3270
|
useHDRI(url, fromFile = false) {
|
3206
3271
|
if (this.isEnvHDRI && fromFile === false || !this.renderer)
|
@@ -3332,7 +3397,7 @@ import {
|
|
3332
3397
|
Box3,
|
3333
3398
|
Color as Color7,
|
3334
3399
|
DoubleSide,
|
3335
|
-
Euler,
|
3400
|
+
Euler as Euler2,
|
3336
3401
|
Group as Group4,
|
3337
3402
|
Line3 as Line32,
|
3338
3403
|
Matrix4 as Matrix42,
|
@@ -3354,7 +3419,7 @@ var CollisionsManager = class {
|
|
3354
3419
|
this.tempMatrix = new Matrix42();
|
3355
3420
|
this.tempMatrix2 = new Matrix42();
|
3356
3421
|
this.tempBox = new Box3();
|
3357
|
-
this.tempEuler = new
|
3422
|
+
this.tempEuler = new Euler2();
|
3358
3423
|
this.tempSegment = new Line32();
|
3359
3424
|
this.tempSegment2 = new Line32();
|
3360
3425
|
this.collisionMeshState = /* @__PURE__ */ new Map();
|
@@ -3547,11 +3612,13 @@ export {
|
|
3547
3612
|
AnimationState,
|
3548
3613
|
CameraManager,
|
3549
3614
|
CharacterManager,
|
3615
|
+
CharacterModelLoader,
|
3550
3616
|
CollisionsManager,
|
3551
3617
|
Composer,
|
3552
3618
|
KeyInputManager,
|
3553
3619
|
MMLCompositionScene,
|
3554
3620
|
Sun,
|
3555
|
-
TimeManager
|
3621
|
+
TimeManager,
|
3622
|
+
TweakPane
|
3556
3623
|
};
|
3557
3624
|
//# sourceMappingURL=index.js.map
|