@mml-io/3d-web-client-core 0.0.0-experimental-8e124c7-20240520 → 0.0.0-experimental-ff88de3-20240530
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 +2 -0
- package/build/character/Character.d.ts +1 -0
- package/build/character/CharacterManager.d.ts +4 -1
- package/build/character/CharacterModel.d.ts +1 -0
- package/build/character/CharacterState.d.ts +2 -1
- package/build/character/LocalController.d.ts +23 -6
- package/build/index.js +368 -69
- package/build/index.js.map +3 -3
- package/build/tweakpane/TweakPane.d.ts +4 -0
- package/build/tweakpane/blades/cameraFolder.d.ts +6 -0
- package/build/tweakpane/blades/characterControlsFolder.d.ts +79 -0
- package/package.json +5 -5
package/build/index.js
CHANGED
@@ -246,7 +246,8 @@ var camValues = {
|
|
246
246
|
invertFOVMapping: false,
|
247
247
|
damping: 0.091,
|
248
248
|
dampingScale: 0.01,
|
249
|
-
zoomScale: 0.
|
249
|
+
zoomScale: 0.05,
|
250
|
+
zoomDamping: 0.3
|
250
251
|
};
|
251
252
|
var camOptions = {
|
252
253
|
initialDistance: { min: 1, max: 5, step: 0.1 },
|
@@ -257,7 +258,8 @@ var camOptions = {
|
|
257
258
|
minFOV: { min: 50, max: 100, step: 1 },
|
258
259
|
damping: { min: 0.01, max: 0.15, step: 0.01 },
|
259
260
|
dampingScale: { min: 1e-3, max: 0.02, step: 1e-3 },
|
260
|
-
zoomScale: { min: 5e-3, max: 0.
|
261
|
+
zoomScale: { min: 5e-3, max: 0.3, step: 1e-3 },
|
262
|
+
zoomDamping: { min: 0, max: 2, step: 0.01 }
|
261
263
|
};
|
262
264
|
var CameraFolder = class {
|
263
265
|
constructor(parentFolder, expand = false) {
|
@@ -277,6 +279,7 @@ var CameraFolder = class {
|
|
277
279
|
this.folder.addBinding(camValues, "damping", camOptions.damping);
|
278
280
|
this.folder.addBinding(camValues, "dampingScale", camOptions.dampingScale);
|
279
281
|
this.folder.addBinding(camValues, "zoomScale", camOptions.zoomScale);
|
282
|
+
this.folder.addBinding(camValues, "zoomDamping", camOptions.zoomDamping);
|
280
283
|
}
|
281
284
|
setupChangeEvent(cameraManager) {
|
282
285
|
this.folder.on("change", (e) => {
|
@@ -342,6 +345,11 @@ var CameraFolder = class {
|
|
342
345
|
cameraManager.zoomScale = value;
|
343
346
|
break;
|
344
347
|
}
|
348
|
+
case "zoomDamping": {
|
349
|
+
const value = e.value;
|
350
|
+
cameraManager.zoomDamping = value;
|
351
|
+
break;
|
352
|
+
}
|
345
353
|
default:
|
346
354
|
break;
|
347
355
|
}
|
@@ -375,6 +383,7 @@ var CameraManager = class {
|
|
375
383
|
this.damping = camValues.damping;
|
376
384
|
this.dampingScale = 0.01;
|
377
385
|
this.zoomScale = camValues.zoomScale;
|
386
|
+
this.zoomDamping = camValues.zoomDamping;
|
378
387
|
this.invertFOVMapping = camValues.invertFOVMapping;
|
379
388
|
this.fov = this.initialFOV;
|
380
389
|
this.targetFOV = this.initialFOV;
|
@@ -400,7 +409,7 @@ var CameraManager = class {
|
|
400
409
|
this.targetPhi = initialPhi;
|
401
410
|
this.theta = initialTheta;
|
402
411
|
this.targetTheta = initialTheta;
|
403
|
-
this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1,
|
412
|
+
this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);
|
404
413
|
this.camera.position.set(0, 1.4, -this.initialDistance);
|
405
414
|
this.rayCaster = new Raycaster();
|
406
415
|
this.hasTouchControl = VirtualJoystick.checkForTouch();
|
@@ -408,7 +417,8 @@ var CameraManager = class {
|
|
408
417
|
[targetElement, "mousedown", this.onMouseDown.bind(this)],
|
409
418
|
[document, "mouseup", this.onMouseUp.bind(this)],
|
410
419
|
[document, "mousemove", this.onMouseMove.bind(this)],
|
411
|
-
[targetElement, "wheel", this.onMouseWheel.bind(this)]
|
420
|
+
[targetElement, "wheel", this.onMouseWheel.bind(this)],
|
421
|
+
[targetElement, "contextmenu", this.onContextMenu.bind(this)]
|
412
422
|
]);
|
413
423
|
if (this.hasTouchControl) {
|
414
424
|
this.eventHandlerCollection.add(targetElement, "touchstart", this.onTouchStart.bind(this), {
|
@@ -458,21 +468,29 @@ var CameraManager = class {
|
|
458
468
|
}
|
459
469
|
}
|
460
470
|
}
|
461
|
-
onMouseDown() {
|
462
|
-
|
471
|
+
onMouseDown(event) {
|
472
|
+
if (event.button === 0 || event.button === 2) {
|
473
|
+
this.dragging = true;
|
474
|
+
document.body.style.cursor = "none";
|
475
|
+
}
|
463
476
|
}
|
464
|
-
onMouseUp(
|
465
|
-
|
477
|
+
onMouseUp(event) {
|
478
|
+
if (event.button === 0 || event.button === 2) {
|
479
|
+
this.dragging = false;
|
480
|
+
document.body.style.cursor = "default";
|
481
|
+
}
|
466
482
|
}
|
467
483
|
onMouseMove(event) {
|
468
|
-
if (
|
484
|
+
if (getTweakpaneActive())
|
469
485
|
return;
|
470
|
-
if (this.
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
486
|
+
if (this.dragging) {
|
487
|
+
if (this.targetTheta === null || this.targetPhi === null)
|
488
|
+
return;
|
489
|
+
this.targetTheta += event.movementX * this.dampingScale;
|
490
|
+
this.targetPhi -= event.movementY * this.dampingScale;
|
491
|
+
this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));
|
492
|
+
event.preventDefault();
|
493
|
+
}
|
476
494
|
}
|
477
495
|
onMouseWheel(event) {
|
478
496
|
const scrollAmount = event.deltaY * this.zoomScale * 0.1;
|
@@ -484,6 +502,9 @@ var CameraManager = class {
|
|
484
502
|
this.desiredDistance = this.targetDistance;
|
485
503
|
event.preventDefault();
|
486
504
|
}
|
505
|
+
onContextMenu(event) {
|
506
|
+
event.preventDefault();
|
507
|
+
}
|
487
508
|
setTarget(target) {
|
488
509
|
if (!this.isLerping) {
|
489
510
|
this.target.copy(target);
|
@@ -562,7 +583,7 @@ var CameraManager = class {
|
|
562
583
|
this.adjustCameraPosition();
|
563
584
|
}
|
564
585
|
if (this.phi !== null && this.targetPhi !== null && this.theta !== null && this.targetTheta !== null) {
|
565
|
-
this.distance += (this.targetDistance - this.distance) * this.damping * 0.21;
|
586
|
+
this.distance += (this.targetDistance - this.distance) * this.damping * (0.21 + this.zoomDamping);
|
566
587
|
this.phi += (this.targetPhi - this.phi) * this.damping;
|
567
588
|
this.theta += (this.targetTheta - this.theta) * this.damping;
|
568
589
|
const x = this.target.x + this.distance * Math.sin(this.phi) * Math.cos(this.theta);
|
@@ -871,6 +892,7 @@ var AnimationState = /* @__PURE__ */ ((AnimationState2) => {
|
|
871
892
|
AnimationState2[AnimationState2["jumpToAir"] = 3] = "jumpToAir";
|
872
893
|
AnimationState2[AnimationState2["air"] = 4] = "air";
|
873
894
|
AnimationState2[AnimationState2["airToGround"] = 5] = "airToGround";
|
895
|
+
AnimationState2[AnimationState2["doubleJump"] = 6] = "doubleJump";
|
874
896
|
return AnimationState2;
|
875
897
|
})(AnimationState || {});
|
876
898
|
|
@@ -884,27 +906,36 @@ var _CharacterModel = class _CharacterModel {
|
|
884
906
|
this.animations = {};
|
885
907
|
this.animationMixer = null;
|
886
908
|
this.currentAnimation = 0 /* idle */;
|
909
|
+
this.isPostDoubleJump = false;
|
887
910
|
}
|
888
911
|
async init() {
|
889
912
|
await this.loadMainMesh();
|
890
|
-
await
|
891
|
-
this.
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
913
|
+
await this.setAnimationFromFile(
|
914
|
+
this.config.animationConfig.idleAnimationFileUrl,
|
915
|
+
0 /* idle */,
|
916
|
+
true
|
917
|
+
);
|
918
|
+
await this.setAnimationFromFile(
|
919
|
+
this.config.animationConfig.jogAnimationFileUrl,
|
920
|
+
1 /* walking */,
|
921
|
+
true
|
922
|
+
);
|
923
|
+
await this.setAnimationFromFile(
|
924
|
+
this.config.animationConfig.sprintAnimationFileUrl,
|
925
|
+
2 /* running */,
|
926
|
+
true
|
927
|
+
);
|
928
|
+
await this.setAnimationFromFile(
|
929
|
+
this.config.animationConfig.airAnimationFileUrl,
|
930
|
+
4 /* air */,
|
931
|
+
true
|
932
|
+
);
|
933
|
+
await this.setAnimationFromFile(
|
934
|
+
this.config.animationConfig.doubleJumpAnimationFileUrl,
|
935
|
+
6 /* doubleJump */,
|
936
|
+
false,
|
937
|
+
1.3
|
938
|
+
);
|
908
939
|
this.applyCustomMaterials();
|
909
940
|
}
|
910
941
|
applyCustomMaterials() {
|
@@ -941,6 +972,13 @@ var _CharacterModel = class _CharacterModel {
|
|
941
972
|
});
|
942
973
|
}
|
943
974
|
updateAnimation(targetAnimation) {
|
975
|
+
if (this.isPostDoubleJump) {
|
976
|
+
if (targetAnimation === 6 /* doubleJump */) {
|
977
|
+
targetAnimation = 4 /* air */;
|
978
|
+
} else {
|
979
|
+
this.isPostDoubleJump = false;
|
980
|
+
}
|
981
|
+
}
|
944
982
|
if (this.currentAnimation !== targetAnimation) {
|
945
983
|
this.transitionToAnimation(targetAnimation);
|
946
984
|
}
|
@@ -1031,16 +1069,21 @@ var _CharacterModel = class _CharacterModel {
|
|
1031
1069
|
});
|
1032
1070
|
return animationClip;
|
1033
1071
|
}
|
1034
|
-
async setAnimationFromFile(animationFileUrl, animationType) {
|
1072
|
+
async setAnimationFromFile(animationFileUrl, animationType, loop = true, playbackSpeed = 1) {
|
1035
1073
|
return new Promise(async (resolve, reject) => {
|
1036
1074
|
const animation = await this.config.characterModelLoader.load(animationFileUrl, "animation");
|
1037
1075
|
const cleanAnimation = this.cleanAnimationClips(this.mesh, animation);
|
1038
1076
|
if (typeof animation !== "undefined" && cleanAnimation instanceof AnimationClip) {
|
1039
1077
|
this.animations[animationType] = this.animationMixer.clipAction(cleanAnimation);
|
1040
1078
|
this.animations[animationType].stop();
|
1079
|
+
this.animations[animationType].timeScale = playbackSpeed;
|
1041
1080
|
if (animationType === 0 /* idle */) {
|
1042
1081
|
this.animations[animationType].play();
|
1043
1082
|
}
|
1083
|
+
if (!loop) {
|
1084
|
+
this.animations[animationType].setLoop(LoopRepeat, 1);
|
1085
|
+
this.animations[animationType].clampWhenFinished = true;
|
1086
|
+
}
|
1044
1087
|
resolve();
|
1045
1088
|
} else {
|
1046
1089
|
reject(`failed to load ${animationType} from ${animationFileUrl}`);
|
@@ -1048,20 +1091,30 @@ var _CharacterModel = class _CharacterModel {
|
|
1048
1091
|
});
|
1049
1092
|
}
|
1050
1093
|
transitionToAnimation(targetAnimation, transitionDuration = 0.15) {
|
1051
|
-
if (!this.mesh)
|
1094
|
+
if (!this.mesh) {
|
1052
1095
|
return;
|
1096
|
+
}
|
1053
1097
|
const currentAction = this.animations[this.currentAnimation];
|
1054
1098
|
this.currentAnimation = targetAnimation;
|
1055
1099
|
const targetAction = this.animations[targetAnimation];
|
1056
|
-
if (!targetAction)
|
1100
|
+
if (!targetAction) {
|
1057
1101
|
return;
|
1102
|
+
}
|
1058
1103
|
if (currentAction) {
|
1059
|
-
currentAction.enabled = true;
|
1060
1104
|
currentAction.fadeOut(transitionDuration);
|
1061
1105
|
}
|
1062
|
-
|
1106
|
+
targetAction.reset();
|
1107
|
+
if (!targetAction.isRunning()) {
|
1063
1108
|
targetAction.play();
|
1064
|
-
|
1109
|
+
}
|
1110
|
+
if (targetAnimation === 6 /* doubleJump */) {
|
1111
|
+
targetAction.getMixer().addEventListener("finished", (_event) => {
|
1112
|
+
if (this.currentAnimation === 6 /* doubleJump */) {
|
1113
|
+
this.isPostDoubleJump = true;
|
1114
|
+
this.updateAnimation(6 /* doubleJump */);
|
1115
|
+
}
|
1116
|
+
});
|
1117
|
+
}
|
1065
1118
|
targetAction.enabled = true;
|
1066
1119
|
targetAction.fadeIn(transitionDuration);
|
1067
1120
|
}
|
@@ -1473,15 +1526,189 @@ import { Euler as Euler2, Group as Group2, Quaternion as Quaternion5, Vector3 as
|
|
1473
1526
|
|
1474
1527
|
// src/character/LocalController.ts
|
1475
1528
|
import { Euler, Line3, Matrix4, Quaternion as Quaternion2, Ray, Raycaster as Raycaster2, Vector3 as Vector35 } from "three";
|
1529
|
+
|
1530
|
+
// src/tweakpane/blades/characterControlsFolder.ts
|
1531
|
+
var characterControllerValues = {
|
1532
|
+
gravity: 28,
|
1533
|
+
jumpForce: 18,
|
1534
|
+
doubleJumpForce: 17.7,
|
1535
|
+
coyoteJump: 120,
|
1536
|
+
airResistance: 0.5,
|
1537
|
+
groundResistance: 0,
|
1538
|
+
airControlModifier: 0.05,
|
1539
|
+
groundWalkControl: 0.75,
|
1540
|
+
groundRunControl: 1,
|
1541
|
+
baseControlMultiplier: 200,
|
1542
|
+
minimumSurfaceAngle: 0.905
|
1543
|
+
};
|
1544
|
+
var characterControllerOptions = {
|
1545
|
+
gravity: { min: 1, max: 100, step: 0.05 },
|
1546
|
+
jumpForce: { min: 1, max: 50, step: 0.05 },
|
1547
|
+
doubleJumpForce: { min: 1, max: 50, step: 0.05 },
|
1548
|
+
coyoteJump: { min: 60, max: 200, step: 1 },
|
1549
|
+
airResistance: { min: 0.01, max: 0.9, step: 0.01 },
|
1550
|
+
groundResistance: { min: -100, max: 0, step: 1 },
|
1551
|
+
airControlModifier: { min: 1e-3, max: 0.15, step: 0.01 },
|
1552
|
+
groundWalkControl: { min: 0.1, max: 1.5, step: 0.01 },
|
1553
|
+
groundRunControl: { min: 0.5, max: 2, step: 0.01 },
|
1554
|
+
baseControlMultiplier: { min: 150, max: 300, step: 1 },
|
1555
|
+
minimumSurfaceAngle: { min: 0.254, max: 1, step: 1e-3 }
|
1556
|
+
};
|
1557
|
+
var CharacterControlsFolder = class {
|
1558
|
+
constructor(parentFolder, expand = false) {
|
1559
|
+
this.characterData = {
|
1560
|
+
position: "(0, 0, 0)",
|
1561
|
+
onGround: "false",
|
1562
|
+
canJump: "false",
|
1563
|
+
canDoubleJump: "false",
|
1564
|
+
jumpCount: "0",
|
1565
|
+
coyoteTime: "false",
|
1566
|
+
coyoteJumped: "false"
|
1567
|
+
};
|
1568
|
+
this.folder = parentFolder.addFolder({ title: "character", expanded: expand });
|
1569
|
+
this.folder.addBinding(this.characterData, "position", { readonly: true });
|
1570
|
+
this.folder.addBinding(this.characterData, "onGround", { readonly: true });
|
1571
|
+
this.folder.addBinding(this.characterData, "canJump", { readonly: true });
|
1572
|
+
this.folder.addBinding(this.characterData, "canDoubleJump", { readonly: true });
|
1573
|
+
this.folder.addBinding(this.characterData, "jumpCount", { readonly: true });
|
1574
|
+
this.folder.addBinding(this.characterData, "coyoteTime", { readonly: true });
|
1575
|
+
this.folder.addBinding(this.characterData, "coyoteJumped", { readonly: true });
|
1576
|
+
this.folder.addBinding(
|
1577
|
+
characterControllerValues,
|
1578
|
+
"gravity",
|
1579
|
+
characterControllerOptions.gravity
|
1580
|
+
);
|
1581
|
+
this.folder.addBinding(
|
1582
|
+
characterControllerValues,
|
1583
|
+
"jumpForce",
|
1584
|
+
characterControllerOptions.jumpForce
|
1585
|
+
);
|
1586
|
+
this.folder.addBinding(
|
1587
|
+
characterControllerValues,
|
1588
|
+
"doubleJumpForce",
|
1589
|
+
characterControllerOptions.doubleJumpForce
|
1590
|
+
);
|
1591
|
+
this.folder.addBinding(
|
1592
|
+
characterControllerValues,
|
1593
|
+
"coyoteJump",
|
1594
|
+
characterControllerOptions.coyoteJump
|
1595
|
+
);
|
1596
|
+
this.folder.addBinding(
|
1597
|
+
characterControllerValues,
|
1598
|
+
"airResistance",
|
1599
|
+
characterControllerOptions.airResistance
|
1600
|
+
);
|
1601
|
+
this.folder.addBinding(
|
1602
|
+
characterControllerValues,
|
1603
|
+
"groundResistance",
|
1604
|
+
characterControllerOptions.groundResistance
|
1605
|
+
);
|
1606
|
+
this.folder.addBinding(
|
1607
|
+
characterControllerValues,
|
1608
|
+
"airControlModifier",
|
1609
|
+
characterControllerOptions.airControlModifier
|
1610
|
+
);
|
1611
|
+
this.folder.addBinding(
|
1612
|
+
characterControllerValues,
|
1613
|
+
"groundWalkControl",
|
1614
|
+
characterControllerOptions.groundWalkControl
|
1615
|
+
);
|
1616
|
+
this.folder.addBinding(
|
1617
|
+
characterControllerValues,
|
1618
|
+
"groundRunControl",
|
1619
|
+
characterControllerOptions.groundRunControl
|
1620
|
+
);
|
1621
|
+
this.folder.addBinding(
|
1622
|
+
characterControllerValues,
|
1623
|
+
"baseControlMultiplier",
|
1624
|
+
characterControllerOptions.baseControlMultiplier
|
1625
|
+
);
|
1626
|
+
this.folder.addBinding(
|
1627
|
+
characterControllerValues,
|
1628
|
+
"minimumSurfaceAngle",
|
1629
|
+
characterControllerOptions.minimumSurfaceAngle
|
1630
|
+
);
|
1631
|
+
}
|
1632
|
+
setupChangeEvent(localController) {
|
1633
|
+
this.folder.on("change", (e) => {
|
1634
|
+
const target = e.target.key;
|
1635
|
+
if (!target)
|
1636
|
+
return;
|
1637
|
+
switch (target) {
|
1638
|
+
case "gravity": {
|
1639
|
+
const value = e.value;
|
1640
|
+
localController.gravity = value * -1;
|
1641
|
+
break;
|
1642
|
+
}
|
1643
|
+
case "jumpForce": {
|
1644
|
+
const value = e.value;
|
1645
|
+
localController.jumpForce = value;
|
1646
|
+
break;
|
1647
|
+
}
|
1648
|
+
case "doubleJumpForce": {
|
1649
|
+
const value = e.value;
|
1650
|
+
localController.doubleJumpForce = value;
|
1651
|
+
break;
|
1652
|
+
}
|
1653
|
+
case "coyoteJump": {
|
1654
|
+
const value = e.value;
|
1655
|
+
localController.coyoteTimeThreshold = value;
|
1656
|
+
break;
|
1657
|
+
}
|
1658
|
+
case "airResistance": {
|
1659
|
+
const value = e.value;
|
1660
|
+
localController.airResistance = value;
|
1661
|
+
break;
|
1662
|
+
}
|
1663
|
+
case "groundResistance": {
|
1664
|
+
const value = e.value;
|
1665
|
+
localController.groundResistance = 0.99999999 + value * 1e-6;
|
1666
|
+
break;
|
1667
|
+
}
|
1668
|
+
case "airControlModifier": {
|
1669
|
+
const value = e.value;
|
1670
|
+
localController.airControlModifier = value;
|
1671
|
+
break;
|
1672
|
+
}
|
1673
|
+
case "groundWalkControl": {
|
1674
|
+
const value = e.value;
|
1675
|
+
localController.groundWalkControl = value;
|
1676
|
+
break;
|
1677
|
+
}
|
1678
|
+
case "groundRunControl": {
|
1679
|
+
const value = e.value;
|
1680
|
+
localController.groundRunControl = value;
|
1681
|
+
break;
|
1682
|
+
}
|
1683
|
+
case "baseControlMultiplier": {
|
1684
|
+
const value = e.value;
|
1685
|
+
localController.baseControl = value;
|
1686
|
+
break;
|
1687
|
+
}
|
1688
|
+
case "minimumSurfaceAngle": {
|
1689
|
+
const value = e.value;
|
1690
|
+
localController.minimumSurfaceAngle = value;
|
1691
|
+
break;
|
1692
|
+
}
|
1693
|
+
default:
|
1694
|
+
break;
|
1695
|
+
}
|
1696
|
+
});
|
1697
|
+
}
|
1698
|
+
update(localController) {
|
1699
|
+
const { x, y, z } = localController.latestPosition;
|
1700
|
+
this.characterData.position = `(${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)})`;
|
1701
|
+
this.characterData.onGround = `${localController.characterOnGround}`;
|
1702
|
+
this.characterData.canJump = `${localController.canJump || localController.coyoteTime ? "true" : "false"}`;
|
1703
|
+
this.characterData.canDoubleJump = `${localController.canDoubleJump}`;
|
1704
|
+
this.characterData.jumpCount = `${localController.jumpCounter}`;
|
1705
|
+
this.characterData.coyoteTime = `${localController.coyoteTime}`;
|
1706
|
+
this.characterData.coyoteJumped = `${localController.coyoteJumped}`;
|
1707
|
+
}
|
1708
|
+
};
|
1709
|
+
|
1710
|
+
// src/character/LocalController.ts
|
1476
1711
|
var downVector = new Vector35(0, -1, 0);
|
1477
|
-
var airResistance = 0.5;
|
1478
|
-
var groundResistance = 0.99999999;
|
1479
|
-
var airControlModifier = 0.05;
|
1480
|
-
var groundWalkControl = 0.75;
|
1481
|
-
var groundRunControl = 1;
|
1482
|
-
var baseControl = 200;
|
1483
|
-
var collisionDetectionSteps = 15;
|
1484
|
-
var minimumSurfaceAngle = 0.9;
|
1485
1712
|
var LocalController = class {
|
1486
1713
|
constructor(config) {
|
1487
1714
|
this.config = config;
|
@@ -1489,12 +1716,26 @@ var LocalController = class {
|
|
1489
1716
|
radius: 0.4,
|
1490
1717
|
segment: new Line3(new Vector35(), new Vector35(0, 1.05, 0))
|
1491
1718
|
};
|
1492
|
-
this.gravity = -
|
1493
|
-
this.jumpForce =
|
1494
|
-
this.
|
1495
|
-
this.
|
1719
|
+
this.gravity = -characterControllerValues.gravity;
|
1720
|
+
this.jumpForce = characterControllerValues.jumpForce;
|
1721
|
+
this.doubleJumpForce = characterControllerValues.doubleJumpForce;
|
1722
|
+
this.coyoteTimeThreshold = characterControllerValues.coyoteJump;
|
1496
1723
|
this.canJump = true;
|
1724
|
+
this.canDoubleJump = true;
|
1725
|
+
this.coyoteJumped = false;
|
1726
|
+
this.doubleJumpUsed = false;
|
1727
|
+
this.jumpCounter = 0;
|
1728
|
+
this.airResistance = characterControllerValues.airResistance;
|
1729
|
+
this.groundResistance = 0.99999999 + characterControllerValues.groundResistance * 1e-7;
|
1730
|
+
this.airControlModifier = characterControllerValues.airControlModifier;
|
1731
|
+
this.groundWalkControl = characterControllerValues.groundWalkControl;
|
1732
|
+
this.groundRunControl = characterControllerValues.groundRunControl;
|
1733
|
+
this.baseControl = characterControllerValues.baseControlMultiplier;
|
1734
|
+
this.minimumSurfaceAngle = characterControllerValues.minimumSurfaceAngle;
|
1735
|
+
this.latestPosition = new Vector35();
|
1497
1736
|
this.characterOnGround = false;
|
1737
|
+
this.coyoteTime = false;
|
1738
|
+
this.collisionDetectionSteps = 15;
|
1498
1739
|
this.characterWasOnGround = false;
|
1499
1740
|
this.characterAirborneSince = 0;
|
1500
1741
|
this.currentHeight = 0;
|
@@ -1521,6 +1762,9 @@ var LocalController = class {
|
|
1521
1762
|
this.surfaceTempVector5 = new Vector35();
|
1522
1763
|
this.surfaceTempRay = new Ray();
|
1523
1764
|
this.lastFrameSurfaceState = null;
|
1765
|
+
this.jumpPressed = false;
|
1766
|
+
// Tracks if the jump button is pressed
|
1767
|
+
this.jumpReleased = true;
|
1524
1768
|
this.networkState = {
|
1525
1769
|
id: this.config.id,
|
1526
1770
|
position: { x: 0, y: 0, z: 0 },
|
@@ -1538,6 +1782,9 @@ var LocalController = class {
|
|
1538
1782
|
this.jump = this.config.keyInputManager.jump;
|
1539
1783
|
this.anyDirection = this.config.keyInputManager.anyDirection || ((_e = this.config.virtualJoystick) == null ? void 0 : _e.hasDirection) || false;
|
1540
1784
|
this.conflictingDirections = this.config.keyInputManager.conflictingDirection;
|
1785
|
+
if (!this.jump) {
|
1786
|
+
this.jumpReleased = true;
|
1787
|
+
}
|
1541
1788
|
}
|
1542
1789
|
update() {
|
1543
1790
|
this.updateControllerState();
|
@@ -1556,10 +1803,10 @@ var LocalController = class {
|
|
1556
1803
|
if (this.anyDirection) {
|
1557
1804
|
this.updateRotation();
|
1558
1805
|
}
|
1559
|
-
for (let i = 0; i < collisionDetectionSteps; i++) {
|
1806
|
+
for (let i = 0; i < this.collisionDetectionSteps; i++) {
|
1560
1807
|
this.updatePosition(
|
1561
1808
|
this.config.timeManager.deltaTime,
|
1562
|
-
this.config.timeManager.deltaTime / collisionDetectionSteps,
|
1809
|
+
this.config.timeManager.deltaTime / this.collisionDetectionSteps,
|
1563
1810
|
i
|
1564
1811
|
);
|
1565
1812
|
}
|
@@ -1573,6 +1820,9 @@ var LocalController = class {
|
|
1573
1820
|
return 0 /* idle */;
|
1574
1821
|
const jumpHeight = this.characterVelocity.y > 0 ? 0.2 : 1.8;
|
1575
1822
|
if (this.currentHeight > jumpHeight && !this.characterOnGround) {
|
1823
|
+
if (this.doubleJumpUsed) {
|
1824
|
+
return 6 /* doubleJump */;
|
1825
|
+
}
|
1576
1826
|
return 4 /* air */;
|
1577
1827
|
}
|
1578
1828
|
if (this.conflictingDirections) {
|
@@ -1632,31 +1882,59 @@ var LocalController = class {
|
|
1632
1882
|
const frameRotation = angularSpeed * this.config.timeManager.deltaTime;
|
1633
1883
|
this.config.character.quaternion.rotateTowards(rotationQuaternion, frameRotation);
|
1634
1884
|
}
|
1635
|
-
|
1636
|
-
const resistance = this.characterOnGround ? groundResistance : airResistance;
|
1637
|
-
const speedFactor = Math.pow(1 - resistance, deltaTime);
|
1638
|
-
this.characterVelocity.multiplyScalar(speedFactor);
|
1639
|
-
const acceleration = this.tempVector.set(0, 0, 0);
|
1885
|
+
processJump(currentAcceleration, deltaTime) {
|
1640
1886
|
if (this.characterOnGround) {
|
1887
|
+
this.coyoteJumped = false;
|
1888
|
+
this.canDoubleJump = false;
|
1889
|
+
this.doubleJumpUsed = false;
|
1890
|
+
this.jumpCounter = 0;
|
1641
1891
|
if (!this.jump) {
|
1892
|
+
this.canDoubleJump = !this.doubleJumpUsed && this.jumpReleased && this.jumpCounter === 1;
|
1642
1893
|
this.canJump = true;
|
1894
|
+
this.jumpReleased = true;
|
1643
1895
|
}
|
1644
|
-
if (this.jump && this.canJump) {
|
1645
|
-
|
1896
|
+
if (this.jump && this.canJump && this.jumpReleased) {
|
1897
|
+
currentAcceleration.y += this.jumpForce / deltaTime;
|
1646
1898
|
this.canJump = false;
|
1899
|
+
this.jumpReleased = false;
|
1900
|
+
this.jumpCounter++;
|
1647
1901
|
} else {
|
1648
|
-
if (this.currentSurfaceAngle.y < minimumSurfaceAngle) {
|
1649
|
-
|
1902
|
+
if (this.currentSurfaceAngle.y < this.minimumSurfaceAngle) {
|
1903
|
+
currentAcceleration.y += this.gravity;
|
1650
1904
|
}
|
1651
1905
|
}
|
1652
|
-
} else if (this.jump && this.coyoteTime) {
|
1653
|
-
acceleration.y += this.jumpForce / deltaTime;
|
1654
|
-
this.canJump = false;
|
1655
1906
|
} else {
|
1656
|
-
|
1657
|
-
|
1907
|
+
if (this.jump && !this.coyoteJumped && this.coyoteTime) {
|
1908
|
+
this.coyoteJumped = true;
|
1909
|
+
currentAcceleration.y += this.jumpForce / deltaTime;
|
1910
|
+
this.canJump = false;
|
1911
|
+
this.jumpReleased = false;
|
1912
|
+
this.jumpCounter++;
|
1913
|
+
} else if (this.jump && this.canDoubleJump) {
|
1914
|
+
currentAcceleration.y += this.doubleJumpForce / deltaTime;
|
1915
|
+
this.doubleJumpUsed = true;
|
1916
|
+
this.jumpReleased = false;
|
1917
|
+
this.jumpCounter++;
|
1918
|
+
} else {
|
1919
|
+
currentAcceleration.y += this.gravity;
|
1920
|
+
this.canJump = false;
|
1921
|
+
}
|
1922
|
+
}
|
1923
|
+
if (!this.jump) {
|
1924
|
+
this.jumpReleased = true;
|
1925
|
+
if (!this.characterOnGround) {
|
1926
|
+
currentAcceleration.y += this.gravity;
|
1927
|
+
}
|
1658
1928
|
}
|
1659
|
-
|
1929
|
+
}
|
1930
|
+
applyControls(deltaTime) {
|
1931
|
+
const resistance = this.characterOnGround ? this.groundResistance : this.airResistance;
|
1932
|
+
const speedFactor = Math.pow(1 - resistance, deltaTime);
|
1933
|
+
this.characterVelocity.multiplyScalar(speedFactor);
|
1934
|
+
const acceleration = this.tempVector.set(0, 0, 0);
|
1935
|
+
this.canDoubleJump = !this.doubleJumpUsed && this.jumpReleased && this.jumpCounter === 1;
|
1936
|
+
this.processJump(acceleration, deltaTime);
|
1937
|
+
const control = (this.characterOnGround ? this.run ? this.groundRunControl : this.groundWalkControl : this.airControlModifier) * this.baseControl;
|
1660
1938
|
const controlAcceleration = this.tempVector2.set(0, 0, 0);
|
1661
1939
|
if (!this.conflictingDirections) {
|
1662
1940
|
if (this.forward) {
|
@@ -1709,10 +1987,18 @@ var LocalController = class {
|
|
1709
1987
|
this.config.character.position.copy(avatarSegment.start);
|
1710
1988
|
const deltaCollisionPosition = avatarSegment.start.sub(positionBeforeCollisions);
|
1711
1989
|
this.characterOnGround = deltaCollisionPosition.y > 0;
|
1990
|
+
if (this.characterOnGround) {
|
1991
|
+
this.doubleJumpUsed = false;
|
1992
|
+
this.jumpCounter = 0;
|
1993
|
+
}
|
1712
1994
|
if (this.characterWasOnGround && !this.characterOnGround) {
|
1713
1995
|
this.characterAirborneSince = Date.now();
|
1714
1996
|
}
|
1997
|
+
if (!this.jump) {
|
1998
|
+
this.jumpReleased = true;
|
1999
|
+
}
|
1715
2000
|
this.coyoteTime = this.characterVelocity.y < 0 && !this.characterOnGround && Date.now() - this.characterAirborneSince < this.coyoteTimeThreshold;
|
2001
|
+
this.latestPosition = this.config.character.position.clone();
|
1716
2002
|
this.characterWasOnGround = this.characterOnGround;
|
1717
2003
|
}
|
1718
2004
|
getMovementFromSurfaces(userPosition, deltaTime) {
|
@@ -1797,6 +2083,9 @@ var LocalController = class {
|
|
1797
2083
|
this.characterVelocity.y = 0;
|
1798
2084
|
this.config.character.position.y = 3;
|
1799
2085
|
this.characterOnGround = false;
|
2086
|
+
this.doubleJumpUsed = false;
|
2087
|
+
this.jumpReleased = true;
|
2088
|
+
this.jumpCounter = 0;
|
1800
2089
|
}
|
1801
2090
|
};
|
1802
2091
|
|
@@ -1917,6 +2206,9 @@ var CharacterManager = class {
|
|
1917
2206
|
this.group.add(character);
|
1918
2207
|
this.localCharacterSpawned = true;
|
1919
2208
|
}
|
2209
|
+
setupTweakPane(tweakPane) {
|
2210
|
+
tweakPane.setupCharacterController(this.localController);
|
2211
|
+
}
|
1920
2212
|
spawnRemoteCharacter(id, username, characterDescription, spawnPosition = new Vector38(), spawnRotation = new Euler2()) {
|
1921
2213
|
const character = new Character({
|
1922
2214
|
username,
|
@@ -3109,6 +3401,7 @@ var TweakPane = class {
|
|
3109
3401
|
this.character = new CharacterFolder(this.gui, false);
|
3110
3402
|
this.environment = new EnvironmentFolder(this.gui, false);
|
3111
3403
|
this.camera = new CameraFolder(this.gui, false);
|
3404
|
+
this.characterControls = new CharacterControlsFolder(this.gui, false);
|
3112
3405
|
this.toneMappingFolder.folder.hidden = rendererValues.toneMapping === 5 ? false : true;
|
3113
3406
|
this.export = this.gui.addFolder({ title: "import / export", expanded: false });
|
3114
3407
|
window.addEventListener("keydown", this.processKey.bind(this));
|
@@ -3162,12 +3455,18 @@ var TweakPane = class {
|
|
3162
3455
|
setupCamPane(cameraManager) {
|
3163
3456
|
this.camera.setupChangeEvent(cameraManager);
|
3164
3457
|
}
|
3458
|
+
setupCharacterController(localController) {
|
3459
|
+
this.characterControls.setupChangeEvent(localController);
|
3460
|
+
}
|
3165
3461
|
updateStats(timeManager) {
|
3166
3462
|
this.renderStatsFolder.update(this.renderer, this.composer, timeManager);
|
3167
3463
|
}
|
3168
3464
|
updateCameraData(cameraManager) {
|
3169
3465
|
this.camera.update(cameraManager);
|
3170
3466
|
}
|
3467
|
+
updateCharacterData(localController) {
|
3468
|
+
this.characterControls.update(localController);
|
3469
|
+
}
|
3171
3470
|
formatDateForFilename() {
|
3172
3471
|
const date = /* @__PURE__ */ new Date();
|
3173
3472
|
const year = date.getFullYear();
|