@mml-io/3d-web-client-core 0.0.0-experimental-aaef76d-20230925 → 0.0.0-experimental-4ca92b1-20231017
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 +491 -430
- 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,137 @@ 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
|
+
this.keys.set(event.key.toLowerCase(), true);
|
1810
|
+
event.preventDefault();
|
1811
|
+
}
|
1763
1812
|
}
|
1764
1813
|
onKeyUp(event) {
|
1765
1814
|
this.keys.set(event.key.toLowerCase(), false);
|
@@ -1795,9 +1844,7 @@ var KeyInputManager = class {
|
|
1795
1844
|
return this.isKeyPressed("w") && this.isKeyPressed("s") || this.isKeyPressed("a") && this.isKeyPressed("d");
|
1796
1845
|
}
|
1797
1846
|
dispose() {
|
1798
|
-
|
1799
|
-
document.removeEventListener("keyup", this.onKeyDown.bind(this));
|
1800
|
-
window.removeEventListener("blur", this.handleUnfocus.bind(this));
|
1847
|
+
this.eventHandlerCollection.clear();
|
1801
1848
|
}
|
1802
1849
|
};
|
1803
1850
|
|
@@ -1805,23 +1852,25 @@ var KeyInputManager = class {
|
|
1805
1852
|
import {
|
1806
1853
|
InteractionManager,
|
1807
1854
|
MMLClickTrigger,
|
1808
|
-
PromptManager
|
1809
|
-
registerCustomElementsToWindow,
|
1810
|
-
setGlobalMScene
|
1855
|
+
PromptManager
|
1811
1856
|
} from "mml-web";
|
1812
1857
|
import { Group as Group2 } from "three";
|
1813
1858
|
var MMLCompositionScene = class {
|
1814
|
-
constructor(renderer, scene, camera, audioListener, collisionsManager, getUserPositionAndRotation
|
1859
|
+
constructor(targetElement, renderer, scene, camera, audioListener, collisionsManager, getUserPositionAndRotation) {
|
1815
1860
|
this.renderer = renderer;
|
1816
1861
|
this.scene = scene;
|
1817
1862
|
this.camera = camera;
|
1818
1863
|
this.audioListener = audioListener;
|
1819
1864
|
this.collisionsManager = collisionsManager;
|
1820
1865
|
this.getUserPositionAndRotation = getUserPositionAndRotation;
|
1821
|
-
this.debug = false;
|
1822
1866
|
this.group = new Group2();
|
1823
|
-
this.promptManager = PromptManager.init(
|
1824
|
-
const { interactionListener } = InteractionManager.init(
|
1867
|
+
this.promptManager = PromptManager.init(targetElement);
|
1868
|
+
const { interactionListener, interactionManager } = InteractionManager.init(
|
1869
|
+
targetElement,
|
1870
|
+
this.camera,
|
1871
|
+
this.scene
|
1872
|
+
);
|
1873
|
+
this.interactionManager = interactionManager;
|
1825
1874
|
this.interactionListener = interactionListener;
|
1826
1875
|
this.mmlScene = {
|
1827
1876
|
getAudioListener: () => this.audioListener,
|
@@ -1852,55 +1901,65 @@ var MMLCompositionScene = class {
|
|
1852
1901
|
this.promptManager.prompt(promptProps, callback);
|
1853
1902
|
}
|
1854
1903
|
};
|
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
|
-
}
|
1904
|
+
this.clickTrigger = MMLClickTrigger.init(targetElement, this.mmlScene);
|
1905
|
+
}
|
1906
|
+
dispose() {
|
1907
|
+
this.promptManager.dispose();
|
1908
|
+
this.clickTrigger.dispose();
|
1909
|
+
this.interactionManager.dispose();
|
1866
1910
|
}
|
1867
1911
|
};
|
1868
1912
|
|
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";
|
1913
|
+
// src/tweakpane/TweakPane.ts
|
1914
|
+
import * as EssentialsPlugin from "@tweakpane/plugin-essentials";
|
1915
|
+
import { Pane } from "tweakpane";
|
1901
1916
|
|
1902
|
-
// src/
|
1903
|
-
|
1917
|
+
// src/tweakpane/blades/bcsFolder.ts
|
1918
|
+
var bcsValues = {
|
1919
|
+
brightness: 0,
|
1920
|
+
contrast: 1.25,
|
1921
|
+
saturation: 1
|
1922
|
+
};
|
1923
|
+
var bcsOptions = {
|
1924
|
+
brightness: {
|
1925
|
+
amount: { min: -1, max: 1, step: 0.01 }
|
1926
|
+
},
|
1927
|
+
contrast: {
|
1928
|
+
amount: { min: 0, max: 2, step: 0.01 }
|
1929
|
+
},
|
1930
|
+
saturation: {
|
1931
|
+
amount: { min: 0, max: 2, step: 0.01 }
|
1932
|
+
}
|
1933
|
+
};
|
1934
|
+
var BrightnessContrastSaturationFolder = class {
|
1935
|
+
constructor(parentFolder, expand = false) {
|
1936
|
+
this.folder = parentFolder.addFolder({
|
1937
|
+
title: "brightness / contrast / sat",
|
1938
|
+
expanded: expand
|
1939
|
+
});
|
1940
|
+
this.folder.addBinding(bcsValues, "brightness", bcsOptions.brightness.amount);
|
1941
|
+
this.folder.addBinding(bcsValues, "contrast", bcsOptions.contrast.amount);
|
1942
|
+
this.folder.addBinding(bcsValues, "saturation", bcsOptions.saturation.amount);
|
1943
|
+
}
|
1944
|
+
setupChangeEvent(brightnessContrastSaturation) {
|
1945
|
+
this.folder.on("change", (e) => {
|
1946
|
+
const target = e.target.key;
|
1947
|
+
if (!target)
|
1948
|
+
return;
|
1949
|
+
switch (target) {
|
1950
|
+
case "brightness":
|
1951
|
+
brightnessContrastSaturation.uniforms.brightness.value = e.value;
|
1952
|
+
break;
|
1953
|
+
case "contrast":
|
1954
|
+
brightnessContrastSaturation.uniforms.contrast.value = e.value;
|
1955
|
+
break;
|
1956
|
+
case "saturation":
|
1957
|
+
brightnessContrastSaturation.uniforms.saturation.value = e.value;
|
1958
|
+
break;
|
1959
|
+
}
|
1960
|
+
});
|
1961
|
+
}
|
1962
|
+
};
|
1904
1963
|
|
1905
1964
|
// src/tweakpane/blades/environmentFolder.ts
|
1906
1965
|
var sunValues = {
|
@@ -2057,135 +2116,6 @@ var EnvironmentFolder = class {
|
|
2057
2116
|
}
|
2058
2117
|
};
|
2059
2118
|
|
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
2119
|
// src/tweakpane/blades/postExtrasFolder.ts
|
2190
2120
|
var extrasValues = {
|
2191
2121
|
grain: 0.055,
|
@@ -2310,9 +2240,52 @@ var RendererFolder = class {
|
|
2310
2240
|
}
|
2311
2241
|
};
|
2312
2242
|
|
2243
|
+
// src/tweakpane/blades/rendererStatsFolder.ts
|
2244
|
+
var RendererStatsFolder = class {
|
2245
|
+
constructor(parentFolder, expanded = true) {
|
2246
|
+
this.statsData = {
|
2247
|
+
triangles: "0",
|
2248
|
+
geometries: "0",
|
2249
|
+
textures: "0",
|
2250
|
+
shaders: "0",
|
2251
|
+
postPasses: "0",
|
2252
|
+
drawCalls: "0",
|
2253
|
+
rawDeltaTime: "0",
|
2254
|
+
deltaTime: "0",
|
2255
|
+
FPS: "0"
|
2256
|
+
};
|
2257
|
+
this.folder = parentFolder.addFolder({ title: "renderStats", expanded });
|
2258
|
+
this.performance = this.folder.addFolder({ title: "performance", expanded: true });
|
2259
|
+
this.defails = this.folder.addFolder({ title: "pipeline details", expanded: false });
|
2260
|
+
this.folder.addBlade({ view: "separator" });
|
2261
|
+
this.performance.addBinding(this.statsData, "FPS", { readonly: true });
|
2262
|
+
this.performance.addBinding(this.statsData, "deltaTime", { readonly: true });
|
2263
|
+
this.performance.addBinding(this.statsData, "rawDeltaTime", { readonly: true });
|
2264
|
+
this.defails.addBinding(this.statsData, "triangles", { readonly: true });
|
2265
|
+
this.defails.addBinding(this.statsData, "geometries", { readonly: true });
|
2266
|
+
this.defails.addBinding(this.statsData, "textures", { readonly: true });
|
2267
|
+
this.defails.addBinding(this.statsData, "shaders", { readonly: true });
|
2268
|
+
this.defails.addBinding(this.statsData, "postPasses", { readonly: true });
|
2269
|
+
this.defails.addBinding(this.statsData, "drawCalls", { readonly: true });
|
2270
|
+
}
|
2271
|
+
update(renderer, composer, timeManager) {
|
2272
|
+
const { geometries, textures } = renderer.info.memory;
|
2273
|
+
const { triangles, calls } = renderer.info.render;
|
2274
|
+
this.statsData.triangles = triangles.toString();
|
2275
|
+
this.statsData.geometries = geometries.toString();
|
2276
|
+
this.statsData.textures = textures.toString();
|
2277
|
+
this.statsData.shaders = renderer.info.programs.length.toString();
|
2278
|
+
this.statsData.postPasses = composer.passes.length.toString();
|
2279
|
+
this.statsData.drawCalls = calls.toString();
|
2280
|
+
this.statsData.rawDeltaTime = (Math.round(timeManager.rawDeltaTime * 1e5) / 1e5).toString();
|
2281
|
+
this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 1e5) / 1e5).toString();
|
2282
|
+
this.statsData.FPS = timeManager.fps.toString();
|
2283
|
+
}
|
2284
|
+
};
|
2285
|
+
|
2313
2286
|
// src/tweakpane/blades/ssaoFolder.ts
|
2314
2287
|
import { BlendFunction } from "postprocessing";
|
2315
|
-
import { Color as
|
2288
|
+
import { Color as Color4 } from "three";
|
2316
2289
|
var ppssaoValues = {
|
2317
2290
|
enabled: false,
|
2318
2291
|
blendFunction: BlendFunction.MULTIPLY,
|
@@ -2504,7 +2477,7 @@ var SSAOFolder = class {
|
|
2504
2477
|
}
|
2505
2478
|
case "color": {
|
2506
2479
|
const value = e.value;
|
2507
|
-
ppssaoEffect.color = new
|
2480
|
+
ppssaoEffect.color = new Color4().setRGB(value.r, value.g, value.b);
|
2508
2481
|
break;
|
2509
2482
|
}
|
2510
2483
|
default: {
|
@@ -2544,7 +2517,7 @@ var SSAOFolder = class {
|
|
2544
2517
|
break;
|
2545
2518
|
case "color":
|
2546
2519
|
const value = e.value;
|
2547
|
-
n8aopass.configuration.color = new
|
2520
|
+
n8aopass.configuration.color = new Color4().setRGB(value.r, value.g, value.b);
|
2548
2521
|
break;
|
2549
2522
|
default:
|
2550
2523
|
break;
|
@@ -2637,53 +2610,6 @@ var ToneMappingFolder = class {
|
|
2637
2610
|
}
|
2638
2611
|
};
|
2639
2612
|
|
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
2613
|
// src/tweakpane/tweakPaneStyle.ts
|
2688
2614
|
var tweakPaneStyle = `
|
2689
2615
|
:root {
|
@@ -2882,6 +2808,122 @@ var TweakPane = class {
|
|
2882
2808
|
}
|
2883
2809
|
};
|
2884
2810
|
|
2811
|
+
// src/rendering/composer.ts
|
2812
|
+
import { N8AOPostPass } from "n8ao";
|
2813
|
+
import {
|
2814
|
+
EffectComposer as EffectComposer2,
|
2815
|
+
RenderPass,
|
2816
|
+
EffectPass as EffectPass2,
|
2817
|
+
FXAAEffect,
|
2818
|
+
ShaderPass,
|
2819
|
+
BloomEffect,
|
2820
|
+
SSAOEffect as SSAOEffect2,
|
2821
|
+
BlendFunction as BlendFunction2,
|
2822
|
+
TextureEffect,
|
2823
|
+
ToneMappingEffect,
|
2824
|
+
SMAAEffect,
|
2825
|
+
SMAAPreset,
|
2826
|
+
EdgeDetectionMode,
|
2827
|
+
PredicationMode,
|
2828
|
+
NormalPass as NormalPass2
|
2829
|
+
} from "postprocessing";
|
2830
|
+
import {
|
2831
|
+
AmbientLight,
|
2832
|
+
Color as Color6,
|
2833
|
+
Fog,
|
2834
|
+
HalfFloatType,
|
2835
|
+
LinearSRGBColorSpace,
|
2836
|
+
LoadingManager as LoadingManager2,
|
2837
|
+
PMREMGenerator,
|
2838
|
+
Scene as Scene3,
|
2839
|
+
Vector2 as Vector22,
|
2840
|
+
WebGLRenderer as WebGLRenderer2
|
2841
|
+
} from "three";
|
2842
|
+
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
|
2843
|
+
|
2844
|
+
// src/sun/Sun.ts
|
2845
|
+
import { CameraHelper, Color as Color5, DirectionalLight, Group as Group3, OrthographicCamera, Vector3 as Vector38 } from "three";
|
2846
|
+
var Sun = class extends Group3 {
|
2847
|
+
constructor() {
|
2848
|
+
super();
|
2849
|
+
this.debug = false;
|
2850
|
+
this.sunOffset = new Vector38(
|
2851
|
+
39 * (Math.PI / 180),
|
2852
|
+
50 * (Math.PI / 180),
|
2853
|
+
100
|
2854
|
+
);
|
2855
|
+
this.shadowResolution = 8192;
|
2856
|
+
this.shadowCamFrustum = 50;
|
2857
|
+
this.camHelper = null;
|
2858
|
+
this.target = null;
|
2859
|
+
this.shadowCamera = new OrthographicCamera(
|
2860
|
+
-this.shadowCamFrustum,
|
2861
|
+
this.shadowCamFrustum,
|
2862
|
+
this.shadowCamFrustum,
|
2863
|
+
-this.shadowCamFrustum,
|
2864
|
+
0.1,
|
2865
|
+
200
|
2866
|
+
);
|
2867
|
+
if (this.debug === true) {
|
2868
|
+
this.camHelper = new CameraHelper(this.shadowCamera);
|
2869
|
+
}
|
2870
|
+
this.directionalLight = new DirectionalLight(16777215, 0.5);
|
2871
|
+
this.directionalLight.shadow.normalBias = 0.05;
|
2872
|
+
this.directionalLight.shadow.radius = 1.5;
|
2873
|
+
this.directionalLight.shadow.camera = this.shadowCamera;
|
2874
|
+
this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);
|
2875
|
+
this.directionalLight.castShadow = true;
|
2876
|
+
this.setColor();
|
2877
|
+
this.updateCharacterPosition(new Vector38(0, 0, 0));
|
2878
|
+
this.add(this.directionalLight);
|
2879
|
+
if (this.debug === true && this.camHelper instanceof CameraHelper) {
|
2880
|
+
this.add(this.camHelper);
|
2881
|
+
}
|
2882
|
+
}
|
2883
|
+
updateCharacterPosition(position) {
|
2884
|
+
if (!position)
|
2885
|
+
return;
|
2886
|
+
this.target = position;
|
2887
|
+
this.setSunPosition(this.sunOffset.x, this.sunOffset.y);
|
2888
|
+
}
|
2889
|
+
setAzimuthalAngle(angle) {
|
2890
|
+
if (this.sunOffset)
|
2891
|
+
this.sunOffset.x = angle;
|
2892
|
+
if (this.target)
|
2893
|
+
this.updateCharacterPosition(this.target);
|
2894
|
+
}
|
2895
|
+
setPolarAngle(angle) {
|
2896
|
+
if (this.sunOffset)
|
2897
|
+
this.sunOffset.y = angle;
|
2898
|
+
if (this.target)
|
2899
|
+
this.updateCharacterPosition(this.target);
|
2900
|
+
}
|
2901
|
+
setIntensity(intensity) {
|
2902
|
+
this.directionalLight.intensity = intensity;
|
2903
|
+
}
|
2904
|
+
setColor() {
|
2905
|
+
this.directionalLight.color = new Color5().setRGB(
|
2906
|
+
sunValues.sunColor.r,
|
2907
|
+
sunValues.sunColor.g,
|
2908
|
+
sunValues.sunColor.b
|
2909
|
+
);
|
2910
|
+
}
|
2911
|
+
setSunPosition(azimuthalAngle, polarAngle) {
|
2912
|
+
if (!this.target)
|
2913
|
+
return;
|
2914
|
+
const distance = this.sunOffset.z;
|
2915
|
+
const sphericalPosition = new Vector38(
|
2916
|
+
distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),
|
2917
|
+
distance * Math.cos(polarAngle),
|
2918
|
+
distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle)
|
2919
|
+
);
|
2920
|
+
const newSunPosition = this.target.clone().add(sphericalPosition);
|
2921
|
+
this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);
|
2922
|
+
this.directionalLight.target.position.copy(this.target.clone());
|
2923
|
+
this.directionalLight.target.updateMatrixWorld();
|
2924
|
+
}
|
2925
|
+
};
|
2926
|
+
|
2885
2927
|
// src/rendering/post-effects/bright-contrast-sat.ts
|
2886
2928
|
import { ShaderMaterial, Uniform } from "three";
|
2887
2929
|
|
@@ -3029,8 +3071,8 @@ var GaussGrainEffect = new ShaderMaterial2({
|
|
3029
3071
|
// src/rendering/composer.ts
|
3030
3072
|
var Composer = class {
|
3031
3073
|
constructor(scene, camera, spawnSun = false) {
|
3032
|
-
this.width =
|
3033
|
-
this.height =
|
3074
|
+
this.width = 1;
|
3075
|
+
this.height = 1;
|
3034
3076
|
this.resolution = new Vector22(this.width, this.height);
|
3035
3077
|
this.isEnvHDRI = false;
|
3036
3078
|
this.bcs = BrightnessContrastSaturation;
|
@@ -3055,11 +3097,9 @@ var Composer = class {
|
|
3055
3097
|
this.renderer.toneMappingExposure = rendererValues.exposure;
|
3056
3098
|
this.setAmbientLight();
|
3057
3099
|
this.setFog();
|
3058
|
-
|
3059
|
-
this.composer = new EffectComposer2(this.renderer, {
|
3100
|
+
this.effectComposer = new EffectComposer2(this.renderer, {
|
3060
3101
|
frameBufferType: HalfFloatType
|
3061
3102
|
});
|
3062
|
-
this.tweakPane = new TweakPane(this.renderer, this.scene, this.composer);
|
3063
3103
|
this.renderPass = new RenderPass(this.scene, this.camera);
|
3064
3104
|
this.normalPass = new NormalPass2(this.scene, this.camera);
|
3065
3105
|
this.normalPass.enabled = ppssaoValues.enabled;
|
@@ -3128,26 +3168,33 @@ var Composer = class {
|
|
3128
3168
|
this.bcs.uniforms.saturation.value = bcsValues.saturation;
|
3129
3169
|
this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, "tDiffuse");
|
3130
3170
|
this.smaaPass = new EffectPass2(this.camera, this.smaaEffect);
|
3131
|
-
this.
|
3171
|
+
this.effectComposer.addPass(this.renderPass);
|
3132
3172
|
if (ppssaoValues.enabled) {
|
3133
|
-
this.
|
3134
|
-
this.
|
3173
|
+
this.effectComposer.addPass(this.normalPass);
|
3174
|
+
this.effectComposer.addPass(this.ppssaoPass);
|
3135
3175
|
}
|
3136
3176
|
if (n8ssaoValues.enabled) {
|
3137
|
-
this.
|
3138
|
-
}
|
3139
|
-
this.
|
3140
|
-
this.
|
3141
|
-
this.
|
3142
|
-
this.
|
3143
|
-
this.
|
3144
|
-
this.
|
3177
|
+
this.effectComposer.addPass(this.n8aopass);
|
3178
|
+
}
|
3179
|
+
this.effectComposer.addPass(this.fxaaPass);
|
3180
|
+
this.effectComposer.addPass(this.smaaPass);
|
3181
|
+
this.effectComposer.addPass(this.bloomPass);
|
3182
|
+
this.effectComposer.addPass(this.toneMappingPass);
|
3183
|
+
this.effectComposer.addPass(this.bcsPass);
|
3184
|
+
this.effectComposer.addPass(this.gaussGrainPass);
|
3145
3185
|
if (this.spawnSun === true) {
|
3146
3186
|
this.sun = new Sun();
|
3147
3187
|
this.scene.add(this.sun);
|
3148
3188
|
}
|
3149
|
-
this.
|
3150
|
-
this.
|
3189
|
+
this.resizeListener = () => {
|
3190
|
+
this.fitContainer();
|
3191
|
+
};
|
3192
|
+
window.addEventListener("resize", this.resizeListener, false);
|
3193
|
+
this.fitContainer();
|
3194
|
+
}
|
3195
|
+
setupTweakPane(tweakPane) {
|
3196
|
+
tweakPane.setupRenderPane(
|
3197
|
+
this.effectComposer,
|
3151
3198
|
this.normalPass,
|
3152
3199
|
this.ppssaoEffect,
|
3153
3200
|
this.ppssaoPass,
|
@@ -3163,14 +3210,32 @@ var Composer = class {
|
|
3163
3210
|
this.setAmbientLight.bind(this),
|
3164
3211
|
this.setFog.bind(this)
|
3165
3212
|
);
|
3166
|
-
window.addEventListener("resize", () => this.updateProjection());
|
3167
|
-
this.updateProjection();
|
3168
3213
|
}
|
3169
|
-
|
3170
|
-
|
3171
|
-
|
3172
|
-
|
3173
|
-
|
3214
|
+
dispose() {
|
3215
|
+
window.removeEventListener("resize", this.resizeListener);
|
3216
|
+
}
|
3217
|
+
fitContainer() {
|
3218
|
+
if (!this) {
|
3219
|
+
console.error("Composer not initialized");
|
3220
|
+
return;
|
3221
|
+
}
|
3222
|
+
const parentElement = this.renderer.domElement.parentNode;
|
3223
|
+
if (!parentElement) {
|
3224
|
+
return;
|
3225
|
+
}
|
3226
|
+
this.width = parentElement.clientWidth;
|
3227
|
+
this.height = parentElement.clientHeight;
|
3228
|
+
this.camera.aspect = this.width / this.height;
|
3229
|
+
this.camera.updateProjectionMatrix();
|
3230
|
+
this.renderer.setPixelRatio(window.devicePixelRatio);
|
3231
|
+
this.resolution.set(
|
3232
|
+
this.width * window.devicePixelRatio,
|
3233
|
+
this.height * window.devicePixelRatio
|
3234
|
+
);
|
3235
|
+
this.effectComposer.setSize(
|
3236
|
+
this.width / window.devicePixelRatio,
|
3237
|
+
this.height / window.devicePixelRatio
|
3238
|
+
);
|
3174
3239
|
this.renderPass.setSize(this.width, this.height);
|
3175
3240
|
if (ppssaoValues.enabled) {
|
3176
3241
|
this.normalPass.setSize(this.width, this.height);
|
@@ -3187,20 +3252,14 @@ var Composer = class {
|
|
3187
3252
|
this.gaussGrainPass.setSize(this.width, this.height);
|
3188
3253
|
this.renderer.setSize(this.width, this.height);
|
3189
3254
|
}
|
3190
|
-
isTweakPaneVisible() {
|
3191
|
-
return this.tweakPane.guiVisible;
|
3192
|
-
}
|
3193
3255
|
render(timeManager) {
|
3194
3256
|
this.renderer.info.reset();
|
3195
3257
|
this.normalPass.texture.needsUpdate = true;
|
3196
3258
|
this.gaussGrainEffect.uniforms.resolution.value = this.resolution;
|
3197
3259
|
this.gaussGrainEffect.uniforms.time.value = timeManager.time;
|
3198
3260
|
this.gaussGrainEffect.uniforms.alpha.value = 1;
|
3199
|
-
this.
|
3261
|
+
this.effectComposer.render();
|
3200
3262
|
this.renderer.render(this.postPostScene, this.camera);
|
3201
|
-
if (this.tweakPane.guiVisible) {
|
3202
|
-
this.tweakPane.updateStats(timeManager);
|
3203
|
-
}
|
3204
3263
|
}
|
3205
3264
|
useHDRI(url, fromFile = false) {
|
3206
3265
|
if (this.isEnvHDRI && fromFile === false || !this.renderer)
|
@@ -3332,7 +3391,7 @@ import {
|
|
3332
3391
|
Box3,
|
3333
3392
|
Color as Color7,
|
3334
3393
|
DoubleSide,
|
3335
|
-
Euler,
|
3394
|
+
Euler as Euler2,
|
3336
3395
|
Group as Group4,
|
3337
3396
|
Line3 as Line32,
|
3338
3397
|
Matrix4 as Matrix42,
|
@@ -3354,7 +3413,7 @@ var CollisionsManager = class {
|
|
3354
3413
|
this.tempMatrix = new Matrix42();
|
3355
3414
|
this.tempMatrix2 = new Matrix42();
|
3356
3415
|
this.tempBox = new Box3();
|
3357
|
-
this.tempEuler = new
|
3416
|
+
this.tempEuler = new Euler2();
|
3358
3417
|
this.tempSegment = new Line32();
|
3359
3418
|
this.tempSegment2 = new Line32();
|
3360
3419
|
this.collisionMeshState = /* @__PURE__ */ new Map();
|
@@ -3547,11 +3606,13 @@ export {
|
|
3547
3606
|
AnimationState,
|
3548
3607
|
CameraManager,
|
3549
3608
|
CharacterManager,
|
3609
|
+
CharacterModelLoader,
|
3550
3610
|
CollisionsManager,
|
3551
3611
|
Composer,
|
3552
3612
|
KeyInputManager,
|
3553
3613
|
MMLCompositionScene,
|
3554
3614
|
Sun,
|
3555
|
-
TimeManager
|
3615
|
+
TimeManager,
|
3616
|
+
TweakPane
|
3556
3617
|
};
|
3557
3618
|
//# sourceMappingURL=index.js.map
|