@needle-tools/engine 2.58.4-pre → 2.59.1-pre
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/CHANGELOG.md +17 -0
- package/dist/needle-engine.js +11763 -11653
- package/dist/needle-engine.umd.cjs +218 -210
- package/lib/engine/debug/debug.d.ts +1 -1
- package/lib/engine/debug/debug_overlay.js +11 -0
- package/lib/engine/debug/debug_overlay.js.map +1 -1
- package/lib/engine/engine_addressables.js +8 -5
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_element.js +2 -1
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_gameobject.d.ts +3 -1
- package/lib/engine/engine_gameobject.js +31 -2
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_hot_reload.d.ts +2 -0
- package/lib/engine/engine_hot_reload.js +15 -2
- package/lib/engine/engine_hot_reload.js.map +1 -1
- package/lib/engine/engine_input.d.ts +2 -0
- package/lib/engine/engine_input.js +16 -0
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_networking_utils.d.ts +1 -1
- package/lib/engine/engine_networking_utils.js +4 -0
- package/lib/engine/engine_networking_utils.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -1
- package/lib/engine/engine_utils.js +5 -2
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_gameobject_data.js +6 -4
- package/lib/engine/extensions/NEEDLE_gameobject_data.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js +6 -6
- package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
- package/lib/engine-components/Animator.js +10 -6
- package/lib/engine-components/Animator.js.map +1 -1
- package/lib/engine-components/AnimatorController.d.ts +1 -1
- package/lib/engine-components/AnimatorController.js +19 -12
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/Component.d.ts +1 -0
- package/lib/engine-components/Component.js +4 -1
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/Networking.d.ts +1 -1
- package/lib/engine-components/OrbitControls.d.ts +7 -2
- package/lib/engine-components/OrbitControls.js +34 -15
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ParticleSystem.d.ts +1 -0
- package/lib/engine-components/ParticleSystem.js +15 -2
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/SpectatorCamera.d.ts +2 -0
- package/lib/engine-components/SpectatorCamera.js +18 -2
- package/lib/engine-components/SpectatorCamera.js.map +1 -1
- package/lib/engine-components/SyncedRoom.d.ts +1 -0
- package/lib/engine-components/SyncedRoom.js +3 -0
- package/lib/engine-components/SyncedRoom.js.map +1 -1
- package/lib/engine-components/WebXR.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.js +5 -2
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +1 -0
- package/lib/engine-components/timeline/TimelineTracks.js +14 -3
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.d.ts +10 -5
- package/lib/engine-components/ui/EventSystem.js +45 -41
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/engine-components/ui/Raycaster.js +2 -2
- package/lib/engine-components/ui/Raycaster.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/engine/debug/debug_overlay.ts +17 -5
- package/src/engine/engine_addressables.ts +8 -5
- package/src/engine/engine_element.ts +2 -1
- package/src/engine/engine_gameobject.ts +34 -3
- package/src/engine/engine_hot_reload.ts +16 -5
- package/src/engine/engine_input.ts +11 -0
- package/src/engine/engine_networking_utils.ts +4 -0
- package/src/engine/engine_utils.ts +4 -3
- package/src/engine/extensions/NEEDLE_gameobject_data.ts +11 -6
- package/src/engine/extensions/NEEDLE_lightmaps.ts +6 -5
- package/src/engine-components/Animator.ts +12 -9
- package/src/engine-components/AnimatorController.ts +20 -13
- package/src/engine-components/Component.ts +5 -1
- package/src/engine-components/OrbitControls.ts +44 -19
- package/src/engine-components/ParticleSystem.ts +18 -3
- package/src/engine-components/SpectatorCamera.ts +9 -2
- package/src/engine-components/SyncedRoom.ts +5 -1
- package/src/engine-components/WebXR.ts +1 -0
- package/src/engine-components/timeline/PlayableDirector.ts +4 -2
- package/src/engine-components/timeline/TimelineTracks.ts +15 -4
- package/src/engine-components/ui/EventSystem.ts +48 -42
- package/src/engine-components/ui/Raycaster.ts +2 -2
|
@@ -8,6 +8,8 @@ import { getParam, isMobileDevice } from "../engine/engine_utils";
|
|
|
8
8
|
|
|
9
9
|
import { Box3, Object3D, PerspectiveCamera, Vector2, Vector3 } from "three";
|
|
10
10
|
import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
|
11
|
+
import { EventSystem, EventSystemEvents } from "./ui/EventSystem";
|
|
12
|
+
import { transformWithEsbuild } from "vite";
|
|
11
13
|
|
|
12
14
|
const freeCam = getParam("freecam");
|
|
13
15
|
|
|
@@ -60,11 +62,40 @@ export class OrbitControls extends Behaviour {
|
|
|
60
62
|
private _enableTime: number = 0; // use to disable double click when double clicking on UI
|
|
61
63
|
private _startedListeningToKeyEvents: boolean = false;
|
|
62
64
|
|
|
65
|
+
private _eventSystem?: EventSystem;
|
|
66
|
+
private _afterHandleInputFn?: any;
|
|
67
|
+
|
|
68
|
+
targetElement: HTMLElement | null = null;
|
|
69
|
+
|
|
63
70
|
awake(): void {
|
|
64
71
|
this._lookTargetPosition = new Vector3();
|
|
65
72
|
this._startedListeningToKeyEvents = false;
|
|
66
73
|
}
|
|
67
74
|
|
|
75
|
+
start() {
|
|
76
|
+
if (this._controls) {
|
|
77
|
+
const camGo = GameObject.getComponent(this.gameObject, Camera);
|
|
78
|
+
if (camGo && !this.setFromTargetPosition()) {
|
|
79
|
+
if (this.debugLog)
|
|
80
|
+
console.log("NO TARGET");
|
|
81
|
+
const forward = new Vector3(0, 0, -1).applyMatrix4(camGo.cam.matrixWorld);
|
|
82
|
+
this.setTarget(forward, true);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
this.startCoroutine(this.startRaycastDelayed());
|
|
86
|
+
|
|
87
|
+
this._eventSystem = EventSystem.get(this.context) ?? undefined;
|
|
88
|
+
if (this._eventSystem) {
|
|
89
|
+
this._afterHandleInputFn = this.afterHandleInput.bind(this);
|
|
90
|
+
this._eventSystem.addEventListener(EventSystemEvents.AfterHandleInput, this._afterHandleInputFn!);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
onDestroy() {
|
|
95
|
+
this._controls?.dispose();
|
|
96
|
+
this._eventSystem?.removeEventListener(EventSystemEvents.AfterHandleInput, this._afterHandleInputFn!);
|
|
97
|
+
}
|
|
98
|
+
|
|
68
99
|
onEnable() {
|
|
69
100
|
this._enableTime = this.context.time.time;
|
|
70
101
|
const camGo = GameObject.getComponent(this.gameObject, Camera);
|
|
@@ -73,7 +104,10 @@ export class OrbitControls extends Behaviour {
|
|
|
73
104
|
console.assert(cam !== null && cam !== undefined, "Missing camera", this);
|
|
74
105
|
if (cam)
|
|
75
106
|
this._cameraObject = cam;
|
|
76
|
-
|
|
107
|
+
// Using the parent if possible to make it possible to disable input on the canvas
|
|
108
|
+
// for having HTML content behind it and still receive input
|
|
109
|
+
const element = this.targetElement ?? this.context.domElement;
|
|
110
|
+
this._controls = new ThreeOrbitControls(cam!, element);
|
|
77
111
|
if (defaultKeys === undefined) defaultKeys = { ...this._controls.keys };
|
|
78
112
|
}
|
|
79
113
|
|
|
@@ -115,6 +149,7 @@ export class OrbitControls extends Behaviour {
|
|
|
115
149
|
this._controls.listenToKeyEvents(window.document.body);
|
|
116
150
|
}
|
|
117
151
|
}
|
|
152
|
+
|
|
118
153
|
}
|
|
119
154
|
|
|
120
155
|
onDisable() {
|
|
@@ -125,21 +160,11 @@ export class OrbitControls extends Behaviour {
|
|
|
125
160
|
}
|
|
126
161
|
}
|
|
127
162
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
start() {
|
|
133
|
-
if (this._controls) {
|
|
134
|
-
const camGo = GameObject.getComponent(this.gameObject, Camera);
|
|
135
|
-
if (camGo && !this.setFromTargetPosition()) {
|
|
136
|
-
if (this.debugLog)
|
|
137
|
-
console.log("NO TARGET");
|
|
138
|
-
const forward = new Vector3(0, 0, -1).applyMatrix4(camGo.cam.matrixWorld);
|
|
139
|
-
this.setTarget(forward, true);
|
|
140
|
-
}
|
|
163
|
+
private _shouldDisable : boolean = false;
|
|
164
|
+
private afterHandleInput() {
|
|
165
|
+
if (this._controls && this._eventSystem) {
|
|
166
|
+
this._shouldDisable = this._eventSystem.hasActiveUI;
|
|
141
167
|
}
|
|
142
|
-
this.startCoroutine(this.startRaycastDelayed());
|
|
143
168
|
}
|
|
144
169
|
|
|
145
170
|
// we need to wait one frame (when starting the scene for the very first time)
|
|
@@ -221,7 +246,7 @@ export class OrbitControls extends Behaviour {
|
|
|
221
246
|
if (this._controls && !this.context.isInXR) {
|
|
222
247
|
if (this.debugLog)
|
|
223
248
|
this._controls.domElement = this.context.renderer.domElement;
|
|
224
|
-
this._controls.enabled =
|
|
249
|
+
this._controls.enabled = !this._shouldDisable;
|
|
225
250
|
this._controls.update();
|
|
226
251
|
}
|
|
227
252
|
}
|
|
@@ -309,11 +334,11 @@ export class OrbitControls extends Behaviour {
|
|
|
309
334
|
for (const object of objects)
|
|
310
335
|
box.expandByObject(object);
|
|
311
336
|
|
|
312
|
-
box.getSize(
|
|
313
|
-
box.getCenter(
|
|
337
|
+
box.getSize(size);
|
|
338
|
+
box.getCenter(center);
|
|
314
339
|
|
|
315
340
|
const maxSize = Math.max(size.x, size.y, size.z);
|
|
316
|
-
const fitHeightDistance = maxSize / (2 * Math.atan(
|
|
341
|
+
const fitHeightDistance = maxSize / (2 * Math.atan(Math.PI * camera.fov / 360));
|
|
317
342
|
const fitWidthDistance = fitHeightDistance / camera.aspect;
|
|
318
343
|
const distance = fitOffset * Math.max(fitHeightDistance, fitWidthDistance);
|
|
319
344
|
|
|
@@ -345,7 +345,6 @@ class VelocityBehaviour extends ParticleSystemBaseBehaviour {
|
|
|
345
345
|
|
|
346
346
|
initialize(particle: Particle): void {
|
|
347
347
|
const factor = 1 + this.scaleFactorDiff;
|
|
348
|
-
|
|
349
348
|
particle.startSpeed = this.system.main.startSpeed.evaluate(Math.random(), Math.random()) * factor;
|
|
350
349
|
particle.velocity.copy(this.system.shape.getDirection(particle.position)).multiplyScalar(particle.startSpeed);
|
|
351
350
|
if (this.system.inheritVelocity?.enabled) {
|
|
@@ -414,6 +413,10 @@ class VelocityBehaviour extends ParticleSystemBaseBehaviour {
|
|
|
414
413
|
// const factor = this.system.worldScale.x;
|
|
415
414
|
limitVelocityOverLifetime.apply(particle.position, baseVelocity, particle.velocity, particle.size, t01, delta, 1);
|
|
416
415
|
}
|
|
416
|
+
|
|
417
|
+
if (this.system.worldspace) {
|
|
418
|
+
particle.velocity.multiply(this.system.worldScale);
|
|
419
|
+
}
|
|
417
420
|
}
|
|
418
421
|
}
|
|
419
422
|
|
|
@@ -421,14 +424,19 @@ const $colorLerpFactor = Symbol("colorLerpFactor");
|
|
|
421
424
|
class ColorBehaviour extends ParticleSystemBaseBehaviour {
|
|
422
425
|
type: string = "NeedleColor";
|
|
423
426
|
|
|
424
|
-
initialize(
|
|
425
|
-
|
|
427
|
+
initialize(_particle: Particle): void {
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
private _init(particle: Particle) {
|
|
431
|
+
const col = this.system.main.startColor.evaluate(Math.random());
|
|
426
432
|
particle.startColor.set(col.r, col.g, col.b, col.alpha);
|
|
427
433
|
particle.color.copy(particle.startColor);
|
|
428
434
|
particle[$colorLerpFactor] = Math.random();
|
|
429
435
|
}
|
|
430
436
|
|
|
431
437
|
update(particle: Particle, _delta: number): void {
|
|
438
|
+
if (particle.age === 0)
|
|
439
|
+
this._init(particle);
|
|
432
440
|
if (this.system.colorOverLifetime.enabled) {
|
|
433
441
|
const t = particle.age / particle.life;
|
|
434
442
|
const col = this.system.colorOverLifetime.color.evaluate(t, particle[$colorLerpFactor]);
|
|
@@ -767,6 +775,13 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
767
775
|
this.addSubParticleSystems();
|
|
768
776
|
}
|
|
769
777
|
|
|
778
|
+
onDestroy(): void {
|
|
779
|
+
this._container?.removeFromParent();
|
|
780
|
+
this._batchSystem?.removeFromParent();
|
|
781
|
+
this._particleSystem?.emitter.removeFromParent();
|
|
782
|
+
this._particleSystem?.dispose();
|
|
783
|
+
}
|
|
784
|
+
|
|
770
785
|
onEnable() {
|
|
771
786
|
if (this.inheritVelocity)
|
|
772
787
|
this.inheritVelocity.system = this;
|
|
@@ -15,6 +15,7 @@ import { RaycastOptions } from "../engine/engine_physics";
|
|
|
15
15
|
import { RoomEvents } from "../engine/engine_networking";
|
|
16
16
|
import { ICamera } from "../engine/engine_types";
|
|
17
17
|
import { IModel } from "../engine/engine_networking_types";
|
|
18
|
+
import { serializable } from "../engine/engine_serialization";
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
export enum SpectatorMode {
|
|
@@ -28,6 +29,10 @@ export class SpectatorCamera extends Behaviour {
|
|
|
28
29
|
|
|
29
30
|
cam: Camera | null = null;
|
|
30
31
|
|
|
32
|
+
/** when enabled pressing F will send a request to all connected users to follow me, ESC to stop */
|
|
33
|
+
@serializable()
|
|
34
|
+
useKeys: boolean = true;
|
|
35
|
+
|
|
31
36
|
private _mode: SpectatorMode = SpectatorMode.FirstPerson;
|
|
32
37
|
|
|
33
38
|
get mode() { return this._mode; }
|
|
@@ -448,7 +453,8 @@ class SpectatorSelectionController {
|
|
|
448
453
|
this.context = context;
|
|
449
454
|
this.spectator = spectator;
|
|
450
455
|
console.log("Click other avatars or cameras to follow them. Press ESC to exit spectator mode.");
|
|
451
|
-
|
|
456
|
+
this.context.domElement.addEventListener("keydown", (evt) => {
|
|
457
|
+
if(!this.spectator.useKeys) return;
|
|
452
458
|
const key = evt.key;
|
|
453
459
|
if (key === "Escape") {
|
|
454
460
|
this.spectator.stopSpectating();
|
|
@@ -544,7 +550,8 @@ class SpectatorCamNetworking {
|
|
|
544
550
|
this.context.connection.beginListen("spectator-follower-changed", this._followerEventMethod);
|
|
545
551
|
this.context.connection.beginListen("spectator-request-follow", this._requestFollowMethod);
|
|
546
552
|
this.context.connection.beginListen(RoomEvents.JoinedRoom, this._joinedRoomMethod);
|
|
547
|
-
|
|
553
|
+
this.context.domElement.addEventListener("keydown", evt => {
|
|
554
|
+
if(!this.spectator.useKeys) return;
|
|
548
555
|
if (evt.key === "f") {
|
|
549
556
|
this.onRequestFollowMe();
|
|
550
557
|
}
|
|
@@ -20,8 +20,12 @@ export class SyncedRoom extends Behaviour {
|
|
|
20
20
|
|
|
21
21
|
private _roomPrefix?: string;
|
|
22
22
|
|
|
23
|
+
public get RoomPrefix(): string | undefined {
|
|
24
|
+
return this._roomPrefix;
|
|
25
|
+
}
|
|
26
|
+
|
|
23
27
|
awake() {
|
|
24
|
-
if(debug) console.log("Room", this.roomName, this.urlParameterName, this.joinRandomRoom, this.requireRoomParameter, this.autoRejoin);
|
|
28
|
+
if (debug) console.log("Room", this.roomName, this.urlParameterName, this.joinRandomRoom, this.requireRoomParameter, this.autoRejoin);
|
|
25
29
|
if (this._roomPrefix === undefined) {
|
|
26
30
|
this._roomPrefix = this.roomName;
|
|
27
31
|
this.roomName = "";
|
|
@@ -126,8 +126,9 @@ export class PlayableDirector extends Behaviour {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
onDestroy(): void {
|
|
129
|
-
for (const
|
|
130
|
-
track
|
|
129
|
+
for (const tracks of this._allTracks) {
|
|
130
|
+
for (const track of tracks)
|
|
131
|
+
track.onDestroy?.();
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
|
|
@@ -151,6 +152,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
stop() {
|
|
155
|
+
for(const track of this._audioTracks) track.stop();
|
|
154
156
|
if (this._isPlaying) {
|
|
155
157
|
this._time = 0;
|
|
156
158
|
this._isPlaying = false;
|
|
@@ -182,7 +182,7 @@ export class AnimationTrackHandler extends TrackHandler {
|
|
|
182
182
|
clip.tracks.push(track);
|
|
183
183
|
this.createPositionInterpolant(clip, clipModel, track);
|
|
184
184
|
}
|
|
185
|
-
else if(!foundRotationTrack){
|
|
185
|
+
else if (!foundRotationTrack) {
|
|
186
186
|
const trackName = clip.tracks[0].name.substring(0, indexOfProperty) + ".quaternion";
|
|
187
187
|
if (debug) console.warn("Create quaternion track", objName, targetObj);
|
|
188
188
|
const rot = targetObj.quaternion;
|
|
@@ -442,6 +442,8 @@ export class AnimationTrackHandler extends TrackHandler {
|
|
|
442
442
|
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
+
const muteAudioTracks = getParam("mutetimeline");
|
|
446
|
+
|
|
445
447
|
export class AudioTrackHandler extends TrackHandler {
|
|
446
448
|
models: Array<Models.ClipModel> = [];
|
|
447
449
|
|
|
@@ -469,7 +471,8 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
469
471
|
const audio = new THREE.Audio(this.listener);
|
|
470
472
|
audio.setVolume(model.asset.volume);
|
|
471
473
|
const loader = new THREE.AudioLoader();
|
|
472
|
-
|
|
474
|
+
if (debug)
|
|
475
|
+
console.log(path, this.director.sourceId);
|
|
473
476
|
loader.load(path, (buffer) => {
|
|
474
477
|
audio.setBuffer(buffer);
|
|
475
478
|
audio.loop = model.asset.loop;
|
|
@@ -495,18 +498,26 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
495
498
|
}
|
|
496
499
|
}
|
|
497
500
|
|
|
501
|
+
stop() {
|
|
502
|
+
for (let i = 0; i < this.audio.length; i++) {
|
|
503
|
+
const audio = this.audio[i];
|
|
504
|
+
if (audio?.isPlaying)
|
|
505
|
+
audio.stop();
|
|
506
|
+
}
|
|
507
|
+
}
|
|
498
508
|
evaluate(time: number) {
|
|
509
|
+
if(muteAudioTracks) return;
|
|
499
510
|
if (this.track.muted) return;
|
|
500
511
|
for (let i = 0; i < this.models.length; i++) {
|
|
501
512
|
const model = this.models[i];
|
|
502
513
|
const audio = this.audio[i];
|
|
503
514
|
if (time >= model.start && time <= model.end) {
|
|
504
|
-
if (this.director.
|
|
515
|
+
if (this.director.isPlaying == false) {
|
|
505
516
|
if (audio.isPlaying)
|
|
506
517
|
audio.stop();
|
|
507
518
|
if (this.lastTime === time) continue;
|
|
508
519
|
}
|
|
509
|
-
if (!audio.isPlaying) {
|
|
520
|
+
else if (!audio.isPlaying) {
|
|
510
521
|
audio.offset = model.clipIn + (time - model.start) * model.timeScale;
|
|
511
522
|
audio.play();
|
|
512
523
|
}
|
|
@@ -16,6 +16,11 @@ import { $shadowDomOwner } from "./BaseUIComponent";
|
|
|
16
16
|
|
|
17
17
|
const debug = getParam("debugeventsystem");
|
|
18
18
|
|
|
19
|
+
export enum EventSystemEvents {
|
|
20
|
+
BeforeHandleInput = "BeforeHandleInput",
|
|
21
|
+
AfterHandleInput = "AfterHandleInput",
|
|
22
|
+
}
|
|
23
|
+
|
|
19
24
|
export class EventSystem extends Behaviour {
|
|
20
25
|
|
|
21
26
|
|
|
@@ -45,6 +50,16 @@ export class EventSystem extends Behaviour {
|
|
|
45
50
|
return this._eventSystemMap.get(context)!;
|
|
46
51
|
}
|
|
47
52
|
|
|
53
|
+
static get(ctx: Context): EventSystem | null {
|
|
54
|
+
const systems = this._eventSystemMap.get(ctx);
|
|
55
|
+
if (systems && systems.length > 0) return systems[0];
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static get instance(): EventSystem | null {
|
|
60
|
+
return this.systems[0];
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
//@ts-ignore
|
|
49
64
|
static ensureUpdateMeshUI(instance, context: Context) {
|
|
50
65
|
MeshUIHelper.update(instance, context);
|
|
@@ -53,12 +68,8 @@ export class EventSystem extends Behaviour {
|
|
|
53
68
|
MeshUIHelper.markDirty();
|
|
54
69
|
}
|
|
55
70
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private orbitControl: OrbitControls | null = null;
|
|
61
|
-
private orbitControlWasEnabled: boolean = false;
|
|
71
|
+
// private orbitControl: OrbitControls | null = null;
|
|
72
|
+
// private orbitControlWasEnabled: boolean = false;
|
|
62
73
|
private raycaster: Raycaster[] = [];
|
|
63
74
|
|
|
64
75
|
constructor() {
|
|
@@ -66,6 +77,9 @@ export class EventSystem extends Behaviour {
|
|
|
66
77
|
EventSystem.systems.push(this);
|
|
67
78
|
}
|
|
68
79
|
|
|
80
|
+
get hasActiveUI() { return this.currentActiveMeshUIComponents.length > 0; }
|
|
81
|
+
get isHoveringObjects() { return this.objectsHoveredThisFrame.length > 0; }
|
|
82
|
+
|
|
69
83
|
onDestroy(): void {
|
|
70
84
|
EventSystem.systems.splice(EventSystem.systems.indexOf(this), 1);
|
|
71
85
|
}
|
|
@@ -90,7 +104,7 @@ export class EventSystem extends Behaviour {
|
|
|
90
104
|
private _selectStartFn?: any;
|
|
91
105
|
private _selectEndFn?: any;
|
|
92
106
|
private _selectUpdateFn?: any;
|
|
93
|
-
private
|
|
107
|
+
private _handleEventFn?: any;
|
|
94
108
|
|
|
95
109
|
onEnable(): void {
|
|
96
110
|
|
|
@@ -150,9 +164,14 @@ export class EventSystem extends Behaviour {
|
|
|
150
164
|
WebXRController.addEventListener(ControllerEvents.Update, this._selectUpdateFn);
|
|
151
165
|
|
|
152
166
|
// TODO: unregister
|
|
153
|
-
this.
|
|
154
|
-
this.context.pre_update_callbacks.push(this.
|
|
155
|
-
|
|
167
|
+
this._handleEventFn ??= this.onHandleEvents.bind(this);
|
|
168
|
+
this.context.pre_update_callbacks.push(this._handleEventFn);
|
|
169
|
+
// If we subscribe to those events here we get duplicate event handling for e.g. button clicks
|
|
170
|
+
// I think this was done as a workaround for the InputField where we needed to handle the event within the browser event method
|
|
171
|
+
// without it (via pre_update callbacks) we handle the events outside of the browser loop delayed which doesnt work for some cases
|
|
172
|
+
// this.context.input.addEventListener(InputEvents.PointerDown, this._handleEventFn);
|
|
173
|
+
// this.context.input.addEventListener(InputEvents.PointerUp, this._handleEventFn);
|
|
174
|
+
// this.context.input.addEventListener(InputEvents.PointerMove, this._handleEventFn);
|
|
156
175
|
}
|
|
157
176
|
|
|
158
177
|
onDisable(): void {
|
|
@@ -160,8 +179,10 @@ export class EventSystem extends Behaviour {
|
|
|
160
179
|
WebXRController.removeEventListener(ControllerEvents.SelectEnd, this._selectEndFn);
|
|
161
180
|
WebXRController.removeEventListener(ControllerEvents.Update, this._selectUpdateFn);
|
|
162
181
|
|
|
163
|
-
this.context.pre_update_callbacks.splice(this.context.pre_update_callbacks.indexOf(this.
|
|
164
|
-
this.context.input.removeEventListener(InputEvents.PointerDown, this.
|
|
182
|
+
this.context.pre_update_callbacks.splice(this.context.pre_update_callbacks.indexOf(this._handleEventFn), 1);
|
|
183
|
+
// this.context.input.removeEventListener(InputEvents.PointerDown, this._handleEventFn);
|
|
184
|
+
// this.context.input.removeEventListener(InputEvents.PointerUp, this._handleEventFn);
|
|
185
|
+
// this.context.input.removeEventListener(InputEvents.PointerMove, this._handleEventFn);
|
|
165
186
|
}
|
|
166
187
|
|
|
167
188
|
|
|
@@ -180,7 +201,8 @@ export class EventSystem extends Behaviour {
|
|
|
180
201
|
|
|
181
202
|
private _didMove: boolean = false;
|
|
182
203
|
|
|
183
|
-
|
|
204
|
+
|
|
205
|
+
onHandleEvents() {
|
|
184
206
|
this.objectsHoveredThisFrame.length = 0;
|
|
185
207
|
this.resetMeshUIStates();
|
|
186
208
|
|
|
@@ -196,7 +218,6 @@ export class EventSystem extends Behaviour {
|
|
|
196
218
|
this._didMove = true;
|
|
197
219
|
}
|
|
198
220
|
|
|
199
|
-
const hits = this.performRaycast(null);
|
|
200
221
|
let pointerId = 0;
|
|
201
222
|
for (const i of this.context.input.foreachPointerId()) {
|
|
202
223
|
const isDown = this.context.input.getPointerDown(i);
|
|
@@ -206,6 +227,7 @@ export class EventSystem extends Behaviour {
|
|
|
206
227
|
break;
|
|
207
228
|
}
|
|
208
229
|
}
|
|
230
|
+
|
|
209
231
|
const ptr = this.context.input.getPointerEvent(pointerId);
|
|
210
232
|
// console.log(ptr);
|
|
211
233
|
const args: PointerEventData = new PointerEventData(ptr);
|
|
@@ -215,42 +237,25 @@ export class EventSystem extends Behaviour {
|
|
|
215
237
|
args.isDown = this.context.input.getPointerDown(pointerId);
|
|
216
238
|
args.isUp = this.context.input.getPointerUp(pointerId);
|
|
217
239
|
args.isPressed = this.context.input.getPointerPressed(pointerId);
|
|
218
|
-
|
|
219
|
-
|
|
240
|
+
if (debug && args.isClicked) console.log("CLICK", pointerId);
|
|
241
|
+
|
|
242
|
+
const hits = this.performRaycast(null);
|
|
220
243
|
if (!hits) return;
|
|
244
|
+
this.lastPointerEvent = args;
|
|
221
245
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (this.context.input.mouseDown && this.currentActiveMeshUIComponents.length > 0 && this.context.mainCameraComponent) {
|
|
227
|
-
orbitControlComponent = GameObject.getComponent(this.context.mainCameraComponent.gameObject, OrbitControls) ?? null;
|
|
228
|
-
if (orbitControlComponent) {
|
|
229
|
-
previousOrbitControlState = orbitControlComponent.enabled;
|
|
230
|
-
orbitControlComponent.enabled = false;
|
|
231
|
-
}
|
|
246
|
+
const evt = {
|
|
247
|
+
sender: this,
|
|
248
|
+
args: args,
|
|
249
|
+
hasActiveUI: this.currentActiveMeshUIComponents.length > 0,
|
|
232
250
|
}
|
|
233
|
-
|
|
234
|
-
// if (args.isClicked)
|
|
235
|
-
// console.log(this.guid, ...hits);
|
|
251
|
+
this.dispatchEvent(new CustomEvent(EventSystemEvents.BeforeHandleInput, { detail: evt }))
|
|
236
252
|
this.handleIntersections(hits, args);
|
|
237
|
-
|
|
238
|
-
if (orbitControlComponent) {
|
|
239
|
-
this.orbitControl = orbitControlComponent;
|
|
240
|
-
if (this.orbitControl?.enabled) {
|
|
241
|
-
this.orbitControlWasEnabled = this.orbitControl.enabled;
|
|
242
|
-
this.orbitControl.enabled = false;
|
|
243
|
-
}
|
|
244
|
-
else if (this.orbitControl && !this.context.input.mousePressed) {
|
|
245
|
-
this.orbitControl.enabled = this.orbitControlWasEnabled;
|
|
246
|
-
this.orbitControl = null;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
253
|
+
this.dispatchEvent(new CustomEvent(EventSystemEvents.AfterHandleInput, { detail: evt }))
|
|
250
254
|
}
|
|
251
255
|
|
|
252
256
|
private _tempComponentsArray: Behaviour[] = [];
|
|
253
257
|
onBeforeRender() {
|
|
258
|
+
|
|
254
259
|
if (this.lastPointerEvent)
|
|
255
260
|
this.lastPointerEvent.used = false;
|
|
256
261
|
else return;
|
|
@@ -374,6 +379,7 @@ export class EventSystem extends Behaviour {
|
|
|
374
379
|
const actualGo = parent[$shadowDomOwner].gameObject;
|
|
375
380
|
if (actualGo) {
|
|
376
381
|
const res = UIRaycastUtils.isInteractable(actualGo, this.out);
|
|
382
|
+
// console.log(actualGo, res);
|
|
377
383
|
if (!res) return this.out.canvasGroup?.interactable ?? false;
|
|
378
384
|
canvasGroup = this.out.canvasGroup ?? null;
|
|
379
385
|
|
|
@@ -9,11 +9,11 @@ export class Raycaster extends Behaviour {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
onEnable(): void {
|
|
12
|
-
EventSystem.
|
|
12
|
+
EventSystem.get(this.context)?.register(this);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
onDisable(): void {
|
|
16
|
-
EventSystem.
|
|
16
|
+
EventSystem.get(this.context)?.unregister(this);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
performRaycast(_opts: RaycastOptions | null = null): THREE.Intersection[] | null {
|