@needle-tools/engine 2.50.0-pre → 2.51.0-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.
Files changed (92) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/needle-engine.d.ts +18 -16
  3. package/dist/needle-engine.js +517 -3590
  4. package/dist/needle-engine.js.map +4 -4
  5. package/dist/needle-engine.min.js +22 -22
  6. package/dist/needle-engine.min.js.map +3 -3
  7. package/lib/engine/engine_addressables.d.ts +1 -1
  8. package/lib/engine/engine_create_objects.d.ts +1 -1
  9. package/lib/engine/engine_element.d.ts +5 -4
  10. package/lib/engine/engine_element.js.map +1 -1
  11. package/lib/engine/engine_element_overlay.d.ts +3 -2
  12. package/lib/engine/engine_element_overlay.js.map +1 -1
  13. package/lib/engine/engine_input.js +15 -9
  14. package/lib/engine/engine_input.js.map +1 -1
  15. package/lib/engine/engine_physics.d.ts +1 -1
  16. package/lib/engine/engine_physics.js +1 -1
  17. package/lib/engine/engine_physics.js.map +1 -1
  18. package/lib/engine/engine_scenetools.d.ts +1 -1
  19. package/lib/engine/engine_serialization_core.d.ts +1 -1
  20. package/lib/engine/engine_setup.d.ts +2 -1
  21. package/lib/engine/engine_setup.js +28 -5
  22. package/lib/engine/engine_setup.js.map +1 -1
  23. package/lib/engine/engine_three_utils.d.ts +1 -0
  24. package/lib/engine/engine_three_utils.js +6 -0
  25. package/lib/engine/engine_three_utils.js.map +1 -1
  26. package/lib/engine/engine_types.d.ts +10 -9
  27. package/lib/engine/engine_utils.d.ts +1 -1
  28. package/lib/engine/extensions/NEEDLE_components.js +15 -11
  29. package/lib/engine/extensions/NEEDLE_components.js.map +1 -1
  30. package/lib/engine/extensions/NEEDLE_lighting_settings.d.ts +1 -1
  31. package/lib/engine-components/Component.d.ts +2 -1
  32. package/lib/engine-components/DragControls.js +10 -4
  33. package/lib/engine-components/DragControls.js.map +1 -1
  34. package/lib/engine-components/Light.js +15 -18
  35. package/lib/engine-components/Light.js.map +1 -1
  36. package/lib/engine-components/OrbitControls.js +19 -14
  37. package/lib/engine-components/OrbitControls.js.map +1 -1
  38. package/lib/engine-components/RigidBody.js +13 -1
  39. package/lib/engine-components/RigidBody.js.map +1 -1
  40. package/lib/engine-components/ScreenCapture.js +2 -0
  41. package/lib/engine-components/ScreenCapture.js.map +1 -1
  42. package/lib/engine-components/VideoPlayer.js +2 -1
  43. package/lib/engine-components/VideoPlayer.js.map +1 -1
  44. package/lib/engine-components/WebARSessionRoot.d.ts +2 -2
  45. package/lib/engine-components/WebARSessionRoot.js.map +1 -1
  46. package/lib/engine-components/WebXR.d.ts +2 -1
  47. package/lib/engine-components/WebXR.js +5 -2
  48. package/lib/engine-components/WebXR.js.map +1 -1
  49. package/lib/engine-components/WebXRAvatar.d.ts +1 -1
  50. package/lib/engine-components/WebXRAvatar.js +6 -1
  51. package/lib/engine-components/WebXRAvatar.js.map +1 -1
  52. package/lib/engine-components/WebXRController.d.ts +2 -1
  53. package/lib/engine-components/WebXRController.js +3 -2
  54. package/lib/engine-components/WebXRController.js.map +1 -1
  55. package/lib/engine-components/WebXRSync.js +5 -0
  56. package/lib/engine-components/WebXRSync.js.map +1 -1
  57. package/lib/engine-components/XRFlag.js +6 -6
  58. package/lib/engine-components/XRFlag.js.map +1 -1
  59. package/lib/engine-components/js-extensions/Vector.js +2 -5
  60. package/lib/engine-components/js-extensions/Vector.js.map +1 -1
  61. package/lib/engine-components/timeline/PlayableDirector.d.ts +1 -1
  62. package/lib/engine-components/timeline/PlayableDirector.js +1 -5
  63. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  64. package/lib/engine-components/ui/EventSystem.d.ts +2 -1
  65. package/lib/engine-components/ui/EventSystem.js +9 -1
  66. package/lib/engine-components/ui/EventSystem.js.map +1 -1
  67. package/lib/engine-components/ui/Utils.d.ts +1 -1
  68. package/package.json +2 -4
  69. package/src/engine/engine_element.ts +5 -5
  70. package/src/engine/engine_element_overlay.ts +2 -2
  71. package/src/engine/engine_input.ts +12 -8
  72. package/src/engine/engine_physics.ts +1 -1
  73. package/src/engine/engine_setup.ts +25 -6
  74. package/src/engine/engine_three_utils.ts +7 -0
  75. package/src/engine/engine_types.ts +3 -3
  76. package/src/engine/extensions/NEEDLE_components.ts +13 -9
  77. package/src/engine-components/Component.ts +1 -1
  78. package/src/engine-components/DragControls.ts +8 -4
  79. package/src/engine-components/Light.ts +14 -14
  80. package/src/engine-components/OrbitControls.ts +19 -14
  81. package/src/engine-components/RigidBody.ts +13 -1
  82. package/src/engine-components/ScreenCapture.ts +1 -0
  83. package/src/engine-components/VideoPlayer.ts +2 -1
  84. package/src/engine-components/WebARSessionRoot.ts +1 -2
  85. package/src/engine-components/WebXR.ts +5 -3
  86. package/src/engine-components/WebXRAvatar.ts +6 -1
  87. package/src/engine-components/WebXRController.ts +4 -3
  88. package/src/engine-components/WebXRSync.ts +6 -1
  89. package/src/engine-components/XRFlag.ts +7 -6
  90. package/src/engine-components/js-extensions/Vector.ts +2 -5
  91. package/src/engine-components/timeline/PlayableDirector.ts +1 -4
  92. package/src/engine-components/ui/EventSystem.ts +12 -1
@@ -3,13 +3,13 @@ import { Behaviour, GameObject } from "./Component";
3
3
  import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls";
4
4
  import { LookAtConstraint } from "./LookAtConstraint";
5
5
  import * as THREE from "three";
6
- import { getWorldPosition } from "../engine/engine_three_utils";
6
+ import { getWorldPosition, setWorldPosition, slerp } from "../engine/engine_three_utils";
7
7
  import { RaycastOptions } from "../engine/engine_physics";
8
8
  import { serializable } from "../engine/engine_serialization_decorator";
9
9
  import { Camera } from "./Camera";
10
- import { getParam } from "../engine/engine_utils";
10
+ import { getParam, isMobileDevice } from "../engine/engine_utils";
11
11
 
12
- const noLimits = getParam("nocamlimits");
12
+ const freeCam = getParam("freecam");
13
13
 
14
14
  export class OrbitControls extends Behaviour {
15
15
  public get controls() {
@@ -40,7 +40,7 @@ export class OrbitControls extends Behaviour {
40
40
  doubleClickToFocus: boolean = true;
41
41
 
42
42
  // remove once slerp works correctly
43
- useSlerp: boolean = false;
43
+ useSlerp: boolean = true;
44
44
 
45
45
 
46
46
  debugLog: boolean = false;
@@ -76,13 +76,21 @@ export class OrbitControls extends Behaviour {
76
76
  }
77
77
 
78
78
  if (this._controls) {
79
+ if (freeCam) {
80
+ this.enablePan = true;
81
+ this.enableZoom = true;
82
+ this.middleClickToFocus = true;
83
+ if(isMobileDevice()) this.doubleClickToFocus = true;
84
+ }
85
+
79
86
  this._controls.enableDamping = this.enableDamping;
87
+ //@ts-ignore (not in types)
80
88
  this._controls.enableKeys = this.enableKeys;
81
89
  this._controls.autoRotate = this.autoRotate;
82
90
  this._controls.autoRotateSpeed = this.autoRotateSpeed;
83
91
  this._controls.enableZoom = this.enableZoom;
84
92
  if (cam?.type === "PerspectiveCamera") {
85
- if (noLimits) {
93
+ if (freeCam) {
86
94
  // dont set limits
87
95
  }
88
96
  else {
@@ -91,7 +99,7 @@ export class OrbitControls extends Behaviour {
91
99
  }
92
100
  }
93
101
  else {
94
- if (noLimits) {
102
+ if (freeCam) {
95
103
  // dont set limits
96
104
  }
97
105
  else {
@@ -183,14 +191,10 @@ export class OrbitControls extends Behaviour {
183
191
 
184
192
  // lerp the camera
185
193
  if (this._lerpCameraToTarget && this._cameraTargetPosition && this._cameraObject) {
186
- if (this.useSlerp && typeof this._cameraObject?.position["slerp"] === "function") {
194
+ // setWorldPosition(this._cameraObject, this._cameraTargetPosition);
195
+ if (this.useSlerp) {
187
196
  const position = this._cameraObject?.position;
188
- position
189
- // TODO fix the offset here
190
- // .sub(this._cameraTargetPosition)
191
- //@ts-ignore
192
- .slerp(this._cameraTargetPosition, step)
193
- // .add(this._cameraTargetPosition);
197
+ slerp(position, this._cameraTargetPosition, step);
194
198
  }
195
199
  else {
196
200
  this._cameraObject?.position.lerp(this._cameraTargetPosition, step);
@@ -210,7 +214,7 @@ export class OrbitControls extends Behaviour {
210
214
  }
211
215
  }
212
216
 
213
- if (this.lookAtConstraint?.locked) this.setFromTargetPosition(0, this.lookAtConstraint01);
217
+ if (!freeCam && this.lookAtConstraint?.locked) this.setFromTargetPosition(0, this.lookAtConstraint01);
214
218
 
215
219
 
216
220
  if (this._controls && !this.context.isInXR) {
@@ -281,6 +285,7 @@ export class OrbitControls extends Behaviour {
281
285
  this._lerpCameraToTarget = true;
282
286
  const pos = getWorldPosition(this.context.mainCamera);
283
287
  this._cameraTargetPosition = pos.clone().sub(this.controls.target).add(this._lookTargetPosition);
288
+ this._cameraObject?.parent?.worldToLocal(this._cameraTargetPosition);
284
289
  }
285
290
  break;
286
291
  }
@@ -3,7 +3,7 @@ import * as THREE from 'three'
3
3
  import { getWorldPosition } from "../engine/engine_three_utils";
4
4
  import { serializable } from "../engine/engine_serialization_decorator";
5
5
  import { Watch } from "../engine/engine_utils";
6
- import { Object3D, Vector3 } from "three";
6
+ import { Matrix4, Object3D, Vector3 } from "three";
7
7
  import { IRigidbody } from "../engine/engine_types";
8
8
  import { CollisionDetectionMode, RigidbodyConstraints } from "../engine/engine_physics.types";
9
9
  import { validate } from "../engine/engine_util_decorator";
@@ -110,6 +110,18 @@ class TransformWatch {
110
110
  this.rotationChanged = true;
111
111
  })
112
112
  }
113
+
114
+ // detect changes in the parent matrix
115
+ const original = this.obj.matrixWorld.multiplyMatrices.bind(this.obj.matrixWorld);
116
+ const lastParentMatrix = new Matrix4();
117
+ this.obj.matrixWorld["multiplyMatrices"] = (parent: Matrix4, matrix: Matrix4) => {
118
+ if (!lastParentMatrix.equals(parent)) {
119
+ this.positionChanged = true;
120
+ this.rotationChanged = true;
121
+ lastParentMatrix.copy(parent);
122
+ }
123
+ return original(parent, matrix);;
124
+ }
113
125
  }
114
126
 
115
127
  stop() {
@@ -40,6 +40,7 @@ declare type ScreenCaptureOptions = {
40
40
  export class ScreenCapture extends Behaviour implements IPointerClickHandler {
41
41
 
42
42
  onPointerClick() {
43
+ if(this.context.connection.isInRoom === false) return;
43
44
  if (this.isReceiving) {
44
45
  if (this.videoPlayer)
45
46
  this.videoPlayer.screenspace = !this.videoPlayer.screenspace;
@@ -290,7 +290,8 @@ export class VideoPlayer extends Behaviour {
290
290
  this._videoTexture.flipY = false;
291
291
  this._videoTexture.encoding = THREE.sRGBEncoding;
292
292
  this.handleBeginPlaying(playAutomatically);
293
- console.log(this);
293
+ if(debug)
294
+ console.log(this);
294
295
  }
295
296
 
296
297
  updateAspect() {
@@ -1,6 +1,5 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
- import { XRSession } from 'three'
3
- import { Matrix4, Object3D, XRPose } from "three";
2
+ import { Matrix4, Object3D } from "three";
4
3
  import { WebAR, WebXR } from "./WebXR";
5
4
  import { InstancingUtil } from "../engine/engine_instancing";
6
5
  import { serializable } from "../engine/engine_serialization_decorator";
@@ -1,4 +1,4 @@
1
- import { ArrayCamera, Color, Euler, EventDispatcher, Group, Matrix4, Mesh, MeshBasicMaterial, Object3D, Quaternion, RingGeometry, Texture, Vector3, XRFrame, XRHitTestSource, XRRigidTransform, XRSession, XRViewerPose } from 'three';
1
+ import { ArrayCamera, Color, Euler, EventDispatcher, Group, Matrix4, Mesh, MeshBasicMaterial, Object3D, Quaternion, RingGeometry, Texture, Vector3 } from 'three';
2
2
  import { ARButton } from '../include/three/ARButton.js';
3
3
  import { VRButton } from '../include/three/VRButton.js';
4
4
 
@@ -7,7 +7,7 @@ import { serializable } from "../engine/engine_serialization_decorator";
7
7
  import { XRSessionMode } from "../engine/engine_setup";
8
8
  import { getWorldPosition, getWorldQuaternion, setWorldPosition, setWorldQuaternion } from "../engine/engine_three_utils";
9
9
  import { INeedleEngineComponent } from "../engine/engine_types";
10
- import { getParam, setOrAddParamsToUrl } from "../engine/engine_utils";
10
+ import { getParam, isMozillaXR, setOrAddParamsToUrl } from "../engine/engine_utils";
11
11
 
12
12
  import { Behaviour, GameObject } from "./Component";
13
13
  import { noVoip } from "./Voip";
@@ -19,6 +19,7 @@ import { XRFlag, XRState, XRStateFlag } from "./XRFlag";
19
19
 
20
20
 
21
21
  export async function detectARSupport() {
22
+ if(isMozillaXR()) return true;
22
23
  if ("xr" in navigator) {
23
24
  //@ts-ignore
24
25
  return (await navigator["xr"].isSessionSupported('immersive-ar')) === true;
@@ -372,6 +373,7 @@ export class WebXR extends Behaviour {
372
373
  // we set layers to sync raycasting and have a similar behaviour to unity
373
374
  const xr = this.context.renderer.xr;
374
375
  if (this.context.mainCamera) {
376
+ //@ts-ignore
375
377
  const cam = xr.getCamera(this.context.mainCamera) as ArrayCamera;
376
378
  for (const c of cam.cameras) {
377
379
  c.layers.enableAll();
@@ -553,7 +555,7 @@ export class WebAR {
553
555
  context.scene.background = null;
554
556
 
555
557
  session.requestReferenceSpace('viewer').then((referenceSpace) => {
556
- session.requestHitTestSource({ space: referenceSpace }).then((source) => {
558
+ session.requestHitTestSource?.call(session, { space: referenceSpace })?.then((source) => {
557
559
  this.hitTestSource = source;
558
560
  }).catch((err) => {
559
561
  this.noHitTestAvailable = true;
@@ -125,7 +125,12 @@ export class WebXRAvatar {
125
125
  if (!this.flags)
126
126
  return;
127
127
  let mask = this.isLocalAvatar ? XRStateFlag.FirstPerson : XRStateFlag.ThirdPerson;
128
- // mask |= XRStateFlag.VR;
128
+ if (this.context.isInVR)
129
+ mask |= XRStateFlag.VR;
130
+ else if (this.context.isInAR)
131
+ mask |= XRStateFlag.AR;
132
+ else
133
+ mask |= XRStateFlag.Browser;
129
134
  for (const f of this.flags) {
130
135
  f.gameObject.visible = true;
131
136
  f.UpdateVisible(mask);
@@ -1,4 +1,4 @@
1
- import { BoxHelper, BufferGeometry, Color, Euler, Group, Intersection, Layers, Line, LineBasicMaterial, Material, Mesh, MeshBasicMaterial, Object3D, PerspectiveCamera, Quaternion, Ray, SphereGeometry, Vector2, Vector3, XRInputSource, XRSession } from "three";
1
+ import { BoxHelper, BufferGeometry, Color, Euler, Group, Intersection, Layers, Line, LineBasicMaterial, Material, Mesh, MeshBasicMaterial, Object3D, PerspectiveCamera, Quaternion, Ray, SphereGeometry, Vector2, Vector3 } from "three";
2
2
  import { OculusHandModel } from 'three/examples/jsm/webxr/OculusHandModel.js';
3
3
  import { OculusHandPointerModel } from 'three/examples/jsm/webxr/OculusHandPointerModel.js';
4
4
  import { XRControllerModel, XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';
@@ -381,11 +381,12 @@ export class WebXRController extends Behaviour {
381
381
  }
382
382
 
383
383
  if (this.raycastLine) {
384
+ const allowRaycastLineVisible = this.showRaycastLine && this.context.isInVR;
384
385
  if (this.type === ControllerType.Touch) {
385
386
  this.raycastLine.visible = false;
386
387
  }
387
388
  else if (this.isUsingHands) {
388
- this.raycastLine.visible = !this.grabbed && this.showRaycastLine;
389
+ this.raycastLine.visible = !this.grabbed && allowRaycastLineVisible;
389
390
  setWorldPosition(this.raycastLine, wp);
390
391
  const jnts = this.hand!['joints'];
391
392
  if (jnts) {
@@ -400,7 +401,7 @@ export class WebXRController extends Behaviour {
400
401
  setWorldQuaternion(this.raycastLine, this.rayRotation);
401
402
  }
402
403
  else {
403
- this.raycastLine.visible = this.showRaycastLine;
404
+ this.raycastLine.visible = allowRaycastLineVisible;
404
405
  setWorldQuaternion(this.raycastLine, this.rayRotation);
405
406
  setWorldPosition(this.raycastLine, wp);
406
407
  }
@@ -1,7 +1,7 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
2
  import { RoomEvents, OwnershipModel, NetworkConnection } from "../engine/engine_networking";
3
3
  import { WebXR, WebXREvent } from "./WebXR";
4
- import { Group, Quaternion, Vector3, Vector4, WebXRManager, XRFrame, XRInputSource, XRRigidTransform, XRSession } from "three";
4
+ import { Group, Quaternion, Vector3, Vector4, WebXRManager } from "three";
5
5
  import { getParam } from "../engine/engine_utils";
6
6
  import { Voip } from "./Voip";
7
7
  import { Builder, Long } from "flatbuffers";
@@ -402,6 +402,11 @@ export class WebXRSync extends Behaviour {
402
402
  private onXRSessionEnded(_evt: { session: XRSession }) {
403
403
  console.log("XR session ended");
404
404
  this.context.connection.send(WebXRSyncEvent.WebXR_UserLeft, { id: this.context.connection.connectionId, mode: XRMode.VR });
405
+ if(this.localAvatar){
406
+ this.localAvatar?.destroy();
407
+ this.avatars[this.localAvatar.guid] = undefined;
408
+ this.localAvatar = null;
409
+ }
405
410
  }
406
411
 
407
412
  private ownership: OwnershipModel | null = null;
@@ -1,5 +1,7 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
2
  import * as utils from "../engine/engine_utils";
3
+
4
+
3
5
  const debug = utils.getParam("debugflags");
4
6
 
5
7
  export enum XRStateFlag {
@@ -21,13 +23,12 @@ export class XRState {
21
23
  public Mask: XRStateFlag = XRStateFlag.Browser | XRStateFlag.ThirdPerson;
22
24
 
23
25
  public Has(state: XRStateFlag) {
24
-
25
26
  const res = (this.Mask & state);
26
- if (debug) console.log("HAS", state, this.Mask, "Result=" + res);
27
27
  return res !== 0;
28
28
  }
29
29
 
30
30
  public Set(state: number) {
31
+ if(debug) console.warn("Set XR flag state to", state)
31
32
  this.Mask = state as number;
32
33
  XRFlag.Apply();
33
34
  }
@@ -108,23 +109,23 @@ export class XRFlag extends Behaviour {
108
109
  const st = state as XRState;
109
110
  if (st) {
110
111
  if (debug)
111
- console.log("use passed in mask")
112
+ console.warn(this.name, "use passed in mask", st.Mask, this.visibleIn)
112
113
  res = st.Has(this.visibleIn);
113
114
  }
114
115
  else {
115
116
  if (debug)
116
- console.log("use global mask")
117
+ console.log(this.name, "use global mask")
117
118
  XRState.Global.Has(this.visibleIn);
118
119
  }
119
120
  if (res === undefined) return;
120
121
  if (res) {
121
122
  if (debug)
122
- console.trace("is visible", this.name, this.gameObject.uuid)
123
+ console.log(this.name, "is visible", this.gameObject.uuid)
123
124
  // this.gameObject.visible = true;
124
125
  GameObject.setActive(this.gameObject, true);
125
126
  } else {
126
127
  if (debug)
127
- console.trace("is not visible", this.name, this.gameObject.uuid);
128
+ console.log(this.name, "is not visible", this.gameObject.uuid);
128
129
  const isVisible = this.gameObject.visible;
129
130
  if(!isVisible) return;
130
131
  this.gameObject.visible = false;
@@ -1,6 +1,6 @@
1
1
  import { applyPrototypeExtensions, registerPrototypeExtensions } from "./ExtensionUtils";
2
- import { Mathf } from "../../engine/engine_math";
3
2
  import { Vector3 } from "three";
3
+ import { slerp } from "../../engine/engine_three_utils";
4
4
 
5
5
  export function apply(object: Vector3) {
6
6
  if (object && object.isVector3 === true) {
@@ -10,10 +10,7 @@ export function apply(object: Vector3) {
10
10
 
11
11
 
12
12
  Vector3.prototype["slerp"] = function (end: Vector3, t: number) {
13
- const len1 = this.length();
14
- const len2 = end.length();
15
- const targetLen = Mathf.lerp(len1, len2, t);
16
- return this.lerp(end, t).normalize().multiplyScalar(targetLen);
13
+ return slerp(this, end, t);
17
14
  }
18
15
 
19
16
  registerPrototypeExtensions(Vector3);
@@ -85,9 +85,6 @@ export class PlayableDirector extends Behaviour {
85
85
  console.log(this, this.playableAsset?.tracks);
86
86
 
87
87
  this.rebuildGraph();
88
- if (this.playOnAwake)
89
- this.play();
90
- else this.evaluate();
91
88
 
92
89
  if (!this.isValid()) console.warn("PlayableDirector is not valid", this.playableAsset, this.playableAsset?.tracks, Array.isArray(this.playableAsset?.tracks), this);
93
90
  }
@@ -230,7 +227,7 @@ export class PlayableDirector extends Behaviour {
230
227
  ];
231
228
 
232
229
  private *internalUpdate() {
233
- while (this._isPlaying) {
230
+ while (this._isPlaying && this.activeAndEnabled) {
234
231
  if (!this._isPaused && this._isPlaying) {
235
232
  this._time += this.context.time.deltaTime;
236
233
  this.evaluate();
@@ -18,6 +18,9 @@ const debug = getParam("debugeventsystem");
18
18
 
19
19
  export class EventSystem extends Behaviour {
20
20
 
21
+
22
+ private static _eventSystemMap = new Map<Context, EventSystem[]>();
23
+
21
24
  static didSearchEventSystem: boolean = false;
22
25
  static createIfNoneExists(context: Context) {
23
26
  if (!this.didSearchEventSystem) {
@@ -33,7 +36,15 @@ export class EventSystem extends Behaviour {
33
36
  GameObject.addNewComponent(go, EventSystem);
34
37
  context.scene.add(go);
35
38
  }
36
- static systems: EventSystem[] = [];
39
+
40
+ static get systems(): EventSystem[]
41
+ {
42
+ const context = Context.Current;
43
+ if (!this._eventSystemMap.has(context)) {
44
+ this._eventSystemMap.set(context, []);
45
+ }
46
+ return this._eventSystemMap.get(context)!;
47
+ }
37
48
 
38
49
  //@ts-ignore
39
50
  static ensureUpdateMeshUI(instance, context: Context) {