@needle-tools/engine 2.66.1-pre → 2.67.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 (230) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/needle-engine.js +34306 -26230
  3. package/dist/needle-engine.umd.cjs +743 -298
  4. package/lib/engine/api.d.ts +4 -0
  5. package/lib/engine/api.js +10 -0
  6. package/lib/engine/api.js.map +1 -1
  7. package/lib/engine/codegen/register_types.js +23 -7
  8. package/lib/engine/codegen/register_types.js.map +1 -1
  9. package/lib/engine/debug/debug_overlay.js +7 -1
  10. package/lib/engine/debug/debug_overlay.js.map +1 -1
  11. package/lib/engine/engine_addressables.js +2 -2
  12. package/lib/engine/engine_addressables.js.map +1 -1
  13. package/lib/engine/engine_assetdatabase.d.ts +17 -51
  14. package/lib/engine/engine_assetdatabase.js +252 -126
  15. package/lib/engine/engine_assetdatabase.js.map +1 -1
  16. package/lib/engine/engine_components.js +13 -1
  17. package/lib/engine/engine_components.js.map +1 -1
  18. package/lib/engine/engine_components_internal.d.ts +8 -0
  19. package/lib/engine/engine_components_internal.js +29 -0
  20. package/lib/engine/engine_components_internal.js.map +1 -0
  21. package/lib/engine/engine_constants.d.ts +1 -0
  22. package/lib/engine/engine_constants.js +1 -0
  23. package/lib/engine/engine_constants.js.map +1 -1
  24. package/lib/engine/engine_context_registry.d.ts +2 -0
  25. package/lib/engine/engine_context_registry.js +6 -0
  26. package/lib/engine/engine_context_registry.js.map +1 -1
  27. package/lib/engine/engine_editor-sync.d.ts +9 -0
  28. package/lib/engine/engine_editor-sync.js +8 -0
  29. package/lib/engine/engine_editor-sync.js.map +1 -0
  30. package/lib/engine/engine_element_loading.js +1 -1
  31. package/lib/engine/engine_element_loading.js.map +1 -1
  32. package/lib/engine/engine_gameobject.js +15 -20
  33. package/lib/engine/engine_gameobject.js.map +1 -1
  34. package/lib/engine/engine_gltf_builtin_components.d.ts +2 -3
  35. package/lib/engine/engine_gltf_builtin_components.js +23 -6
  36. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  37. package/lib/engine/engine_networking_auto.d.ts +1 -0
  38. package/lib/engine/engine_networking_auto.js +42 -9
  39. package/lib/engine/engine_networking_auto.js.map +1 -1
  40. package/lib/engine/engine_patcher.d.ts +8 -0
  41. package/lib/engine/engine_patcher.js +98 -0
  42. package/lib/engine/engine_patcher.js.map +1 -0
  43. package/lib/engine/engine_physics.d.ts +5 -1
  44. package/lib/engine/engine_physics.js +11 -1
  45. package/lib/engine/engine_physics.js.map +1 -1
  46. package/lib/engine/engine_scenetools.js +0 -1
  47. package/lib/engine/engine_scenetools.js.map +1 -1
  48. package/lib/engine/engine_serialization_core.js +4 -0
  49. package/lib/engine/engine_serialization_core.js.map +1 -1
  50. package/lib/engine/engine_setup.d.ts +1 -1
  51. package/lib/engine/engine_setup.js +9 -5
  52. package/lib/engine/engine_setup.js.map +1 -1
  53. package/lib/engine/engine_texture.d.ts +6 -1
  54. package/lib/engine/engine_texture.js +39 -1
  55. package/lib/engine/engine_texture.js.map +1 -1
  56. package/lib/engine/engine_types.d.ts +4 -0
  57. package/lib/engine/engine_types.js.map +1 -1
  58. package/lib/engine/engine_utils.js +3 -2
  59. package/lib/engine/engine_utils.js.map +1 -1
  60. package/lib/engine/extensions/NEEDLE_progressive.d.ts +0 -1
  61. package/lib/engine/extensions/NEEDLE_progressive.js +24 -26
  62. package/lib/engine/extensions/NEEDLE_progressive.js.map +1 -1
  63. package/lib/engine/extensions/extensions.d.ts +4 -1
  64. package/lib/engine/extensions/extensions.js +16 -0
  65. package/lib/engine/extensions/extensions.js.map +1 -1
  66. package/lib/engine/extensions/usage_tracker.d.ts +12 -0
  67. package/lib/engine/extensions/usage_tracker.js +59 -0
  68. package/lib/engine/extensions/usage_tracker.js.map +1 -0
  69. package/lib/engine-components/AnimatorController.js +4 -0
  70. package/lib/engine-components/AnimatorController.js.map +1 -1
  71. package/lib/engine-components/AudioSource.js +2 -1
  72. package/lib/engine-components/AudioSource.js.map +1 -1
  73. package/lib/engine-components/Camera.d.ts +6 -0
  74. package/lib/engine-components/Camera.js +70 -31
  75. package/lib/engine-components/Camera.js.map +1 -1
  76. package/lib/engine-components/Component.d.ts +52 -0
  77. package/lib/engine-components/Component.js +55 -14
  78. package/lib/engine-components/Component.js.map +1 -1
  79. package/lib/engine-components/Networking.js +19 -0
  80. package/lib/engine-components/Networking.js.map +1 -1
  81. package/lib/engine-components/OrbitControls.d.ts +2 -0
  82. package/lib/engine-components/OrbitControls.js +9 -0
  83. package/lib/engine-components/OrbitControls.js.map +1 -1
  84. package/lib/engine-components/ParticleSystem.js +11 -1
  85. package/lib/engine-components/ParticleSystem.js.map +1 -1
  86. package/lib/engine-components/ReflectionProbe.js +18 -6
  87. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  88. package/lib/engine-components/Renderer.d.ts +1 -1
  89. package/lib/engine-components/Renderer.js +24 -6
  90. package/lib/engine-components/Renderer.js.map +1 -1
  91. package/lib/engine-components/Skybox.js +2 -0
  92. package/lib/engine-components/Skybox.js.map +1 -1
  93. package/lib/engine-components/SmoothFollow.js +1 -2
  94. package/lib/engine-components/SmoothFollow.js.map +1 -1
  95. package/lib/engine-components/WebARCameraBackground.d.ts +19 -0
  96. package/lib/engine-components/WebARCameraBackground.js +185 -0
  97. package/lib/engine-components/WebARCameraBackground.js.map +1 -0
  98. package/lib/engine-components/WebXR.d.ts +4 -0
  99. package/lib/engine-components/WebXR.js +11 -8
  100. package/lib/engine-components/WebXR.js.map +1 -1
  101. package/lib/engine-components/WebXRAvatar.js +1 -0
  102. package/lib/engine-components/WebXRAvatar.js.map +1 -1
  103. package/lib/engine-components/codegen/components.d.ts +14 -6
  104. package/lib/engine-components/codegen/components.js +14 -6
  105. package/lib/engine-components/codegen/components.js.map +1 -1
  106. package/lib/engine-components/js-extensions/Object3D.js +4 -1
  107. package/lib/engine-components/js-extensions/Object3D.js.map +1 -1
  108. package/lib/engine-components/postprocessing/Effects/Antialiasing.d.ts +13 -0
  109. package/lib/engine-components/postprocessing/Effects/Antialiasing.js +46 -0
  110. package/lib/engine-components/postprocessing/Effects/Antialiasing.js.map +1 -0
  111. package/lib/engine-components/postprocessing/Effects/Bloom.d.ts +12 -0
  112. package/lib/engine-components/postprocessing/Effects/Bloom.js +76 -0
  113. package/lib/engine-components/postprocessing/Effects/Bloom.js.map +1 -0
  114. package/lib/engine-components/postprocessing/Effects/ChromaticAberration.d.ts +8 -0
  115. package/lib/engine-components/postprocessing/Effects/ChromaticAberration.js +39 -0
  116. package/lib/engine-components/postprocessing/Effects/ChromaticAberration.js.map +1 -0
  117. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.d.ts +12 -0
  118. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js +96 -0
  119. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js.map +1 -0
  120. package/lib/engine-components/postprocessing/Effects/DepthOfField.d.ts +21 -0
  121. package/lib/engine-components/postprocessing/Effects/DepthOfField.js +87 -0
  122. package/lib/engine-components/postprocessing/Effects/DepthOfField.js.map +1 -0
  123. package/lib/engine-components/postprocessing/Effects/Pixelation.d.ts +7 -0
  124. package/lib/engine-components/postprocessing/Effects/Pixelation.js +30 -0
  125. package/lib/engine-components/postprocessing/Effects/Pixelation.js.map +1 -0
  126. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.d.ts +11 -0
  127. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js +70 -0
  128. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js.map +1 -0
  129. package/lib/engine-components/postprocessing/Effects/Tonemapping.d.ts +16 -0
  130. package/lib/engine-components/postprocessing/Effects/Tonemapping.js +52 -0
  131. package/lib/engine-components/postprocessing/Effects/Tonemapping.js.map +1 -0
  132. package/lib/engine-components/postprocessing/Effects/Vignette.d.ts +11 -0
  133. package/lib/engine-components/postprocessing/Effects/Vignette.js +57 -0
  134. package/lib/engine-components/postprocessing/Effects/Vignette.js.map +1 -0
  135. package/lib/engine-components/postprocessing/PostProcessingEffect.d.ts +29 -0
  136. package/lib/engine-components/postprocessing/PostProcessingEffect.js +89 -0
  137. package/lib/engine-components/postprocessing/PostProcessingEffect.js.map +1 -0
  138. package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +13 -0
  139. package/lib/engine-components/postprocessing/PostProcessingHandler.js +119 -0
  140. package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -0
  141. package/lib/engine-components/postprocessing/Volume.d.ts +23 -0
  142. package/lib/engine-components/postprocessing/Volume.js +176 -0
  143. package/lib/engine-components/postprocessing/Volume.js.map +1 -0
  144. package/lib/engine-components/postprocessing/VolumeParameter.d.ts +21 -0
  145. package/lib/engine-components/postprocessing/VolumeParameter.js +75 -0
  146. package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -0
  147. package/lib/engine-components/postprocessing/VolumeProfile.d.ts +7 -0
  148. package/lib/engine-components/postprocessing/VolumeProfile.js +42 -0
  149. package/lib/engine-components/postprocessing/VolumeProfile.js.map +1 -0
  150. package/lib/engine-components/timeline/TimelineTracks.js +14 -15
  151. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  152. package/lib/engine-components/ui/Text.js +28 -170
  153. package/lib/engine-components/ui/Text.js.map +1 -1
  154. package/lib/engine-components-experimental/networking/PlayerSync.d.ts +18 -0
  155. package/lib/engine-components-experimental/networking/PlayerSync.js +61 -7
  156. package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -1
  157. package/lib/include/three/ARButton.d.ts +1 -1
  158. package/lib/include/three/ARButton.js +11 -19
  159. package/lib/include/three/ARButton.js.map +1 -1
  160. package/lib/include/three/VRButton.js +1 -4
  161. package/lib/include/three/VRButton.js.map +1 -1
  162. package/package.json +3 -2
  163. package/plugins/vite/drop-client.js +77 -0
  164. package/plugins/vite/drop.js +81 -0
  165. package/plugins/vite/editor-connection.js +121 -0
  166. package/plugins/vite/index.js +9 -4
  167. package/src/engine/api.ts +30 -1
  168. package/src/engine/codegen/register_types.js +25 -9
  169. package/src/engine/debug/debug_overlay.ts +7 -1
  170. package/src/engine/engine_addressables.ts +2 -2
  171. package/src/engine/engine_assetdatabase.ts +291 -184
  172. package/src/engine/engine_components.ts +20 -1
  173. package/src/engine/engine_components_internal.ts +30 -0
  174. package/src/engine/engine_constants.ts +4 -1
  175. package/src/engine/engine_context_registry.ts +7 -0
  176. package/src/engine/engine_editor-sync.ts +21 -0
  177. package/src/engine/engine_element_loading.ts +1 -1
  178. package/src/engine/engine_gameobject.ts +16 -21
  179. package/src/engine/engine_gltf_builtin_components.ts +30 -15
  180. package/src/engine/engine_networking_auto.ts +48 -11
  181. package/src/engine/engine_patcher.ts +113 -0
  182. package/src/engine/engine_physics.ts +15 -2
  183. package/src/engine/engine_scenetools.ts +0 -1
  184. package/src/engine/engine_serialization_core.ts +6 -0
  185. package/src/engine/engine_setup.ts +11 -5
  186. package/src/engine/engine_texture.ts +54 -5
  187. package/src/engine/engine_types.ts +6 -1
  188. package/src/engine/engine_utils.ts +6 -5
  189. package/src/engine/extensions/NEEDLE_progressive.ts +32 -32
  190. package/src/engine/extensions/extensions.ts +22 -1
  191. package/src/engine/extensions/usage_tracker.ts +91 -0
  192. package/src/engine-components/AnimatorController.ts +2 -0
  193. package/src/engine-components/AudioSource.ts +1 -1
  194. package/src/engine-components/Camera.ts +77 -37
  195. package/src/engine-components/Component.ts +74 -30
  196. package/src/engine-components/Networking.ts +9 -1
  197. package/src/engine-components/OrbitControls.ts +11 -2
  198. package/src/engine-components/ParticleSystem.ts +9 -1
  199. package/src/engine-components/ReflectionProbe.ts +17 -7
  200. package/src/engine-components/Renderer.ts +22 -5
  201. package/src/engine-components/Skybox.ts +2 -0
  202. package/src/engine-components/SmoothFollow.ts +4 -4
  203. package/src/engine-components/WebARCameraBackground.ts +215 -0
  204. package/src/engine-components/WebXR.ts +12 -8
  205. package/src/engine-components/WebXRAvatar.ts +1 -0
  206. package/src/engine-components/codegen/components.ts +14 -6
  207. package/src/engine-components/js-extensions/Object3D.ts +6 -1
  208. package/src/engine-components/postprocessing/Effects/Antialiasing.ts +52 -0
  209. package/src/engine-components/postprocessing/Effects/Bloom.ts +75 -0
  210. package/src/engine-components/postprocessing/Effects/ChromaticAberration.ts +36 -0
  211. package/src/engine-components/postprocessing/Effects/ColorAdjustments.ts +114 -0
  212. package/src/engine-components/postprocessing/Effects/DepthOfField.ts +90 -0
  213. package/src/engine-components/postprocessing/Effects/Pixelation.ts +28 -0
  214. package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.ts +71 -0
  215. package/src/engine-components/postprocessing/Effects/Tonemapping.ts +55 -0
  216. package/src/engine-components/postprocessing/Effects/Vignette.ts +55 -0
  217. package/src/engine-components/postprocessing/PostProcessingEffect.ts +112 -0
  218. package/src/engine-components/postprocessing/PostProcessingHandler.ts +148 -0
  219. package/src/engine-components/postprocessing/Volume.ts +194 -0
  220. package/src/engine-components/postprocessing/VolumeParameter.ts +85 -0
  221. package/src/engine-components/postprocessing/VolumeProfile.ts +40 -0
  222. package/src/engine-components/timeline/TimelineTracks.ts +16 -17
  223. package/src/engine-components/ui/Text.ts +37 -174
  224. package/src/engine-components-experimental/networking/PlayerSync.ts +68 -7
  225. package/src/include/three/ARButton.js +13 -24
  226. package/src/include/three/VRButton.js +1 -7
  227. package/lib/engine-components/Volume.d.ts +0 -34
  228. package/lib/engine-components/Volume.js +0 -140
  229. package/lib/engine-components/Volume.js.map +0 -1
  230. package/src/engine-components/Volume.ts +0 -141
@@ -1,4 +1,4 @@
1
- import { Object3D } from "three";
1
+ import { BufferGeometry, InstancedBufferGeometry, Material, Mesh, Object3D, Texture } from "three";
2
2
  import { processNewScripts } from "./engine_mainloop_utils";
3
3
  import { InstantiateIdProvider } from "./engine_networking_instantiate";
4
4
  import { Context, registerComponent } from "./engine_setup";
@@ -9,6 +9,9 @@ import { apply } from "../engine-components/js-extensions/Object3D";
9
9
  import { $isUsingInstancing, InstancingUtil } from "./engine_instancing";
10
10
  import { activeInHierarchyFieldName } from "./engine_constants";
11
11
  import { assign } from "./engine_serialization_core";
12
+ import { disposeObjectResources, __internalNotifyObjectDestroyed as __internalRemoveReferences } from "./engine_assetdatabase";
13
+ import { $originalGuid } from "./engine_constants";
14
+ import { __internalDispatchComponentLifecycleEvent, ComponentEvents } from "./engine_components_internal";
12
15
 
13
16
  const debug = getParam("debuggetcomponent");
14
17
  const debugInstantiate = getParam("debuginstantiate");
@@ -119,15 +122,16 @@ function internalDestroy(instance: Object3D | Component, recursive: boolean = tr
119
122
 
120
123
 
121
124
  const obj = instance as GameObject;
122
- if (dispose) disposeObject(obj);
123
125
  setDestroyed(obj, true);
124
-
126
+ if (dispose) disposeObjectResources(obj);
127
+ // This needs to be called after disposing because it removes the references to resources
128
+ __internalRemoveReferences(obj);
125
129
 
126
130
  if (debug) console.log(obj);
127
131
 
128
132
  if (recursive && obj.children) {
129
133
  for (const ch of obj.children) {
130
- internalDestroy(ch, recursive, false, false);
134
+ internalDestroy(ch, recursive, dispose, false);
131
135
  }
132
136
  }
133
137
 
@@ -153,21 +157,6 @@ function internalDestroy(instance: Object3D | Component, recursive: boolean = tr
153
157
  obj.removeFromParent();
154
158
  }
155
159
 
156
- function disposeObject(obj: Object3D) {
157
- if (!obj) return;
158
- const mesh = obj as THREE.Mesh;
159
- if (mesh.geometry) {
160
- mesh.geometry.dispose();
161
- }
162
- if (mesh.material) {
163
- if (Array.isArray(mesh.material)) {
164
- mesh.material.forEach(m => m.dispose());
165
- } else {
166
- mesh.material.dispose();
167
- }
168
- }
169
- }
170
-
171
160
  declare type ForEachComponentCallback = (comp: Component) => any;
172
161
 
173
162
  export function foreachComponent(instance: THREE.Object3D, cb: ForEachComponentCallback, recursive: boolean = true): any {
@@ -304,12 +293,14 @@ function internalInstantiate(
304
293
  let clone: THREE.Object3D | GameObject;
305
294
  clone = instance.clone(false);
306
295
  apply(clone);
296
+ // if(instance[$originalGuid])
297
+ // clone[$originalGuid] = instance[$originalGuid];
307
298
  instance.userData = userData;
308
299
  instance.children = children;
309
300
 
310
301
  // make reference from old id to new object
311
302
  newGameObjectsMap[instance.uuid] = { original: instance, clone: clone };
312
- if(debugInstantiate) console.log("ADD", instance, clone)
303
+ if (debugInstantiate) console.log("ADD", instance, clone)
313
304
 
314
305
  if (instance.type === "SkinnedMesh") {
315
306
  skinnedMeshesMap[instance.uuid] = { original: instance, clone: clone };
@@ -379,12 +370,16 @@ function internalInstantiate(
379
370
  clone.userData.components = newComponents;
380
371
  for (let i = 0; i < components.length; i++) {
381
372
  const comp = components[i];
382
- const copy = Object.create(comp);
373
+ const copy = new comp.constructor();
383
374
  assign(copy, comp);
375
+ // make sure the original guid stays intact
376
+ if (comp[$originalGuid] !== undefined)
377
+ copy[$originalGuid] = comp[$originalGuid];
384
378
  newComponents.push(copy);
385
379
  copy.gameObject = clone;
386
380
  // copy.transform = clone;
387
381
  componentsList.push(copy);
382
+ __internalDispatchComponentLifecycleEvent(ComponentEvents.Added, copy);
388
383
  }
389
384
  }
390
385
 
@@ -1,15 +1,15 @@
1
1
  import "./codegen/register_types";
2
2
  import { TypeStore } from "./engine_typestore";
3
3
  import * as THREE from "three";
4
- import { Component, GameObject } from "../engine-components/Component";
4
+ // import { GameObject } from "../engine-components/Component";
5
5
  import { InstantiateIdProvider } from "./engine_networking_instantiate"
6
6
  import { Context } from "./engine_setup";
7
7
  import { deserializeObject, serializeObject } from "./engine_serialization";
8
8
  import { assign, ImplementationInformation, ISerializable, SerializationContext } from "./engine_serialization_core";
9
9
  import { NEEDLE_components } from "./extensions/NEEDLE_components";
10
10
  import { debugExtension } from "./engine_default_parameters";
11
- import { builtinComponentKeyName } from "./engine_constants";
12
- import { GuidsMap, SourceIdentifier } from "./engine_types";
11
+ import { $originalGuid, builtinComponentKeyName } from "./engine_constants";
12
+ import { GuidsMap, IComponent, IGameObject, SourceIdentifier } from "./engine_types";
13
13
  import { UIDProvider } from "./engine_types";
14
14
  import { addNewComponent } from "./engine_components";
15
15
  import { getParam } from "./engine_utils";
@@ -21,7 +21,7 @@ const debug = debugExtension;
21
21
  const debugTypeStore = getParam("debugtypestore");
22
22
  if (debugTypeStore) console.log(TypeStore);
23
23
 
24
- export function writeBuiltinComponentData(comp: Component, context: SerializationContext): object | null {
24
+ export function writeBuiltinComponentData(comp: IComponent, context: SerializationContext): object | null {
25
25
 
26
26
  // const fn = (comp as unknown as ISerializable)?.onBeforeSerialize;
27
27
  // if (fn) {
@@ -39,6 +39,7 @@ export function writeBuiltinComponentData(comp: Component, context: Serializatio
39
39
  }
40
40
 
41
41
  const typeImplementationInformation = new ImplementationInformation();
42
+ const $context_deserialize_queue = Symbol("deserialize-queue");
42
43
 
43
44
  export async function createBuiltinComponents(context: Context, gltfId: SourceIdentifier, gltf, seed: number | null | UIDProvider = null, extension?: NEEDLE_components) {
44
45
  if (!gltf) return;
@@ -56,26 +57,34 @@ export async function createBuiltinComponents(context: Context, gltfId: SourceId
56
57
  serializationContext.nodeToObject = extension?.nodeToObjectMap;
57
58
  serializationContext.implementationInformation = typeImplementationInformation;
58
59
 
59
- const deserialize: DeserializeData[] = [];
60
+ // If we're loading multiple gltf files in one scene we need to make sure we deserialize all of them in one go
61
+ // for that we collect them in one list per context
62
+ let deserializeQueue = context[$context_deserialize_queue];
63
+ if (!deserializeQueue) deserializeQueue = context[$context_deserialize_queue] = [];
60
64
 
61
65
  if (gltf.scenes) {
62
66
  for (const scene of gltf.scenes) {
63
- await onCreateBuiltinComponents(serializationContext, scene, deserialize, lateResolve);
67
+ await onCreateBuiltinComponents(serializationContext, scene, deserializeQueue, lateResolve);
64
68
  }
65
69
  }
66
70
  if (gltf.children) {
67
71
  for (const ch of gltf.children) {
68
- await onCreateBuiltinComponents(serializationContext, ch, deserialize, lateResolve);
72
+ await onCreateBuiltinComponents(serializationContext, ch, deserializeQueue, lateResolve);
69
73
  }
70
74
  }
71
75
 
72
-
73
76
  context.new_scripts_pre_setup_callbacks.push(() => {
74
-
75
- for (const des of deserialize) {
76
- handleDeserialization(des, serializationContext);
77
+ // First deserialize ALL components that were loaded before pre setup
78
+ // Down below they get new guids assigned so we have to do all of them first
79
+ // E.g. in cases where we load multiple glb files on startup from one scene
80
+ // and they might have cross-glb references
81
+ const queue = context[$context_deserialize_queue];
82
+ if (queue) {
83
+ for (const des of queue) {
84
+ handleDeserialization(des, serializationContext);
85
+ }
86
+ queue.length = 0;
77
87
  }
78
-
79
88
  // when dropping the same file multiple times we need to generate new guids
80
89
  // e.g. SyncTransform sends its own guid to the server to know about ownership
81
90
  // so it requires a unique guid for a new instance
@@ -95,7 +104,7 @@ export async function createBuiltinComponents(context: Context, gltfId: SourceId
95
104
  // console.log("finished creating builtin components", gltf.scene?.name, gltf);
96
105
  }
97
106
 
98
- function recursiveCreateGuids(obj: GameObject, idProvider: UIDProvider | null, guidsMap: GuidsMap) {
107
+ function recursiveCreateGuids(obj: IGameObject, idProvider: UIDProvider | null, guidsMap: GuidsMap) {
99
108
  if (idProvider === null) return;
100
109
  if (!obj) return;
101
110
  const prev = obj.guid;
@@ -117,7 +126,7 @@ function recursiveCreateGuids(obj: GameObject, idProvider: UIDProvider | null, g
117
126
  }
118
127
  if (obj.children) {
119
128
  for (const child of obj.children) {
120
- recursiveCreateGuids(child as GameObject, idProvider, guidsMap);
129
+ recursiveCreateGuids(child as IGameObject, idProvider, guidsMap);
121
130
  }
122
131
  }
123
132
  }
@@ -140,6 +149,7 @@ declare type LateResolveCallback = (gltf: THREE.Object3D) => void;
140
149
 
141
150
  const unknownComponentsBuffer: Array<string> = [];
142
151
 
152
+
143
153
  async function onCreateBuiltinComponents(context: SerializationContext, obj: THREE.Object3D,
144
154
  deserialize: DeserializeData[], lateResolve: LateResolveCallback[]) {
145
155
  if (!obj) return;
@@ -156,11 +166,16 @@ async function onCreateBuiltinComponents(context: SerializationContext, obj: THR
156
166
  const type = TypeStore.get(compData.name);
157
167
  // console.log(compData, compData.name, type, TypeStore);
158
168
  if (type !== undefined && type !== null) {
159
- const instance: Component = new type() as Component;
169
+ const instance: IComponent = new type() as IComponent;
160
170
  instance.sourceId = context.gltfId;
161
171
 
162
172
  // assign basic fields
163
173
  assign(instance, compData, context.implementationInformation);
174
+
175
+ // assign the guid of the original instance
176
+ if("guid" in compData)
177
+ instance[$originalGuid] = compData.guid;
178
+
164
179
  // Object.assign(instance, compData);
165
180
  // dont call awake here because some references might not be resolved yet and components that access those fields in awake will throw
166
181
  // for example Duplicatable reference to object might still be { node: id }
@@ -4,6 +4,7 @@ import { RoomEvents } from "./engine_networking";
4
4
 
5
5
  const debug = getParam("debugautosync");
6
6
 
7
+ const $syncerId = Symbol("syncerId");
7
8
  class ComponentsSyncerManager {
8
9
  private _syncers: { [key: string]: ComponentPropertiesSyncer } = {};
9
10
 
@@ -11,9 +12,14 @@ class ComponentsSyncerManager {
11
12
  if (!comp.guid) return null;
12
13
  if (this._syncers[comp.guid]) return this._syncers[comp.guid];
13
14
  const syncer = new ComponentPropertiesSyncer(comp);
14
- this._syncers[comp.guid] = syncer;
15
+ syncer[$syncerId] = comp.guid;
16
+ this._syncers[syncer[$syncerId]] = syncer;
15
17
  return syncer;
16
18
  }
19
+
20
+ removeSyncer(syncer: ComponentPropertiesSyncer) {
21
+ delete this._syncers[syncer[$syncerId]];
22
+ }
17
23
  }
18
24
  const syncerHandler = new ComponentsSyncerManager();
19
25
 
@@ -35,6 +41,7 @@ class ComponentPropertiesSyncer {
35
41
  private data = {};
36
42
 
37
43
  private _boundEvent?: Function;
44
+ private _handleReceivingMethod?: Function;
38
45
 
39
46
  get networkingKey(): string {
40
47
  const obj = this.comp as object;
@@ -46,6 +53,7 @@ class ComponentPropertiesSyncer {
46
53
  private _isReceiving: boolean = false;
47
54
  private _isInit = false;
48
55
 
56
+
49
57
  init(comp) {
50
58
  if (this._isInit) return;
51
59
  this._isInit = true;
@@ -53,10 +61,22 @@ class ComponentPropertiesSyncer {
53
61
  // console.log("INIT", this.comp.name, this.networkingKey);
54
62
  this._boundEvent = this.onHandleSending.bind(this);
55
63
  this.comp.context.post_render_callbacks.push(this._boundEvent);
56
- this.comp.context.connection.beginListen(this.networkingKey, this.onHandleReceiving.bind(this));
64
+ this._handleReceivingMethod = this.onHandleReceiving.bind(this);
65
+ this.comp.context.connection.beginListen(this.networkingKey, this._handleReceivingMethod);
57
66
 
58
67
  const state = this.comp.context.connection.tryGetState(this.comp.guid);
59
- if(state) this.onHandleReceiving(state);
68
+ if (state) this.onHandleReceiving(state);
69
+ }
70
+
71
+ destroy() {
72
+ if (!this._isInit) return;
73
+ if (this._boundEvent)
74
+ this.comp.context.post_render_callbacks.splice(this.comp.context.post_render_callbacks.indexOf(this._boundEvent), 1);
75
+ if (this._handleReceivingMethod)
76
+ this.comp.context.connection.stopListen(this.networkingKey, this._handleReceivingMethod);
77
+ //@ts-ignore
78
+ this.comp = null;
79
+ this._isInit = false;
60
80
  }
61
81
 
62
82
  notifyChanged(propertyName: string, value: any) {
@@ -156,16 +176,26 @@ function testValueChanged(newValue, previousValue): boolean {
156
176
  return valueChanged;
157
177
  }
158
178
 
179
+ const $syncer = Symbol("AutoSyncHandler");
159
180
  function getSyncer(instance): ComponentPropertiesSyncer | null {
160
- if (instance["__autoPropertySyncHandler"]) {
161
- return instance["__autoPropertySyncHandler"];
181
+ if (instance[$syncer]) {
182
+ return instance[$syncer];
162
183
  }
163
184
  const syncer = syncerHandler.getOrCreateSyncer(instance);
164
185
  syncer?.init(instance);
165
- instance["__autoPropertySyncHandler"] = syncer;
186
+ instance[$syncer] = syncer;
166
187
  return syncer;
167
188
  }
168
189
 
190
+ function destroySyncer(instance) {
191
+ const syncer = instance[$syncer];
192
+ if (syncer) {
193
+ syncerHandler.removeSyncer(syncer);
194
+ syncer.destroy();
195
+ delete instance[$syncer];
196
+ }
197
+ }
198
+
169
199
  export declare type SyncFieldOptions = {
170
200
  onPropertyChanged: Function,
171
201
  };
@@ -190,7 +220,7 @@ export const syncField = function (onFieldChanged?: string) {
190
220
  const internalAwake = t.__internalAwake;
191
221
  if (debug)
192
222
  console.log(propertyKey);
193
- const backingFieldName = propertyKey + "k__BackingField";
223
+ const backingFieldName = Symbol(propertyKey);
194
224
 
195
225
  t.__internalAwake = function () {
196
226
  if (this[backingFieldName] !== undefined) {
@@ -221,7 +251,13 @@ export const syncField = function (onFieldChanged?: string) {
221
251
  }
222
252
 
223
253
  syncer?.init(this);
224
-
254
+
255
+ }
256
+
257
+ const internalDestroy = t.__internalDestroy;
258
+ t.__internalDestroy = function () {
259
+ destroySyncer(this);
260
+ internalDestroy.call(this);
225
261
  }
226
262
 
227
263
  }
@@ -233,6 +269,7 @@ export declare type SyncOptions = {
233
269
  fieldName?: string,
234
270
  };
235
271
 
272
+ /** experimental - use syncField instead */
236
273
  export const sync = function (_options?: SyncOptions) {
237
274
 
238
275
  return function <T>(target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
@@ -253,14 +290,14 @@ export const sync = function (_options?: SyncOptions) {
253
290
  // inject getter and setter
254
291
  if (!descriptor.get) {
255
292
  const previousSetter = descriptor.set;
256
- const backingFieldName = _propertyKey + "k__BackingField";
293
+ const $backingField = Symbol(_propertyKey);
257
294
  Object.defineProperty(target, _propertyKey, {
258
295
  set: function (value) {
259
- this[backingFieldName] = value;
296
+ this[$backingField] = value;
260
297
  previousSetter?.call(this, value);
261
298
  },
262
299
  get: function () {
263
- return this[backingFieldName];
300
+ return this[$backingField];
264
301
  }
265
302
  });
266
303
  const newDescriptor = Object.getOwnPropertyDescriptor(target, _propertyKey);
@@ -0,0 +1,113 @@
1
+
2
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn
3
+
4
+ const _wrappedMethods = new WeakSet();
5
+
6
+ export declare type FieldPatch = (instance: object, oldValue: any, newValue: any) => any;
7
+ export type MethodPatch<T> = (instance: T, result: any, ...args) => any;
8
+
9
+ /**
10
+ * Use patcher for patching properties insteadof calling Object.defineProperty individually
11
+ * since this will cause conflicts if multiple patches need to be applied to the same property
12
+ */
13
+ export function addPatch<TType extends object, TCallback extends (FieldPatch | MethodPatch<any>)>(prototype: TType, fieldName: string, cb: TCallback) {
14
+
15
+ // TODO: we probably want to turn this into a symbol to prevent anyone from overriding it
16
+ // But when we need to store the symbol per prototype to allow e.g. material disposing to iterate those and dispose all
17
+ const backingField = fieldName + "__needle";// Symbol(fieldName);// + " (patched)";
18
+
19
+ internalAddPatch(prototype, fieldName, cb);
20
+
21
+ const desc = Object.getOwnPropertyDescriptor(prototype, fieldName);
22
+
23
+ if (desc) {
24
+ // TODO: check if the property is writable
25
+ // the property might be a method in which case we want to wrap it
26
+ if (typeof desc.value === "function") {
27
+ const method = desc.value;
28
+ if (method) {
29
+ if (_wrappedMethods.has(method)) {
30
+ return;
31
+ }
32
+ _wrappedMethods.add(method);
33
+ prototype[fieldName] = function (this: object, ...args: any[]) {
34
+ // call the original method
35
+ const result = method.apply(this, args);
36
+ // call the patches
37
+ const patches = getPatches(prototype, fieldName);
38
+ if (patches) {
39
+ for (const patch of patches) {
40
+ patch(this, result, ...args);
41
+ }
42
+ }
43
+ return result;
44
+ }
45
+ }
46
+ else {
47
+ // TODO: declare method?
48
+ }
49
+ }
50
+ }
51
+ else if (prototype.hasOwnProperty(backingField)) {
52
+ }
53
+ else {
54
+ Object.defineProperty(prototype, fieldName, {
55
+ set: function (this: object, value: any) {
56
+ const prev = this[backingField];
57
+ this[backingField] = value;
58
+ executePatches(prototype, fieldName, this, prev, value);
59
+ },
60
+ get: function (this: any) {
61
+ return this[backingField];
62
+ }
63
+ });
64
+ }
65
+ }
66
+
67
+ export function removePatch(prototype: object, fieldName: string, cb: Function) {
68
+ const patches = getPatches(prototype, fieldName);
69
+ if (patches) {
70
+ for (let i = patches.length - 1; i >= 0; i--) {
71
+ if (patches[i] === cb) {
72
+ patches.splice(i, 1);
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+
79
+
80
+
81
+ const patches = new WeakMap<object, Map<string, Function[]>>();
82
+
83
+ function getPatches(prototype, fieldName: string) {
84
+ let patchesMap = patches.get(prototype);
85
+ if (!patchesMap) {
86
+ return;
87
+ }
88
+ return patchesMap.get(fieldName);;
89
+ }
90
+
91
+ function internalAddPatch(prototype, fieldName: string, cb: Function) {
92
+ let patchesMap = patches.get(prototype);
93
+ if (!patchesMap) {
94
+ patchesMap = new Map();
95
+ patches.set(prototype, patchesMap);
96
+ }
97
+ let patchList = patchesMap.get(fieldName);
98
+ if (!patchList) {
99
+ patchList = [];
100
+ patchesMap.set(fieldName, patchList);
101
+ }
102
+ patchList.push(cb);
103
+ }
104
+
105
+ function executePatches(prototype, fieldName: string, instance: object, oldValue: any, newValue: any) {
106
+ if (!instance) return;
107
+ const patches = getPatches(prototype, fieldName);
108
+ if (patches) {
109
+ for (const patch of patches) {
110
+ patch(instance, oldValue, newValue);
111
+ }
112
+ }
113
+ }
@@ -19,6 +19,7 @@ import RAPIER, { ActiveEvents, CoefficientCombineRule, Collider, ColliderDesc, E
19
19
  import { CollisionDetectionMode, PhysicsMaterialCombine } from '../engine/engine_physics.types';
20
20
  import { Gizmos } from './engine_gizmos';
21
21
  import { Mathf } from './engine_math';
22
+ import { Layer } from './extensions/NEEDLE_animator_controller_model';
22
23
  export type Rapier = typeof RAPIER;
23
24
 
24
25
 
@@ -41,6 +42,8 @@ const $bodyKey = Symbol("physics body");
41
42
  const $colliderRigidbody = Symbol("rigidbody");
42
43
  // const $removed = Symbol("removed");
43
44
 
45
+ const layerMaskHelper: Layers = new Layers();
46
+
44
47
  export class RaycastOptions {
45
48
  ray: Ray | undefined = undefined;
46
49
  cam: Camera | undefined | null = undefined;
@@ -52,6 +55,7 @@ export class RaycastOptions {
52
55
  minDistance: number | undefined = undefined;
53
56
  maxDistance: number | undefined = undefined;
54
57
  lineThreshold: number | undefined = undefined;
58
+ /** raw layer mask, use setLayer to set an individual layer active */
55
59
  layerMask: Layers | number | undefined = undefined;
56
60
  ignore: Object3D[] | undefined = undefined;
57
61
 
@@ -61,6 +65,13 @@ export class RaycastOptions {
61
65
  this.screenPoint.y = -(oy / window.innerHeight) * 2 + 1;
62
66
  }
63
67
 
68
+ /** sets one layer for raycasting (e.g. layer 4, only objects on layer 4 will then be hit) */
69
+ setLayer(layer: number) {
70
+ layerMaskHelper.set(layer);
71
+ this.layerMask = layerMaskHelper;
72
+ }
73
+
74
+ /** sets the layer.mask value directly, use setLayer if you want to set e.g. an individual layer only active. See https://threejs.org/docs/#api/en/core/Layers for more information about layers */
64
75
  setMask(mask: number) {
65
76
  if (!this.layerMask) this.layerMask = new Layers();
66
77
  const lm = this.layerMask as Layers;
@@ -69,7 +80,7 @@ export class RaycastOptions {
69
80
  else this.layerMask = mask;
70
81
  }
71
82
 
72
- public static AllLayers = 0xFFFFFFFF;
83
+ public static readonly AllLayers = 0xFFFFFFFF;
73
84
  }
74
85
 
75
86
  export class SphereIntersection implements Intersection {
@@ -191,7 +202,8 @@ export class Physics {
191
202
  else {
192
203
  const cam = options.cam ?? this.context.mainCamera;
193
204
  if (!cam) {
194
- console.error("Can not perform raycast - no main camera found");
205
+ if (debugPhysics)
206
+ console.error("Can not perform raycast - no main camera found");
195
207
  if (this.defaultRaycastOptions.results) this.defaultRaycastOptions.results.length = 0;
196
208
  return this.defaultRaycastOptions.results ?? [];
197
209
  }
@@ -216,6 +228,7 @@ export class Physics {
216
228
  rc.layers.mask = options.layerMask.mask;
217
229
  else
218
230
  rc.layers.mask = options.layerMask;
231
+ console.log(rc.layers.mask, options.layerMask);
219
232
  }
220
233
  else {
221
234
  rc.layers.enableAll();
@@ -88,7 +88,6 @@ function invokeEvents(type: GltfLoadEventType, event: GltfLoadEvent) {
88
88
  async function handleLoadedGltf(context: Context, gltfId: string, gltf, seed: number | null | UIDProvider, componentsExtension) {
89
89
  if (printGltf)
90
90
  console.log(gltf);
91
- await context.assets.registerGltf(gltf);
92
91
  await getLoader().createBuiltinComponents(context, gltfId, gltf, seed, componentsExtension);
93
92
 
94
93
  // load and assign animation
@@ -614,7 +614,13 @@ export function assign(target: any, source: any, info?: ImplementationInformatio
614
614
 
615
615
  for (const key of Object.keys(source)) {
616
616
  const desc = getPropertyDescriptor(target, key);
617
+
617
618
  if (onlyDeclared && desc === undefined) continue;
619
+
620
+ if (typeof desc?.value == "function") {
621
+ // arrow functions are defined as properties on the object
622
+ continue;
623
+ }
618
624
  if (!desc || desc.writable === true) {
619
625
  target[key] = source[key];
620
626
  }
@@ -8,8 +8,7 @@ import { NetworkConnection } from './engine_networking';
8
8
  import * as looputils from './engine_mainloop_utils';
9
9
  import * as utils from "./engine_utils";
10
10
 
11
- import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
12
- import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
11
+ import { EffectComposer, RenderPass } from "postprocessing";
13
12
 
14
13
  import { AssetDatabase } from './engine_assetdatabase';
15
14
 
@@ -323,7 +322,8 @@ export class Context implements IContext {
323
322
  this.renderer.domElement.style.height = "100%";
324
323
  if (this.composer) {
325
324
  this.composer.setSize?.call(this.composer, width, height);
326
- this.composer.setPixelRatio?.call(this.composer, window.devicePixelRatio);
325
+ if("setPixelRatio" in this.composer && typeof this.composer.setPixelRatio === "function")
326
+ this.composer.setPixelRatio?.call(this.composer, window.devicePixelRatio);
327
327
  }
328
328
  }
329
329
  }
@@ -571,7 +571,7 @@ export class Context implements IContext {
571
571
  }
572
572
  else {
573
573
  ContextRegistry.dispatchCallback(ContextEvent.MissingCamera, this);
574
- if (!this.mainCamera)
574
+ if (!this.mainCamera && !this.isManagedExternally)
575
575
  console.error("MISSING camera", this);
576
576
  }
577
577
  }
@@ -608,6 +608,7 @@ export class Context implements IContext {
608
608
 
609
609
  private render(_, frame) {
610
610
 
611
+
611
612
  this._currentFrameEvent = -1;
612
613
 
613
614
  if (this.onHandlePaused()) return;
@@ -757,10 +758,15 @@ export class Context implements IContext {
757
758
  }
758
759
  this._isRendering = true;
759
760
  this.renderRequiredTextures();
761
+ // if (camera === this.mainCameraComponent?.cam) {
762
+ // if (this.mainCameraComponent.activeTexture) {
763
+
764
+ // }
765
+ // }
760
766
  if (this.composer && !this.isInXR) {
761
767
  this.composer.render();
762
768
  }
763
- else if (this.mainCamera) {
769
+ else if (camera) {
764
770
  this.renderer.render(this.scene, camera);
765
771
  }
766
772
  this._isRendering = false;
@@ -1,6 +1,55 @@
1
- import { WebGLRenderTarget } from "three"
1
+ import { Camera, Mesh, Object3D, Texture, WebGLRenderer, WebGLRenderTarget } from "three";
2
+ import { EffectComposer } from "postprocessing";
3
+ import { findUsers } from "./engine_assetdatabase";
4
+
5
+
6
+ const _prevVisible = Symbol("previous-visibility");
7
+
8
+ export class RenderTexture extends WebGLRenderTarget {
9
+
10
+
11
+ render(scene: Object3D, camera: Camera, renderer: WebGLRenderer | EffectComposer) {
12
+ if (renderer instanceof EffectComposer) {
13
+ if (!this["_unsupported_effectcomposer_warning"]) {
14
+ console.warn("RenderTexture.render() does not yet support EffectComposer");
15
+ this["_unsupported_effectcomposer_warning"] = true;
16
+ }
17
+ }
18
+ else {
19
+ this.onBeforeRender();
20
+ const prev = renderer.getRenderTarget();
21
+ renderer.setRenderTarget(this);
22
+ renderer.render(scene, camera);
23
+ renderer.setRenderTarget(prev);
24
+ this.onAfterRender();
25
+ }
26
+ }
27
+
28
+
29
+ private static _userSet: Set<object> = new Set();
30
+
31
+ private onBeforeRender() {
32
+ RenderTexture._userSet.clear();
33
+ const users = findUsers(this.texture, true, null, RenderTexture._userSet);
34
+ for (const user of users) {
35
+ if (user instanceof Mesh) {
36
+ user[_prevVisible] = user.visible;
37
+ user.visible = false;
38
+ }
39
+ }
40
+ }
41
+
42
+ private onAfterRender() {
43
+ for (const user of RenderTexture._userSet) {
44
+ if (user instanceof Mesh) {
45
+ user.visible = user[_prevVisible];
46
+ }
47
+ }
48
+ RenderTexture._userSet.clear();
49
+ }
50
+ }
51
+
52
+
53
+
54
+
2
55
 
3
- export class RenderTexture extends WebGLRenderTarget
4
- {
5
-
6
- }