@mml-io/3d-web-client-core 0.12.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,7 +31,13 @@ export declare class CameraManager {
31
31
  private lerpTarget;
32
32
  private lerpFactor;
33
33
  private lerpDuration;
34
+ private hasTouchControl;
35
+ private lastTouchX;
36
+ private lastTouchY;
34
37
  constructor(targetElement: HTMLElement, collisionsManager: CollisionsManager, initialPhi?: number, initialTheta?: number);
38
+ private onTouchStart;
39
+ private onTouchMove;
40
+ private onTouchEnd;
35
41
  private onMouseDown;
36
42
  private onMouseUp;
37
43
  private onMouseMove;
package/build/index.js CHANGED
@@ -82,6 +82,169 @@ var EventHandlerCollection = class _EventHandlerCollection {
82
82
  }
83
83
  };
84
84
 
85
+ // src/input/VirtualJoystick.ts
86
+ var _VirtualJoystick = class _VirtualJoystick {
87
+ constructor(attrs) {
88
+ this.left = false;
89
+ this.right = false;
90
+ this.up = false;
91
+ this.down = false;
92
+ this.hasDirection = false;
93
+ this.clearFlags = () => {
94
+ this.left = false;
95
+ this.right = false;
96
+ this.up = false;
97
+ this.down = false;
98
+ this.hasDirection = false;
99
+ this.control.style.left = `${this.width / 2 - this.inner_radius}px`;
100
+ this.control.style.top = `${this.height / 2 - this.inner_radius}px`;
101
+ };
102
+ this.radius = attrs.radius || 50;
103
+ this.inner_radius = attrs.inner_radius || this.radius / 2;
104
+ this.anchor = attrs.anchor || "left";
105
+ this.x = attrs.x || 0;
106
+ this.y = attrs.y || 0;
107
+ this.width = attrs.width || this.radius * 2 + this.inner_radius * 2;
108
+ this.height = attrs.height || this.radius * 2 + this.inner_radius * 2;
109
+ this.mouse_support = this.checkTouch() || attrs.mouse_support === true;
110
+ this.initializeJoystick();
111
+ }
112
+ static checkForTouch() {
113
+ try {
114
+ document.createEvent("TouchEvent");
115
+ return true;
116
+ } catch (e) {
117
+ return false;
118
+ }
119
+ }
120
+ static isTouchOnJoystick(touch) {
121
+ if (!_VirtualJoystick.JOYSTICK_DIV) {
122
+ return false;
123
+ }
124
+ const divRect = _VirtualJoystick.JOYSTICK_DIV.getBoundingClientRect();
125
+ return touch.clientX >= divRect.left && touch.clientX <= divRect.right && touch.clientY >= divRect.top && touch.clientY <= divRect.bottom;
126
+ }
127
+ checkTouch() {
128
+ return _VirtualJoystick.checkForTouch();
129
+ }
130
+ initializeJoystick() {
131
+ if (!_VirtualJoystick.JOYSTICK_DIV) {
132
+ this.div = document.createElement("div");
133
+ const divStyle = this.div.style;
134
+ divStyle.display = this.checkTouch() || this.mouse_support ? "visible" : "none";
135
+ divStyle.position = "fixed";
136
+ if (this.anchor === "left") {
137
+ divStyle.left = `${this.x}px`;
138
+ } else {
139
+ divStyle.right = `${this.x}px`;
140
+ }
141
+ divStyle.bottom = `${this.y}px`;
142
+ divStyle.width = `${this.width}px`;
143
+ divStyle.height = `${this.height}px`;
144
+ divStyle.zIndex = "10000";
145
+ divStyle.overflow = "hidden";
146
+ document.body.appendChild(this.div);
147
+ _VirtualJoystick.JOYSTICK_DIV = this.div;
148
+ }
149
+ this.setupBaseAndControl();
150
+ this.bindEvents();
151
+ }
152
+ setupBaseAndControl() {
153
+ this.base = document.createElement("span");
154
+ let divStyle = this.base.style;
155
+ divStyle.width = `${this.radius * 2}px`;
156
+ divStyle.height = `${this.radius * 2}px`;
157
+ divStyle.position = "absolute";
158
+ divStyle.left = `${this.width / 2 - this.radius}px`;
159
+ divStyle.bottom = `${this.height / 2 - this.radius}px`;
160
+ divStyle.borderRadius = "50%";
161
+ divStyle.borderColor = "rgba(200,200,200,0.5)";
162
+ divStyle.borderWidth = "2px";
163
+ divStyle.borderStyle = "solid";
164
+ this.div.appendChild(this.base);
165
+ this.control = document.createElement("span");
166
+ divStyle = this.control.style;
167
+ divStyle.width = `${this.inner_radius * 2}px`;
168
+ divStyle.height = `${this.inner_radius * 2}px`;
169
+ divStyle.position = "absolute";
170
+ divStyle.left = `${this.width / 2 - this.inner_radius}px`;
171
+ divStyle.bottom = `${this.height / 2 - this.inner_radius}px`;
172
+ divStyle.borderRadius = "50%";
173
+ divStyle.backgroundColor = "rgba(200,200,200,0.3)";
174
+ divStyle.borderWidth = "1px";
175
+ divStyle.borderColor = "rgba(200,200,200,0.8)";
176
+ divStyle.borderStyle = "solid";
177
+ this.div.appendChild(this.control);
178
+ }
179
+ bindEvents() {
180
+ this.div.addEventListener("touchstart", this.handleTouchStart.bind(this), false);
181
+ this.div.addEventListener("touchmove", this.handleTouchMove.bind(this), false);
182
+ this.div.addEventListener("touchend", this.clearFlags.bind(this), false);
183
+ if (this.mouse_support) {
184
+ this.div.addEventListener("mousedown", this.handleMouseDown.bind(this));
185
+ this.div.addEventListener("mousemove", this.handleMouseMove.bind(this));
186
+ this.div.addEventListener("mouseup", this.handleMouseUp.bind(this));
187
+ }
188
+ }
189
+ handleTouchStart(evt) {
190
+ evt.preventDefault();
191
+ if (evt.touches) {
192
+ const touch = evt.touches[0];
193
+ this.updateControlAndDirection(touch);
194
+ }
195
+ }
196
+ handleTouchMove(evt) {
197
+ evt.preventDefault();
198
+ if (evt.touches.length > 0) {
199
+ const touch = evt.touches[0];
200
+ this.updateControlAndDirection(touch);
201
+ }
202
+ }
203
+ handleMouseDown(evt) {
204
+ evt.preventDefault();
205
+ this.updateControlAndDirection(evt);
206
+ }
207
+ handleMouseMove(evt) {
208
+ if (evt.buttons === 1) {
209
+ evt.preventDefault();
210
+ this.updateControlAndDirection(evt);
211
+ }
212
+ }
213
+ handleMouseUp(evt) {
214
+ this.clearFlags();
215
+ }
216
+ updateControlAndDirection(input) {
217
+ const rect = this.div.getBoundingClientRect();
218
+ const dx = input.clientX - (rect.left + this.div.offsetWidth / 2);
219
+ const dy = input.clientY - (rect.top + this.div.offsetHeight / 2);
220
+ const distance = Math.min(Math.sqrt(dx * dx + dy * dy), this.radius);
221
+ const angle = Math.atan2(dy, dx);
222
+ const constrainedX = distance * Math.cos(angle);
223
+ const constrainedY = distance * Math.sin(angle);
224
+ this.control.style.left = `${constrainedX + this.width / 2 - this.inner_radius}px`;
225
+ this.control.style.top = `${constrainedY + this.height / 2 - this.inner_radius}px`;
226
+ this.up = this.isUp(dx, dy);
227
+ this.down = this.isDown(dx, dy);
228
+ this.left = this.isLeft(dx, dy);
229
+ this.right = this.isRight(dx, dy);
230
+ this.hasDirection = this.up || this.down || this.left || this.right;
231
+ }
232
+ isUp(dx, dy) {
233
+ return dy < 0 && Math.abs(dx) <= 2 * Math.abs(dy);
234
+ }
235
+ isDown(dx, dy) {
236
+ return dy > 0 && Math.abs(dx) <= 2 * Math.abs(dy);
237
+ }
238
+ isLeft(dx, dy) {
239
+ return dx < 0 && Math.abs(dy) <= 2 * Math.abs(dx);
240
+ }
241
+ isRight(dx, dy) {
242
+ return dx > 0 && Math.abs(dy) <= 2 * Math.abs(dx);
243
+ }
244
+ };
245
+ _VirtualJoystick.JOYSTICK_DIV = null;
246
+ var VirtualJoystick = _VirtualJoystick;
247
+
85
248
  // src/tweakpane/tweakPaneActivity.ts
86
249
  var isTweakpaneActive = false;
87
250
  function setTweakpaneActive(status) {
@@ -119,6 +282,9 @@ var CameraManager = class {
119
282
  this.lerpTarget = new Vector32();
120
283
  this.lerpFactor = 0;
121
284
  this.lerpDuration = 2.1;
285
+ this.hasTouchControl = false;
286
+ this.lastTouchX = 0;
287
+ this.lastTouchY = 0;
122
288
  this.phi = initialPhi;
123
289
  this.targetPhi = initialPhi;
124
290
  this.theta = initialTheta;
@@ -126,12 +292,61 @@ var CameraManager = class {
126
292
  this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);
127
293
  this.camera.position.set(0, 1.4, -this.initialDistance);
128
294
  this.rayCaster = new Raycaster();
295
+ this.hasTouchControl = VirtualJoystick.checkForTouch();
129
296
  this.eventHandlerCollection = EventHandlerCollection.create([
130
297
  [targetElement, "mousedown", this.onMouseDown.bind(this)],
131
298
  [document, "mouseup", this.onMouseUp.bind(this)],
132
299
  [document, "mousemove", this.onMouseMove.bind(this)],
133
300
  [targetElement, "wheel", this.onMouseWheel.bind(this)]
134
301
  ]);
302
+ if (this.hasTouchControl) {
303
+ this.eventHandlerCollection.add(targetElement, "touchstart", this.onTouchStart.bind(this), {
304
+ passive: false
305
+ });
306
+ this.eventHandlerCollection.add(document, "touchmove", this.onTouchMove.bind(this), {
307
+ passive: false
308
+ });
309
+ this.eventHandlerCollection.add(document, "touchend", this.onTouchEnd.bind(this), {
310
+ passive: false
311
+ });
312
+ }
313
+ }
314
+ onTouchStart(evt) {
315
+ Array.from(evt.touches).forEach((touch) => {
316
+ if (!VirtualJoystick.isTouchOnJoystick(touch)) {
317
+ this.dragging = true;
318
+ this.lastTouchX = touch.clientX;
319
+ this.lastTouchY = touch.clientY;
320
+ }
321
+ });
322
+ }
323
+ onTouchMove(evt) {
324
+ if (!this.dragging || getTweakpaneActive()) {
325
+ return;
326
+ }
327
+ evt.preventDefault();
328
+ const touch = Array.from(evt.touches).find((t) => !VirtualJoystick.isTouchOnJoystick(t));
329
+ if (touch) {
330
+ const dx = touch.clientX - this.lastTouchX;
331
+ const dy = touch.clientY - this.lastTouchY;
332
+ this.lastTouchX = touch.clientX;
333
+ this.lastTouchY = touch.clientY;
334
+ if (this.targetTheta !== null && this.targetPhi !== null) {
335
+ this.targetTheta += dx * 0.01;
336
+ this.targetPhi -= dy * 0.01;
337
+ this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));
338
+ }
339
+ }
340
+ }
341
+ onTouchEnd(evt) {
342
+ if (this.dragging) {
343
+ const touchEnded = Array.from(evt.changedTouches).some(
344
+ (t) => !VirtualJoystick.isTouchOnJoystick(t)
345
+ );
346
+ if (touchEnded) {
347
+ this.dragging = false;
348
+ }
349
+ }
135
350
  }
136
351
  onMouseDown() {
137
352
  this.dragging = true;
@@ -619,7 +834,7 @@ var CharacterModel = class {
619
834
  }
620
835
  setMainMesh(mainMesh) {
621
836
  this.mesh = mainMesh;
622
- this.mesh.position.set(0, -0.4, 0);
837
+ this.mesh.position.set(0, -0.44, 0);
623
838
  this.mesh.traverse((child) => {
624
839
  if (child.type === "SkinnedMesh") {
625
840
  child.castShadow = true;
@@ -694,8 +909,9 @@ var CharacterModel = class {
694
909
  }
695
910
  });
696
911
  animationClip.tracks = animationClip.tracks.filter((track) => {
697
- const trackName = track.name.split(".")[0];
698
- return availableBones.has(trackName);
912
+ const [trackName, trackProperty] = track.name.split(".");
913
+ const shouldAnimate = availableBones.has(trackName) && trackProperty !== "position" && trackProperty !== "scale";
914
+ return shouldAnimate;
699
915
  });
700
916
  return animationClip;
701
917
  }
@@ -958,10 +1174,10 @@ var fontScale = 5;
958
1174
  var defaultLabelColor = new Color2(0);
959
1175
  var defaultFontColor = new Color2(16777215);
960
1176
  var defaultLabelAlignment = "center" /* center */;
961
- var defaultLabelFontSize = 9;
1177
+ var defaultLabelFontSize = 8;
962
1178
  var defaultLabelPadding = 0;
963
1179
  var defaultLabelWidth = 0.25;
964
- var defaultLabelHeight = 0.125;
1180
+ var defaultLabelHeight = 0.1;
965
1181
  var defaultLabelCastShadows = true;
966
1182
  var tooltipGeometry = new PlaneGeometry(1, 1, 1, 1);
967
1183
  var CharacterTooltip = class extends Mesh3 {
@@ -970,7 +1186,7 @@ var CharacterTooltip = class extends Mesh3 {
970
1186
  this.visibleOpacity = 0.85;
971
1187
  this.targetOpacity = 0;
972
1188
  this.fadingSpeed = 0.02;
973
- this.secondsToFadeOut = 15;
1189
+ this.secondsToFadeOut = 10;
974
1190
  this.props = {
975
1191
  content: "",
976
1192
  alignment: defaultLabelAlignment,
@@ -1027,7 +1243,7 @@ var CharacterTooltip = class extends Mesh3 {
1027
1243
  this.tooltipMaterial.needsUpdate = true;
1028
1244
  this.scale.x = width / (100 * fontScale);
1029
1245
  this.scale.y = height / (100 * fontScale);
1030
- this.position.y = 1.6;
1246
+ this.position.y = 1.4;
1031
1247
  }
1032
1248
  setText(text, temporary = false) {
1033
1249
  this.redrawText(text);
@@ -1573,7 +1789,7 @@ var CharacterManager = class {
1573
1789
  );
1574
1790
  this.localCharacter.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);
1575
1791
  this.localCharacter.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);
1576
- (_a = character.tooltip) == null ? void 0 : _a.setText(`${id}`);
1792
+ (_a = character.tooltip) == null ? void 0 : _a.setText(`${id}`, true);
1577
1793
  this.group.add(character);
1578
1794
  this.localCharacterSpawned = true;
1579
1795
  }
@@ -1795,9 +2011,17 @@ var KeyInputManager = class {
1795
2011
  this.shouldCaptureKeyPress = shouldCaptureKeyPress;
1796
2012
  this.keys = /* @__PURE__ */ new Map();
1797
2013
  this.eventHandlerCollection = new EventHandlerCollection();
2014
+ this.directionJoystick = null;
1798
2015
  this.eventHandlerCollection.add(document, "keydown", this.onKeyDown.bind(this));
1799
2016
  this.eventHandlerCollection.add(document, "keyup", this.onKeyUp.bind(this));
1800
2017
  this.eventHandlerCollection.add(window, "blur", this.handleUnfocus.bind(this));
2018
+ this.directionJoystick = new VirtualJoystick({
2019
+ radius: 70,
2020
+ inner_radius: 20,
2021
+ x: 70,
2022
+ y: 0,
2023
+ mouse_support: false
2024
+ });
1801
2025
  }
1802
2026
  handleUnfocus(_event) {
1803
2027
  this.keys.clear();
@@ -1821,19 +2045,19 @@ var KeyInputManager = class {
1821
2045
  return this.keys.get(key) || false;
1822
2046
  }
1823
2047
  isMovementKeyPressed() {
1824
- return ["w" /* W */, "a" /* A */, "s" /* S */, "d" /* D */].some((key) => this.isKeyPressed(key));
2048
+ return ["w" /* W */, "a" /* A */, "s" /* S */, "d" /* D */].some((key) => this.isKeyPressed(key)) || this.directionJoystick.hasDirection;
1825
2049
  }
1826
2050
  get forward() {
1827
- return this.isKeyPressed("w" /* W */);
2051
+ return this.isKeyPressed("w" /* W */) || this.directionJoystick.up;
1828
2052
  }
1829
2053
  get backward() {
1830
- return this.isKeyPressed("s" /* S */);
2054
+ return this.isKeyPressed("s" /* S */) || this.directionJoystick.down;
1831
2055
  }
1832
2056
  get left() {
1833
- return this.isKeyPressed("a" /* A */);
2057
+ return this.isKeyPressed("a" /* A */) || this.directionJoystick.left;
1834
2058
  }
1835
2059
  get right() {
1836
- return this.isKeyPressed("d" /* D */);
2060
+ return this.isKeyPressed("d" /* D */) || this.directionJoystick.right;
1837
2061
  }
1838
2062
  get run() {
1839
2063
  return this.isKeyPressed("shift" /* SHIFT */);
@@ -2341,7 +2565,7 @@ var ppssaoOptions = {
2341
2565
  };
2342
2566
  var n8ssaoValues = {
2343
2567
  enabled: true,
2344
- halfRes: false,
2568
+ halfRes: true,
2345
2569
  aoRadius: 5,
2346
2570
  distanceFalloff: 3,
2347
2571
  intensity: 1,