@mml-io/3d-web-client-core 0.0.0-experimental-1e55576-20240116 → 0.0.0-experimental-79fca4a-20240117
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.
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Line3 } from "three";
|
1
|
+
import { Line3, Quaternion, Vector3 } from "three";
|
2
2
|
import { CameraManager } from "../camera/CameraManager";
|
3
3
|
import { CollisionsManager } from "../collisions/CollisionsManager";
|
4
4
|
import { KeyInputManager } from "../input/KeyInputManager";
|
@@ -12,13 +12,10 @@ export declare class LocalController {
|
|
12
12
|
private readonly keyInputManager;
|
13
13
|
private readonly cameraManager;
|
14
14
|
private readonly timeManager;
|
15
|
-
private collisionDetectionSteps;
|
16
15
|
capsuleInfo: {
|
17
16
|
radius: number;
|
18
17
|
segment: Line3;
|
19
18
|
};
|
20
|
-
private maxWalkSpeed;
|
21
|
-
private maxRunSpeed;
|
22
19
|
private gravity;
|
23
20
|
private jumpForce;
|
24
21
|
private coyoteTimeThreshold;
|
@@ -28,6 +25,7 @@ export declare class LocalController {
|
|
28
25
|
private characterWasOnGround;
|
29
26
|
private characterAirborneSince;
|
30
27
|
private currentHeight;
|
28
|
+
private currentSurfaceAngle;
|
31
29
|
private characterVelocity;
|
32
30
|
private vectorUp;
|
33
31
|
private vectorDown;
|
@@ -35,9 +33,21 @@ export declare class LocalController {
|
|
35
33
|
private azimuthalAngle;
|
36
34
|
private tempMatrix;
|
37
35
|
private tempSegment;
|
36
|
+
private tempQuaternion;
|
37
|
+
private tempEuler;
|
38
38
|
private tempVector;
|
39
39
|
private tempVector2;
|
40
|
+
private tempVector3;
|
40
41
|
private rayCaster;
|
42
|
+
private surfaceTempQuaternion;
|
43
|
+
private surfaceTempQuaternion2;
|
44
|
+
private surfaceTempVector1;
|
45
|
+
private surfaceTempVector2;
|
46
|
+
private surfaceTempVector3;
|
47
|
+
private surfaceTempVector4;
|
48
|
+
private surfaceTempVector5;
|
49
|
+
private surfaceTempRay;
|
50
|
+
private lastFrameSurfaceState;
|
41
51
|
private forward;
|
42
52
|
private backward;
|
43
53
|
private left;
|
@@ -46,18 +56,21 @@ export declare class LocalController {
|
|
46
56
|
private jump;
|
47
57
|
private anyDirection;
|
48
58
|
private conflictingDirections;
|
49
|
-
private speed;
|
50
|
-
private targetSpeed;
|
51
59
|
networkState: CharacterState;
|
52
60
|
constructor(character: Character, id: number, collisionsManager: CollisionsManager, keyInputManager: KeyInputManager, cameraManager: CameraManager, timeManager: TimeManager);
|
61
|
+
private updateControllerState;
|
53
62
|
update(): void;
|
54
63
|
private getTargetAnimation;
|
55
64
|
private updateRotationOffset;
|
56
65
|
private updateAzimuthalAngle;
|
57
66
|
private computeAngularDifference;
|
58
67
|
private updateRotation;
|
59
|
-
private
|
68
|
+
private applyControls;
|
60
69
|
private updatePosition;
|
70
|
+
getMovementFromSurfaces(userPosition: Vector3, deltaTime: number): {
|
71
|
+
rotation: Quaternion;
|
72
|
+
position: Vector3;
|
73
|
+
} | null;
|
61
74
|
private updateNetworkState;
|
62
75
|
private resetPosition;
|
63
76
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { MElement } from "mml-web";
|
2
|
-
import { Group, Line3, Matrix4, Ray, Scene } from "three";
|
2
|
+
import { Group, Line3, Matrix4, Ray, Scene, Vector3 } from "three";
|
3
3
|
import { MeshBVH } from "three-mesh-bvh";
|
4
|
-
type CollisionMeshState = {
|
4
|
+
export type CollisionMeshState = {
|
5
5
|
matrix: Matrix4;
|
6
6
|
source: Group;
|
7
7
|
meshBVH: MeshBVH;
|
@@ -14,6 +14,7 @@ export declare class CollisionsManager {
|
|
14
14
|
private tempVector;
|
15
15
|
private tempVector2;
|
16
16
|
private tempVector3;
|
17
|
+
private tempQuaternion;
|
17
18
|
private tempRay;
|
18
19
|
private tempMatrix;
|
19
20
|
private tempMatrix2;
|
@@ -24,7 +25,7 @@ export declare class CollisionsManager {
|
|
24
25
|
collisionMeshState: Map<Group, CollisionMeshState>;
|
25
26
|
private collisionTrigger;
|
26
27
|
constructor(scene: Scene);
|
27
|
-
|
28
|
+
raycastFirst(ray: Ray): [number, Vector3, CollisionMeshState] | null;
|
28
29
|
private createCollisionMeshState;
|
29
30
|
addMeshesGroup(group: Group, mElement?: MElement): void;
|
30
31
|
updateMeshesGroup(group: Group): void;
|
@@ -32,4 +33,3 @@ export declare class CollisionsManager {
|
|
32
33
|
private applyCollider;
|
33
34
|
applyColliders(tempSegment: Line3, radius: number): void;
|
34
35
|
}
|
35
|
-
export {};
|
package/build/index.js
CHANGED
@@ -203,10 +203,10 @@ var CameraManager = class {
|
|
203
203
|
this.camera.position,
|
204
204
|
this.target.clone().sub(this.camera.position).normalize()
|
205
205
|
);
|
206
|
-
const
|
206
|
+
const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);
|
207
207
|
const cameraToPlayerDistance = this.camera.position.distanceTo(this.target);
|
208
|
-
if (
|
209
|
-
this.targetDistance = cameraToPlayerDistance -
|
208
|
+
if (firstRaycastHit !== null && firstRaycastHit[0] <= cameraToPlayerDistance) {
|
209
|
+
this.targetDistance = cameraToPlayerDistance - firstRaycastHit[0];
|
210
210
|
this.distance = this.targetDistance;
|
211
211
|
} else {
|
212
212
|
this.targetDistance += (this.desiredDistance - this.targetDistance) * this.dampingFactor * 4;
|
@@ -1136,10 +1136,19 @@ var Character = class extends Group {
|
|
1136
1136
|
};
|
1137
1137
|
|
1138
1138
|
// src/character/CharacterManager.ts
|
1139
|
-
import { Euler, Group as Group2, Quaternion as Quaternion5, Vector3 as Vector38 } from "three";
|
1139
|
+
import { Euler as Euler2, Group as Group2, Quaternion as Quaternion5, Vector3 as Vector38 } from "three";
|
1140
1140
|
|
1141
1141
|
// src/character/LocalController.ts
|
1142
|
-
import { Line3, Matrix4, Quaternion as Quaternion2, Raycaster as Raycaster2, Vector3 as Vector35 } from "three";
|
1142
|
+
import { Euler, Line3, Matrix4, Quaternion as Quaternion2, Ray, Raycaster as Raycaster2, Vector3 as Vector35 } from "three";
|
1143
|
+
var downVector = new Vector35(0, -1, 0);
|
1144
|
+
var airResistance = 0.5;
|
1145
|
+
var groundResistance = 0.99999999;
|
1146
|
+
var airControlModifier = 0.05;
|
1147
|
+
var groundWalkControl = 0.75;
|
1148
|
+
var groundRunControl = 1;
|
1149
|
+
var baseControl = 200;
|
1150
|
+
var collisionDetectionSteps = 15;
|
1151
|
+
var minimumSurfaceAngle = 0.9;
|
1143
1152
|
var LocalController = class {
|
1144
1153
|
constructor(character, id, collisionsManager, keyInputManager, cameraManager, timeManager) {
|
1145
1154
|
this.character = character;
|
@@ -1148,15 +1157,12 @@ var LocalController = class {
|
|
1148
1157
|
this.keyInputManager = keyInputManager;
|
1149
1158
|
this.cameraManager = cameraManager;
|
1150
1159
|
this.timeManager = timeManager;
|
1151
|
-
this.collisionDetectionSteps = 15;
|
1152
1160
|
this.capsuleInfo = {
|
1153
1161
|
radius: 0.4,
|
1154
1162
|
segment: new Line3(new Vector35(), new Vector35(0, 1.05, 0))
|
1155
1163
|
};
|
1156
|
-
this.maxWalkSpeed = 6;
|
1157
|
-
this.maxRunSpeed = 8.5;
|
1158
1164
|
this.gravity = -42;
|
1159
|
-
this.jumpForce =
|
1165
|
+
this.jumpForce = 20;
|
1160
1166
|
this.coyoteTimeThreshold = 70;
|
1161
1167
|
this.coyoteTime = false;
|
1162
1168
|
this.canJump = true;
|
@@ -1164,6 +1170,7 @@ var LocalController = class {
|
|
1164
1170
|
this.characterWasOnGround = false;
|
1165
1171
|
this.characterAirborneSince = 0;
|
1166
1172
|
this.currentHeight = 0;
|
1173
|
+
this.currentSurfaceAngle = new Vector35();
|
1167
1174
|
this.characterVelocity = new Vector35();
|
1168
1175
|
this.vectorUp = new Vector35(0, 1, 0);
|
1169
1176
|
this.vectorDown = new Vector35(0, -1, 0);
|
@@ -1171,11 +1178,21 @@ var LocalController = class {
|
|
1171
1178
|
this.azimuthalAngle = 0;
|
1172
1179
|
this.tempMatrix = new Matrix4();
|
1173
1180
|
this.tempSegment = new Line3();
|
1181
|
+
this.tempQuaternion = new Quaternion2();
|
1182
|
+
this.tempEuler = new Euler();
|
1174
1183
|
this.tempVector = new Vector35();
|
1175
1184
|
this.tempVector2 = new Vector35();
|
1185
|
+
this.tempVector3 = new Vector35();
|
1176
1186
|
this.rayCaster = new Raycaster2();
|
1177
|
-
this.
|
1178
|
-
this.
|
1187
|
+
this.surfaceTempQuaternion = new Quaternion2();
|
1188
|
+
this.surfaceTempQuaternion2 = new Quaternion2();
|
1189
|
+
this.surfaceTempVector1 = new Vector35();
|
1190
|
+
this.surfaceTempVector2 = new Vector35();
|
1191
|
+
this.surfaceTempVector3 = new Vector35();
|
1192
|
+
this.surfaceTempVector4 = new Vector35();
|
1193
|
+
this.surfaceTempVector5 = new Vector35();
|
1194
|
+
this.surfaceTempRay = new Ray();
|
1195
|
+
this.lastFrameSurfaceState = null;
|
1179
1196
|
this.networkState = {
|
1180
1197
|
id: this.id,
|
1181
1198
|
position: { x: 0, y: 0, z: 0 },
|
@@ -1183,47 +1200,55 @@ var LocalController = class {
|
|
1183
1200
|
state: 0 /* idle */
|
1184
1201
|
};
|
1185
1202
|
}
|
1203
|
+
updateControllerState() {
|
1204
|
+
this.forward = this.keyInputManager.forward;
|
1205
|
+
this.backward = this.keyInputManager.backward;
|
1206
|
+
this.left = this.keyInputManager.left;
|
1207
|
+
this.right = this.keyInputManager.right;
|
1208
|
+
this.run = this.keyInputManager.run;
|
1209
|
+
this.jump = this.keyInputManager.jump;
|
1210
|
+
this.anyDirection = this.keyInputManager.anyDirection;
|
1211
|
+
this.conflictingDirections = this.keyInputManager.conflictingDirection;
|
1212
|
+
}
|
1186
1213
|
update() {
|
1187
|
-
|
1188
|
-
this.forward = forward;
|
1189
|
-
this.backward = backward;
|
1190
|
-
this.left = left;
|
1191
|
-
this.right = right;
|
1192
|
-
this.run = run;
|
1193
|
-
this.jump = jump;
|
1194
|
-
this.anyDirection = anyDirection;
|
1195
|
-
this.conflictingDirections = conflictingDirection;
|
1196
|
-
this.targetSpeed = this.run ? this.maxRunSpeed : this.maxWalkSpeed;
|
1197
|
-
this.speed += ease(this.targetSpeed, this.speed, 0.07);
|
1214
|
+
this.updateControllerState();
|
1198
1215
|
this.rayCaster.set(this.character.position, this.vectorDown);
|
1199
|
-
const
|
1200
|
-
if (
|
1201
|
-
this.currentHeight =
|
1216
|
+
const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);
|
1217
|
+
if (firstRaycastHit !== null) {
|
1218
|
+
this.currentHeight = firstRaycastHit[0];
|
1219
|
+
this.currentSurfaceAngle.copy(firstRaycastHit[1]);
|
1202
1220
|
}
|
1203
|
-
if (anyDirection || !this.characterOnGround) {
|
1221
|
+
if (this.anyDirection || !this.characterOnGround) {
|
1204
1222
|
const targetAnimation = this.getTargetAnimation();
|
1205
1223
|
this.character.updateAnimation(targetAnimation);
|
1206
1224
|
} else {
|
1207
1225
|
this.character.updateAnimation(0 /* idle */);
|
1208
1226
|
}
|
1209
|
-
if (this.anyDirection)
|
1227
|
+
if (this.anyDirection) {
|
1210
1228
|
this.updateRotation();
|
1211
|
-
for (let i = 0; i < this.collisionDetectionSteps; i++) {
|
1212
|
-
this.updatePosition(this.timeManager.deltaTime / this.collisionDetectionSteps, i);
|
1213
1229
|
}
|
1214
|
-
|
1230
|
+
for (let i = 0; i < collisionDetectionSteps; i++) {
|
1231
|
+
this.updatePosition(
|
1232
|
+
this.timeManager.deltaTime,
|
1233
|
+
this.timeManager.deltaTime / collisionDetectionSteps,
|
1234
|
+
i
|
1235
|
+
);
|
1236
|
+
}
|
1237
|
+
if (this.character.position.y < 0) {
|
1215
1238
|
this.resetPosition();
|
1239
|
+
}
|
1216
1240
|
this.updateNetworkState();
|
1217
1241
|
}
|
1218
1242
|
getTargetAnimation() {
|
1219
1243
|
if (!this.character)
|
1220
1244
|
return 0 /* idle */;
|
1221
|
-
if (this.conflictingDirections)
|
1222
|
-
return 0 /* idle */;
|
1223
1245
|
const jumpHeight = this.characterVelocity.y > 0 ? 0.2 : 1.8;
|
1224
1246
|
if (this.currentHeight > jumpHeight && !this.characterOnGround) {
|
1225
1247
|
return 4 /* air */;
|
1226
1248
|
}
|
1249
|
+
if (this.conflictingDirections) {
|
1250
|
+
return 0 /* idle */;
|
1251
|
+
}
|
1227
1252
|
return this.run && this.anyDirection ? 2 /* running */ : this.anyDirection ? 1 /* walking */ : 0 /* idle */;
|
1228
1253
|
}
|
1229
1254
|
updateRotationOffset() {
|
@@ -1253,9 +1278,7 @@ var LocalController = class {
|
|
1253
1278
|
);
|
1254
1279
|
const isCameraFirstPerson = camToModelDistance < 2;
|
1255
1280
|
if (isCameraFirstPerson) {
|
1256
|
-
const cameraForward =
|
1257
|
-
this.cameraManager.camera.quaternion
|
1258
|
-
);
|
1281
|
+
const cameraForward = this.tempVector.set(0, 0, 1).applyQuaternion(this.cameraManager.camera.quaternion);
|
1259
1282
|
this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);
|
1260
1283
|
} else {
|
1261
1284
|
this.azimuthalAngle = Math.atan2(
|
@@ -1270,91 +1293,162 @@ var LocalController = class {
|
|
1270
1293
|
updateRotation() {
|
1271
1294
|
this.updateRotationOffset();
|
1272
1295
|
this.updateAzimuthalAngle();
|
1273
|
-
const rotationQuaternion =
|
1274
|
-
|
1296
|
+
const rotationQuaternion = this.tempQuaternion.setFromAxisAngle(
|
1297
|
+
this.vectorUp,
|
1298
|
+
this.azimuthalAngle + this.rotationOffset
|
1299
|
+
);
|
1275
1300
|
const angularDifference = this.computeAngularDifference(rotationQuaternion);
|
1276
1301
|
const desiredTime = 0.07;
|
1277
1302
|
const angularSpeed = angularDifference / desiredTime;
|
1278
1303
|
const frameRotation = angularSpeed * this.timeManager.deltaTime;
|
1279
1304
|
this.character.quaternion.rotateTowards(rotationQuaternion, frameRotation);
|
1280
1305
|
}
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1306
|
+
applyControls(deltaTime) {
|
1307
|
+
const resistance = this.characterOnGround ? groundResistance : airResistance;
|
1308
|
+
const speedFactor = Math.pow(1 - resistance, deltaTime);
|
1309
|
+
this.characterVelocity.multiplyScalar(speedFactor);
|
1310
|
+
const acceleration = this.tempVector.set(0, 0, 0);
|
1285
1311
|
if (this.characterOnGround) {
|
1286
|
-
if (!this.jump)
|
1312
|
+
if (!this.jump) {
|
1287
1313
|
this.canJump = true;
|
1314
|
+
}
|
1288
1315
|
if (this.jump && this.canJump) {
|
1289
|
-
|
1316
|
+
acceleration.y += this.jumpForce / deltaTime;
|
1290
1317
|
this.canJump = false;
|
1291
1318
|
} else {
|
1292
|
-
this.
|
1319
|
+
if (this.currentSurfaceAngle.y < minimumSurfaceAngle) {
|
1320
|
+
acceleration.y += this.gravity;
|
1321
|
+
}
|
1293
1322
|
}
|
1294
1323
|
} else if (this.jump && this.coyoteTime) {
|
1295
|
-
|
1324
|
+
acceleration.y += this.jumpForce / deltaTime;
|
1296
1325
|
this.canJump = false;
|
1297
1326
|
} else {
|
1298
|
-
|
1327
|
+
acceleration.y += this.gravity;
|
1299
1328
|
this.canJump = false;
|
1300
1329
|
}
|
1301
|
-
this.
|
1302
|
-
this.
|
1303
|
-
if (this.
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1330
|
+
const control = (this.characterOnGround ? this.run ? groundRunControl : groundWalkControl : airControlModifier) * baseControl;
|
1331
|
+
const controlAcceleration = this.tempVector2.set(0, 0, 0);
|
1332
|
+
if (!this.conflictingDirections) {
|
1333
|
+
if (this.forward) {
|
1334
|
+
const forward = this.tempVector3.set(0, 0, -1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1335
|
+
controlAcceleration.add(forward);
|
1336
|
+
}
|
1337
|
+
if (this.backward) {
|
1338
|
+
const backward = this.tempVector3.set(0, 0, 1).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1339
|
+
controlAcceleration.add(backward);
|
1340
|
+
}
|
1341
|
+
if (this.left) {
|
1342
|
+
const left = this.tempVector3.set(-1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1343
|
+
controlAcceleration.add(left);
|
1344
|
+
}
|
1345
|
+
if (this.right) {
|
1346
|
+
const right = this.tempVector3.set(1, 0, 0).applyAxisAngle(this.vectorUp, this.azimuthalAngle);
|
1347
|
+
controlAcceleration.add(right);
|
1348
|
+
}
|
1314
1349
|
}
|
1315
|
-
if (
|
1316
|
-
|
1317
|
-
|
1350
|
+
if (controlAcceleration.length() > 0) {
|
1351
|
+
controlAcceleration.normalize();
|
1352
|
+
controlAcceleration.multiplyScalar(control);
|
1318
1353
|
}
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1354
|
+
acceleration.add(controlAcceleration);
|
1355
|
+
this.characterVelocity.addScaledVector(acceleration, deltaTime);
|
1356
|
+
this.character.position.addScaledVector(this.characterVelocity, deltaTime);
|
1357
|
+
}
|
1358
|
+
updatePosition(deltaTime, stepDeltaTime, iter) {
|
1359
|
+
this.applyControls(stepDeltaTime);
|
1360
|
+
if (iter === 0) {
|
1361
|
+
const lastMovement = this.getMovementFromSurfaces(this.character.position, deltaTime);
|
1362
|
+
if (lastMovement) {
|
1363
|
+
this.character.position.add(lastMovement.position);
|
1364
|
+
const asQuaternion = this.tempQuaternion.setFromEuler(this.character.rotation);
|
1365
|
+
const lastMovementEuler = this.tempEuler.setFromQuaternion(lastMovement.rotation);
|
1366
|
+
lastMovementEuler.x = 0;
|
1367
|
+
lastMovementEuler.z = 0;
|
1368
|
+
lastMovement.rotation.setFromEuler(lastMovementEuler);
|
1369
|
+
asQuaternion.multiply(lastMovement.rotation);
|
1370
|
+
this.character.rotation.setFromQuaternion(asQuaternion);
|
1371
|
+
}
|
1322
1372
|
}
|
1323
1373
|
this.character.updateMatrixWorld();
|
1324
|
-
this.tempSegment
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
const
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
deltaVector.normalize().multiplyScalar(offset);
|
1334
|
-
this.character.position.add(deltaVector);
|
1335
|
-
this.characterOnGround = deltaVector.y > Math.abs(deltaTime * this.characterVelocity.y * 0.25);
|
1374
|
+
const avatarSegment = this.tempSegment;
|
1375
|
+
avatarSegment.copy(this.capsuleInfo.segment);
|
1376
|
+
avatarSegment.start.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);
|
1377
|
+
avatarSegment.end.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);
|
1378
|
+
const positionBeforeCollisions = this.tempVector.copy(avatarSegment.start);
|
1379
|
+
this.collisionsManager.applyColliders(avatarSegment, this.capsuleInfo.radius);
|
1380
|
+
this.character.position.copy(avatarSegment.start);
|
1381
|
+
const deltaCollisionPosition = avatarSegment.start.sub(positionBeforeCollisions);
|
1382
|
+
this.characterOnGround = deltaCollisionPosition.y > 0;
|
1336
1383
|
if (this.characterWasOnGround && !this.characterOnGround) {
|
1337
1384
|
this.characterAirborneSince = Date.now();
|
1338
1385
|
}
|
1339
1386
|
this.coyoteTime = this.characterVelocity.y < 0 && !this.characterOnGround && Date.now() - this.characterAirborneSince < this.coyoteTimeThreshold;
|
1340
1387
|
this.characterWasOnGround = this.characterOnGround;
|
1341
|
-
|
1342
|
-
|
1388
|
+
}
|
1389
|
+
getMovementFromSurfaces(userPosition, deltaTime) {
|
1390
|
+
let lastMovement = null;
|
1391
|
+
if (this.lastFrameSurfaceState !== null) {
|
1392
|
+
const meshState = this.lastFrameSurfaceState[0];
|
1393
|
+
const currentFrameMatrix = meshState.matrix;
|
1394
|
+
const lastFrameMatrix = this.lastFrameSurfaceState[1].lastMatrix;
|
1395
|
+
if (lastFrameMatrix.equals(currentFrameMatrix)) {
|
1396
|
+
} else {
|
1397
|
+
const lastMeshPosition = this.surfaceTempVector1;
|
1398
|
+
const lastMeshRotation = this.surfaceTempQuaternion;
|
1399
|
+
lastFrameMatrix.decompose(lastMeshPosition, lastMeshRotation, this.surfaceTempVector3);
|
1400
|
+
const currentMeshPosition = this.surfaceTempVector2;
|
1401
|
+
const currentMeshRotation = this.surfaceTempQuaternion2;
|
1402
|
+
currentFrameMatrix.decompose(
|
1403
|
+
currentMeshPosition,
|
1404
|
+
currentMeshRotation,
|
1405
|
+
this.surfaceTempVector3
|
1406
|
+
);
|
1407
|
+
const meshTranslationDelta = this.surfaceTempVector5.copy(currentMeshPosition).sub(lastMeshPosition);
|
1408
|
+
const lastFrameRelativeUserPosition = this.surfaceTempVector3.copy(userPosition).sub(lastMeshPosition);
|
1409
|
+
const meshRotationDelta = lastMeshRotation.invert().multiply(currentMeshRotation);
|
1410
|
+
const translationDueToRotation = this.surfaceTempVector4.copy(lastFrameRelativeUserPosition).applyQuaternion(meshRotationDelta).sub(lastFrameRelativeUserPosition);
|
1411
|
+
const translationAndRotationPositionDelta = this.surfaceTempVector1.copy(meshTranslationDelta).add(translationDueToRotation);
|
1412
|
+
lastMovement = {
|
1413
|
+
position: translationAndRotationPositionDelta,
|
1414
|
+
rotation: meshRotationDelta
|
1415
|
+
};
|
1416
|
+
lastFrameMatrix.copy(currentFrameMatrix);
|
1417
|
+
}
|
1418
|
+
}
|
1419
|
+
const newPosition = this.surfaceTempVector3.copy(userPosition);
|
1420
|
+
if (lastMovement) {
|
1421
|
+
newPosition.add(lastMovement.position);
|
1422
|
+
}
|
1423
|
+
newPosition.setY(newPosition.y + 0.05);
|
1424
|
+
const ray = this.surfaceTempRay.set(newPosition, downVector);
|
1425
|
+
const hit = this.collisionsManager.raycastFirst(ray);
|
1426
|
+
if (hit && hit[0] < 0.8) {
|
1427
|
+
const currentCollisionMeshState = hit[2];
|
1428
|
+
this.lastFrameSurfaceState = [
|
1429
|
+
currentCollisionMeshState,
|
1430
|
+
{ lastMatrix: currentCollisionMeshState.matrix.clone() }
|
1431
|
+
];
|
1343
1432
|
} else {
|
1344
|
-
|
1345
|
-
|
1433
|
+
if (this.lastFrameSurfaceState !== null && lastMovement) {
|
1434
|
+
this.characterVelocity.add(
|
1435
|
+
lastMovement.position.clone().divideScalar(deltaTime)
|
1436
|
+
// The position delta is the result of one tick which is deltaTime seconds, so we need to divide by deltaTime to get the velocity per second
|
1437
|
+
);
|
1438
|
+
}
|
1439
|
+
this.lastFrameSurfaceState = null;
|
1346
1440
|
}
|
1441
|
+
return lastMovement;
|
1347
1442
|
}
|
1348
1443
|
updateNetworkState() {
|
1349
|
-
const characterQuaternion = this.character.getWorldQuaternion(
|
1350
|
-
const positionUpdate = new Vector35(
|
1351
|
-
this.character.position.x,
|
1352
|
-
this.character.position.y,
|
1353
|
-
this.character.position.z
|
1354
|
-
);
|
1444
|
+
const characterQuaternion = this.character.getWorldQuaternion(this.tempQuaternion);
|
1355
1445
|
this.networkState = {
|
1356
1446
|
id: this.id,
|
1357
|
-
position:
|
1447
|
+
position: {
|
1448
|
+
x: this.character.position.x,
|
1449
|
+
y: this.character.position.y,
|
1450
|
+
z: this.character.position.z
|
1451
|
+
},
|
1358
1452
|
rotation: { quaternionY: characterQuaternion.y, quaternionW: characterQuaternion.w },
|
1359
1453
|
state: this.character.getCurrentAnimation()
|
1360
1454
|
};
|
@@ -1445,7 +1539,7 @@ var CharacterManager = class {
|
|
1445
1539
|
this.speakingCharacters = /* @__PURE__ */ new Map();
|
1446
1540
|
this.group = new Group2();
|
1447
1541
|
}
|
1448
|
-
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector38(), spawnRotation = new
|
1542
|
+
spawnCharacter(characterDescription, id, isLocal = false, spawnPosition = new Vector38(), spawnRotation = new Euler2()) {
|
1449
1543
|
var _a;
|
1450
1544
|
this.characterDescription = characterDescription;
|
1451
1545
|
const character = new Character(
|
@@ -1526,16 +1620,16 @@ var CharacterManager = class {
|
|
1526
1620
|
if (this.speakingCharacters.has(this.id)) {
|
1527
1621
|
(_a = this.localCharacter.speakingIndicator) == null ? void 0 : _a.setSpeaking(this.speakingCharacters.get(this.id));
|
1528
1622
|
}
|
1623
|
+
this.localController.update();
|
1624
|
+
if (this.timeManager.frame % 2 === 0) {
|
1625
|
+
this.sendUpdate(this.localController.networkState);
|
1626
|
+
}
|
1529
1627
|
this.cameraOffsetTarget = this.cameraManager.targetDistance <= 0.4 ? 0.13 : 0;
|
1530
1628
|
this.cameraOffset += ease(this.cameraOffsetTarget, this.cameraOffset, 0.1);
|
1531
1629
|
const targetOffset = new Vector38(0, 0, this.cameraOffset);
|
1532
1630
|
targetOffset.add(this.headTargetOffset);
|
1533
1631
|
targetOffset.applyQuaternion(this.localCharacter.quaternion);
|
1534
1632
|
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);
|
1538
|
-
}
|
1539
1633
|
for (const [id, update] of this.clientStates) {
|
1540
1634
|
if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {
|
1541
1635
|
const character = this.remoteCharacters.get(id);
|
@@ -4621,13 +4715,14 @@ import {
|
|
4621
4715
|
Box3,
|
4622
4716
|
Color as Color8,
|
4623
4717
|
DoubleSide,
|
4624
|
-
Euler as
|
4718
|
+
Euler as Euler3,
|
4625
4719
|
Group as Group5,
|
4626
4720
|
Line3 as Line32,
|
4627
4721
|
Matrix4 as Matrix46,
|
4628
4722
|
Mesh as Mesh5,
|
4629
4723
|
MeshBasicMaterial as MeshBasicMaterial3,
|
4630
|
-
|
4724
|
+
Quaternion as Quaternion6,
|
4725
|
+
Ray as Ray2,
|
4631
4726
|
Vector3 as Vector314
|
4632
4727
|
} from "three";
|
4633
4728
|
import { VertexNormalsHelper } from "three/examples/jsm/helpers/VertexNormalsHelper.js";
|
@@ -4639,33 +4734,41 @@ var CollisionsManager = class {
|
|
4639
4734
|
this.tempVector = new Vector314();
|
4640
4735
|
this.tempVector2 = new Vector314();
|
4641
4736
|
this.tempVector3 = new Vector314();
|
4642
|
-
this.
|
4737
|
+
this.tempQuaternion = new Quaternion6();
|
4738
|
+
this.tempRay = new Ray2();
|
4643
4739
|
this.tempMatrix = new Matrix46();
|
4644
4740
|
this.tempMatrix2 = new Matrix46();
|
4645
4741
|
this.tempBox = new Box3();
|
4646
|
-
this.tempEuler = new
|
4742
|
+
this.tempEuler = new Euler3();
|
4647
4743
|
this.tempSegment = new Line32();
|
4648
4744
|
this.tempSegment2 = new Line32();
|
4649
4745
|
this.collisionMeshState = /* @__PURE__ */ new Map();
|
4650
4746
|
this.scene = scene;
|
4651
4747
|
this.collisionTrigger = MMLCollisionTrigger.init();
|
4652
4748
|
}
|
4653
|
-
|
4749
|
+
raycastFirst(ray) {
|
4654
4750
|
let minimumDistance = null;
|
4655
|
-
|
4656
|
-
|
4657
|
-
|
4751
|
+
let minimumHit = null;
|
4752
|
+
let minimumNormal = new Vector314();
|
4753
|
+
for (const [, collisionMeshState] of this.collisionMeshState) {
|
4754
|
+
this.tempRay.copy(ray).applyMatrix4(this.tempMatrix.copy(collisionMeshState.matrix).invert());
|
4755
|
+
const hit = collisionMeshState.meshBVH.raycastFirst(this.tempRay, DoubleSide);
|
4658
4756
|
if (hit) {
|
4659
4757
|
this.tempSegment.start.copy(this.tempRay.origin);
|
4660
4758
|
this.tempSegment.end.copy(hit.point);
|
4661
|
-
this.tempSegment.applyMatrix4(
|
4759
|
+
this.tempSegment.applyMatrix4(collisionMeshState.matrix);
|
4662
4760
|
const dist = this.tempSegment.distance();
|
4663
4761
|
if (minimumDistance === null || dist < minimumDistance) {
|
4664
4762
|
minimumDistance = dist;
|
4763
|
+
minimumHit = collisionMeshState;
|
4764
|
+
minimumNormal = (hit.normal ? minimumNormal.copy(hit.normal) : minimumNormal).applyQuaternion(this.tempQuaternion.setFromRotationMatrix(collisionMeshState.matrix)).normalize();
|
4665
4765
|
}
|
4666
4766
|
}
|
4667
4767
|
}
|
4668
|
-
|
4768
|
+
if (minimumDistance === null || minimumNormal === null || minimumHit === null) {
|
4769
|
+
return null;
|
4770
|
+
}
|
4771
|
+
return [minimumDistance, minimumNormal, minimumHit];
|
4669
4772
|
}
|
4670
4773
|
createCollisionMeshState(group, trackCollisions) {
|
4671
4774
|
const geometries = [];
|