@needle-tools/engine 2.53.0-pre → 2.55.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 (199) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/needle-engine.d.ts +2477 -2267
  3. package/dist/needle-engine.js +425 -425
  4. package/dist/needle-engine.js.map +4 -4
  5. package/dist/needle-engine.min.js +40 -40
  6. package/dist/needle-engine.min.js.map +4 -4
  7. package/dist/needle-engine.tsbuildinfo +1 -0
  8. package/lib/engine/codegen/register_types.d.ts +1 -0
  9. package/lib/engine/codegen/register_types.js +346 -0
  10. package/lib/engine/codegen/register_types.js.map +1 -0
  11. package/lib/engine/debug/debug.d.ts +1 -0
  12. package/lib/engine/debug/debug.js +4 -0
  13. package/lib/engine/debug/debug.js.map +1 -1
  14. package/lib/engine/debug/debug_console.js +2 -1
  15. package/lib/engine/debug/debug_console.js.map +1 -1
  16. package/lib/engine/debug/debug_overlay.js +3 -1
  17. package/lib/engine/debug/debug_overlay.js.map +1 -1
  18. package/lib/engine/engine_default_parameters.d.ts +2 -2
  19. package/lib/engine/engine_element.js +4 -2
  20. package/lib/engine/engine_element.js.map +1 -1
  21. package/lib/engine/engine_element_loading.d.ts +1 -0
  22. package/lib/engine/engine_element_loading.js +17 -6
  23. package/lib/engine/engine_element_loading.js.map +1 -1
  24. package/lib/engine/engine_element_overlay.js +4 -2
  25. package/lib/engine/engine_element_overlay.js.map +1 -1
  26. package/lib/engine/engine_fileloader.d.ts +3 -0
  27. package/lib/engine/engine_fileloader.js +8 -0
  28. package/lib/engine/engine_fileloader.js.map +1 -0
  29. package/lib/engine/engine_generic_utils.d.ts +1 -0
  30. package/lib/engine/engine_generic_utils.js +14 -0
  31. package/lib/engine/engine_generic_utils.js.map +1 -0
  32. package/lib/engine/engine_input.js +4 -0
  33. package/lib/engine/engine_input.js.map +1 -1
  34. package/lib/engine/engine_lightdata.js +1 -1
  35. package/lib/engine/engine_lightdata.js.map +1 -1
  36. package/lib/engine/engine_mainloop_utils.js +8 -0
  37. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  38. package/lib/engine/engine_networking_websocket.d.ts +1 -0
  39. package/lib/engine/engine_networking_websocket.js +1 -1
  40. package/lib/engine/engine_networking_websocket.js.map +1 -1
  41. package/lib/engine/engine_physics.d.ts +1 -1
  42. package/lib/engine/engine_physics.js +44 -3
  43. package/lib/engine/engine_physics.js.map +1 -1
  44. package/lib/engine/engine_physics.types.d.ts +13 -0
  45. package/lib/engine/engine_physics.types.js +7 -0
  46. package/lib/engine/engine_physics.types.js.map +1 -1
  47. package/lib/engine/engine_serialization_builtin_serializer.js +6 -3
  48. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  49. package/lib/engine/engine_setup.js +2 -2
  50. package/lib/engine/engine_setup.js.map +1 -1
  51. package/lib/engine/engine_time.d.ts +1 -0
  52. package/lib/engine/engine_time.js +7 -0
  53. package/lib/engine/engine_time.js.map +1 -1
  54. package/lib/engine/engine_types.d.ts +4 -1
  55. package/lib/engine/engine_types.js.map +1 -1
  56. package/lib/engine/engine_utils.d.ts +2 -1
  57. package/lib/engine/engine_utils.js +6 -0
  58. package/lib/engine/engine_utils.js.map +1 -1
  59. package/lib/engine/extensions/NEEDLE_components.d.ts +1 -1
  60. package/lib/engine/extensions/NEEDLE_progressive.d.ts +22 -0
  61. package/lib/engine/extensions/NEEDLE_progressive.js +172 -44
  62. package/lib/engine/extensions/NEEDLE_progressive.js.map +1 -1
  63. package/lib/engine-components/Collider.d.ts +2 -0
  64. package/lib/engine-components/Collider.js +4 -0
  65. package/lib/engine-components/Collider.js.map +1 -1
  66. package/lib/engine-components/GroundProjection.d.ts +2 -1
  67. package/lib/engine-components/GroundProjection.js +19 -12
  68. package/lib/engine-components/GroundProjection.js.map +1 -1
  69. package/lib/engine-components/ParticleSystem.d.ts +1 -0
  70. package/lib/engine-components/ParticleSystem.js +10 -5
  71. package/lib/engine-components/ParticleSystem.js.map +1 -1
  72. package/lib/engine-components/ParticleSystemModules.d.ts +2 -2
  73. package/lib/engine-components/ParticleSystemModules.js +65 -55
  74. package/lib/engine-components/ParticleSystemModules.js.map +1 -1
  75. package/lib/engine-components/ReflectionProbe.d.ts +1 -1
  76. package/lib/engine-components/Renderer.d.ts +2 -1
  77. package/lib/engine-components/Renderer.js +8 -8
  78. package/lib/engine-components/Renderer.js.map +1 -1
  79. package/lib/engine-components/RigidBody.js +1 -19
  80. package/lib/engine-components/RigidBody.js.map +1 -1
  81. package/lib/engine-components/SyncedTransform.js +1 -3
  82. package/lib/engine-components/SyncedTransform.js.map +1 -1
  83. package/lib/engine-components/VideoPlayer.d.ts +2 -1
  84. package/lib/engine-components/VideoPlayer.js +54 -51
  85. package/lib/engine-components/VideoPlayer.js.map +1 -1
  86. package/lib/engine-components/Volume.js +8 -1
  87. package/lib/engine-components/Volume.js.map +1 -1
  88. package/lib/engine-components/WebARSessionRoot.js +5 -0
  89. package/lib/engine-components/WebARSessionRoot.js.map +1 -1
  90. package/lib/engine-components/WebXR.d.ts +2 -2
  91. package/lib/engine-components/WebXR.js +13 -13
  92. package/lib/engine-components/WebXR.js.map +1 -1
  93. package/lib/engine-components/WebXRAvatar.d.ts +1 -1
  94. package/lib/engine-components/WebXRController.js +1 -2
  95. package/lib/engine-components/WebXRController.js.map +1 -1
  96. package/lib/engine-components/codegen/components.d.ts +99 -99
  97. package/lib/engine-components/codegen/components.js +99 -99
  98. package/lib/engine-components/codegen/components.js.map +1 -1
  99. package/lib/engine-components/export/usdz/USDZExporter.d.ts +1 -0
  100. package/lib/engine-components/export/usdz/USDZExporter.js +17 -1
  101. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  102. package/lib/engine-components/ui/Button.js +30 -0
  103. package/lib/engine-components/ui/Button.js.map +1 -1
  104. package/lib/engine-components/ui/InputField.d.ts +2 -0
  105. package/lib/engine-components/ui/InputField.js +23 -1
  106. package/lib/engine-components/ui/InputField.js.map +1 -1
  107. package/lib/engine-components/ui/Utils.d.ts +2 -0
  108. package/lib/engine-components/ui/Utils.js +10 -9
  109. package/lib/engine-components/ui/Utils.js.map +1 -1
  110. package/lib/engine-components-experimental/Presentation.d.ts +6 -0
  111. package/lib/engine-components-experimental/Presentation.js +11 -0
  112. package/lib/engine-components-experimental/Presentation.js.map +1 -0
  113. package/lib/engine-components-experimental/annotation/LineDrawer.d.ts +18 -0
  114. package/lib/engine-components-experimental/annotation/LineDrawer.js +175 -0
  115. package/lib/engine-components-experimental/annotation/LineDrawer.js.map +1 -0
  116. package/lib/engine-components-experimental/annotation/LinesManager.d.ts +54 -0
  117. package/lib/engine-components-experimental/annotation/LinesManager.js +155 -0
  118. package/lib/engine-components-experimental/annotation/LinesManager.js.map +1 -0
  119. package/lib/engine-components-experimental/networking/PlayerSync.d.ts +26 -0
  120. package/lib/engine-components-experimental/networking/PlayerSync.js +121 -0
  121. package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -0
  122. package/lib/engine-schemes/vec2.d.ts +10 -0
  123. package/lib/engine-schemes/vec2.js +26 -0
  124. package/lib/engine-schemes/vec2.js.map +1 -0
  125. package/lib/include/three/ARButton.d.ts +3 -0
  126. package/lib/include/three/ARButton.js +158 -0
  127. package/lib/include/three/ARButton.js.map +1 -0
  128. package/lib/include/three/EXT_mesh_gpu_instancing_exporter.d.ts +6 -0
  129. package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js +46 -0
  130. package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js.map +1 -0
  131. package/lib/include/three/VRButton.d.ts +5 -0
  132. package/lib/include/three/VRButton.js +122 -0
  133. package/lib/include/three/VRButton.js.map +1 -0
  134. package/lib/tsconfig.tsbuildinfo +1 -0
  135. package/package.json +1 -1
  136. package/src/engine/codegen/register_types.js +214 -214
  137. package/src/engine/debug/debug.ts +5 -0
  138. package/src/engine/debug/debug_console.ts +3 -2
  139. package/src/engine/debug/debug_overlay.ts +3 -1
  140. package/src/engine/engine_element.ts +4 -2
  141. package/src/engine/engine_element_loading.ts +13 -6
  142. package/src/engine/engine_element_overlay.ts +4 -2
  143. package/src/engine/engine_input.ts +4 -0
  144. package/src/engine/engine_lightdata.ts +1 -1
  145. package/src/engine/engine_mainloop_utils.ts +6 -0
  146. package/src/engine/engine_networking_websocket.ts +3 -1
  147. package/src/engine/engine_physics.ts +47 -5
  148. package/src/engine/engine_physics.types.ts +17 -0
  149. package/src/engine/engine_serialization_builtin_serializer.ts +8 -5
  150. package/src/engine/engine_setup.ts +2 -2
  151. package/src/engine/engine_time.ts +7 -1
  152. package/src/engine/engine_types.ts +5 -2
  153. package/src/engine/engine_utils.ts +7 -1
  154. package/src/engine/extensions/NEEDLE_progressive.ts +185 -43
  155. package/src/engine-components/Collider.ts +3 -0
  156. package/src/engine-components/GroundProjection.ts +18 -12
  157. package/src/engine-components/ParticleSystem.ts +10 -5
  158. package/src/engine-components/ParticleSystemModules.ts +69 -59
  159. package/src/engine-components/Renderer.ts +11 -9
  160. package/src/engine-components/RigidBody.ts +1 -20
  161. package/src/engine-components/SyncedTransform.ts +1 -3
  162. package/src/engine-components/VideoPlayer.ts +55 -51
  163. package/src/engine-components/Volume.ts +8 -1
  164. package/src/engine-components/WebARSessionRoot.ts +5 -0
  165. package/src/engine-components/WebXR.ts +17 -15
  166. package/src/engine-components/WebXRController.ts +1 -2
  167. package/src/engine-components/codegen/components.ts +99 -99
  168. package/src/engine-components/export/usdz/USDZExporter.ts +19 -2
  169. package/src/engine-components/ui/Button.ts +8 -8
  170. package/src/engine-components/ui/InputField.ts +25 -2
  171. package/src/engine-components/ui/Utils.ts +12 -11
  172. package/src/engine-components-experimental/annotation/LineDrawer.ts +10 -7
  173. package/src/engine-components-experimental/annotation/LinesManager.ts +6 -6
  174. package/src/engine-components-experimental/networking/PlayerSync.ts +1 -1
  175. package/lib/engine/engine_caching.d.ts +0 -0
  176. package/lib/engine/engine_caching.js +0 -2
  177. package/lib/engine/engine_caching.js.map +0 -1
  178. package/lib/engine/tests/simulate_avatars.d.ts +0 -0
  179. package/lib/engine/tests/simulate_avatars.js +0 -3
  180. package/lib/engine/tests/simulate_avatars.js.map +0 -1
  181. package/lib/engine-components/NavMesh.d.ts +0 -0
  182. package/lib/engine-components/NavMesh.js +0 -101
  183. package/lib/engine-components/NavMesh.js.map +0 -1
  184. package/lib/engine-components/ParticleSystemBehaviours.d.ts +0 -0
  185. package/lib/engine-components/ParticleSystemBehaviours.js +0 -2
  186. package/lib/engine-components/ParticleSystemBehaviours.js.map +0 -1
  187. package/lib/engine-components/SpringJoint.d.ts +0 -0
  188. package/lib/engine-components/SpringJoint.js +0 -43
  189. package/lib/engine-components/SpringJoint.js.map +0 -1
  190. package/lib/engine-components/ui/CanvasScaler.d.ts +0 -0
  191. package/lib/engine-components/ui/CanvasScaler.js +0 -17
  192. package/lib/engine-components/ui/CanvasScaler.js.map +0 -1
  193. package/src/engine/dist/engine_three_utils.js +0 -279
  194. package/src/engine/engine_caching.ts +0 -0
  195. package/src/engine/tests/simulate_avatars.ts +0 -2
  196. package/src/engine-components/NavMesh.ts +0 -117
  197. package/src/engine-components/ParticleSystemBehaviours.ts +0 -0
  198. package/src/engine-components/SpringJoint.ts +0 -45
  199. package/src/engine-components/ui/CanvasScaler.ts +0 -21
@@ -3,7 +3,7 @@ import { GLTF, GLTFLoader, GLTFLoaderPlugin, GLTFParser } from "three/examples/j
3
3
  import { SourceIdentifier } from "../engine_types";
4
4
  import { Context } from "../engine_setup";
5
5
  import { addDracoAndKTX2Loaders } from "../engine_loaders";
6
- import { getParam, getPath } from "../engine_utils";
6
+ import { delay, getParam, getPath } from "../engine_utils";
7
7
 
8
8
  export const EXTENSION_NAME = "NEEDLE_progressive";
9
9
 
@@ -14,6 +14,7 @@ declare type ProgressiveTextureSchema = {
14
14
  guid: string;
15
15
  }
16
16
 
17
+
17
18
  const debug_toggle_maps: Map<Material, { [key: string]: { original: Texture, lod0: Texture } }> = new Map();
18
19
  let show_lod0 = false;
19
20
  if (debug) {
@@ -71,7 +72,6 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
71
72
  }
72
73
  }
73
74
 
74
-
75
75
  get name(): string {
76
76
  return EXTENSION_NAME;
77
77
  }
@@ -125,6 +125,7 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
125
125
 
126
126
  private static cache = new Map<string, ProgressiveTextureSchema>();
127
127
  private static resolved: { [key: string]: Texture } = {};
128
+ private static currentlyLoading: { [key: string]: Promise<Texture | null> } = {};
128
129
 
129
130
  private static async getOrLoadTexture(context: Context, source: SourceIdentifier | undefined, material: Material, slot: string, current: Texture, _level: number): Promise<Texture | null> {
130
131
 
@@ -145,53 +146,82 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
145
146
  return this.resolved[resolveKey];
146
147
  }
147
148
 
148
- const loader = new GLTFLoader();
149
- addDracoAndKTX2Loaders(loader, context);
150
- if (debug) console.log("Load " + uri, material.name, slot, ext.guid);
151
- const gltf = await loader.loadAsync(uri);
152
- const parser = gltf.parser;
153
- if (debug) console.log("Loading finished " + uri, material.name, slot, ext.guid);
154
- let index = -1;
155
- let found = false;
156
- for (const tex of gltf.parser.json.textures) {
157
- index++;
158
- if (tex?.extensions) {
159
- const other: ProgressiveTextureSchema = tex?.extensions[EXTENSION_NAME];
160
- if (other?.guid) {
161
- if (other.guid === ext.guid) {
162
- found = true;
163
- break;
164
- // if (debug)
165
- // console.log(material.name, slot, "change \"" + current.name + "\" → \"" + tex.name + "\"", uri, index, tex, material);
166
- // this.resolved[resolveKey] = tex as Texture;
167
- // return tex;
149
+ const info = this.onProgressiveLoadStart(context, source, uri, material, slot);
150
+ try {
151
+ if(this.currentlyLoading[resolveKey] !== undefined) {
152
+ if(debug)
153
+ console.log("Already loading:", material.name + "." + slot, resolveKey);
154
+ const tex = await this.currentlyLoading[resolveKey];
155
+ return tex;
156
+ }
157
+ const request = new Promise<Texture | null>(async (resolve, _) => {
158
+ const loader = new GLTFLoader();
159
+ addDracoAndKTX2Loaders(loader, context);
160
+
161
+ if (debug) console.log("Load " + uri, material.name, slot, ext.guid);
162
+ if (debug) {
163
+ await delay(Math.random() * 1000);
164
+ }
165
+
166
+ const gltf = await loader.loadAsync(uri);
167
+ const parser = gltf.parser;
168
+ if (debug) console.log("Loading finished " + uri, material.name, slot, ext.guid);
169
+ let index = -1;
170
+ let found = false;
171
+ for (const tex of gltf.parser.json.textures) {
172
+ index++;
173
+ if (tex?.extensions) {
174
+ const other: ProgressiveTextureSchema = tex?.extensions[EXTENSION_NAME];
175
+ if (other?.guid) {
176
+ if (other.guid === ext.guid) {
177
+ found = true;
178
+ break;
179
+ }
180
+ }
168
181
  }
169
182
  }
170
- }
171
- }
172
- if (!found)
173
- return null;
183
+ if (!found)
184
+ return resolve(null);
174
185
 
175
- // const index = Number.parseInt(ext.pointer.substring("textures/".length));
176
- const tex = await parser.getDependency("texture", index);
177
- tex.encoding = current.encoding;
178
- if (tex) {
179
- tex.guid = ext.guid;
186
+ const tex = await parser.getDependency("texture", index);
187
+ tex.encoding = current.encoding;
188
+ if (tex) {
189
+ tex.guid = ext.guid;
190
+ }
191
+ this.resolved[resolveKey] = tex as Texture;
192
+ if (debug)
193
+ console.log(material.name, slot, "change \"" + current.name + "\" → \"" + tex.name + "\"", uri, index, tex, material, resolveKey);
194
+ resolve(tex);
195
+ });
196
+ this.currentlyLoading[resolveKey] = request;
197
+ const tex = await request;
198
+ return tex;
199
+ }
200
+ finally {
201
+ delete this.currentlyLoading[resolveKey];
202
+ this.onProgressiveLoadEnd(info);
180
203
  }
181
- this.resolved[resolveKey] = tex as Texture;
182
- if (debug)
183
- console.log(material.name, slot, "change \"" + current.name + "\" → \"" + tex.name + "\"", uri, index, tex, material, resolveKey);
184
- return tex;
185
204
  }
186
205
  else {
187
- if (debug) console.log("Load texture from uri: " + uri);
188
- const loader = new TextureLoader();
189
- const loaded = await loader.loadAsync(uri);
190
- if (loaded && debug) {
191
- console.log(ext, loaded);
206
+ const info = this.onProgressiveLoadStart(context, source, uri, material, slot);
207
+ try {
208
+ if (debug) console.log("Load texture from uri: " + uri);
209
+ const loader = new TextureLoader();
210
+ const tex = await loader.loadAsync(uri);
211
+ if (tex) {
212
+ (tex as any).guid = ext.guid;
213
+ tex.flipY = false;
214
+ tex.needsUpdate = true;
215
+ tex.encoding = current.encoding;
216
+ if (debug)
217
+ console.log(ext, tex);
218
+ }
219
+ else if (debug) console.warn("failed loading", uri);
220
+ return tex;
221
+ }
222
+ finally {
223
+ this.onProgressiveLoadEnd(info);
192
224
  }
193
- else console.warn("failed loading", uri);
194
- return loaded;
195
225
  }
196
226
  // loader.then((h: Texture) => {
197
227
  // // console.log(t, h);
@@ -212,4 +242,116 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
212
242
  }
213
243
  return null;
214
244
  }
215
- }
245
+
246
+
247
+ /** subscribe to events whenever a loading event starts, invoked for every single loading process that starts */
248
+ static beginListenStart(context: Context, evt: ProgressiveLoadingEvent) {
249
+ if (!this._progressiveEventListeners.has(context)) {
250
+ this._progressiveEventListeners.set(context, new ProgressiveLoadingEventHandler());
251
+ }
252
+ this._progressiveEventListeners.get(context)!.start.push(evt);
253
+ }
254
+ static stopListenStart(context: Context, evt: ProgressiveLoadingEvent) {
255
+ if (!this._progressiveEventListeners.has(context)) {
256
+ return;
257
+ }
258
+ const listeners = this._progressiveEventListeners.get(context)!.start;
259
+ const index = listeners.indexOf(evt);
260
+ if (index >= 0) {
261
+ listeners.splice(index, 1);
262
+ }
263
+ }
264
+
265
+ /** subscribe to loading event ended event */
266
+ static beginListenEnd(context: Context, evt: ProgressiveLoadingEvent) {
267
+ if (!this._progressiveEventListeners.has(context)) {
268
+ this._progressiveEventListeners.set(context, new ProgressiveLoadingEventHandler());
269
+ }
270
+ this._progressiveEventListeners.get(context)!.end.push(evt);
271
+ }
272
+ static stopListenEnd(context: Context, evt: ProgressiveLoadingEvent) {
273
+ if (!this._progressiveEventListeners.has(context)) {
274
+ return;
275
+ }
276
+ const listeners = this._progressiveEventListeners.get(context)!.end;
277
+ const index = listeners.indexOf(evt);
278
+ if (index >= 0) {
279
+ listeners.splice(index, 1);
280
+ }
281
+ }
282
+
283
+ /** event listeners per context */
284
+ private static _progressiveEventListeners: Map<Context, ProgressiveLoadingEventHandler> = new Map();
285
+ //** loading info per context, contains an array of urls that are currently being loaded */
286
+ private static _currentProgressiveLoadingInfo: Map<Context, ProgressiveLoadingInfo[]> = new Map();
287
+
288
+ // called whenever a progressive loading event starts
289
+ private static onProgressiveLoadStart(context: Context, source: SourceIdentifier | undefined, uri: string, material: Material, slot: string): ProgressiveLoadingInfo {
290
+ if (!this._currentProgressiveLoadingInfo.has(context)) {
291
+ this._currentProgressiveLoadingInfo.set(context, []);
292
+ }
293
+ const info = new ProgressiveLoadingInfo(context, source, uri, material, slot);
294
+ const current = this._currentProgressiveLoadingInfo.get(context)!;
295
+ const listener = this._progressiveEventListeners.get(context);
296
+ if (listener) listener.onStart(info);
297
+
298
+ current.push(info);
299
+ return info;
300
+ }
301
+
302
+ private static onProgressiveLoadEnd(info: ProgressiveLoadingInfo) {
303
+ if (!info) return;
304
+ const context = info.context;
305
+ if (!this._currentProgressiveLoadingInfo.has(context)) {
306
+ return;
307
+ }
308
+ const current = this._currentProgressiveLoadingInfo.get(context)!;
309
+ const index = current.indexOf(info);
310
+ if (index < 0) {
311
+ return;
312
+ }
313
+ current.splice(index, 1);
314
+ const listener = this._progressiveEventListeners.get(context);
315
+ if (listener) listener.onEnd(info);
316
+ }
317
+ }
318
+
319
+
320
+ /** info object that holds information about a file that is currently being loaded */
321
+ export class ProgressiveLoadingInfo {
322
+ readonly context: Context;
323
+ readonly source: SourceIdentifier | undefined;
324
+ readonly uri: string;
325
+ readonly material?: Material;
326
+ readonly slot?: string;
327
+ // TODO: can contain information if the event is a background process / preloading or if the object is currently visible
328
+
329
+ constructor(context: Context, source: SourceIdentifier | undefined, uri: string, material?: Material, slot?: string) {
330
+ this.context = context;
331
+ this.source = source;
332
+ this.uri = uri;
333
+ this.material = material;
334
+ this.slot = slot;
335
+ }
336
+ };
337
+
338
+
339
+ export declare type ProgressiveLoadingEvent = (info: ProgressiveLoadingInfo) => void;
340
+
341
+ /** progressive loading event handler implementation */
342
+ class ProgressiveLoadingEventHandler {
343
+ start: ProgressiveLoadingEvent[] = [];
344
+ end: ProgressiveLoadingEvent[] = [];
345
+
346
+ onStart(listener: ProgressiveLoadingInfo) {
347
+ for (const l of this.start) {
348
+ l(listener);
349
+ }
350
+ }
351
+
352
+ onEnd(listener: ProgressiveLoadingInfo) {
353
+ for (const l of this.end) {
354
+ l(listener);
355
+ }
356
+ }
357
+ }
@@ -5,6 +5,7 @@ import { Event, Mesh, Object3D, Vector3 } from "three"
5
5
  // import { IColliderProvider, registerColliderProvider } from "../engine/engine_physics";
6
6
  import { ICollider } from "../engine/engine_types";
7
7
  import { getWorldScale } from "../engine/engine_three_utils";
8
+ import { PhysicsMaterial } from "../engine/engine_physics.types";
8
9
 
9
10
 
10
11
  export class Collider extends Behaviour implements ICollider {
@@ -18,6 +19,8 @@ export class Collider extends Behaviour implements ICollider {
18
19
  @serializable()
19
20
  isTrigger: boolean = false;
20
21
 
22
+ @serializable()
23
+ sharedMaterial?: PhysicsMaterial;
21
24
 
22
25
  awake() {
23
26
  super.awake();
@@ -7,6 +7,9 @@ import { Texture } from "three";
7
7
 
8
8
  export class GroundProjectedEnv extends Behaviour {
9
9
 
10
+ @serializable()
11
+ applyOnAwake: boolean = false;
12
+
10
13
  @serializable()
11
14
  set scale(val: number) {
12
15
  this._scale = val;
@@ -40,14 +43,23 @@ export class GroundProjectedEnv extends Behaviour {
40
43
  private _watcher?: Watch;
41
44
 
42
45
 
43
- onEnable() {
44
- // TODO: if we do this in the first frame we can not disable it again. Something buggy with the watch?!
45
- if (this.context.time.frameCount > 0)
46
+ awake() {
47
+ if (this.applyOnAwake)
46
48
  this.updateAndCreate();
47
49
  }
48
50
 
49
- start() {
50
- this.updateAndCreate();
51
+ onEnable() {
52
+ // TODO: if we do this in the first frame we can not disable it again. Something buggy with the watch?!
53
+ if (this.context.time.frameCount > 0) {
54
+ if (this.applyOnAwake)
55
+ this.updateAndCreate();
56
+ }
57
+ if (!this._watcher) {
58
+ this._watcher = new Watch(this.context.scene, "environment");
59
+ this._watcher.subscribeWrite(_ => {
60
+ this.updateProjection();
61
+ });
62
+ }
51
63
  }
52
64
 
53
65
  onDisable() {
@@ -57,13 +69,7 @@ export class GroundProjectedEnv extends Behaviour {
57
69
 
58
70
  private updateAndCreate() {
59
71
  this.updateProjection();
60
- if (!this._watcher) {
61
- this._watcher = new Watch(this.context.scene, "environment");
62
- this._watcher.subscribeWrite(_ => {
63
- this.updateProjection();
64
- });
65
- }
66
- this._watcher.apply();
72
+ this._watcher?.apply();
67
73
  }
68
74
 
69
75
  updateProjection() {
@@ -548,6 +548,8 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
548
548
  private _state?: ParticlesEmissionState;
549
549
  emit(count: number) {
550
550
  if (this._particleSystem) {
551
+ // we need to call update the matrices etc e.g. if we call emit from a physics callback
552
+ this.onUpdate();
551
553
  count = Math.min(count, this.maxParticles - this.currentParticles);
552
554
  if (!this._state) this._state = new ParticlesEmissionState();
553
555
  this._state.waitEmiting = count;
@@ -768,6 +770,14 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
768
770
  }
769
771
 
770
772
  onBeforeRender() {
773
+ this.onUpdate();
774
+ const dt = this.deltaTime;
775
+ this._batchSystem?.update(dt);
776
+ this._time += dt;
777
+ if (this._time > this.duration) this._time = 0;
778
+ }
779
+
780
+ private onUpdate(){
771
781
  if (this._bursts) {
772
782
  this.emission.bursts = this._bursts;
773
783
  delete this._bursts;
@@ -796,17 +806,12 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
796
806
  this._container.matrix.identity();
797
807
  this._container.matrix.scale(scale);
798
808
  }
799
-
800
809
  this.emission.system = this;
801
- const dt = this.deltaTime;
802
810
  this._interface.update();
803
811
  this.shape.update(this, this.context, this.main.simulationSpace, this.gameObject);
804
812
  this.noise.update(this.context);
805
813
  this.inheritVelocity?.update(this.context);
806
814
  this.velocityOverLifetime.update(this);
807
- this._batchSystem?.update(dt);
808
- this._time += dt;
809
- if (this._time > this.duration) this._time = 0;
810
815
  }
811
816
 
812
817
  private addSubParticleSystems() {
@@ -6,6 +6,11 @@ import { AnimationCurve } from "./AnimationCurve";
6
6
  import { Vec2, Vec3 } from "../engine/engine_types";
7
7
  import { Context } from "../engine/engine_setup";
8
8
  import { EmitterShape, FrameOverLife, Particle, ShapeJSON } from "three.quarks";
9
+ import { createNoise4D, NoiseFunction4D } from 'simplex-noise';
10
+ import { Gizmos } from "../engine/engine_gizmos";
11
+ import { getParam } from "../engine/engine_utils";
12
+
13
+ const debug = getParam("debugparticles");
9
14
 
10
15
  declare type Color4 = { r: number, g: number, b: number, a: number };
11
16
  declare type ColorKey = { time: number, color: Color4 };
@@ -457,10 +462,10 @@ export class SizeOverLifetimeModule {
457
462
 
458
463
  export class ShapeModule implements EmitterShape {
459
464
 
465
+ // Emittershape start
460
466
  get type(): string {
461
467
  return ParticleSystemShapeType[this.shapeType];
462
468
  }
463
-
464
469
  initialize(particle: Particle): void {
465
470
  this.getPosition();
466
471
  particle.position.copy(this._vector);
@@ -471,6 +476,7 @@ export class ShapeModule implements EmitterShape {
471
476
  clone(): EmitterShape {
472
477
  return new ShapeModule();
473
478
  }
479
+ // EmitterShape end
474
480
 
475
481
  @serializable()
476
482
  shapeType: ParticleSystemShapeType = ParticleSystemShapeType.Box;
@@ -517,9 +523,9 @@ export class ShapeModule implements EmitterShape {
517
523
  private readonly _worldSpaceMatrixInverse: Matrix4 = new Matrix4();
518
524
 
519
525
 
520
- constructor() {
521
- // console.log(this);
522
- }
526
+ // constructor() {
527
+ // console.log(this);
528
+ // }
523
529
 
524
530
  update(system: IParticleSystem, _context: Context, simulationSpace: ParticleSystemSimulationSpace, obj: Object3D) {
525
531
  this.system = system;
@@ -534,6 +540,16 @@ export class ShapeModule implements EmitterShape {
534
540
  }
535
541
  }
536
542
 
543
+ private updateRotation() {
544
+ const isRotated = this.rotation.x !== 0 || this.rotation.y !== 0 || this.rotation.z !== 0;
545
+ if (isRotated) {
546
+ this._rotation.x = Mathf.toRadians(this.rotation.x);
547
+ this._rotation.y = -Mathf.toRadians(this.rotation.y);
548
+ this._rotation.z = -Mathf.toRadians(this.rotation.z);
549
+ }
550
+ return isRotated;
551
+ }
552
+
537
553
  /** nebula implementations: */
538
554
 
539
555
  /** initializer implementation */
@@ -544,61 +560,49 @@ export class ShapeModule implements EmitterShape {
544
560
  return this._vector;
545
561
  }
546
562
  getPosition(): void {
547
- if (!this.enabled) {
548
- this._vector.set(0, 0, 0);
549
- return;
550
- }
563
+ this._vector.set(0, 0, 0);
551
564
  const pos = this._temp.copy(this.position);
552
565
  const isWorldSpace = this._space === ParticleSystemSimulationSpace.World;
553
566
  if (isWorldSpace) {
554
567
  pos.applyQuaternion(this.system.worldQuaternion);
555
568
  }
556
-
557
- const isRotated = this.rotation.x !== 0 || this.rotation.y !== 0 || this.rotation.z !== 0;
558
- if (isRotated) {
559
- this._rotation.x = Mathf.toRadians(this.rotation.x);
560
- this._rotation.y = -Mathf.toRadians(this.rotation.y);
561
- this._rotation.z = -Mathf.toRadians(this.rotation.z);
562
- }
563
-
564
569
  let radius = this.radius;
565
570
  if (isWorldSpace) radius *= this.system.worldScale.x;
566
- switch (this.shapeType) {
567
- case ParticleSystemShapeType.Box:
568
- this._vector.x = Math.random() * this.scale.x - this.scale.x / 2;
569
- this._vector.y = Math.random() * this.scale.y - this.scale.y / 2;
570
- this._vector.z = Math.random() * this.scale.z - this.scale.z / 2;
571
- this._vector.add(pos);
572
- break;
573
- case ParticleSystemShapeType.Cone:
574
- this.randomConePoint(this.position, this.angle, radius, this.radiusThickness, this.arc, this.arcMode, this._vector);
575
- break;
576
- case ParticleSystemShapeType.Sphere:
577
- this.randomSpherePoint(this.position, radius, this.radiusThickness, this.arc, this._vector);
578
- this._vector.x *= this.scale.x;
579
- this._vector.y *= this.scale.y;
580
- this._vector.z *= this.scale.z;
581
- break;
582
- case ParticleSystemShapeType.Circle:
583
- this.randomSpherePoint(this.position, radius, this.radiusThickness, this.arc, this._vector);
584
- this._vector.x *= this.scale.x;
585
- this._vector.y *= this.scale.y;
586
- this._vector.z *= 0;
587
- break;
588
- default:
589
- this._vector.set(0, 0, 0);
590
- break;
591
- // case ParticleSystemShapeType.Hemisphere:
592
- // randomSpherePoint(this.position.x, this.position.y, this.position.z, this.radius, this.radiusThickness, 180, this._vector);
593
- // break;
594
- }
571
+ if (this.enabled) {
572
+ switch (this.shapeType) {
573
+ case ParticleSystemShapeType.Box:
574
+ this._vector.x = Math.random() * this.scale.x - this.scale.x / 2;
575
+ this._vector.y = Math.random() * this.scale.y - this.scale.y / 2;
576
+ this._vector.z = Math.random() * this.scale.z - this.scale.z / 2;
577
+ this._vector.add(pos);
578
+ break;
579
+ case ParticleSystemShapeType.Cone:
580
+ this.randomConePoint(this.position, this.angle, radius, this.radiusThickness, this.arc, this.arcMode, this._vector);
581
+ break;
582
+ case ParticleSystemShapeType.Sphere:
583
+ this.randomSpherePoint(this.position, radius, this.radiusThickness, this.arc, this._vector, this.scale);
584
+ break;
585
+ case ParticleSystemShapeType.Circle:
586
+ this._temp.copy(this.scale);
587
+ this._temp.z = 0;
588
+ this.randomSpherePoint(this.position, radius, this.radiusThickness, this.arc, this._vector, this._temp);
589
+ break;
590
+ default:
591
+ this._vector.set(0, 0, 0);
592
+ break;
593
+ // case ParticleSystemShapeType.Hemisphere:
594
+ // randomSpherePoint(this.position.x, this.position.y, this.position.z, this.radius, this.radiusThickness, 180, this._vector);
595
+ // break;
596
+ }
595
597
 
596
- this.randomizePosition(this._vector, this.randomPositionAmount);
598
+ this.randomizePosition(this._vector, this.randomPositionAmount);
599
+ }
597
600
 
598
- if (isRotated)
601
+ if (this.updateRotation())
599
602
  this._vector.applyEuler(this._rotation);
600
603
 
601
- if (this._space === ParticleSystemSimulationSpace.World) {
604
+ if (isWorldSpace) {
605
+ this._vector.applyQuaternion(this.system.worldQuaternion);
602
606
  this._vector.add(this.system.worldPos);
603
607
  }
604
608
  }
@@ -606,7 +610,8 @@ export class ShapeModule implements EmitterShape {
606
610
 
607
611
 
608
612
  private _dir: Vector3 = new Vector3();
609
- getDirection(position): Vector3 {
613
+
614
+ getDirection(pos: Vec3): Vector3 {
610
615
  if (!this.enabled) {
611
616
  this._dir.set(0, 0, 1);
612
617
  return this._dir;
@@ -622,10 +627,11 @@ export class ShapeModule implements EmitterShape {
622
627
  break;
623
628
  case ParticleSystemShapeType.Circle:
624
629
  case ParticleSystemShapeType.Sphere:
625
- const rx = position.x;
626
- const ry = position.y;
627
- const rz = position.z;
628
- this._dir.set(rx, ry, rz).sub(this.position)
630
+ const rx = pos.x;
631
+ const ry = pos.y;
632
+ const rz = pos.z;
633
+ this._dir.set(rx, ry, rz)
634
+ this._dir.sub(this.position)
629
635
  break;
630
636
  default:
631
637
  this._dir.set(0, 0, 1);
@@ -634,10 +640,15 @@ export class ShapeModule implements EmitterShape {
634
640
  if (this._space === ParticleSystemSimulationSpace.World) {
635
641
  this._dir.applyMatrix4(this._worldSpaceMatrixInverse);
636
642
  }
643
+ if (this.updateRotation())
644
+ this._dir.applyEuler(this._rotation);
637
645
  this._dir.normalize();
638
646
  this.spherizeDirection(this._dir, this.sphericalDirectionAmount);
639
647
  this.randomizeDirection(this._dir, this.randomDirectionAmount);
640
- // Gizmos.DrawDirection(position, this._dir, 0xff0000, .5);
648
+ if (debug) {
649
+ Gizmos.DrawSphere(pos, .01, 0x883300, .5, true);
650
+ Gizmos.DrawDirection(pos, this._dir, 0x883300, .5, true);
651
+ }
641
652
  return this._dir;
642
653
  }
643
654
 
@@ -674,15 +685,15 @@ export class ShapeModule implements EmitterShape {
674
685
  dir.lerp(v, amount);
675
686
  }
676
687
 
677
- private randomSpherePoint(pos: Vec3, radius: number, thickness: number, arc: number, vec: Vec3) {
688
+ private randomSpherePoint(pos: Vec3, radius: number, thickness: number, arc: number, vec: Vec3, scale: Vec3) {
678
689
  const u = Math.random();
679
690
  const v = Math.random();
680
691
  const theta = 2 * Math.PI * u * (arc / 360);
681
692
  const phi = Math.acos(2 * v - 1);
682
693
  const r = Mathf.lerp(1, 1 - (Math.pow(1 - Math.random(), Math.PI)), thickness) * (radius);
683
- const x = pos.x + (-r * Math.sin(phi) * Math.cos(theta));
684
- const y = pos.y + (r * Math.sin(phi) * Math.sin(theta));
685
- const z = pos.z + (r * Math.cos(phi));
694
+ const x = pos.x + scale.x * (-r * Math.sin(phi) * Math.cos(theta));
695
+ const y = pos.y + scale.y * (r * Math.sin(phi) * Math.sin(theta));
696
+ const z = pos.z + scale.z * (r * Math.cos(phi));
686
697
  vec.x = x;
687
698
  vec.y = y;
688
699
  vec.z = z;
@@ -735,7 +746,6 @@ export class ShapeModule implements EmitterShape {
735
746
 
736
747
 
737
748
 
738
- import { createNoise4D, NoiseFunction4D } from 'simplex-noise';
739
749
 
740
750
  export class NoiseModule {
741
751
  @serializable()
@@ -229,6 +229,12 @@ export class Renderer extends Behaviour implements IRenderer {
229
229
 
230
230
  allowProgressiveLoading: boolean = true;
231
231
 
232
+ registering() {
233
+ if (!this.enabled) {
234
+ this.setVisibility(false);
235
+ }
236
+ }
237
+
232
238
  awake() {
233
239
  this.clearInstancingState();
234
240
 
@@ -463,14 +469,10 @@ export class Renderer extends Behaviour implements IRenderer {
463
469
  if (!suppressProgressiveLoading && material._didRequestTextureLOD === undefined && this.allowProgressiveLoading) {
464
470
  material._didRequestTextureLOD = 0;
465
471
  if (debugProgressiveLoading) {
466
- console.log("Load material LOD (with delay)", material.name);
467
- setTimeout(() => {
468
- NEEDLE_progressive.assignTextureLOD(this.context, this.sourceId, material);
469
- }, 2000);
470
- }
471
- else {
472
- NEEDLE_progressive.assignTextureLOD(this.context, this.sourceId, material);
472
+ console.log("Load material LOD", material.name);
473
473
  }
474
+ NEEDLE_progressive.assignTextureLOD(this.context, this.sourceId, material);
475
+
474
476
  }
475
477
 
476
478
  if (material.envMapIntensity !== undefined) {
@@ -549,10 +551,10 @@ export class Renderer extends Behaviour implements IRenderer {
549
551
  // update the reflection probe right before rendering
550
552
  // if we do it immediately the reflection probe might not be enabled yet
551
553
  // (since this method is called from onEnable)
552
- this.startCoroutine(this._updateReflectionProbe(), FrameEvent.OnBeforeRender);
554
+ this.startCoroutine(this._updateReflectionProbe(), FrameEvent.LateUpdate);
553
555
  }
554
556
  }
555
- private *_updateReflectionProbe(){
557
+ private *_updateReflectionProbe() {
556
558
  const obj = this.probeAnchor || this.gameObject;
557
559
  const isAnchor = this.probeAnchor ? true : false;
558
560
  this._reflectionProbe = ReflectionProbe.get(obj, this.context, isAnchor);