Needle Engine

Changes between version 3.12.1-beta and 3.12.2-beta
Files changed (7) hide show
  1. src/engine/api.ts +1 -0
  2. src/engine-components/AudioListener.ts +2 -2
  3. src/engine/engine_networking_peer.ts +24 -3
  4. src/engine/engine_typestore.ts +9 -11
  5. src/engine-components/Networking.ts +2 -0
  6. src/engine-components/ScreenCapture.ts +19 -6
  7. src/engine-components/Voip.ts +2 -1
src/engine/api.ts CHANGED
@@ -25,6 +25,7 @@
25
25
  export * from "./engine_networking_files.js";
26
26
  export * from "./engine_networking_instantiate.js";
27
27
  export * from "./engine_networking_utils.js";
28
+ export * from "./engine_networking_peer.js";
28
29
  export * from "./engine_patcher.js";
29
30
  export * from "./engine_playerview.js";
30
31
  export * from "./engine_physics.js";
src/engine-components/AudioListener.ts CHANGED
@@ -22,8 +22,8 @@
22
22
  // if the listener is already parented to some object d0nt change it
23
23
  if (listener.parent) return;
24
24
 
25
- const cam = GameObject.getComponentInParent(this.gameObject, Camera);
26
- if (cam) {
25
+ const cam = this.context.mainCameraComponent || GameObject.getComponentInParent(this.gameObject, Camera);
26
+ if (cam?.cam) {
27
27
  cam.cam.add(listener);
28
28
  }
29
29
  else
src/engine/engine_networking_peer.ts CHANGED
@@ -1,11 +1,32 @@
1
- import type Peer from "peerjs";
2
- import { type DataConnection } from "peerjs";
1
+ import Peer, { PeerConnectOption } from "peerjs";
2
+ import { type DataConnection, type PeerJSOption } from "peerjs";
3
3
  import { ConstructorConcrete } from "./engine_types.js";
4
4
 
5
+ let peerOptions: PeerJSOption | undefined = undefined;
6
+
7
+ export function getPeerOptions() {
8
+ return peerOptions;
9
+ }
10
+ export function setPeerOptions(opts: PeerJSOption) {
11
+ peerOptions = opts;
12
+ }
13
+ export function getPeerjsInstance(id?: string, opts?: PeerJSOption): Peer {
14
+ if (!opts) opts = {}
15
+ opts = {
16
+ ...peerOptions,
17
+ ...opts,
18
+ }
19
+ if (id)
20
+ return new Peer(id, opts);
21
+ return new Peer(opts);
22
+ }
23
+
24
+
25
+
5
26
  async function importPeer(): Promise<ConstructorConcrete<Peer>> {
6
27
  const pkg = await import("peerjs");
7
28
  console.log(pkg);
8
- if(pkg.default === undefined) return pkg as any;
29
+ if (pkg.default === undefined) return pkg as any;
9
30
  return pkg.default;
10
31
  }
11
32
 
src/engine/engine_typestore.ts CHANGED
@@ -2,18 +2,16 @@
2
2
 
3
3
  const debug = getParam("debugtypes");
4
4
 
5
- /**
6
- * global types
7
- */
8
- const _types = globalThis["__NEEDLE_ENGINE_TYPES"] = globalThis["__NEEDLE_ENGINE_TYPES"] || {};
9
5
 
10
- export class TypeStore {
6
+ class _TypeStore {
11
7
 
12
- public static add(key, type) {
8
+ private _types = {};
9
+
10
+ public add(key, type) {
13
11
  if (debug) console.warn("ADD TYPE", key);
14
- const existing = _types[key];
12
+ const existing = this._types[key];
15
13
  if (existing === undefined)
16
- _types[key] = type;
14
+ this._types[key] = type;
17
15
  else {
18
16
  if (debug) {
19
17
  if (existing !== type) {
@@ -23,14 +21,14 @@
23
21
  }
24
22
  }
25
23
 
26
- public static get(key) {
27
- return _types[key];
24
+ public get(key) {
25
+ return this._types[key];
28
26
  }
29
27
  }
30
28
 
31
29
  export const $BuiltInTypeFlag = Symbol("BuiltInType");
30
+ export const TypeStore = new _TypeStore();
32
31
 
33
-
34
32
  /**
35
33
  * add to a class declaration to automatically register it to the TypeStore (required for HMR right now)
36
34
  *
src/engine-components/Networking.ts CHANGED
@@ -59,6 +59,8 @@
59
59
 
60
60
  if (url?.startsWith("/")) {
61
61
  const base = useLocalHostUrl ? result : window.location.origin;
62
+ if(base?.endsWith("/") && url.startsWith("/"))
63
+ url = url.substring(1);
62
64
  result = base + url;
63
65
  }
64
66
 
src/engine-components/ScreenCapture.ts CHANGED
@@ -11,6 +11,7 @@
11
11
  import { getParam } from "../engine/engine_utils.js";
12
12
  import { IModel } from "../engine/engine_networking_types.js";
13
13
  import { showBalloonWarning } from "../engine/debug/index.js";
14
+ import { getPeerjsInstance } from "../engine/engine_networking_peer.js";
14
15
 
15
16
  const debug = getParam("debugscreensharing");
16
17
 
@@ -34,22 +35,30 @@
34
35
 
35
36
  declare type ScreenCaptureOptions = {
36
37
  device?: ScreenCaptureDevice,
38
+ constraints?: MediaTrackConstraints,
39
+ /** Filter video device by id. Alternatively pass in a deviceFilter callback to manually filter available devices */
37
40
  deviceId?: string,
38
- constraints?: MediaTrackConstraints,
41
+ /** Return false to skip the available device */
42
+ deviceFilter?: (device: MediaDeviceInfo) => boolean,
39
43
  }
40
44
 
41
45
  export class ScreenCapture extends Behaviour implements IPointerClickHandler {
42
46
 
47
+ allowStartOnClick: boolean = true;
48
+
43
49
  onPointerEnter() {
50
+ if (!this.allowStartOnClick) return;
44
51
  this.context.input.setCursorPointer();
45
52
  }
46
53
  onPointerExit() {
54
+ if (!this.allowStartOnClick) return;
47
55
  this.context.input.setCursorNormal();
48
56
  }
49
57
 
50
- onPointerClick(evt : PointerEventData) {
51
- if(evt && evt.pointerId !== 0) return;
52
- if(this.context.connection.isInRoom === false) return;
58
+ onPointerClick(evt: PointerEventData) {
59
+ if (!this.allowStartOnClick) return;
60
+ if (evt && evt.pointerId !== 0) return;
61
+ if (this.context.connection.isInRoom === false) return;
53
62
  if (this.isReceiving && this.videoPlayer?.isPlaying) {
54
63
  if (this.videoPlayer)
55
64
  this.videoPlayer.screenspace = !this.videoPlayer.screenspace;
@@ -129,6 +138,7 @@
129
138
  this._net.addEventListener(PeerEvent.ReceiveVideo, this.onReceiveVideo.bind(this));
130
139
  }
131
140
 
141
+ /** Call to begin screensharing */
132
142
  async share(opts?: ScreenCaptureOptions) {
133
143
 
134
144
  if (opts?.device)
@@ -277,6 +287,9 @@
277
287
  if (id !== options.deviceId)
278
288
  continue;
279
289
  }
290
+ const useDevice = options?.deviceFilter?.call(this, dev);
291
+ if (useDevice === false) continue;
292
+
280
293
  if (opts.video !== false) {
281
294
  if (typeof opts.video === "undefined" || typeof opts.video === "boolean") {
282
295
  opts.video = {};
@@ -487,8 +500,8 @@
487
500
  this._enabledPeer = true;
488
501
  if (!this._peer) {
489
502
  const peerId = this.getMyPeerId();
490
- if(peerId)
491
- this._peer = new Peer(peerId);
503
+ if (peerId)
504
+ this._peer = getPeerjsInstance(peerId);
492
505
  else console.error("Failed to setup peerjs because we dont have a connection id", this.context.connection.connectionId);
493
506
  }
494
507
  if (this._enabled)
src/engine-components/Voip.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  import * as utils from "../engine/engine_utils.js"
8
8
  import { AudioAnalyser } from "three";
9
9
  import { SendQueue } from "../engine/engine_networking_types.js";
10
+ import { getPeerjsInstance } from "../engine/engine_networking_peer.js";
10
11
 
11
12
  export const noVoip = "noVoip";
12
13
  const debug = utils.getParam("debugvoip");
@@ -312,7 +313,7 @@
312
313
  return;
313
314
  }
314
315
 
315
- this.peer = new Peer();
316
+ this.peer = getPeerjsInstance();
316
317
  navigator["getUserMedia"] = (navigator["getUserMedia"] || navigator["webkitGetUserMedia"] || navigator["mozGetUserMedia"] || navigator["msGetUserMedia"]);