@needle-tools/engine 2.58.1-pre → 2.58.2-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 (74) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/needle-engine.js +61659 -690
  3. package/dist/needle-engine.umd.cjs +4269 -0
  4. package/lib/engine/debug/debug.js +0 -2
  5. package/lib/engine/debug/debug.js.map +1 -1
  6. package/lib/engine/debug/debug_overlay.js +3 -3
  7. package/lib/engine/debug/debug_overlay.js.map +1 -1
  8. package/lib/engine/debug/index.d.ts +1 -0
  9. package/lib/engine/debug/index.js +2 -0
  10. package/lib/engine/debug/index.js.map +1 -0
  11. package/lib/engine/engine_addressables.js.map +1 -1
  12. package/lib/engine/engine_context_registry.d.ts +21 -0
  13. package/lib/engine/engine_context_registry.js +40 -0
  14. package/lib/engine/engine_context_registry.js.map +1 -0
  15. package/lib/engine/engine_hot_reload.js +2 -2
  16. package/lib/engine/engine_hot_reload.js.map +1 -1
  17. package/lib/engine/engine_loaders.js +6 -4
  18. package/lib/engine/engine_loaders.js.map +1 -1
  19. package/lib/engine/engine_mainloop_utils.d.ts +8 -9
  20. package/lib/engine/engine_mainloop_utils.js +2 -2
  21. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  22. package/lib/engine/engine_networking.js.map +1 -1
  23. package/lib/engine/engine_networking_files.js +4 -0
  24. package/lib/engine/engine_networking_files.js.map +1 -1
  25. package/lib/engine/engine_networking_instantiate.js +6 -0
  26. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  27. package/lib/engine/engine_serialization_core.js +6 -4
  28. package/lib/engine/engine_serialization_core.js.map +1 -1
  29. package/lib/engine/engine_setup.d.ts +2 -8
  30. package/lib/engine/engine_setup.js +12 -9
  31. package/lib/engine/engine_setup.js.map +1 -1
  32. package/lib/engine/engine_types.d.ts +33 -1
  33. package/lib/engine/engine_types.js.map +1 -1
  34. package/lib/engine-components/Camera.js +11 -1
  35. package/lib/engine-components/Camera.js.map +1 -1
  36. package/lib/engine-components/CameraUtils.js +4 -0
  37. package/lib/engine-components/CameraUtils.js.map +1 -1
  38. package/lib/engine-components/ReflectionProbe.d.ts +1 -1
  39. package/lib/engine-components/ReflectionProbe.js +13 -5
  40. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  41. package/lib/engine-components/Renderer.js +1 -1
  42. package/lib/engine-components/Renderer.js.map +1 -1
  43. package/lib/engine-components/js-extensions/RGBAColor.d.ts +1 -0
  44. package/lib/engine-components/js-extensions/RGBAColor.js +4 -0
  45. package/lib/engine-components/js-extensions/RGBAColor.js.map +1 -1
  46. package/lib/tsconfig.tsbuildinfo +1 -1
  47. package/lib/vite.config.d.ts +2 -0
  48. package/lib/vite.config.js +26 -0
  49. package/lib/vite.config.js.map +1 -0
  50. package/package.json +22 -8
  51. package/src/engine/debug/debug.ts +0 -3
  52. package/src/engine/debug/debug_overlay.ts +5 -3
  53. package/src/engine/debug/index.ts +1 -0
  54. package/src/engine/engine_addressables.ts +1 -1
  55. package/src/engine/engine_context_registry.ts +50 -0
  56. package/src/engine/engine_hot_reload.ts +2 -2
  57. package/src/engine/engine_loaders.ts +7 -4
  58. package/src/engine/engine_mainloop_utils.ts +12 -12
  59. package/src/engine/engine_networking.ts +0 -41
  60. package/src/engine/engine_networking_files.ts +7 -0
  61. package/src/engine/engine_networking_instantiate.ts +10 -1
  62. package/src/engine/engine_serialization_core.ts +6 -5
  63. package/src/engine/engine_setup.ts +17 -17
  64. package/src/engine/engine_types.ts +43 -3
  65. package/src/engine-components/Camera.ts +14 -1
  66. package/src/engine-components/CameraUtils.ts +7 -0
  67. package/src/engine-components/ReflectionProbe.ts +12 -4
  68. package/src/engine-components/Renderer.ts +1 -1
  69. package/src/engine-components/js-extensions/RGBAColor.ts +5 -0
  70. package/dist/needle-engine.d.ts +0 -6653
  71. package/dist/needle-engine.js.map +0 -7
  72. package/dist/needle-engine.min.js +0 -320
  73. package/dist/needle-engine.min.js.map +0 -7
  74. package/dist/needle-engine.tsbuildinfo +0 -1
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vite").UserConfigExport;
2
+ export default _default;
@@ -0,0 +1,26 @@
1
+ // vite.config.ts
2
+ import { resolve } from 'path';
3
+ import { defineConfig } from 'vite';
4
+ // https://vitejs.dev/guide/build.html#library-mode
5
+ export default defineConfig({
6
+ build: {
7
+ lib: {
8
+ entry: resolve(__dirname, 'needle-engine.ts'),
9
+ name: 'needle-engine',
10
+ fileName: 'dist/needle-engine',
11
+ },
12
+ rollupOptions: {
13
+ // external: ["@dimforge/rapier3d-compat"]
14
+ // external: id => {
15
+ // // console.log(id);
16
+ // let exclude = id.includes("include/");
17
+ // if(exclude) {
18
+ // console.log("\n> ", id);
19
+ // return true;
20
+ // }
21
+ // return false;
22
+ // }
23
+ }
24
+ }
25
+ });
26
+ //# sourceMappingURL=vite.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.config.js","sourceRoot":"","sources":["../../vite.config.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEpC,mDAAmD;AACnD,eAAe,YAAY,CAAC;IACxB,KAAK,EAAE;QACH,GAAG,EAAE;YACD,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC;YAC7C,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,oBAAoB;SACjC;QACD,aAAa,EAAE;QACX,0CAA0C;QAC1C,oBAAoB;QACpB,0BAA0B;QAC1B,6CAA6C;QAC7C,oBAAoB;QACpB,mCAAmC;QACnC,uBAAuB;QACvB,QAAQ;QACR,oBAAoB;QACpB,IAAI;SACP;KACJ;CACJ,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@needle-tools/engine",
3
- "version": "2.58.1-pre",
3
+ "version": "2.58.2-pre",
4
4
  "description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development, and can be deployed anywhere. It is flexible, extensible, and collaboration and XR come naturally.",
5
- "main": "dist/needle-engine.js",
6
- "module": "src/needle-engine.ts",
5
+ "main": "dist/needle-engine.umd.cjs",
6
+ "module": "dist/needle-engine.js",
7
7
  "type": "module",
8
8
  "repository": {
9
9
  "type": "git",
@@ -47,12 +47,30 @@
47
47
  "peerjs": "1.3.2",
48
48
  "simplex-noise": "^4.0.1",
49
49
  "stats.js": "^0.17.0",
50
- "three": "npm:@needle-tools/three@^0.146.2",
50
+ "three": "npm:@needle-tools/three@^0.146.3",
51
51
  "three-mesh-ui": "^6.4.5",
52
52
  "three.quarks": "^0.7.3",
53
53
  "uuid": "^9.0.0",
54
54
  "websocket-ts": "^1.1.1"
55
55
  },
56
+ "devDependencies": {
57
+ "@babel/runtime": "^7.16.0",
58
+ "@luncheon/esbuild-plugin-gzip": "^0.1.0",
59
+ "@needle-tools/gltf-transform-extensions": "^0.10.5-pre",
60
+ "@needle-tools/needle-component-compiler": "1.9.3",
61
+ "@needle-tools/helper": "^0.2.1-pre",
62
+ "@types/three": "0.146.0",
63
+ "copy-files-from-to": "^3.3.0",
64
+ "esbuild": "^0.15.10",
65
+ "esbuild-node-externals": "^1.5.0",
66
+ "jsdoc-babel": "^0.5.0",
67
+ "jsdoc-to-markdown": "^7.1.1",
68
+ "madge": "^5.0.1",
69
+ "msdf-bmfont-xml": "^2.7.0",
70
+ "npm-watch": "^0.11.0",
71
+ "typescript": "^4.5.5",
72
+ "vite": "^4.0.4"
73
+ },
56
74
  "watch": {
57
75
  "test:circular-imports": {
58
76
  "patterns": [
@@ -73,10 +91,6 @@
73
91
  "quiet": false
74
92
  }
75
93
  },
76
- "publishConfig": {
77
- "access": "public",
78
- "registry": "https://registry.npmjs.org"
79
- },
80
94
  "typings": "lib/needle-engine.d.ts",
81
95
  "types": "lib/needle-engine.d.ts"
82
96
  }
@@ -3,13 +3,10 @@ import { showDebugConsole } from "./debug_console";
3
3
  import { isLocalNetwork } from "../engine_networking_utils";
4
4
 
5
5
  export { showDebugConsole }
6
-
7
6
  export { LogType };
8
7
 
9
8
  export function showBalloonMessage(text: string, logType: LogType = LogType.Log) {
10
9
  addLog(logType, text);
11
- // addLog(LogType.Error, text);
12
- // addLog(LogType.Log, text);
13
10
  }
14
11
 
15
12
  export function showBalloonWarning(text: string) {
@@ -1,11 +1,13 @@
1
1
  import { getParam } from "../engine_utils";
2
2
  import { isLocalNetwork } from "../engine_networking_utils";
3
- import { Context } from "../engine_setup";
4
- import { arContainerClassName } from "../engine_element_overlay";
3
+ import { ContextRegistry } from "../engine_context_registry";
4
+
5
+
5
6
 
6
7
  const debug = getParam("debugdebug");
7
8
  const hide = getParam("noerrors");
8
9
 
10
+ const arContainerClassName = "ar";
9
11
  const errorContainer: Map<HTMLElement, HTMLElement> = new Map();
10
12
  const locationRegex = new RegExp(" at .+\/(.+?\.ts)", "g");
11
13
 
@@ -52,7 +54,7 @@ function onReceivedError(){
52
54
 
53
55
  export function addLog(type: LogType, message: string | any[], _file?: string | null, _line?: number | null) {
54
56
  if(hide) return;
55
- const context = Context.Current;
57
+ const context = ContextRegistry.Current;
56
58
  const domElement = context?.domElement ?? document.querySelector("needle-engine");
57
59
  if (!domElement) return;
58
60
  if (Array.isArray(message)) {
@@ -0,0 +1 @@
1
+ export * from "./debug";
@@ -4,7 +4,7 @@ import { SerializationContext, TypeSerializer } from "./engine_serialization_cor
4
4
  import { Context } from "./engine_setup";
5
5
  import { Group, Object3D, Scene } from "three";
6
6
  import { processNewScripts } from "./engine_mainloop_utils";
7
- import { InstantiateEvent, registerPrefabProvider, syncInstantiate } from "./engine_networking_instantiate";
7
+ import { registerPrefabProvider, syncInstantiate } from "./engine_networking_instantiate";
8
8
  import { download, hash } from "./engine_web_api";
9
9
  import { getLoader } from "./engine_gltf";
10
10
  import { SourceIdentifier } from "./engine_types";
@@ -0,0 +1,50 @@
1
+ import { IContext } from "./engine_types";
2
+
3
+ export enum ContextEvent {
4
+ ContextCreated = "ContextCreated",
5
+ ContextDestroyed = "ContextDestroyed",
6
+ MissingCamera = "MissingCamera",
7
+ }
8
+
9
+ export type ContextEventArgs = {
10
+ event: ContextEvent;
11
+ context: IContext;
12
+ }
13
+
14
+ export type ContextCallback = (evt: ContextEventArgs) => void;
15
+
16
+ export class ContextRegistry {
17
+ static Current: IContext;
18
+
19
+ static Registered: IContext[] = [];
20
+
21
+ static register(ctx: IContext) {
22
+ this.Registered.push(ctx);
23
+ }
24
+
25
+ static unregister(ctx: IContext) {
26
+ const index = this.Registered.indexOf(ctx);
27
+ if (index === -1) return;
28
+ this.Registered.splice(index, 1);
29
+ }
30
+
31
+ private static _callbacks: { [evt: string]: Array<ContextCallback> } = {};
32
+
33
+ static registerCallback(evt: ContextEvent, callback: ContextCallback) {
34
+ if (!this._callbacks[evt]) this._callbacks[evt] = [];
35
+ this._callbacks[evt].push(callback);
36
+ }
37
+
38
+ static unregisterCallback(evt: ContextEvent, callback: ContextCallback) {
39
+ if (!this._callbacks[evt]) return;
40
+ const index = this._callbacks[evt].indexOf(callback);
41
+ if (index === -1) return;
42
+ this._callbacks[evt].splice(index, 1);
43
+ }
44
+
45
+ static dispatchCallback(evt: ContextEvent, context:IContext) {
46
+ if (!this._callbacks[evt]) return;
47
+ const args = { event: evt, context }
48
+ this._callbacks[evt].forEach(cb => cb(args));
49
+ }
50
+ }
@@ -93,8 +93,9 @@ export function applyChanges(newModule): boolean {
93
93
  continue;
94
94
  }
95
95
  const newType = newModule[key];
96
+ const instancesOfType = instances.get(newType.name);
96
97
 
97
- console.log("[Needle Engine] Updating type: " + key);
98
+ console.log("[Needle Engine] Updating type: " + key + " [" + instancesOfType?.length + "]");
98
99
 
99
100
  // Update prototype (methods and properties)
100
101
  const previousMethods = Object.getOwnPropertyNames(typeToUpdate.prototype);
@@ -113,7 +114,6 @@ export function applyChanges(newModule): boolean {
113
114
 
114
115
  // Update fields (we only add new fields if they are undefined)
115
116
  // we create a instance to get access to the fields
116
- const instancesOfType = instances.get(newType.name);
117
117
  if (instancesOfType) {
118
118
  const newTypeInstance = new newType();
119
119
  const keys = Object.getOwnPropertyDescriptors(newTypeInstance);
@@ -7,6 +7,9 @@ import { getParam } from "./engine_utils";
7
7
 
8
8
  const debug = getParam("debugdecoders");
9
9
 
10
+ const DEFAULT_DRACO_DECODER_LOCATION ='https://www.gstatic.com/draco/versioned/decoders/1.4.1/';
11
+ const DEFAULT_KTX2_TRANSCODER_LOCATION ='https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/';
12
+
10
13
  let dracoLoader: DRACOLoader;
11
14
  let ktx2Loader: KTX2Loader;
12
15
 
@@ -40,14 +43,14 @@ export function setKtx2TranscoderPath(path: string) {
40
43
  export function addDracoAndKTX2Loaders(loader: GLTFLoader, context: Context) {
41
44
  if (!dracoLoader) {
42
45
  dracoLoader = new DRACOLoader();
43
- dracoLoader.setDecoderPath('./include/draco/');
46
+ dracoLoader.setDecoderPath(DEFAULT_DRACO_DECODER_LOCATION);
44
47
  dracoLoader.setDecoderConfig({ type: 'js' });
45
- if(debug) console.log("Setting draco decoder path to", './include/draco/');
48
+ if (debug) console.log("Setting draco decoder path to", DEFAULT_DRACO_DECODER_LOCATION);
46
49
  }
47
50
  if (!ktx2Loader) {
48
51
  ktx2Loader = new KTX2Loader();
49
- ktx2Loader.setTranscoderPath('./include/ktx2/');
50
- if(debug) console.log("Setting ktx2 transcoder path to", './include/ktx2/');
52
+ ktx2Loader.setTranscoderPath(DEFAULT_KTX2_TRANSCODER_LOCATION);
53
+ if (debug) console.log("Setting ktx2 transcoder path to", DEFAULT_KTX2_TRANSCODER_LOCATION);
51
54
  if (context.renderer)
52
55
  ktx2Loader.detectSupport(context.renderer);
53
56
  }
@@ -1,10 +1,10 @@
1
- import { Context } from './engine_setup';
2
1
  import * as utils from "./engine_generic_utils";
3
2
  import * as constants from "./engine_constants";
4
3
  import { getParam } from './engine_utils';
5
4
  import { CubeCamera, Object3D, WebGLCubeRenderTarget } from 'three';
6
- import { IComponent } from './engine_types';
7
- import { isActiveSelf, setActive } from './engine_gameobject';
5
+ import { IComponent, IContext } from './engine_types';
6
+ import { isActiveSelf } from './engine_gameobject';
7
+ import { ContextRegistry } from "./engine_context_registry";
8
8
 
9
9
  const debug = getParam("debugnewscripts");
10
10
 
@@ -13,7 +13,7 @@ const debug = getParam("debugnewscripts");
13
13
  // so we use this copy buffer
14
14
  const new_scripts_buffer: any[] = [];
15
15
 
16
- export function processNewScripts(context: Context) {
16
+ export function processNewScripts(context: IContext) {
17
17
  if (context.new_scripts.length <= 0) return;
18
18
  if (debug)
19
19
  console.log("Register new components", context.new_scripts.length, context.alias ? ("element: " + context.alias) : "");
@@ -153,7 +153,7 @@ export function processRemoveFromScene(script: IComponent) {
153
153
  removeScriptFromContext(script, script.context);
154
154
  }
155
155
 
156
- export function processStart(context: Context, object?: Object3D) {
156
+ export function processStart(context: IContext, object?: Object3D) {
157
157
  // Call start on scripts
158
158
  for (let i = 0; i < context.new_script_start.length; i++) {
159
159
  try {
@@ -182,7 +182,7 @@ export function processStart(context: Context, object?: Object3D) {
182
182
  }
183
183
 
184
184
 
185
- export function addScriptToArrays(script: any, context: Context) {
185
+ export function addScriptToArrays(script: any, context: IContext) {
186
186
  // TODO: not sure if this is ideal - maybe we should add a map if we have many scripts?
187
187
  const index = context.scripts.indexOf(script);
188
188
  if (index !== -1) return;
@@ -196,7 +196,7 @@ export function addScriptToArrays(script: any, context: Context) {
196
196
  }
197
197
 
198
198
 
199
- export function removeScriptFromContext(script: any, context: Context) {
199
+ export function removeScriptFromContext(script: any, context: IContext) {
200
200
  removeFromArray(script, context.new_scripts);
201
201
  removeFromArray(script, context.new_script_start);
202
202
  removeFromArray(script, context.scripts);
@@ -218,7 +218,7 @@ const previousActiveMap: { [key: string]: boolean } = {};
218
218
  const previousActiveInHierarchyMap: { [key: string]: boolean } = {};
219
219
 
220
220
  export function updateIsActive(obj?: Object3D) {
221
- if (!obj) obj = Context.Current.scene;
221
+ if (!obj) obj = ContextRegistry.Current.scene;
222
222
  if (!obj) {
223
223
  console.trace("Invalid call - no current context.");
224
224
  return;
@@ -325,12 +325,12 @@ function perComponent(go: THREE.Object3D, evt: (comp: IComponent) => void) {
325
325
  }
326
326
 
327
327
 
328
- const prewarmList: Map<Context, Object3D[]> = new Map();
328
+ const prewarmList: Map<IContext, Object3D[]> = new Map();
329
329
  const $prewarmedFlag = Symbol("prewarmFlag");
330
330
  const $waitingForPrewarm = Symbol("waitingForPrewarm");
331
331
  const debugPrewarm = getParam("debugprewarm");
332
332
 
333
- export function registerPrewarmObject(obj: Object3D, context: Context) {
333
+ export function registerPrewarmObject(obj: Object3D, context: IContext) {
334
334
  if (!obj) return;
335
335
  // allow objects to be marked as prewarmed in which case we dont need to register them again
336
336
  if (obj[$prewarmedFlag] === true) return;
@@ -348,7 +348,7 @@ let prewarmTarget: WebGLCubeRenderTarget | null = null;
348
348
  let prewarmCamera: CubeCamera | null = null;
349
349
 
350
350
  // called by the engine to remove scroll or animation hiccup when objects are rendered/compiled for the first time
351
- export function runPrewarm(context: Context) {
351
+ export function runPrewarm(context: IContext) {
352
352
  if (!context) return;
353
353
  const list = prewarmList.get(context);
354
354
  if (!list?.length) return;
@@ -371,7 +371,7 @@ export function runPrewarm(context: Context) {
371
371
  }
372
372
  }
373
373
 
374
- export function clearPrewarmList(context: Context) {
374
+ export function clearPrewarmList(context: IContext) {
375
375
  const list = prewarmList.get(context);
376
376
  if (list) {
377
377
  for (const obj of list) {
@@ -631,45 +631,4 @@ export class NetworkConnection implements INetworkConnection {
631
631
  }
632
632
 
633
633
 
634
- // GECKOS IO ------------------------------------------------------------
635
-
636
- // private channel!: ClientChannel;
637
-
638
- // private sendGeckosIo(key: string, data: MessageData) {
639
- // this.channel.emit(key, data);
640
- // }
641
-
642
- // private onConnectGeckosIo(err) {
643
- // if (err) {
644
- // console.error(err);
645
- // return;
646
- // }
647
- // const self = this;
648
- // const { id: _channelId, maxMessageSize } = this.channel;
649
- // this.channelId = _channelId;
650
- // this.connected = true;
651
- // console.log("Connected to", this.channelId);
652
-
653
- // this.channel.onDisconnect(() => {
654
- // console.log("Disconnected from", this.channelId);
655
- // this.connected = false;
656
- // this.connect();
657
- // })
658
-
659
- // this.channel.emit('chat message', "Hello everyone, I'm " + this.channel.id + " from three");
660
-
661
- // this.channel.on('chat message', function (data) {
662
- // console.log(data);
663
- // // channel.emit('chat message', "three received " + data);
664
- // })
665
-
666
- // this.channel.on('transform update', function (data) {
667
- // console.log(data);
668
- // for (let i = 0; i < self._listeners['transform update'].length; i++) {
669
- // self._listeners['transform update'][i](data);
670
- // }
671
- // // channel.emit('chat message', "three received " + data);
672
- // });
673
- // }
674
-
675
634
  }
@@ -10,6 +10,7 @@ import { getLoader } from "../engine/engine_gltf";
10
10
  import { IModel } from "./engine_networking_types";
11
11
  import { IGameObject } from "./engine_types";
12
12
  import { findByGuid } from "./engine_gameobject";
13
+ import { ContextEvent, ContextRegistry } from "./engine_context_registry";
13
14
 
14
15
  export enum File_Event {
15
16
  File_Spawned = "file-spawned",
@@ -97,6 +98,12 @@ export async function addFileFromUrl(url: URL, context: Context): Promise<GLTF |
97
98
  });
98
99
  }
99
100
 
101
+
102
+ ContextRegistry.registerCallback(ContextEvent.ContextCreated, evt => {
103
+ beginListenFileSpawn(evt.context as Context);
104
+ })
105
+
106
+
100
107
  export function beginListenFileSpawn(context: Context) {
101
108
  context.connection.beginListen(File_Event.File_Spawned, async (evt: FileSpawnModel) => {
102
109
  if (evt.sender !== context.connection.connectionId) {
@@ -14,10 +14,19 @@ import { SendQueue } from "./engine_networking_types";
14
14
  import { destroy, findByGuid, instantiate } from "./engine_gameobject";
15
15
  import { Object3D } from "three";
16
16
  import { InstantiateOptions } from "./engine_gameobject";
17
+ import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry";
17
18
 
18
19
 
19
- const debug = utils.getParam("debugcomponents");
20
20
 
21
+ ContextRegistry.registerCallback(ContextEvent.ContextCreated, evt => {
22
+ const context = evt.context as Context;
23
+ beginListenInstantiate(context);
24
+ beginListenDestroy(context);
25
+ });
26
+
27
+
28
+
29
+ const debug = utils.getParam("debugcomponents");
21
30
 
22
31
 
23
32
  const ID_NAMESPACE = 'eff8ba80-635d-11ec-90d6-0242ac120003';
@@ -3,9 +3,9 @@ import { getParam } from "./engine_utils";
3
3
  import { Object3D } from "three";
4
4
  import { Context } from "./engine_setup";
5
5
  import { isPersistentAsset } from "./extensions/NEEDLE_persistent_assets";
6
- import { IComponent, SourceIdentifier } from "./engine_types";
6
+ import { SourceIdentifier } from "./engine_types";
7
7
  import { debugExtension } from "../engine/engine_default_parameters";
8
- import { LogType, showBalloonMessage, showBalloonWarning } from "./debug/debug";
8
+ import { LogType, addLog } from "./debug/debug_overlay";
9
9
  import { isLocalNetwork } from "./engine_networking_utils";
10
10
  import { $BuiltInTypeFlag } from "./engine_typestore";
11
11
 
@@ -370,6 +370,7 @@ function checkObjectAssignments(obj: any, serializedData: any, implementationInf
370
370
  for (const key of ownKeys) {
371
371
  if (key === "sourceId") continue;
372
372
  const value = obj[key];
373
+ if(value == null) continue;
373
374
  const serialized = serializedData[key];
374
375
  // check if the field is defined in the class
375
376
  if (implementationInformation?.getDefinedKey(typeName, key) === false) {
@@ -378,7 +379,7 @@ function checkObjectAssignments(obj: any, serializedData: any, implementationInf
378
379
  // because all fields are serialized in lowercase
379
380
  const firstCharUppercase = key.charAt(0).toUpperCase() + key.slice(1);
380
381
  if (implementationInformation.getDefinedKey(typeName, firstCharUppercase)) {
381
- showBalloonWarning("<strong>Please rename</strong> \"" + firstCharUppercase + "\" to \"" + key + "\" in " + typeName);
382
+ addLog(LogType.Warn, "<strong>Please rename</strong> \"" + firstCharUppercase + "\" to \"" + key + "\" in " + typeName);
382
383
  console.warn("Please use lowercase for field: \"" + firstCharUppercase + "\" in " + typeName, serialized, obj);
383
384
  }
384
385
 
@@ -393,7 +394,7 @@ function checkObjectAssignments(obj: any, serializedData: any, implementationInf
393
394
  }
394
395
  const hasOtherKeys = value !== undefined && Object.keys(value).length > 1;
395
396
  if (!hasOtherKeys) {
396
- showBalloonMessage(`<strong>Missing serialization for object reference!</strong>\n\nPlease change to: \n@serializable(Object3D)\n${key}? : Object3D;\n\nin script ${typeName}.ts\n<a href="https://docs.needle.tools/serializable" target="_blank">documentation</a>`, LogType.Warn);
397
+ addLog(LogType.Warn, `<strong>Missing serialization for object reference!</strong>\n\nPlease change to: \n@serializable(Object3D)\n${key}? : Object3D;\n\nin script ${typeName}.ts\n<a href="https://docs.needle.tools/serializable" target="_blank">documentation</a>`);
397
398
  console.warn(typeName, key, obj[key], obj);
398
399
  continue;
399
400
  }
@@ -402,7 +403,7 @@ function checkObjectAssignments(obj: any, serializedData: any, implementationInf
402
403
  }
403
404
  if (typeof value === "string") {
404
405
  if (serialized.endsWith(".gltf") || serialized.endsWith(".glb")) {
405
- showBalloonMessage(`<strong>Missing serialization for object reference!</strong>\n\nPlease change to: \n@serializable(AssetReference)\n${key}? : AssetReference;\n\nin script ${typeName}.ts\n<a href="https://docs.needle.tools/serializable" target="_blank">documentation</a>`, LogType.Warn);
406
+ addLog(LogType.Warn, `<strong>Missing serialization for object reference!</strong>\n\nPlease change to: \n@serializable(AssetReference)\n${key}? : AssetReference;\n\nin script ${typeName}.ts\n<a href="https://docs.needle.tools/serializable" target="_blank">documentation</a>`);
406
407
  console.warn(typeName, key, obj[key], obj);
407
408
  continue;
408
409
  }
@@ -4,7 +4,6 @@ import { Input } from './engine_input';
4
4
  import { Physics } from './engine_physics';
5
5
  import { Time } from './engine_time';
6
6
  import { NetworkConnection } from './engine_networking';
7
- import { beginListenDestroy, beginListenInstantiate } from './engine_networking_instantiate';
8
7
 
9
8
  import * as looputils from './engine_mainloop_utils';
10
9
  import * as utils from "./engine_utils";
@@ -12,7 +11,6 @@ import * as utils from "./engine_utils";
12
11
  import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
13
12
  import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
14
13
 
15
- import { beginListenFileSpawn } from './engine_networking_files';
16
14
  import { AssetDatabase } from './engine_assetdatabase';
17
15
 
18
16
  import { logHierarchy } from './engine_three_utils';
@@ -24,9 +22,10 @@ import { Application } from './engine_application';
24
22
  import { LightDataRegistry, ILightDataRegistry } from './engine_lightdata';
25
23
  import { PlayerViewManager } from './engine_playerview';
26
24
 
27
- import { ICamera, IComponent, ILight } from "./engine_types"
25
+ import { CoroutineData, ICamera, IComponent, IContext, ILight } from "./engine_types"
28
26
  import { destroy, foreachComponent } from './engine_gameobject';
29
- import { createCameraWithOrbitControl } from '../engine-components/CameraUtils';
27
+ import { ContextEvent, ContextRegistry } from './engine_context_registry';
28
+ // import { createCameraWithOrbitControl } from '../engine-components/CameraUtils';
30
29
 
31
30
 
32
31
  const debug = utils.getParam("debugSetup");
@@ -38,12 +37,6 @@ const debugActive = utils.getParam("debugactive");
38
37
  // those will be accessed from our custom html element to load them into their context
39
38
  export const build_scene_functions: { [name: string]: (context: Context) => Promise<void> } = {};
40
39
 
41
- declare type CoroutineData = {
42
- comp: IComponent,
43
- main: Generator,
44
- chained?: Array<Generator>
45
- }
46
-
47
40
  export declare class LoadingProgressArgs {
48
41
  name: string;
49
42
  progress: ProgressEvent;
@@ -92,7 +85,7 @@ export function registerComponent(script: IComponent, context?: Context) {
92
85
  }
93
86
  }
94
87
 
95
- export class Context {
88
+ export class Context implements IContext {
96
89
 
97
90
  private static _current: Context;
98
91
 
@@ -101,6 +94,7 @@ export class Context {
101
94
  }
102
95
 
103
96
  static set Current(context: Context) {
97
+ ContextRegistry.Current = context;
104
98
  this._current = context;
105
99
  }
106
100
 
@@ -272,6 +266,8 @@ export class Context {
272
266
 
273
267
  this.scene = new THREE.Scene();
274
268
 
269
+ ContextRegistry.register(this);
270
+
275
271
  this.application = new Application(this);
276
272
  this.time = new Time();
277
273
  this.input = new Input(this);
@@ -362,6 +358,9 @@ export class Context {
362
358
  if (this.domElement?.parentElement) {
363
359
  this.domElement.parentElement.removeChild(this.domElement);
364
360
  }
361
+
362
+ ContextRegistry.dispatchCallback(ContextEvent.ContextDestroyed, this);
363
+ ContextRegistry.unregister(this);
365
364
  }
366
365
 
367
366
  registerCoroutineUpdate(script: IComponent, coroutine: Generator, evt: FrameEvent): Generator {
@@ -480,6 +479,7 @@ export class Context {
480
479
  return style.visibility !== "hidden" && style.display !== "none" && style.opacity !== "0";
481
480
  }
482
481
 
482
+
483
483
  private async internalOnCreate(buildScene?: (context: Context, opts?: LoadingOptions) => Promise<void>, opts?: LoadingOptions) {
484
484
 
485
485
  // TODO: we could configure if we need physics
@@ -503,9 +503,8 @@ export class Context {
503
503
  if (!this.isManagedExternally)
504
504
  this.domElement.prepend(this.renderer.domElement);
505
505
 
506
- beginListenInstantiate(this);
507
- beginListenDestroy(this);
508
- beginListenFileSpawn(this);
506
+ Context._current = this;
507
+ ContextRegistry.dispatchCallback(ContextEvent.ContextCreated, this);
509
508
 
510
509
  // Setup
511
510
  Context._current = this;
@@ -560,8 +559,9 @@ export class Context {
560
559
  this.setCurrentCamera(camera);
561
560
  }
562
561
  else {
563
- console.error("MISSING camera", this);
564
- createCameraWithOrbitControl(this.scene, "unknown");
562
+ ContextRegistry.dispatchCallback(ContextEvent.MissingCamera, this);
563
+ if (!this.mainCamera)
564
+ console.error("MISSING camera", this);
565
565
  }
566
566
  }
567
567
 
@@ -605,7 +605,7 @@ export class Context {
605
605
  this.time.update();
606
606
 
607
607
  looputils.processNewScripts(this);
608
- looputils.updateIsActive();
608
+ looputils.updateIsActive(this.scene);
609
609
  looputils.processStart(this);
610
610
 
611
611
  while (this._cameraStack.length > 0 && (!this.mainCameraComponent || this.mainCameraComponent.destroyed)) {
@@ -1,7 +1,6 @@
1
- import { Camera, Color, Material, Object3D, Vector3, Quaternion, Ray } from "three";
1
+ import { Camera, Color, Material, Object3D, Vector3, Quaternion, Ray, Scene, Renderer, WebGLRenderer } from "three";
2
2
  import { RGBAColor } from "../engine-components/js-extensions/RGBAColor";
3
3
  import { CollisionDetectionMode, PhysicsMaterial, RigidbodyConstraints } from "./engine_physics.types";
4
- import { getWorldPosition } from "./engine_three_utils";
5
4
  import { CircularBuffer } from "./engine_utils";
6
5
 
7
6
  /** used to find data registered via gltf files e.g. find lightmaps for a Renderer component that were shipped inside a gltf */
@@ -20,6 +19,47 @@ export interface UIDProvider {
20
19
  generateUUID(): string;
21
20
  }
22
21
 
22
+
23
+ export declare type CoroutineData = {
24
+ comp: IComponent,
25
+ main: Generator,
26
+ chained?: Array<Generator>
27
+ }
28
+
29
+
30
+ export interface IContext {
31
+ alias?: string | null;
32
+
33
+ scene : Scene;
34
+ renderer : WebGLRenderer;
35
+ mainCamera : Camera | null;
36
+ domElement : HTMLElement;
37
+
38
+ scripts: IComponent[];
39
+ scripts_pausedChanged: IComponent[];
40
+ // scripts with update event
41
+ scripts_earlyUpdate: IComponent[];
42
+ scripts_update: IComponent[];
43
+ scripts_lateUpdate: IComponent[];
44
+ scripts_onBeforeRender: IComponent[];
45
+ scripts_onAfterRender: IComponent[];
46
+ scripts_WithCorroutines: IComponent[];
47
+ coroutines: { [FrameEvent: number]: Array<CoroutineData> };
48
+
49
+ post_setup_callbacks: Function[];
50
+ pre_update_callbacks: Function[];
51
+ pre_render_callbacks: Function[];
52
+ post_render_callbacks: Function[];
53
+
54
+ new_scripts: IComponent[];
55
+ new_script_start: IComponent[];
56
+ new_scripts_pre_setup_callbacks: Function[];
57
+ new_scripts_post_setup_callbacks: Function[];
58
+
59
+ stopAllCoroutinesFrom(script: IComponent);
60
+ }
61
+
62
+
23
63
  export declare interface INeedleEngineComponent extends HTMLElement {
24
64
  getAROverlayContainer(): HTMLElement;
25
65
  onEnterAR(session: XRSession, overlayContainer: HTMLElement);
@@ -150,7 +190,7 @@ export declare interface IRigidbody extends IComponent {
150
190
  drag: number;
151
191
  angularDrag: number;
152
192
  useGravity: boolean;
153
- gravityScale : number;
193
+ gravityScale: number;
154
194
  collisionDetectionMode: CollisionDetectionMode;
155
195
 
156
196
  lockPositionX: boolean;