@mml-io/3d-web-client-core 0.0.0-experimental-ec6e197-20231110 → 0.0.0-experimental-f92224e-20231121
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 +1 -1
- package/build/character/Character.d.ts +9 -18
- package/build/character/CharacterManager.d.ts +6 -5
- package/build/character/CharacterModel.d.ts +2 -4
- package/build/character/CharacterModelLoader.d.ts +0 -4
- package/build/character/CharacterTooltip.d.ts +4 -6
- package/build/character/LocalController.d.ts +3 -4
- package/build/character/RemoteController.d.ts +1 -9
- package/build/character/url-position.d.ts +12 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +319 -440
- package/build/index.js.map +4 -4
- package/build/mml/MMLCompositionScene.d.ts +1 -0
- package/package.json +3 -3
package/build/index.js
CHANGED
@@ -34,6 +34,9 @@ var round = (n, digits) => {
|
|
34
34
|
var ease = (target, n, factor) => {
|
35
35
|
return round((target - n) * factor, 5);
|
36
36
|
};
|
37
|
+
function clamp(value, min, max) {
|
38
|
+
return Math.min(Math.max(value, min), max);
|
39
|
+
}
|
37
40
|
var remap = (value, minValue, maxValue, minScaledValue, maxScaledValue) => {
|
38
41
|
return minScaledValue + (maxScaledValue - minScaledValue) * (value - minValue) / (maxValue - minValue);
|
39
42
|
};
|
@@ -106,6 +109,8 @@ var CameraManager = class {
|
|
106
109
|
this.targetDistance = this.initialDistance;
|
107
110
|
this.distance = this.initialDistance;
|
108
111
|
this.desiredDistance = this.initialDistance;
|
112
|
+
this.phi = Math.PI / 2;
|
113
|
+
this.theta = Math.PI / 2;
|
109
114
|
this.dragging = false;
|
110
115
|
this.target = new Vector32(0, 1.55, 0);
|
111
116
|
this.hadTarget = false;
|
@@ -174,17 +179,24 @@ var CameraManager = class {
|
|
174
179
|
this.setTarget(target);
|
175
180
|
}
|
176
181
|
reverseUpdateFromPositions() {
|
177
|
-
if (this.phi === null || this.theta == null)
|
178
|
-
return;
|
179
182
|
const dx = this.camera.position.x - this.target.x;
|
180
183
|
const dy = this.camera.position.y - this.target.y;
|
181
184
|
const dz = this.camera.position.z - this.target.z;
|
182
185
|
this.targetDistance = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
183
|
-
this.targetTheta =
|
184
|
-
this.targetPhi = Math.
|
186
|
+
this.targetTheta = Math.atan2(dz, dx);
|
187
|
+
this.targetPhi = Math.acos(dy / this.targetDistance);
|
185
188
|
this.phi = this.targetPhi;
|
186
189
|
this.theta = this.targetTheta;
|
187
190
|
this.distance = this.targetDistance;
|
191
|
+
this.desiredDistance = this.targetDistance;
|
192
|
+
this.targetFOV = remap(
|
193
|
+
this.targetDistance,
|
194
|
+
this.minDistance,
|
195
|
+
this.maxDistance,
|
196
|
+
this.minFOV,
|
197
|
+
this.maxFOV
|
198
|
+
);
|
199
|
+
this.fov = this.targetFOV;
|
188
200
|
}
|
189
201
|
adjustCameraPosition() {
|
190
202
|
this.rayCaster.set(
|
@@ -244,14 +256,13 @@ var CameraManager = class {
|
|
244
256
|
};
|
245
257
|
|
246
258
|
// src/character/Character.ts
|
247
|
-
import { Color as Color3, Vector3 as
|
259
|
+
import { Color as Color3, Group, Vector3 as Vector34 } from "three";
|
248
260
|
|
249
261
|
// src/character/CharacterModel.ts
|
250
262
|
import {
|
251
263
|
AnimationClip,
|
252
264
|
AnimationMixer,
|
253
265
|
LoopRepeat,
|
254
|
-
MeshStandardMaterial,
|
255
266
|
Object3D
|
256
267
|
} from "three";
|
257
268
|
|
@@ -659,36 +670,10 @@ var CharacterModel = class {
|
|
659
670
|
);
|
660
671
|
this.applyMaterialToAllSkinnedMeshes(this.material);
|
661
672
|
}
|
662
|
-
updateAnimation(targetAnimation
|
663
|
-
var _a;
|
673
|
+
updateAnimation(targetAnimation) {
|
664
674
|
if (this.currentAnimation !== targetAnimation) {
|
665
675
|
this.transitionToAnimation(targetAnimation);
|
666
676
|
}
|
667
|
-
(_a = this.animationMixer) == null ? void 0 : _a.update(deltaTime);
|
668
|
-
}
|
669
|
-
hideMaterialByMeshName(meshName) {
|
670
|
-
if (!this.mesh)
|
671
|
-
return;
|
672
|
-
this.mesh.traverse((child) => {
|
673
|
-
if (child.type === "Bone" && child.name === "mixamorigHeadTop_End") {
|
674
|
-
this.headBone = child;
|
675
|
-
}
|
676
|
-
if (child.type === "SkinnedMesh" && child.name === meshName) {
|
677
|
-
child.material = new MeshStandardMaterial({
|
678
|
-
color: 16711680,
|
679
|
-
transparent: true,
|
680
|
-
opacity: 0
|
681
|
-
});
|
682
|
-
}
|
683
|
-
});
|
684
|
-
}
|
685
|
-
setShadows(mesh, castShadow = true, receiveShadow = true) {
|
686
|
-
mesh.traverse((child) => {
|
687
|
-
if (child.type === "SkinnedMesh") {
|
688
|
-
child.castShadow = castShadow;
|
689
|
-
child.receiveShadow = receiveShadow;
|
690
|
-
}
|
691
|
-
});
|
692
677
|
}
|
693
678
|
applyMaterialToAllSkinnedMeshes(material) {
|
694
679
|
if (!this.mesh)
|
@@ -699,11 +684,6 @@ var CharacterModel = class {
|
|
699
684
|
}
|
700
685
|
});
|
701
686
|
}
|
702
|
-
initAnimationMixer() {
|
703
|
-
if (this.animationMixer !== null || this.mesh === null)
|
704
|
-
return;
|
705
|
-
this.animationMixer = new AnimationMixer(this.mesh);
|
706
|
-
}
|
707
687
|
async loadMainMesh() {
|
708
688
|
const mainMeshUrl = this.characterDescription.meshFileUrl;
|
709
689
|
const scale = this.characterDescription.modelScale;
|
@@ -717,12 +697,17 @@ var CharacterModel = class {
|
|
717
697
|
this.mesh.add(model);
|
718
698
|
this.mesh.name = name;
|
719
699
|
this.mesh.scale.set(scale, scale, scale);
|
720
|
-
this.
|
700
|
+
this.mesh.traverse((child) => {
|
701
|
+
if (child.type === "SkinnedMesh") {
|
702
|
+
child.castShadow = true;
|
703
|
+
child.receiveShadow = true;
|
704
|
+
}
|
705
|
+
});
|
706
|
+
this.animationMixer = new AnimationMixer(this.mesh);
|
721
707
|
}
|
722
708
|
}
|
723
709
|
async setAnimationFromFile(animationFileUrl, animationType) {
|
724
710
|
return new Promise(async (resolve, reject) => {
|
725
|
-
this.initAnimationMixer();
|
726
711
|
const animation = await this.characterModelLoader.load(animationFileUrl, "animation");
|
727
712
|
if (typeof animation !== "undefined" && animation instanceof AnimationClip) {
|
728
713
|
this.animations[animationType] = this.animationMixer.clipAction(animation);
|
@@ -737,9 +722,10 @@ var CharacterModel = class {
|
|
737
722
|
});
|
738
723
|
}
|
739
724
|
transitionToAnimation(targetAnimation, transitionDuration = 0.15) {
|
740
|
-
if (!this.mesh
|
725
|
+
if (!this.mesh)
|
741
726
|
return;
|
742
727
|
const currentAction = this.animations[this.currentAnimation];
|
728
|
+
this.currentAnimation = targetAnimation;
|
743
729
|
const targetAction = this.animations[targetAnimation];
|
744
730
|
if (!targetAction)
|
745
731
|
return;
|
@@ -752,7 +738,11 @@ var CharacterModel = class {
|
|
752
738
|
targetAction.setLoop(LoopRepeat, Infinity);
|
753
739
|
targetAction.enabled = true;
|
754
740
|
targetAction.fadeIn(transitionDuration);
|
755
|
-
|
741
|
+
}
|
742
|
+
update(time) {
|
743
|
+
if (this.animationMixer) {
|
744
|
+
this.animationMixer.update(time);
|
745
|
+
}
|
756
746
|
}
|
757
747
|
};
|
758
748
|
|
@@ -978,8 +968,10 @@ var defaultLabelPadding = 0;
|
|
978
968
|
var defaultLabelWidth = 0.25;
|
979
969
|
var defaultLabelHeight = 0.125;
|
980
970
|
var defaultLabelCastShadows = true;
|
981
|
-
var
|
982
|
-
|
971
|
+
var tooltipGeometry = new PlaneGeometry(1, 1, 1, 1);
|
972
|
+
var CharacterTooltip = class extends Mesh3 {
|
973
|
+
constructor() {
|
974
|
+
super(tooltipGeometry);
|
983
975
|
this.visibleOpacity = 0.85;
|
984
976
|
this.targetOpacity = 0;
|
985
977
|
this.fadingSpeed = 0.02;
|
@@ -995,25 +987,22 @@ var CharacterTooltip = class {
|
|
995
987
|
fontColor: defaultFontColor,
|
996
988
|
castShadows: defaultLabelCastShadows
|
997
989
|
};
|
998
|
-
this.
|
999
|
-
this.material = new MeshBasicMaterial2({
|
990
|
+
this.tooltipMaterial = new MeshBasicMaterial2({
|
1000
991
|
map: null,
|
1001
992
|
transparent: true,
|
1002
|
-
opacity: 0
|
993
|
+
opacity: 0,
|
994
|
+
side: FrontSide
|
1003
995
|
});
|
1004
|
-
this.material
|
1005
|
-
this.
|
1006
|
-
this.
|
1007
|
-
this.mesh.position.set(0, 1.6, 0);
|
1008
|
-
this.mesh.visible = false;
|
1009
|
-
parentModel.add(this.mesh);
|
996
|
+
this.material = this.tooltipMaterial;
|
997
|
+
this.position.set(0, 1.6, 0);
|
998
|
+
this.visible = false;
|
1010
999
|
}
|
1011
1000
|
redrawText(content) {
|
1012
|
-
if (!this.
|
1001
|
+
if (!this.tooltipMaterial) {
|
1013
1002
|
return;
|
1014
1003
|
}
|
1015
|
-
if (this.
|
1016
|
-
this.
|
1004
|
+
if (this.tooltipMaterial.map) {
|
1005
|
+
this.tooltipMaterial.map.dispose();
|
1017
1006
|
}
|
1018
1007
|
const { texture, width, height } = THREECanvasTextTexture(content, {
|
1019
1008
|
bold: true,
|
@@ -1037,17 +1026,17 @@ var CharacterTooltip = class {
|
|
1037
1026
|
},
|
1038
1027
|
alignment: this.props.alignment
|
1039
1028
|
});
|
1040
|
-
this.
|
1041
|
-
this.
|
1042
|
-
this.
|
1043
|
-
this.
|
1044
|
-
this.
|
1045
|
-
this.
|
1046
|
-
this.
|
1029
|
+
this.tooltipMaterial.map = texture;
|
1030
|
+
this.tooltipMaterial.map.magFilter = LinearFilter2;
|
1031
|
+
this.tooltipMaterial.map.minFilter = LinearFilter2;
|
1032
|
+
this.tooltipMaterial.needsUpdate = true;
|
1033
|
+
this.scale.x = width / (100 * fontScale);
|
1034
|
+
this.scale.y = height / (100 * fontScale);
|
1035
|
+
this.position.y = 1.6;
|
1047
1036
|
}
|
1048
1037
|
setText(text, temporary = false) {
|
1049
1038
|
this.redrawText(text);
|
1050
|
-
this.
|
1039
|
+
this.visible = true;
|
1051
1040
|
this.targetOpacity = this.visibleOpacity;
|
1052
1041
|
if (temporary) {
|
1053
1042
|
setTimeout(() => {
|
@@ -1059,37 +1048,101 @@ var CharacterTooltip = class {
|
|
1059
1048
|
this.targetOpacity = 0;
|
1060
1049
|
}
|
1061
1050
|
update(camera) {
|
1062
|
-
this.
|
1063
|
-
const opacity = this.
|
1051
|
+
this.lookAt(camera.position);
|
1052
|
+
const opacity = this.tooltipMaterial.opacity;
|
1064
1053
|
if (opacity < this.targetOpacity) {
|
1065
|
-
this.
|
1066
|
-
this.
|
1054
|
+
this.tooltipMaterial.opacity = Math.min(
|
1055
|
+
this.tooltipMaterial.opacity + this.fadingSpeed,
|
1067
1056
|
this.targetOpacity
|
1068
1057
|
);
|
1069
1058
|
} else if (opacity > this.targetOpacity) {
|
1070
|
-
this.
|
1071
|
-
this.
|
1059
|
+
this.tooltipMaterial.opacity = Math.max(
|
1060
|
+
this.tooltipMaterial.opacity - this.fadingSpeed,
|
1072
1061
|
this.targetOpacity
|
1073
1062
|
);
|
1074
|
-
if (opacity >= 1 && this.
|
1075
|
-
this.
|
1076
|
-
this.
|
1077
|
-
} else if (opacity > 0 && opacity < 1 && this.
|
1078
|
-
this.
|
1079
|
-
this.
|
1063
|
+
if (opacity >= 1 && this.tooltipMaterial.transparent) {
|
1064
|
+
this.tooltipMaterial.transparent = false;
|
1065
|
+
this.tooltipMaterial.needsUpdate = true;
|
1066
|
+
} else if (opacity > 0 && opacity < 1 && !this.tooltipMaterial.transparent) {
|
1067
|
+
this.tooltipMaterial.transparent = true;
|
1068
|
+
this.tooltipMaterial.needsUpdate = true;
|
1080
1069
|
}
|
1081
|
-
if (this.
|
1082
|
-
this.
|
1070
|
+
if (this.tooltipMaterial.opacity <= 0) {
|
1071
|
+
this.visible = false;
|
1083
1072
|
}
|
1084
1073
|
}
|
1085
1074
|
}
|
1086
1075
|
};
|
1087
1076
|
|
1077
|
+
// src/character/Character.ts
|
1078
|
+
var Character = class extends Group {
|
1079
|
+
constructor(characterDescription, characterModelLoader, characterId, modelLoadedCallback, cameraManager, composer) {
|
1080
|
+
super();
|
1081
|
+
this.characterDescription = characterDescription;
|
1082
|
+
this.characterModelLoader = characterModelLoader;
|
1083
|
+
this.characterId = characterId;
|
1084
|
+
this.modelLoadedCallback = modelLoadedCallback;
|
1085
|
+
this.cameraManager = cameraManager;
|
1086
|
+
this.composer = composer;
|
1087
|
+
this.model = null;
|
1088
|
+
this.color = new Color3();
|
1089
|
+
this.tooltip = null;
|
1090
|
+
this.speakingIndicator = null;
|
1091
|
+
this.tooltip = new CharacterTooltip();
|
1092
|
+
this.add(this.tooltip);
|
1093
|
+
this.load();
|
1094
|
+
}
|
1095
|
+
async load() {
|
1096
|
+
this.model = new CharacterModel(this.characterDescription, this.characterModelLoader);
|
1097
|
+
await this.model.init();
|
1098
|
+
this.add(this.model.mesh);
|
1099
|
+
if (this.speakingIndicator === null) {
|
1100
|
+
this.speakingIndicator = new CharacterSpeakingIndicator(this.composer.postPostScene);
|
1101
|
+
}
|
1102
|
+
this.color = this.model.material.colorsCube216[this.characterId];
|
1103
|
+
this.modelLoadedCallback();
|
1104
|
+
}
|
1105
|
+
updateAnimation(targetAnimation) {
|
1106
|
+
var _a;
|
1107
|
+
(_a = this.model) == null ? void 0 : _a.updateAnimation(targetAnimation);
|
1108
|
+
}
|
1109
|
+
update(time, deltaTime) {
|
1110
|
+
var _a;
|
1111
|
+
if (!this.model)
|
1112
|
+
return;
|
1113
|
+
if (this.tooltip) {
|
1114
|
+
this.tooltip.update(this.cameraManager.camera);
|
1115
|
+
}
|
1116
|
+
if (this.speakingIndicator) {
|
1117
|
+
this.speakingIndicator.setTime(time);
|
1118
|
+
if (this.model.mesh && this.model.headBone) {
|
1119
|
+
this.speakingIndicator.setBillboarding(
|
1120
|
+
(_a = this.model.headBone) == null ? void 0 : _a.getWorldPosition(new Vector34()),
|
1121
|
+
this.cameraManager.camera
|
1122
|
+
);
|
1123
|
+
}
|
1124
|
+
}
|
1125
|
+
if (typeof this.model.material.uniforms.time !== "undefined") {
|
1126
|
+
this.model.material.uniforms.time.value = time;
|
1127
|
+
this.model.material.uniforms.diffuseRandomColor.value = this.color;
|
1128
|
+
this.model.material.update();
|
1129
|
+
}
|
1130
|
+
this.model.update(deltaTime);
|
1131
|
+
}
|
1132
|
+
getCurrentAnimation() {
|
1133
|
+
var _a;
|
1134
|
+
return ((_a = this.model) == null ? void 0 : _a.currentAnimation) || 0 /* idle */;
|
1135
|
+
}
|
1136
|
+
};
|
1137
|
+
|
1138
|
+
// src/character/CharacterManager.ts
|
1139
|
+
import { Euler, Group as Group2, Quaternion as Quaternion5, Vector3 as Vector38 } from "three";
|
1140
|
+
|
1088
1141
|
// src/character/LocalController.ts
|
1089
|
-
import { Line3, Matrix4, Quaternion as Quaternion2, Raycaster as Raycaster2, Vector3 as
|
1142
|
+
import { Line3, Matrix4, Quaternion as Quaternion2, Raycaster as Raycaster2, Vector3 as Vector35 } from "three";
|
1090
1143
|
var LocalController = class {
|
1091
|
-
constructor(
|
1092
|
-
this.
|
1144
|
+
constructor(character, id, collisionsManager, keyInputManager, cameraManager, timeManager) {
|
1145
|
+
this.character = character;
|
1093
1146
|
this.id = id;
|
1094
1147
|
this.collisionsManager = collisionsManager;
|
1095
1148
|
this.keyInputManager = keyInputManager;
|
@@ -1098,7 +1151,7 @@ var LocalController = class {
|
|
1098
1151
|
this.collisionDetectionSteps = 15;
|
1099
1152
|
this.capsuleInfo = {
|
1100
1153
|
radius: 0.4,
|
1101
|
-
segment: new Line3(new
|
1154
|
+
segment: new Line3(new Vector35(), new Vector35(0, 1.05, 0))
|
1102
1155
|
};
|
1103
1156
|
this.maxWalkSpeed = 6;
|
1104
1157
|
this.maxRunSpeed = 8.5;
|
@@ -1111,17 +1164,16 @@ var LocalController = class {
|
|
1111
1164
|
this.characterWasOnGround = false;
|
1112
1165
|
this.characterAirborneSince = 0;
|
1113
1166
|
this.currentHeight = 0;
|
1114
|
-
this.characterVelocity = new
|
1115
|
-
this.vectorUp = new
|
1116
|
-
this.vectorDown = new
|
1167
|
+
this.characterVelocity = new Vector35();
|
1168
|
+
this.vectorUp = new Vector35(0, 1, 0);
|
1169
|
+
this.vectorDown = new Vector35(0, -1, 0);
|
1117
1170
|
this.rotationOffset = 0;
|
1118
1171
|
this.azimuthalAngle = 0;
|
1119
1172
|
this.tempMatrix = new Matrix4();
|
1120
1173
|
this.tempSegment = new Line3();
|
1121
|
-
this.tempVector = new
|
1122
|
-
this.tempVector2 = new
|
1174
|
+
this.tempVector = new Vector35();
|
1175
|
+
this.tempVector2 = new Vector35();
|
1123
1176
|
this.rayCaster = new Raycaster2();
|
1124
|
-
this.thirdPersonCamera = null;
|
1125
1177
|
this.speed = 0;
|
1126
1178
|
this.targetSpeed = 0;
|
1127
1179
|
this.networkState = {
|
@@ -1132,11 +1184,6 @@ var LocalController = class {
|
|
1132
1184
|
};
|
1133
1185
|
}
|
1134
1186
|
update() {
|
1135
|
-
var _a, _b;
|
1136
|
-
if (!((_a = this.model) == null ? void 0 : _a.mesh) || !((_b = this.model) == null ? void 0 : _b.animationMixer))
|
1137
|
-
return;
|
1138
|
-
if (!this.thirdPersonCamera)
|
1139
|
-
this.thirdPersonCamera = this.cameraManager.camera;
|
1140
1187
|
const { forward, backward, left, right, run, jump, anyDirection, conflictingDirection } = this.keyInputManager;
|
1141
1188
|
this.forward = forward;
|
1142
1189
|
this.backward = backward;
|
@@ -1148,28 +1195,28 @@ var LocalController = class {
|
|
1148
1195
|
this.conflictingDirections = conflictingDirection;
|
1149
1196
|
this.targetSpeed = this.run ? this.maxRunSpeed : this.maxWalkSpeed;
|
1150
1197
|
this.speed += ease(this.targetSpeed, this.speed, 0.07);
|
1151
|
-
this.rayCaster.set(this.
|
1198
|
+
this.rayCaster.set(this.character.position, this.vectorDown);
|
1152
1199
|
const minimumDistance = this.collisionsManager.raycastFirstDistance(this.rayCaster.ray);
|
1153
1200
|
if (minimumDistance !== null) {
|
1154
1201
|
this.currentHeight = minimumDistance;
|
1155
1202
|
}
|
1156
1203
|
if (anyDirection || !this.characterOnGround) {
|
1157
1204
|
const targetAnimation = this.getTargetAnimation();
|
1158
|
-
this.
|
1205
|
+
this.character.updateAnimation(targetAnimation);
|
1159
1206
|
} else {
|
1160
|
-
this.
|
1207
|
+
this.character.updateAnimation(0 /* idle */);
|
1161
1208
|
}
|
1162
1209
|
if (this.anyDirection)
|
1163
1210
|
this.updateRotation();
|
1164
1211
|
for (let i = 0; i < this.collisionDetectionSteps; i++) {
|
1165
1212
|
this.updatePosition(this.timeManager.deltaTime / this.collisionDetectionSteps, i);
|
1166
1213
|
}
|
1167
|
-
if (this.
|
1214
|
+
if (this.character.position.y < 0)
|
1168
1215
|
this.resetPosition();
|
1169
1216
|
this.updateNetworkState();
|
1170
1217
|
}
|
1171
1218
|
getTargetAnimation() {
|
1172
|
-
if (!this.
|
1219
|
+
if (!this.character)
|
1173
1220
|
return 0 /* idle */;
|
1174
1221
|
if (this.conflictingDirections)
|
1175
1222
|
return 0 /* idle */;
|
@@ -1201,31 +1248,26 @@ var LocalController = class {
|
|
1201
1248
|
}
|
1202
1249
|
}
|
1203
1250
|
updateAzimuthalAngle() {
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
const camToModelDistance = this.thirdPersonCamera.position.distanceTo(this.model.mesh.position);
|
1251
|
+
const camToModelDistance = this.cameraManager.camera.position.distanceTo(
|
1252
|
+
this.character.position
|
1253
|
+
);
|
1208
1254
|
const isCameraFirstPerson = camToModelDistance < 2;
|
1209
1255
|
if (isCameraFirstPerson) {
|
1210
|
-
const cameraForward = new
|
1256
|
+
const cameraForward = new Vector35(0, 0, 1).applyQuaternion(
|
1257
|
+
this.cameraManager.camera.quaternion
|
1258
|
+
);
|
1211
1259
|
this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);
|
1212
1260
|
} else {
|
1213
1261
|
this.azimuthalAngle = Math.atan2(
|
1214
|
-
this.
|
1215
|
-
this.
|
1262
|
+
this.cameraManager.camera.position.x - this.character.position.x,
|
1263
|
+
this.cameraManager.camera.position.z - this.character.position.z
|
1216
1264
|
);
|
1217
1265
|
}
|
1218
1266
|
}
|
1219
1267
|
computeAngularDifference(rotationQuaternion) {
|
1220
|
-
|
1221
|
-
if (!((_a = this.model) == null ? void 0 : _a.mesh))
|
1222
|
-
return 0;
|
1223
|
-
return 2 * Math.acos(Math.abs(this.model.mesh.quaternion.dot(rotationQuaternion)));
|
1268
|
+
return 2 * Math.acos(Math.abs(this.character.quaternion.dot(rotationQuaternion)));
|
1224
1269
|
}
|
1225
1270
|
updateRotation() {
|
1226
|
-
var _a;
|
1227
|
-
if (!this.thirdPersonCamera || !((_a = this.model) == null ? void 0 : _a.mesh))
|
1228
|
-
return;
|
1229
1271
|
this.updateRotationOffset();
|
1230
1272
|
this.updateAzimuthalAngle();
|
1231
1273
|
const rotationQuaternion = new Quaternion2();
|
@@ -1234,18 +1276,12 @@ var LocalController = class {
|
|
1234
1276
|
const desiredTime = 0.07;
|
1235
1277
|
const angularSpeed = angularDifference / desiredTime;
|
1236
1278
|
const frameRotation = angularSpeed * this.timeManager.deltaTime;
|
1237
|
-
this.
|
1279
|
+
this.character.quaternion.rotateTowards(rotationQuaternion, frameRotation);
|
1238
1280
|
}
|
1239
1281
|
addScaledVectorToCharacter(deltaTime) {
|
1240
|
-
|
1241
|
-
if (!((_a = this.model) == null ? void 0 : _a.mesh))
|
1242
|
-
return;
|
1243
|
-
this.model.mesh.position.addScaledVector(this.tempVector, this.speed * deltaTime);
|
1282
|
+
this.character.position.addScaledVector(this.tempVector, this.speed * deltaTime);
|
1244
1283
|
}
|
1245
1284
|
updatePosition(deltaTime, _iter) {
|
1246
|
-
var _a;
|
1247
|
-
if (!((_a = this.model) == null ? void 0 : _a.mesh))
|
1248
|
-
return;
|
1249
1285
|
if (this.characterOnGround) {
|
1250
1286
|
if (!this.jump)
|
1251
1287
|
this.canJump = true;
|
@@ -1262,45 +1298,45 @@ var LocalController = class {
|
|
1262
1298
|
this.characterVelocity.y += deltaTime * this.gravity;
|
1263
1299
|
this.canJump = false;
|
1264
1300
|
}
|
1265
|
-
this.
|
1301
|
+
this.character.position.addScaledVector(this.characterVelocity, deltaTime);
|
1266
1302
|
this.tempVector.set(0, 0, 0);
|
1267
1303
|
if (this.forward) {
|
1268
|
-
const forward = new
|
1304
|
+
const forward = new Vector35(0, 0, -1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1269
1305
|
this.tempVector.add(forward);
|
1270
1306
|
}
|
1271
1307
|
if (this.backward) {
|
1272
|
-
const backward = new
|
1308
|
+
const backward = new Vector35(0, 0, 1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1273
1309
|
this.tempVector.add(backward);
|
1274
1310
|
}
|
1275
1311
|
if (this.left) {
|
1276
|
-
const left = new
|
1312
|
+
const left = new Vector35(-1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1277
1313
|
this.tempVector.add(left);
|
1278
1314
|
}
|
1279
1315
|
if (this.right) {
|
1280
|
-
const right = new
|
1316
|
+
const right = new Vector35(1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1281
1317
|
this.tempVector.add(right);
|
1282
1318
|
}
|
1283
1319
|
if (this.tempVector.length() > 0) {
|
1284
1320
|
this.tempVector.normalize();
|
1285
1321
|
this.addScaledVectorToCharacter(deltaTime);
|
1286
1322
|
}
|
1287
|
-
this.
|
1323
|
+
this.character.updateMatrixWorld();
|
1288
1324
|
this.tempSegment.copy(this.capsuleInfo.segment);
|
1289
|
-
this.tempSegment.start.applyMatrix4(this.
|
1290
|
-
this.tempSegment.end.applyMatrix4(this.
|
1325
|
+
this.tempSegment.start.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);
|
1326
|
+
this.tempSegment.end.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);
|
1291
1327
|
this.collisionsManager.applyColliders(this.tempSegment, this.capsuleInfo.radius);
|
1292
1328
|
const newPosition = this.tempVector;
|
1293
1329
|
newPosition.copy(this.tempSegment.start);
|
1294
1330
|
const deltaVector = this.tempVector2;
|
1295
|
-
deltaVector.subVectors(newPosition, this.
|
1331
|
+
deltaVector.subVectors(newPosition, this.character.position);
|
1296
1332
|
const offset = Math.max(0, deltaVector.length() - 1e-5);
|
1297
1333
|
deltaVector.normalize().multiplyScalar(offset);
|
1298
|
-
this.
|
1334
|
+
this.character.position.add(deltaVector);
|
1299
1335
|
this.characterOnGround = deltaVector.y > Math.abs(deltaTime * this.characterVelocity.y * 0.25);
|
1300
1336
|
if (this.characterWasOnGround && !this.characterOnGround) {
|
1301
1337
|
this.characterAirborneSince = Date.now();
|
1302
1338
|
}
|
1303
|
-
this.coyoteTime = this.characterVelocity.y < 0 && this.characterOnGround
|
1339
|
+
this.coyoteTime = this.characterVelocity.y < 0 && !this.characterOnGround && Date.now() - this.characterAirborneSince < this.coyoteTimeThreshold;
|
1304
1340
|
this.characterWasOnGround = this.characterOnGround;
|
1305
1341
|
if (this.characterOnGround) {
|
1306
1342
|
this.characterVelocity.set(0, 0, 0);
|
@@ -1310,130 +1346,33 @@ var LocalController = class {
|
|
1310
1346
|
}
|
1311
1347
|
}
|
1312
1348
|
updateNetworkState() {
|
1313
|
-
|
1314
|
-
|
1315
|
-
this.
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
this.model.mesh.position.y,
|
1326
|
-
this.model.mesh.position.z
|
1327
|
-
);
|
1328
|
-
this.networkState = {
|
1329
|
-
id: this.id,
|
1330
|
-
position: positionUpdate,
|
1331
|
-
rotation: { quaternionY: characterQuaternion.y, quaternionW: characterQuaternion.w },
|
1332
|
-
state: this.model.currentAnimation
|
1333
|
-
};
|
1334
|
-
}
|
1349
|
+
const characterQuaternion = this.character.getWorldQuaternion(new Quaternion2());
|
1350
|
+
const positionUpdate = new Vector35(
|
1351
|
+
this.character.position.x,
|
1352
|
+
this.character.position.y,
|
1353
|
+
this.character.position.z
|
1354
|
+
);
|
1355
|
+
this.networkState = {
|
1356
|
+
id: this.id,
|
1357
|
+
position: positionUpdate,
|
1358
|
+
rotation: { quaternionY: characterQuaternion.y, quaternionW: characterQuaternion.w },
|
1359
|
+
state: this.character.getCurrentAnimation()
|
1360
|
+
};
|
1335
1361
|
}
|
1336
1362
|
resetPosition() {
|
1337
|
-
var _a;
|
1338
|
-
if (!((_a = this.model) == null ? void 0 : _a.mesh))
|
1339
|
-
return;
|
1340
1363
|
this.characterVelocity.y = 0;
|
1341
|
-
this.
|
1364
|
+
this.character.position.y = 3;
|
1342
1365
|
this.characterOnGround = false;
|
1343
1366
|
}
|
1344
1367
|
};
|
1345
1368
|
|
1346
|
-
// src/character/Character.ts
|
1347
|
-
var Character = class {
|
1348
|
-
constructor(characterDescription, characterModelLoader, id, isLocal, modelLoadedCallback, collisionsManager, keyInputManager, cameraManager, timeManager, composer) {
|
1349
|
-
this.characterDescription = characterDescription;
|
1350
|
-
this.characterModelLoader = characterModelLoader;
|
1351
|
-
this.id = id;
|
1352
|
-
this.isLocal = isLocal;
|
1353
|
-
this.modelLoadedCallback = modelLoadedCallback;
|
1354
|
-
this.collisionsManager = collisionsManager;
|
1355
|
-
this.keyInputManager = keyInputManager;
|
1356
|
-
this.cameraManager = cameraManager;
|
1357
|
-
this.timeManager = timeManager;
|
1358
|
-
this.composer = composer;
|
1359
|
-
this.controller = null;
|
1360
|
-
this.name = null;
|
1361
|
-
this.model = null;
|
1362
|
-
this.color = new Color3();
|
1363
|
-
this.position = new Vector35();
|
1364
|
-
this.tooltip = null;
|
1365
|
-
this.speakingIndicator = null;
|
1366
|
-
this.load();
|
1367
|
-
}
|
1368
|
-
async load() {
|
1369
|
-
this.model = new CharacterModel(this.characterDescription, this.characterModelLoader);
|
1370
|
-
await this.model.init();
|
1371
|
-
if (this.tooltip === null) {
|
1372
|
-
this.tooltip = new CharacterTooltip(this.model.mesh);
|
1373
|
-
}
|
1374
|
-
if (this.speakingIndicator === null) {
|
1375
|
-
this.speakingIndicator = new CharacterSpeakingIndicator(this.composer.postPostScene);
|
1376
|
-
}
|
1377
|
-
this.color = this.model.material.colorsCube216[this.id];
|
1378
|
-
if (this.isLocal) {
|
1379
|
-
this.controller = new LocalController(
|
1380
|
-
this.model,
|
1381
|
-
this.id,
|
1382
|
-
this.collisionsManager,
|
1383
|
-
this.keyInputManager,
|
1384
|
-
this.cameraManager,
|
1385
|
-
this.timeManager
|
1386
|
-
);
|
1387
|
-
}
|
1388
|
-
this.modelLoadedCallback();
|
1389
|
-
}
|
1390
|
-
update(time) {
|
1391
|
-
var _a;
|
1392
|
-
if (!this.model)
|
1393
|
-
return;
|
1394
|
-
if (this.tooltip) {
|
1395
|
-
this.tooltip.update(this.cameraManager.camera);
|
1396
|
-
}
|
1397
|
-
if (this.speakingIndicator) {
|
1398
|
-
this.speakingIndicator.setTime(time);
|
1399
|
-
if (this.model.mesh && this.model.headBone) {
|
1400
|
-
this.speakingIndicator.setBillboarding(
|
1401
|
-
(_a = this.model.headBone) == null ? void 0 : _a.getWorldPosition(new Vector35()),
|
1402
|
-
this.cameraManager.camera
|
1403
|
-
);
|
1404
|
-
}
|
1405
|
-
}
|
1406
|
-
this.model.mesh.getWorldPosition(this.position);
|
1407
|
-
if (typeof this.model.material.uniforms.time !== "undefined") {
|
1408
|
-
this.model.material.uniforms.time.value = time;
|
1409
|
-
this.model.material.uniforms.diffuseRandomColor.value = this.color;
|
1410
|
-
this.model.material.update();
|
1411
|
-
}
|
1412
|
-
}
|
1413
|
-
};
|
1414
|
-
|
1415
|
-
// src/character/CharacterManager.ts
|
1416
|
-
import { Euler, Group, Quaternion as Quaternion4, Vector3 as Vector37 } from "three";
|
1417
|
-
|
1418
1369
|
// src/character/RemoteController.ts
|
1419
|
-
import {
|
1420
|
-
AnimationMixer as AnimationMixer2,
|
1421
|
-
Object3D as Object3D4,
|
1422
|
-
Quaternion as Quaternion3,
|
1423
|
-
Vector3 as Vector36
|
1424
|
-
} from "three";
|
1370
|
+
import { Quaternion as Quaternion3, Vector3 as Vector36 } from "three";
|
1425
1371
|
var RemoteController = class {
|
1426
|
-
constructor(character,
|
1372
|
+
constructor(character, id) {
|
1427
1373
|
this.character = character;
|
1428
|
-
this.characterModelLoader = characterModelLoader;
|
1429
1374
|
this.id = id;
|
1430
|
-
this.characterModel = null;
|
1431
|
-
this.animationMixer = new AnimationMixer2(new Object3D4());
|
1432
|
-
this.animations = /* @__PURE__ */ new Map();
|
1433
1375
|
this.currentAnimation = 0 /* idle */;
|
1434
|
-
this.characterModel = this.character.model.mesh;
|
1435
|
-
this.characterModel.updateMatrixWorld();
|
1436
|
-
this.animationMixer = new AnimationMixer2(this.characterModel);
|
1437
1376
|
this.networkState = {
|
1438
1377
|
id: this.id,
|
1439
1378
|
position: { x: 0, y: 0, z: 0 },
|
@@ -1444,48 +1383,23 @@ var RemoteController = class {
|
|
1444
1383
|
update(clientUpdate, time, deltaTime) {
|
1445
1384
|
if (!this.character)
|
1446
1385
|
return;
|
1447
|
-
this.character.update(time);
|
1448
1386
|
this.updateFromNetwork(clientUpdate);
|
1449
|
-
this.
|
1450
|
-
}
|
1451
|
-
async setAnimationFromFile(animationType, fileName) {
|
1452
|
-
const animation = await this.characterModelLoader.load(fileName, "animation");
|
1453
|
-
const animationAction = this.animationMixer.clipAction(animation);
|
1454
|
-
this.animations.set(animationType, animationAction);
|
1455
|
-
if (animationType === 0 /* idle */) {
|
1456
|
-
animationAction.play();
|
1457
|
-
}
|
1458
|
-
}
|
1459
|
-
transitionToAnimation(targetAnimation, transitionDuration = 0.15) {
|
1460
|
-
if (this.currentAnimation === targetAnimation)
|
1461
|
-
return;
|
1462
|
-
const currentAction = this.animations.get(this.currentAnimation);
|
1463
|
-
const targetAction = this.animations.get(targetAnimation);
|
1464
|
-
if (!targetAction)
|
1465
|
-
return;
|
1466
|
-
if (currentAction) {
|
1467
|
-
currentAction.enabled = true;
|
1468
|
-
targetAction.reset().setEffectiveTimeScale(1).setEffectiveWeight(1).fadeIn(transitionDuration).play();
|
1469
|
-
currentAction.crossFadeTo(targetAction, transitionDuration, true);
|
1470
|
-
} else {
|
1471
|
-
targetAction.play();
|
1472
|
-
}
|
1473
|
-
this.currentAnimation = targetAnimation;
|
1387
|
+
this.character.update(time, deltaTime);
|
1474
1388
|
}
|
1475
1389
|
updateFromNetwork(clientUpdate) {
|
1476
|
-
if (!this.characterModel)
|
1477
|
-
return;
|
1478
1390
|
const { position, rotation, state } = clientUpdate;
|
1479
|
-
this.
|
1391
|
+
this.character.position.lerp(new Vector36(position.x, position.y, position.z), 0.15);
|
1480
1392
|
const rotationQuaternion = new Quaternion3(0, rotation.quaternionY, 0, rotation.quaternionW);
|
1481
|
-
this.
|
1393
|
+
this.character.quaternion.slerp(rotationQuaternion, 0.6);
|
1482
1394
|
if (state !== this.currentAnimation) {
|
1483
|
-
this.
|
1395
|
+
this.currentAnimation = state;
|
1396
|
+
this.character.updateAnimation(state);
|
1484
1397
|
}
|
1485
1398
|
}
|
1486
1399
|
};
|
1487
1400
|
|
1488
|
-
// src/character/
|
1401
|
+
// src/character/url-position.ts
|
1402
|
+
import { Quaternion as Quaternion4, Vector3 as Vector37 } from "three";
|
1489
1403
|
function encodeCharacterAndCamera(character, camera) {
|
1490
1404
|
return [
|
1491
1405
|
...toArray(character.position),
|
@@ -1494,135 +1408,96 @@ function encodeCharacterAndCamera(character, camera) {
|
|
1494
1408
|
...toArray(camera.quaternion)
|
1495
1409
|
].join(",");
|
1496
1410
|
}
|
1497
|
-
function decodeCharacterAndCamera(hash
|
1411
|
+
function decodeCharacterAndCamera(hash) {
|
1498
1412
|
const values = hash.split(",").map(Number);
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1413
|
+
return {
|
1414
|
+
character: {
|
1415
|
+
position: new Vector37(values[0], values[1], values[2]),
|
1416
|
+
quaternion: new Quaternion4(values[3], values[4], values[5], values[6])
|
1417
|
+
},
|
1418
|
+
camera: {
|
1419
|
+
position: new Vector37(values[7], values[8], values[9]),
|
1420
|
+
quaternion: new Quaternion4(values[10], values[11], values[12], values[13])
|
1421
|
+
}
|
1422
|
+
};
|
1503
1423
|
}
|
1424
|
+
|
1425
|
+
// src/character/CharacterManager.ts
|
1504
1426
|
var CharacterManager = class {
|
1505
|
-
constructor(composer, characterModelLoader, collisionsManager, cameraManager, timeManager,
|
1427
|
+
constructor(composer, characterModelLoader, collisionsManager, cameraManager, timeManager, keyInputManager, clientStates, sendUpdate) {
|
1506
1428
|
this.composer = composer;
|
1507
1429
|
this.characterModelLoader = characterModelLoader;
|
1508
1430
|
this.collisionsManager = collisionsManager;
|
1509
1431
|
this.cameraManager = cameraManager;
|
1510
1432
|
this.timeManager = timeManager;
|
1511
|
-
this.
|
1433
|
+
this.keyInputManager = keyInputManager;
|
1512
1434
|
this.clientStates = clientStates;
|
1513
1435
|
this.sendUpdate = sendUpdate;
|
1514
|
-
|
1515
|
-
|
1516
|
-
character was standing on a model and the page is reloaded the character falls into the model before it loads and
|
1517
|
-
can be trapped).
|
1518
|
-
*/
|
1519
|
-
this.updateLocationHash = false;
|
1436
|
+
this.updateLocationHash = true;
|
1437
|
+
this.headTargetOffset = new Vector38(0, 1.3, 0);
|
1520
1438
|
this.id = 0;
|
1521
|
-
this.loadingCharacters = /* @__PURE__ */ new Map();
|
1522
1439
|
this.remoteCharacters = /* @__PURE__ */ new Map();
|
1523
1440
|
this.remoteCharacterControllers = /* @__PURE__ */ new Map();
|
1524
1441
|
this.characterDescription = null;
|
1525
|
-
this.
|
1442
|
+
this.localCharacter = null;
|
1526
1443
|
this.cameraOffsetTarget = 0;
|
1527
1444
|
this.cameraOffset = 0;
|
1528
1445
|
this.speakingCharacters = /* @__PURE__ */ new Map();
|
1529
|
-
this.group = new
|
1530
|
-
}
|
1531
|
-
|
1532
|
-
|
1533
|
-
2) Make this synchronous to avoid having loadingCharacters and instead manage
|
1534
|
-
the mesh loading async (would allow us to show a nameplate where a remote
|
1535
|
-
user is before the asset loads).
|
1536
|
-
*/
|
1537
|
-
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector37(), spawnRotation = new Euler()) {
|
1446
|
+
this.group = new Group2();
|
1447
|
+
}
|
1448
|
+
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector38(), spawnRotation = new Euler()) {
|
1449
|
+
var _a;
|
1538
1450
|
this.characterDescription = characterDescription;
|
1539
|
-
const
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1451
|
+
const character = new Character(
|
1452
|
+
characterDescription,
|
1453
|
+
this.characterModelLoader,
|
1454
|
+
id,
|
1455
|
+
() => {
|
1456
|
+
},
|
1457
|
+
this.cameraManager,
|
1458
|
+
this.composer
|
1459
|
+
);
|
1460
|
+
if (isLocal) {
|
1461
|
+
const quaternion = new Quaternion5().setFromEuler(character.rotation);
|
1462
|
+
this.sendUpdate({
|
1543
1463
|
id,
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
decodeCharacterAndCamera(
|
1549
|
-
window.location.hash.substring(1),
|
1550
|
-
character.model.mesh,
|
1551
|
-
this.cameraManager.camera
|
1552
|
-
);
|
1553
|
-
} else {
|
1554
|
-
spawnPosition = spawnPosition || getSpawnPositionInsideCircle(3, 30, id, 0.4);
|
1555
|
-
character.model.mesh.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1556
|
-
character.model.mesh.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);
|
1557
|
-
character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1558
|
-
character.model.mesh.updateMatrixWorld();
|
1559
|
-
const quaternion = new Quaternion4().setFromEuler(character.model.mesh.rotation);
|
1560
|
-
this.sendUpdate({
|
1561
|
-
id,
|
1562
|
-
position: {
|
1563
|
-
x: spawnPosition.x,
|
1564
|
-
y: spawnPosition.y,
|
1565
|
-
z: spawnPosition.z
|
1566
|
-
},
|
1567
|
-
rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },
|
1568
|
-
state: 0 /* idle */
|
1569
|
-
});
|
1570
|
-
}
|
1571
|
-
character.model.hideMaterialByMeshName("SK_Mannequin_2");
|
1572
|
-
if (!isLocal) {
|
1573
|
-
(_b = (_a = character.model) == null ? void 0 : _a.mesh) == null ? void 0 : _b.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1574
|
-
(_d = (_c = character.model) == null ? void 0 : _c.mesh) == null ? void 0 : _d.updateMatrixWorld();
|
1575
|
-
character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1576
|
-
}
|
1577
|
-
this.group.add(character.model.mesh);
|
1578
|
-
if (isLocal) {
|
1579
|
-
this.id = id;
|
1580
|
-
this.character = character;
|
1581
|
-
(_e = this.character.tooltip) == null ? void 0 : _e.setText(`${id}`);
|
1582
|
-
} else {
|
1583
|
-
this.remoteCharacters.set(id, character);
|
1584
|
-
const remoteController = new RemoteController(character, this.characterModelLoader, id);
|
1585
|
-
remoteController.setAnimationFromFile(
|
1586
|
-
0 /* idle */,
|
1587
|
-
characterDescription.idleAnimationFileUrl
|
1588
|
-
);
|
1589
|
-
remoteController.setAnimationFromFile(
|
1590
|
-
1 /* walking */,
|
1591
|
-
characterDescription.jogAnimationFileUrl
|
1592
|
-
);
|
1593
|
-
remoteController.setAnimationFromFile(
|
1594
|
-
2 /* running */,
|
1595
|
-
characterDescription.sprintAnimationFileUrl
|
1596
|
-
);
|
1597
|
-
remoteController.setAnimationFromFile(
|
1598
|
-
4 /* air */,
|
1599
|
-
characterDescription.airAnimationFileUrl
|
1600
|
-
);
|
1601
|
-
(_f = remoteController.characterModel) == null ? void 0 : _f.position.set(
|
1602
|
-
spawnPosition.x,
|
1603
|
-
spawnPosition.y,
|
1604
|
-
spawnPosition.z
|
1605
|
-
);
|
1606
|
-
this.remoteCharacterControllers.set(id, remoteController);
|
1607
|
-
(_g = character.tooltip) == null ? void 0 : _g.setText(`${id}`);
|
1608
|
-
}
|
1609
|
-
resolve(character);
|
1464
|
+
position: {
|
1465
|
+
x: spawnPosition.x,
|
1466
|
+
y: spawnPosition.y,
|
1467
|
+
z: spawnPosition.z
|
1610
1468
|
},
|
1469
|
+
rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },
|
1470
|
+
state: 0 /* idle */
|
1471
|
+
});
|
1472
|
+
}
|
1473
|
+
if (isLocal) {
|
1474
|
+
this.id = id;
|
1475
|
+
this.localCharacter = character;
|
1476
|
+
this.localController = new LocalController(
|
1477
|
+
this.localCharacter,
|
1478
|
+
this.id,
|
1611
1479
|
this.collisionsManager,
|
1612
|
-
this.
|
1480
|
+
this.keyInputManager,
|
1613
1481
|
this.cameraManager,
|
1614
|
-
this.timeManager
|
1615
|
-
this.composer
|
1482
|
+
this.timeManager
|
1616
1483
|
);
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1484
|
+
this.localCharacter.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1485
|
+
this.localCharacter.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);
|
1486
|
+
} else {
|
1487
|
+
this.remoteCharacters.set(id, character);
|
1488
|
+
const remoteController = new RemoteController(character, id);
|
1489
|
+
remoteController.character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
|
1490
|
+
remoteController.character.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);
|
1491
|
+
this.remoteCharacterControllers.set(id, remoteController);
|
1492
|
+
}
|
1493
|
+
(_a = character.tooltip) == null ? void 0 : _a.setText(`${id}`);
|
1494
|
+
this.group.add(character);
|
1620
1495
|
}
|
1621
1496
|
getLocalCharacterPositionAndRotation() {
|
1622
|
-
if (this.
|
1497
|
+
if (this.localCharacter && this.localCharacter && this.localCharacter) {
|
1623
1498
|
return {
|
1624
|
-
position: this.
|
1625
|
-
rotation: this.
|
1499
|
+
position: this.localCharacter.position,
|
1500
|
+
rotation: this.localCharacter.rotation
|
1626
1501
|
};
|
1627
1502
|
}
|
1628
1503
|
return {
|
@@ -1632,54 +1507,48 @@ var CharacterManager = class {
|
|
1632
1507
|
}
|
1633
1508
|
clear() {
|
1634
1509
|
for (const [id, character] of this.remoteCharacters) {
|
1635
|
-
this.group.remove(character
|
1510
|
+
this.group.remove(character);
|
1636
1511
|
this.remoteCharacters.delete(id);
|
1637
1512
|
this.remoteCharacterControllers.delete(id);
|
1638
1513
|
}
|
1639
|
-
if (this.
|
1640
|
-
this.group.remove(this.
|
1641
|
-
this.
|
1514
|
+
if (this.localCharacter) {
|
1515
|
+
this.group.remove(this.localCharacter);
|
1516
|
+
this.localCharacter = null;
|
1642
1517
|
}
|
1643
|
-
this.loadingCharacters.clear();
|
1644
1518
|
}
|
1645
1519
|
setSpeakingCharacter(id, value) {
|
1646
1520
|
this.speakingCharacters.set(id, value);
|
1647
1521
|
}
|
1648
1522
|
update() {
|
1649
|
-
var _a, _b, _c
|
1650
|
-
if (this.
|
1651
|
-
this.
|
1523
|
+
var _a, _b, _c;
|
1524
|
+
if (this.localCharacter) {
|
1525
|
+
this.localCharacter.update(this.timeManager.time, this.timeManager.deltaTime);
|
1652
1526
|
if (this.speakingCharacters.has(this.id)) {
|
1653
|
-
(_a = this.
|
1527
|
+
(_a = this.localCharacter.speakingIndicator) == null ? void 0 : _a.setSpeaking(this.speakingCharacters.get(this.id));
|
1654
1528
|
}
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
if (this.
|
1663
|
-
this.
|
1664
|
-
if (this.timeManager.frame % 2 === 0) {
|
1665
|
-
this.sendUpdate(this.character.controller.networkState);
|
1666
|
-
}
|
1529
|
+
this.cameraOffsetTarget = this.cameraManager.targetDistance <= 0.4 ? 0.13 : 0;
|
1530
|
+
this.cameraOffset += ease(this.cameraOffsetTarget, this.cameraOffset, 0.1);
|
1531
|
+
const targetOffset = new Vector38(0, 0, this.cameraOffset);
|
1532
|
+
targetOffset.add(this.headTargetOffset);
|
1533
|
+
targetOffset.applyQuaternion(this.localCharacter.quaternion);
|
1534
|
+
this.cameraManager.setTarget(targetOffset.add(this.localCharacter.position));
|
1535
|
+
this.localController.update();
|
1536
|
+
if (this.timeManager.frame % 2 === 0) {
|
1537
|
+
this.sendUpdate(this.localController.networkState);
|
1667
1538
|
}
|
1668
1539
|
for (const [id, update] of this.clientStates) {
|
1669
1540
|
if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {
|
1670
1541
|
const character = this.remoteCharacters.get(id);
|
1671
|
-
(
|
1542
|
+
(_b = character == null ? void 0 : character.speakingIndicator) == null ? void 0 : _b.setSpeaking(this.speakingCharacters.get(id));
|
1672
1543
|
}
|
1673
1544
|
const { position } = update;
|
1674
|
-
if (!this.remoteCharacters.has(id)
|
1545
|
+
if (!this.remoteCharacters.has(id)) {
|
1675
1546
|
this.spawnCharacter(
|
1676
1547
|
this.characterDescription,
|
1677
1548
|
id,
|
1678
1549
|
false,
|
1679
|
-
new
|
1680
|
-
)
|
1681
|
-
this.loadingCharacters.delete(id);
|
1682
|
-
});
|
1550
|
+
new Vector38(position.x, position.y, position.z)
|
1551
|
+
);
|
1683
1552
|
}
|
1684
1553
|
const characterController = this.remoteCharacterControllers.get(id);
|
1685
1554
|
if (characterController) {
|
@@ -1688,15 +1557,15 @@ var CharacterManager = class {
|
|
1688
1557
|
}
|
1689
1558
|
for (const [id, character] of this.remoteCharacters) {
|
1690
1559
|
if (!this.clientStates.has(id)) {
|
1691
|
-
(
|
1692
|
-
this.group.remove(character
|
1560
|
+
(_c = character.speakingIndicator) == null ? void 0 : _c.dispose();
|
1561
|
+
this.group.remove(character);
|
1693
1562
|
this.remoteCharacters.delete(id);
|
1694
1563
|
this.remoteCharacterControllers.delete(id);
|
1695
1564
|
}
|
1696
1565
|
}
|
1697
1566
|
if (this.updateLocationHash && this.timeManager.frame % 60 === 0) {
|
1698
1567
|
window.location.hash = encodeCharacterAndCamera(
|
1699
|
-
this.
|
1568
|
+
this.localCharacter,
|
1700
1569
|
this.cameraManager.camera
|
1701
1570
|
);
|
1702
1571
|
}
|
@@ -1749,20 +1618,13 @@ var LRUCache = class {
|
|
1749
1618
|
this.cache.set(key, value);
|
1750
1619
|
}
|
1751
1620
|
};
|
1752
|
-
var
|
1621
|
+
var CharacterModelLoader = class {
|
1753
1622
|
constructor(maxCacheSize = 100) {
|
1754
1623
|
this.ongoingLoads = /* @__PURE__ */ new Map();
|
1755
1624
|
this.loadingManager = new LoadingManager();
|
1756
1625
|
this.gltfLoader = new CachedGLTFLoader(this.loadingManager);
|
1757
1626
|
this.modelCache = new LRUCache(maxCacheSize);
|
1758
1627
|
}
|
1759
|
-
/* TODO: decide between below lazy initialization or eager on this file's bottom export */
|
1760
|
-
static getInstance() {
|
1761
|
-
if (!_CharacterModelLoader.instance) {
|
1762
|
-
_CharacterModelLoader.instance = new _CharacterModelLoader();
|
1763
|
-
}
|
1764
|
-
return _CharacterModelLoader.instance;
|
1765
|
-
}
|
1766
1628
|
async load(fileUrl, fileType) {
|
1767
1629
|
const cachedModel = this.modelCache.get(fileUrl);
|
1768
1630
|
if (cachedModel) {
|
@@ -1773,16 +1635,22 @@ var _CharacterModelLoader = class _CharacterModelLoader {
|
|
1773
1635
|
console.log(`Loading ${fileUrl} from server`);
|
1774
1636
|
const ongoingLoad = this.ongoingLoads.get(fileUrl);
|
1775
1637
|
if (ongoingLoad)
|
1776
|
-
return ongoingLoad
|
1638
|
+
return ongoingLoad.then((loadedModel) => {
|
1639
|
+
const blobURL = URL.createObjectURL(loadedModel.blob);
|
1640
|
+
return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);
|
1641
|
+
});
|
1777
1642
|
const loadPromise = fetch(fileUrl).then((response) => response.blob()).then((blob) => {
|
1778
1643
|
const originalExtension = fileUrl.split(".").pop() || "";
|
1779
|
-
|
1780
|
-
|
1644
|
+
const cached = { blob, originalExtension };
|
1645
|
+
this.modelCache.set(fileUrl, cached);
|
1781
1646
|
this.ongoingLoads.delete(fileUrl);
|
1782
|
-
return
|
1647
|
+
return cached;
|
1783
1648
|
});
|
1784
1649
|
this.ongoingLoads.set(fileUrl, loadPromise);
|
1785
|
-
return loadPromise
|
1650
|
+
return loadPromise.then((loadedModel) => {
|
1651
|
+
const blobURL = URL.createObjectURL(loadedModel.blob);
|
1652
|
+
return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);
|
1653
|
+
});
|
1786
1654
|
}
|
1787
1655
|
}
|
1788
1656
|
async loadFromUrl(url, fileType, extension) {
|
@@ -1813,9 +1681,6 @@ var _CharacterModelLoader = class _CharacterModelLoader {
|
|
1813
1681
|
}
|
1814
1682
|
}
|
1815
1683
|
};
|
1816
|
-
_CharacterModelLoader.instance = null;
|
1817
|
-
var CharacterModelLoader = _CharacterModelLoader;
|
1818
|
-
var MODEL_LOADER = CharacterModelLoader.getInstance();
|
1819
1684
|
|
1820
1685
|
// src/input/KeyInputManager.ts
|
1821
1686
|
var KeyInputManager = class {
|
@@ -1884,9 +1749,10 @@ var KeyInputManager = class {
|
|
1884
1749
|
import {
|
1885
1750
|
InteractionManager,
|
1886
1751
|
MMLClickTrigger,
|
1887
|
-
PromptManager
|
1752
|
+
PromptManager,
|
1753
|
+
LoadingProgressManager
|
1888
1754
|
} from "mml-web";
|
1889
|
-
import { Group as
|
1755
|
+
import { Group as Group3 } from "three";
|
1890
1756
|
var MMLCompositionScene = class {
|
1891
1757
|
constructor(targetElement, renderer, scene, camera, audioListener, collisionsManager, getUserPositionAndRotation) {
|
1892
1758
|
this.renderer = renderer;
|
@@ -1896,7 +1762,7 @@ var MMLCompositionScene = class {
|
|
1896
1762
|
this.collisionsManager = collisionsManager;
|
1897
1763
|
this.getUserPositionAndRotation = getUserPositionAndRotation;
|
1898
1764
|
this.chatProbes = /* @__PURE__ */ new Set();
|
1899
|
-
this.group = new
|
1765
|
+
this.group = new Group3();
|
1900
1766
|
this.promptManager = PromptManager.init(targetElement);
|
1901
1767
|
const { interactionListener, interactionManager } = InteractionManager.init(
|
1902
1768
|
targetElement,
|
@@ -1905,6 +1771,7 @@ var MMLCompositionScene = class {
|
|
1905
1771
|
);
|
1906
1772
|
this.interactionManager = interactionManager;
|
1907
1773
|
this.interactionListener = interactionListener;
|
1774
|
+
this.loadingProgressManager = new LoadingProgressManager();
|
1908
1775
|
this.mmlScene = {
|
1909
1776
|
getAudioListener: () => this.audioListener,
|
1910
1777
|
getRenderer: () => this.renderer,
|
@@ -1940,6 +1807,9 @@ var MMLCompositionScene = class {
|
|
1940
1807
|
},
|
1941
1808
|
prompt: (promptProps, callback) => {
|
1942
1809
|
this.promptManager.prompt(promptProps, callback);
|
1810
|
+
},
|
1811
|
+
getLoadingProgressManager: () => {
|
1812
|
+
return this.loadingProgressManager;
|
1943
1813
|
}
|
1944
1814
|
};
|
1945
1815
|
this.clickTrigger = MMLClickTrigger.init(targetElement, this.mmlScene);
|
@@ -2888,12 +2758,12 @@ import {
|
|
2888
2758
|
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
|
2889
2759
|
|
2890
2760
|
// src/sun/Sun.ts
|
2891
|
-
import { CameraHelper, Color as Color5, DirectionalLight, Group as
|
2892
|
-
var Sun = class extends
|
2761
|
+
import { CameraHelper, Color as Color5, DirectionalLight, Group as Group4, OrthographicCamera, Vector3 as Vector39 } from "three";
|
2762
|
+
var Sun = class extends Group4 {
|
2893
2763
|
constructor() {
|
2894
2764
|
super();
|
2895
2765
|
this.debug = false;
|
2896
|
-
this.sunOffset = new
|
2766
|
+
this.sunOffset = new Vector39(
|
2897
2767
|
39 * (Math.PI / 180),
|
2898
2768
|
50 * (Math.PI / 180),
|
2899
2769
|
100
|
@@ -2920,7 +2790,7 @@ var Sun = class extends Group3 {
|
|
2920
2790
|
this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);
|
2921
2791
|
this.directionalLight.castShadow = true;
|
2922
2792
|
this.setColor();
|
2923
|
-
this.updateCharacterPosition(new
|
2793
|
+
this.updateCharacterPosition(new Vector39(0, 0, 0));
|
2924
2794
|
this.add(this.directionalLight);
|
2925
2795
|
if (this.debug === true && this.camHelper instanceof CameraHelper) {
|
2926
2796
|
this.add(this.camHelper);
|
@@ -2958,7 +2828,7 @@ var Sun = class extends Group3 {
|
|
2958
2828
|
if (!this.target)
|
2959
2829
|
return;
|
2960
2830
|
const distance = this.sunOffset.z;
|
2961
|
-
const sphericalPosition = new
|
2831
|
+
const sphericalPosition = new Vector39(
|
2962
2832
|
distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),
|
2963
2833
|
distance * Math.cos(polarAngle),
|
2964
2834
|
distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle)
|
@@ -3438,13 +3308,13 @@ import {
|
|
3438
3308
|
Color as Color7,
|
3439
3309
|
DoubleSide,
|
3440
3310
|
Euler as Euler2,
|
3441
|
-
Group as
|
3311
|
+
Group as Group5,
|
3442
3312
|
Line3 as Line32,
|
3443
3313
|
Matrix4 as Matrix42,
|
3444
3314
|
Mesh as Mesh4,
|
3445
3315
|
MeshBasicMaterial as MeshBasicMaterial3,
|
3446
3316
|
Ray,
|
3447
|
-
Vector3 as
|
3317
|
+
Vector3 as Vector310
|
3448
3318
|
} from "three";
|
3449
3319
|
import { VertexNormalsHelper } from "three/examples/jsm/helpers/VertexNormalsHelper.js";
|
3450
3320
|
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
@@ -3452,9 +3322,9 @@ import { MeshBVH, MeshBVHVisualizer } from "three-mesh-bvh";
|
|
3452
3322
|
var CollisionsManager = class {
|
3453
3323
|
constructor(scene) {
|
3454
3324
|
this.debug = false;
|
3455
|
-
this.tempVector = new
|
3456
|
-
this.tempVector2 = new
|
3457
|
-
this.tempVector3 = new
|
3325
|
+
this.tempVector = new Vector310();
|
3326
|
+
this.tempVector2 = new Vector310();
|
3327
|
+
this.tempVector3 = new Vector310();
|
3458
3328
|
this.tempRay = new Ray();
|
3459
3329
|
this.tempMatrix = new Matrix42();
|
3460
3330
|
this.tempMatrix2 = new Matrix42();
|
@@ -3524,7 +3394,7 @@ var CollisionsManager = class {
|
|
3524
3394
|
const normalsHelper = new VertexNormalsHelper(wireframeMesh, 0.25, 65280);
|
3525
3395
|
const visualizer = new MeshBVHVisualizer(wireframeMesh, 4);
|
3526
3396
|
visualizer.edgeMaterial.color = new Color7("blue");
|
3527
|
-
const debugGroup = new
|
3397
|
+
const debugGroup = new Group5();
|
3528
3398
|
debugGroup.add(wireframeMesh, normalsHelper, visualizer);
|
3529
3399
|
group.matrixWorld.decompose(debugGroup.position, debugGroup.quaternion, debugGroup.scale);
|
3530
3400
|
visualizer.update();
|
@@ -3603,7 +3473,7 @@ var CollisionsManager = class {
|
|
3603
3473
|
const realDistance = intersectionSegment.distance();
|
3604
3474
|
if (realDistance < capsuleRadius) {
|
3605
3475
|
if (!collisionPosition) {
|
3606
|
-
collisionPosition = new
|
3476
|
+
collisionPosition = new Vector310().copy(closestPointOnSegment).applyMatrix4(meshState.matrix);
|
3607
3477
|
}
|
3608
3478
|
const ratio = realDistance / modelReferenceDistance;
|
3609
3479
|
const realDepth = capsuleRadius - realDistance;
|
@@ -3659,6 +3529,15 @@ export {
|
|
3659
3529
|
MMLCompositionScene,
|
3660
3530
|
Sun,
|
3661
3531
|
TimeManager,
|
3662
|
-
TweakPane
|
3532
|
+
TweakPane,
|
3533
|
+
clamp,
|
3534
|
+
decodeCharacterAndCamera,
|
3535
|
+
ease,
|
3536
|
+
encodeCharacterAndCamera,
|
3537
|
+
getSpawnPositionInsideCircle,
|
3538
|
+
remap,
|
3539
|
+
round,
|
3540
|
+
roundToDecimalPlaces,
|
3541
|
+
toArray
|
3663
3542
|
};
|
3664
3543
|
//# sourceMappingURL=index.js.map
|