@needle-tools/engine 2.65.2-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 (289) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/needle-engine.js +34490 -26304
  3. package/dist/needle-engine.umd.cjs +748 -303
  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 +11 -2
  10. package/lib/engine/debug/debug_overlay.js.map +1 -1
  11. package/lib/engine/engine_addressables.js +4 -4
  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.d.ts +1 -0
  31. package/lib/engine/engine_element.js +4 -1
  32. package/lib/engine/engine_element.js.map +1 -1
  33. package/lib/engine/engine_element_loading.d.ts +3 -2
  34. package/lib/engine/engine_element_loading.js +19 -15
  35. package/lib/engine/engine_element_loading.js.map +1 -1
  36. package/lib/engine/engine_gameobject.js +21 -23
  37. package/lib/engine/engine_gameobject.js.map +1 -1
  38. package/lib/engine/engine_gizmos.js +3 -1
  39. package/lib/engine/engine_gizmos.js.map +1 -1
  40. package/lib/engine/engine_gltf_builtin_components.d.ts +2 -3
  41. package/lib/engine/engine_gltf_builtin_components.js +23 -6
  42. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  43. package/lib/engine/engine_networking.d.ts +3 -1
  44. package/lib/engine/engine_networking.js +10 -8
  45. package/lib/engine/engine_networking.js.map +1 -1
  46. package/lib/engine/engine_networking_auto.d.ts +1 -0
  47. package/lib/engine/engine_networking_auto.js +42 -9
  48. package/lib/engine/engine_networking_auto.js.map +1 -1
  49. package/lib/engine/engine_patcher.d.ts +8 -0
  50. package/lib/engine/engine_patcher.js +98 -0
  51. package/lib/engine/engine_patcher.js.map +1 -0
  52. package/lib/engine/engine_physics.d.ts +34 -2
  53. package/lib/engine/engine_physics.js +110 -11
  54. package/lib/engine/engine_physics.js.map +1 -1
  55. package/lib/engine/engine_scenetools.js +0 -1
  56. package/lib/engine/engine_scenetools.js.map +1 -1
  57. package/lib/engine/engine_serialization_core.js +4 -0
  58. package/lib/engine/engine_serialization_core.js.map +1 -1
  59. package/lib/engine/engine_setup.d.ts +1 -1
  60. package/lib/engine/engine_setup.js +12 -5
  61. package/lib/engine/engine_setup.js.map +1 -1
  62. package/lib/engine/engine_texture.d.ts +6 -1
  63. package/lib/engine/engine_texture.js +39 -1
  64. package/lib/engine/engine_texture.js.map +1 -1
  65. package/lib/engine/engine_types.d.ts +4 -0
  66. package/lib/engine/engine_types.js.map +1 -1
  67. package/lib/engine/engine_utils.js +3 -2
  68. package/lib/engine/engine_utils.js.map +1 -1
  69. package/lib/engine/extensions/NEEDLE_progressive.d.ts +0 -1
  70. package/lib/engine/extensions/NEEDLE_progressive.js +24 -26
  71. package/lib/engine/extensions/NEEDLE_progressive.js.map +1 -1
  72. package/lib/engine/extensions/NEEDLE_render_objects.js +9 -0
  73. package/lib/engine/extensions/NEEDLE_render_objects.js.map +1 -1
  74. package/lib/engine/extensions/extensions.d.ts +4 -1
  75. package/lib/engine/extensions/extensions.js +16 -0
  76. package/lib/engine/extensions/extensions.js.map +1 -1
  77. package/lib/engine/extensions/usage_tracker.d.ts +12 -0
  78. package/lib/engine/extensions/usage_tracker.js +59 -0
  79. package/lib/engine/extensions/usage_tracker.js.map +1 -0
  80. package/lib/engine-components/Animator.js +0 -1
  81. package/lib/engine-components/Animator.js.map +1 -1
  82. package/lib/engine-components/AnimatorController.js +4 -0
  83. package/lib/engine-components/AnimatorController.js.map +1 -1
  84. package/lib/engine-components/AudioSource.js +2 -1
  85. package/lib/engine-components/AudioSource.js.map +1 -1
  86. package/lib/engine-components/Camera.d.ts +6 -0
  87. package/lib/engine-components/Camera.js +70 -31
  88. package/lib/engine-components/Camera.js.map +1 -1
  89. package/lib/engine-components/CharacterController.d.ts +1 -0
  90. package/lib/engine-components/CharacterController.js +14 -9
  91. package/lib/engine-components/CharacterController.js.map +1 -1
  92. package/lib/engine-components/Collider.js +14 -1
  93. package/lib/engine-components/Collider.js.map +1 -1
  94. package/lib/engine-components/Component.d.ts +52 -0
  95. package/lib/engine-components/Component.js +55 -14
  96. package/lib/engine-components/Component.js.map +1 -1
  97. package/lib/engine-components/Networking.js +19 -0
  98. package/lib/engine-components/Networking.js.map +1 -1
  99. package/lib/engine-components/OrbitControls.d.ts +2 -0
  100. package/lib/engine-components/OrbitControls.js +9 -0
  101. package/lib/engine-components/OrbitControls.js.map +1 -1
  102. package/lib/engine-components/ParticleSystem.d.ts +5 -1
  103. package/lib/engine-components/ParticleSystem.js +52 -7
  104. package/lib/engine-components/ParticleSystem.js.map +1 -1
  105. package/lib/engine-components/ParticleSystemModules.d.ts +2 -0
  106. package/lib/engine-components/ParticleSystemModules.js +26 -0
  107. package/lib/engine-components/ParticleSystemModules.js.map +1 -1
  108. package/lib/engine-components/ParticleSystemSubEmitter.js +5 -2
  109. package/lib/engine-components/ParticleSystemSubEmitter.js.map +1 -1
  110. package/lib/engine-components/ReflectionProbe.js +18 -6
  111. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  112. package/lib/engine-components/Renderer.d.ts +1 -1
  113. package/lib/engine-components/Renderer.js +33 -11
  114. package/lib/engine-components/Renderer.js.map +1 -1
  115. package/lib/engine-components/ScreenCapture.js +3 -3
  116. package/lib/engine-components/ScreenCapture.js.map +1 -1
  117. package/lib/engine-components/Skybox.js +2 -0
  118. package/lib/engine-components/Skybox.js.map +1 -1
  119. package/lib/engine-components/SmoothFollow.js +1 -2
  120. package/lib/engine-components/SmoothFollow.js.map +1 -1
  121. package/lib/engine-components/SpectatorCamera.js +3 -3
  122. package/lib/engine-components/SpectatorCamera.js.map +1 -1
  123. package/lib/engine-components/SyncedCamera.js +1 -1
  124. package/lib/engine-components/SyncedCamera.js.map +1 -1
  125. package/lib/engine-components/SyncedTransform.js +2 -2
  126. package/lib/engine-components/SyncedTransform.js.map +1 -1
  127. package/lib/engine-components/TestRunner.js +1 -1
  128. package/lib/engine-components/TestRunner.js.map +1 -1
  129. package/lib/engine-components/WebARCameraBackground.d.ts +19 -0
  130. package/lib/engine-components/WebARCameraBackground.js +185 -0
  131. package/lib/engine-components/WebARCameraBackground.js.map +1 -0
  132. package/lib/engine-components/WebARSessionRoot.js +3 -2
  133. package/lib/engine-components/WebARSessionRoot.js.map +1 -1
  134. package/lib/engine-components/WebXR.d.ts +4 -0
  135. package/lib/engine-components/WebXR.js +11 -8
  136. package/lib/engine-components/WebXR.js.map +1 -1
  137. package/lib/engine-components/WebXRAvatar.js +1 -0
  138. package/lib/engine-components/WebXRAvatar.js.map +1 -1
  139. package/lib/engine-components/WebXRGrabRendering.js +2 -2
  140. package/lib/engine-components/WebXRGrabRendering.js.map +1 -1
  141. package/lib/engine-components/WebXRSync.js +2 -2
  142. package/lib/engine-components/WebXRSync.js.map +1 -1
  143. package/lib/engine-components/codegen/components.d.ts +14 -6
  144. package/lib/engine-components/codegen/components.js +14 -6
  145. package/lib/engine-components/codegen/components.js.map +1 -1
  146. package/lib/engine-components/js-extensions/Object3D.js +4 -1
  147. package/lib/engine-components/js-extensions/Object3D.js.map +1 -1
  148. package/lib/engine-components/postprocessing/Effects/Antialiasing.d.ts +13 -0
  149. package/lib/engine-components/postprocessing/Effects/Antialiasing.js +46 -0
  150. package/lib/engine-components/postprocessing/Effects/Antialiasing.js.map +1 -0
  151. package/lib/engine-components/postprocessing/Effects/Bloom.d.ts +12 -0
  152. package/lib/engine-components/postprocessing/Effects/Bloom.js +76 -0
  153. package/lib/engine-components/postprocessing/Effects/Bloom.js.map +1 -0
  154. package/lib/engine-components/postprocessing/Effects/ChromaticAberration.d.ts +8 -0
  155. package/lib/engine-components/postprocessing/Effects/ChromaticAberration.js +39 -0
  156. package/lib/engine-components/postprocessing/Effects/ChromaticAberration.js.map +1 -0
  157. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.d.ts +12 -0
  158. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js +96 -0
  159. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js.map +1 -0
  160. package/lib/engine-components/postprocessing/Effects/DepthOfField.d.ts +21 -0
  161. package/lib/engine-components/postprocessing/Effects/DepthOfField.js +87 -0
  162. package/lib/engine-components/postprocessing/Effects/DepthOfField.js.map +1 -0
  163. package/lib/engine-components/postprocessing/Effects/Pixelation.d.ts +7 -0
  164. package/lib/engine-components/postprocessing/Effects/Pixelation.js +30 -0
  165. package/lib/engine-components/postprocessing/Effects/Pixelation.js.map +1 -0
  166. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.d.ts +11 -0
  167. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js +70 -0
  168. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js.map +1 -0
  169. package/lib/engine-components/postprocessing/Effects/Tonemapping.d.ts +16 -0
  170. package/lib/engine-components/postprocessing/Effects/Tonemapping.js +52 -0
  171. package/lib/engine-components/postprocessing/Effects/Tonemapping.js.map +1 -0
  172. package/lib/engine-components/postprocessing/Effects/Vignette.d.ts +11 -0
  173. package/lib/engine-components/postprocessing/Effects/Vignette.js +57 -0
  174. package/lib/engine-components/postprocessing/Effects/Vignette.js.map +1 -0
  175. package/lib/engine-components/postprocessing/PostProcessingEffect.d.ts +29 -0
  176. package/lib/engine-components/postprocessing/PostProcessingEffect.js +89 -0
  177. package/lib/engine-components/postprocessing/PostProcessingEffect.js.map +1 -0
  178. package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +13 -0
  179. package/lib/engine-components/postprocessing/PostProcessingHandler.js +119 -0
  180. package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -0
  181. package/lib/engine-components/postprocessing/Volume.d.ts +23 -0
  182. package/lib/engine-components/postprocessing/Volume.js +176 -0
  183. package/lib/engine-components/postprocessing/Volume.js.map +1 -0
  184. package/lib/engine-components/postprocessing/VolumeParameter.d.ts +21 -0
  185. package/lib/engine-components/postprocessing/VolumeParameter.js +75 -0
  186. package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -0
  187. package/lib/engine-components/postprocessing/VolumeProfile.d.ts +7 -0
  188. package/lib/engine-components/postprocessing/VolumeProfile.js +42 -0
  189. package/lib/engine-components/postprocessing/VolumeProfile.js.map +1 -0
  190. package/lib/engine-components/timeline/TimelineTracks.js +14 -15
  191. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  192. package/lib/engine-components/ui/Text.js +28 -170
  193. package/lib/engine-components/ui/Text.js.map +1 -1
  194. package/lib/engine-components-experimental/networking/PlayerSync.d.ts +18 -0
  195. package/lib/engine-components-experimental/networking/PlayerSync.js +62 -8
  196. package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -1
  197. package/lib/include/three/ARButton.d.ts +1 -1
  198. package/lib/include/three/ARButton.js +11 -19
  199. package/lib/include/three/ARButton.js.map +1 -1
  200. package/lib/include/three/VRButton.js +1 -4
  201. package/lib/include/three/VRButton.js.map +1 -1
  202. package/package.json +3 -2
  203. package/plugins/vite/drop-client.js +77 -0
  204. package/plugins/vite/drop.js +81 -0
  205. package/plugins/vite/editor-connection.js +121 -0
  206. package/plugins/vite/index.js +9 -4
  207. package/plugins/vite/meta.js +3 -0
  208. package/plugins/vite/poster-client.js +6 -4
  209. package/src/engine/api.ts +30 -1
  210. package/src/engine/codegen/register_types.js +25 -9
  211. package/src/engine/debug/debug_overlay.ts +11 -2
  212. package/src/engine/engine_addressables.ts +4 -4
  213. package/src/engine/engine_assetdatabase.ts +291 -184
  214. package/src/engine/engine_components.ts +20 -1
  215. package/src/engine/engine_components_internal.ts +30 -0
  216. package/src/engine/engine_constants.ts +4 -1
  217. package/src/engine/engine_context_registry.ts +7 -0
  218. package/src/engine/engine_editor-sync.ts +21 -0
  219. package/src/engine/engine_element.ts +8 -1
  220. package/src/engine/engine_element_loading.ts +19 -15
  221. package/src/engine/engine_gameobject.ts +579 -583
  222. package/src/engine/engine_gizmos.ts +3 -2
  223. package/src/engine/engine_gltf_builtin_components.ts +30 -15
  224. package/src/engine/engine_networking.ts +10 -8
  225. package/src/engine/engine_networking_auto.ts +48 -11
  226. package/src/engine/engine_patcher.ts +113 -0
  227. package/src/engine/engine_physics.ts +128 -12
  228. package/src/engine/engine_scenetools.ts +0 -1
  229. package/src/engine/engine_serialization_core.ts +6 -0
  230. package/src/engine/engine_setup.ts +15 -5
  231. package/src/engine/engine_texture.ts +54 -5
  232. package/src/engine/engine_types.ts +6 -1
  233. package/src/engine/engine_utils.ts +6 -5
  234. package/src/engine/extensions/NEEDLE_progressive.ts +32 -32
  235. package/src/engine/extensions/NEEDLE_render_objects.ts +10 -1
  236. package/src/engine/extensions/extensions.ts +22 -1
  237. package/src/engine/extensions/usage_tracker.ts +91 -0
  238. package/src/engine-components/Animator.ts +0 -1
  239. package/src/engine-components/AnimatorController.ts +2 -0
  240. package/src/engine-components/AudioSource.ts +1 -1
  241. package/src/engine-components/Camera.ts +77 -37
  242. package/src/engine-components/CharacterController.ts +12 -9
  243. package/src/engine-components/Collider.ts +16 -2
  244. package/src/engine-components/Component.ts +74 -30
  245. package/src/engine-components/Networking.ts +9 -1
  246. package/src/engine-components/OrbitControls.ts +11 -2
  247. package/src/engine-components/ParticleSystem.ts +54 -10
  248. package/src/engine-components/ParticleSystemModules.ts +28 -1
  249. package/src/engine-components/ParticleSystemSubEmitter.ts +5 -3
  250. package/src/engine-components/ReflectionProbe.ts +17 -7
  251. package/src/engine-components/Renderer.ts +36 -16
  252. package/src/engine-components/ScreenCapture.ts +3 -3
  253. package/src/engine-components/Skybox.ts +2 -0
  254. package/src/engine-components/SmoothFollow.ts +4 -4
  255. package/src/engine-components/SpectatorCamera.ts +3 -3
  256. package/src/engine-components/SyncedCamera.ts +1 -1
  257. package/src/engine-components/SyncedTransform.ts +2 -2
  258. package/src/engine-components/TestRunner.ts +1 -1
  259. package/src/engine-components/WebARCameraBackground.ts +215 -0
  260. package/src/engine-components/WebARSessionRoot.ts +3 -2
  261. package/src/engine-components/WebXR.ts +12 -8
  262. package/src/engine-components/WebXRAvatar.ts +1 -1
  263. package/src/engine-components/WebXRGrabRendering.ts +2 -2
  264. package/src/engine-components/WebXRSync.ts +2 -2
  265. package/src/engine-components/codegen/components.ts +14 -6
  266. package/src/engine-components/js-extensions/Object3D.ts +6 -1
  267. package/src/engine-components/postprocessing/Effects/Antialiasing.ts +52 -0
  268. package/src/engine-components/postprocessing/Effects/Bloom.ts +75 -0
  269. package/src/engine-components/postprocessing/Effects/ChromaticAberration.ts +36 -0
  270. package/src/engine-components/postprocessing/Effects/ColorAdjustments.ts +114 -0
  271. package/src/engine-components/postprocessing/Effects/DepthOfField.ts +90 -0
  272. package/src/engine-components/postprocessing/Effects/Pixelation.ts +28 -0
  273. package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.ts +71 -0
  274. package/src/engine-components/postprocessing/Effects/Tonemapping.ts +55 -0
  275. package/src/engine-components/postprocessing/Effects/Vignette.ts +55 -0
  276. package/src/engine-components/postprocessing/PostProcessingEffect.ts +112 -0
  277. package/src/engine-components/postprocessing/PostProcessingHandler.ts +148 -0
  278. package/src/engine-components/postprocessing/Volume.ts +194 -0
  279. package/src/engine-components/postprocessing/VolumeParameter.ts +85 -0
  280. package/src/engine-components/postprocessing/VolumeProfile.ts +40 -0
  281. package/src/engine-components/timeline/TimelineTracks.ts +16 -17
  282. package/src/engine-components/ui/Text.ts +37 -174
  283. package/src/engine-components-experimental/networking/PlayerSync.ts +69 -8
  284. package/src/include/three/ARButton.js +13 -24
  285. package/src/include/three/VRButton.js +1 -7
  286. package/lib/engine-components/Volume.d.ts +0 -34
  287. package/lib/engine-components/Volume.js +0 -140
  288. package/lib/engine-components/Volume.js.map +0 -1
  289. package/src/engine-components/Volume.ts +0 -141
@@ -1,44 +1,10 @@
1
- import * as THREE from 'three';
2
- import { Scene } from 'three';
3
- // import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
4
- import * as utils from "./engine_utils";
5
-
6
- const debug = utils.getParam("debugassets");
7
-
8
- class TextureInfo {
9
- name!: string;
10
- sampler!: number;
11
- source!: number;
12
- extras: { guid: string } | undefined;
13
- }
14
-
15
- class ImageInfo {
16
- bufferView!: number;
17
- mimeType: string | undefined;
18
- extras: { guid: string } | undefined;
19
- }
1
+ import { InternalUsageTrackerPlugin } from "./extensions/usage_tracker";
2
+ import { Bone, BufferAttribute, BufferGeometry, InterleavedBuffer, InterleavedBufferAttribute, Material, Mesh, Object3D, Skeleton, SkinnedMesh, Texture, WebGLRenderer } from "three";
3
+ import { addPatch } from "./engine_patcher";
4
+ import { getParam } from "./engine_utils";
20
5
 
21
- class GltfJson {
22
- textures!: TextureInfo[];
23
- bufferViews!: Array<{ buffer: number, byteOffset: number, byteLength: number }>;
24
- }
25
6
 
26
- declare class GltfParser {
27
- cache: any;
28
- json: GltfJson;
29
- associations: Map<any, any>;
30
- textureLoader: THREE.TextureLoader;
31
- loadTexture: Function;
32
- }
33
-
34
- declare class Gltf {
35
- parser: GltfParser;
36
- scene: Scene;
37
- }
38
-
39
- /** @deprecated */
40
7
  export class AssetDatabase {
41
-
42
8
  constructor() {
43
9
  window.addEventListener('unhandledrejection', (event: PromiseRejectionEvent) => {
44
10
  if (event.defaultPrevented) return;
@@ -52,164 +18,305 @@ export class AssetDatabase {
52
18
  }
53
19
  });
54
20
  }
21
+ }
22
+
23
+ const trackUsageParam = getParam("trackusage");
24
+
25
+ function autoDispose() {
26
+ return trackUsageParam === "dispose";
27
+ }
55
28
 
56
- private texturesLoader: THREE.TextureLoader = new THREE.TextureLoader();
57
- private textures: { [key: string]: THREE.Texture | PromiseLike<THREE.Texture> } = {};
58
- private texturesLoading: { [key: string]: THREE.Texture | PromiseLike<THREE.Texture> } = {};
29
+ // For testing only track when explictly enabled
30
+ let allowUsageTracking = trackUsageParam !== undefined && trackUsageParam !== false && trackUsageParam !== 0;
59
31
 
60
- /** @deprecated */
61
- public async loadTexture(url: string): Promise<THREE.Texture | null> {
62
- if (this.textures[url]) {
63
- return this.textures[url];
32
+ export function setUsageTrackingEnabled(enabled: boolean) {
33
+ allowUsageTracking = enabled;
34
+ }
35
+ export function isUsageTrackingEnabled() {
36
+ return allowUsageTracking;
37
+ }
38
+
39
+
40
+ /** Recursive disposes all referenced resources by this object. Does not traverse children */
41
+ export function disposeObjectResources(obj: object) {
42
+ if (!obj) return;
43
+
44
+ if (obj instanceof SkinnedMesh) {
45
+ disposeObjectResources(obj.geometry);
46
+ disposeObjectResources(obj.material);
47
+ disposeObjectResources(obj.skeleton);
48
+ }
49
+ else if (obj instanceof Mesh) {
50
+ disposeObjectResources(obj.geometry);
51
+ disposeObjectResources(obj.material);
52
+ }
53
+ else if (obj instanceof BufferGeometry) {
54
+ free(obj);
55
+ for (const key of Object.keys(obj.attributes)) {
56
+ const value = obj.attributes[key];
57
+ disposeObjectResources(value);
58
+ }
59
+ }
60
+ else if (obj instanceof BufferAttribute || obj instanceof InterleavedBufferAttribute) {
61
+ // Currently not supported by three
62
+ // https://github.com/mrdoob/three.js/issues/15261
63
+ // https://github.com/mrdoob/three.js/pull/17063#issuecomment-737993363
64
+ }
65
+ else if (obj instanceof Array<Material>) {
66
+ for (const entry of obj) {
67
+ if (entry)
68
+ disposeObjectResources(entry);
69
+ }
70
+ }
71
+ else if (obj instanceof Material) {
72
+ for (const key of Object.keys(obj)) {
73
+ const value = obj[key];
74
+ if (value instanceof Texture)
75
+ disposeObjectResources(value);
64
76
  }
65
- if (this.texturesLoading[url]) {
66
- return await this.texturesLoading[url];
77
+ free(obj);
78
+ }
79
+ else if (obj instanceof Texture) {
80
+ free(obj);
81
+ if (obj.source?.data instanceof ImageBitmap) {
82
+ free(obj.source.data);
67
83
  }
68
- const loading = this.texturesLoader.loadAsync(url);
69
- this.texturesLoading[url] = loading;
70
- const res = await loading;
71
- delete this.texturesLoading[url];
72
- this.textures[url] = res;
73
- return res;
74
84
  }
85
+ else if (obj instanceof Skeleton) {
86
+ free(obj.boneTexture);
87
+ }
88
+ else if (obj instanceof Bone) {
75
89
 
76
- /** @deprecated */
77
- public getTexture(guid: string): THREE.Texture | null {
78
- return this._textures.get(guid) || null;
79
90
  }
91
+ else {
92
+ if (!(obj instanceof Object3D) && debug)
93
+ console.warn("Unknown object type", obj);
94
+ }
95
+ }
80
96
 
81
- /** @deprecated */
82
- public findTexture(name: string): THREE.Texture | null {
83
- for (const texture of this._textures.values()) {
84
- if (texture.name === name) {
85
- return texture;
86
- }
97
+ function free(obj: any) {
98
+ if (debug || autoDispose() || trackUsageParam) console.warn("🧨 FREE", obj);
99
+ if (!obj) {
100
+ return;
101
+ }
102
+ if (obj instanceof ImageBitmap) {
103
+ obj.close();
104
+ }
105
+ else {
106
+ obj.dispose();
107
+ }
108
+ }
109
+
110
+ export function __internalNotifyObjectDestroyed(obj: Object3D) {
111
+ if (obj instanceof Mesh || obj instanceof SkinnedMesh) {
112
+ obj.material = null;
113
+ obj.geometry = null;
114
+ }
115
+ }
116
+
117
+ const usersBuffer = new Set<object>();
118
+
119
+ export type UserFilter = (user: object) => boolean;
120
+
121
+ /**
122
+ * Find all users of an object
123
+ * @param object Object to find users of
124
+ * @param recursive Find users of users
125
+ * @param predicate Filter users
126
+ * @param set Set to add users to, a new one will be created if none is provided
127
+ * @returns a set of users
128
+ */
129
+ export function findUsers(object: object, recursive: boolean, predicate: UserFilter | null | undefined = null, set?: Set<object>): Set<object> {
130
+ if (!set) {
131
+ set = usersBuffer;
132
+ set.clear();
133
+ }
134
+ if (!object) return set;
135
+ const users = object[$objectUsersKey] as Set<object>;
136
+ if (users) {
137
+ for (const user of users) {
138
+ // Prevent infinite loop if recursive references
139
+ if (set.has(user)) continue;
140
+ // Allow filtering
141
+ if (predicate?.call(null, user) === false) continue;
142
+ set.add(user);
143
+ if (recursive)
144
+ findUsers(user, true, predicate, set);
145
+ }
146
+ }
147
+ return set;
148
+ }
149
+
150
+ export function getUserCount(object: object): number | undefined {
151
+ return object[$objectUsersCountKey];
152
+ }
153
+
154
+
155
+
156
+ const debug = getParam("debugusers");
157
+
158
+ // Should we check if the type has the
159
+ const $objectUsersKey = Symbol("needle-users");
160
+ const $objectUsersCountKey = Symbol("needle-users-count");
161
+
162
+ function trackValueChange(prototype, fieldName) {
163
+ addPatch(prototype, fieldName, (obj, oldValue, newValue) => {
164
+ if (allowUsageTracking) {
165
+ updateUsers($objectUsersKey, obj, oldValue, false);
166
+ updateUsers($objectUsersKey, obj, newValue, true);
167
+ }
168
+ });
169
+ }
170
+
171
+ // function stopTracking(prototype, fieldName) {
172
+ // const $key = Symbol("needle-using-" + fieldName);
173
+ // const currentValue = prototype[$key];
174
+ // delete prototype[$key];
175
+ // prototype[fieldName] = currentValue;
176
+ // updateUsers($objectUsersKey, fieldName, prototype, currentValue, true);
177
+ // }
178
+
179
+
180
+ trackValueChange(Mesh.prototype, "material");
181
+ trackValueChange(Mesh.prototype, "geometry");
182
+ trackValueChange(Material.prototype, "map");
183
+ trackValueChange(Material.prototype, "bumpMap");
184
+ trackValueChange(Material.prototype, "alphaMap");
185
+ trackValueChange(Material.prototype, "normalMap");
186
+ trackValueChange(Material.prototype, "displacementMap");
187
+ trackValueChange(Material.prototype, "roughnessMap");
188
+ trackValueChange(Material.prototype, "metalnessMap");
189
+ trackValueChange(Material.prototype, "emissiveMap");
190
+ trackValueChange(Material.prototype, "specularMap");
191
+ trackValueChange(Material.prototype, "envMap");
192
+ trackValueChange(Material.prototype, "lightMap");
193
+ trackValueChange(Material.prototype, "aoMap");
194
+ trackValueChange(Material.prototype, "gradientMap");
195
+ // trackValueChange(Object3D.prototype, "parent");
196
+
197
+
198
+ // setTimeout(()=>{
199
+ // stopTracking(Mesh.prototype, "material");
200
+ // },100);
201
+
202
+
203
+ // TODO: patch dispose?
204
+
205
+
206
+ function onDispose(obj: object) {
207
+ if (allowUsageTracking === false) return;
208
+ const users = obj[$objectUsersKey] as Set<object>;
209
+ if (users) {
210
+ for (const user of users) {
211
+ updateUsers($objectUsersKey, user, obj, false);
87
212
  }
88
- return null;
89
213
  }
214
+ }
90
215
 
91
- /** @deprecated */
92
- public findMesh(name: string): THREE.Mesh | null {
93
- for (const mesh of this._meshes.values()) {
94
- if (mesh.name === name)
95
- return mesh;
216
+ function trackDispose(prototype, methodName: string) {
217
+ addPatch(prototype, methodName, (instance) => {
218
+ onDispose(instance);
219
+ });
220
+ }
221
+
222
+ trackDispose(Material.prototype, "dispose");
223
+
224
+
225
+
226
+
227
+
228
+ let noUpdateScope = 0;
229
+
230
+ // Main method called by wrapped fields/properties to update the users for an object
231
+ function updateUsers(symbol: symbol, user: object, object: object | object[], added: boolean) {
232
+
233
+ // If we are rendering we dont want to update users
234
+ if (noUpdateScope > 0) return;
235
+
236
+ if (Array.isArray(object)) {
237
+ for (const m of object) {
238
+ updateUsers(symbol, user, m, added);
96
239
  }
97
- return null;
240
+ return;
98
241
  }
242
+ if (!object) return;
99
243
 
100
- /** @deprecated */
101
- public findMaterial(name:string) : THREE.Material | null {
102
- for (const material of this._materials.values()) {
103
- if (material.name === name)
104
- return material;
244
+ let users = object[symbol];
245
+ if (!users) users = new Set();
246
+ if (added) {
247
+ if (user && !users.has(user)) {
248
+ users.add(user);
249
+ let count = object[$objectUsersCountKey] || 0;
250
+ count += 1;
251
+ object[$objectUsersCountKey] = count;
252
+ if (debug) console.warn(`🟢 Added user of "${object["type"]}"`, user, object, count, "users:", users);
253
+ }
254
+ } else {
255
+ if (user && users.has(user)) {
256
+ users.delete(user);
257
+ let count = object[$objectUsersCountKey] || 0;
258
+ if (count > 0) {
259
+ count -= 1;
260
+ object[$objectUsersCountKey] = count;
261
+ }
262
+ if (debug) console.warn(`🔴 Removed user of "${object["type"]}"`, user, object, count, "users:", users);
263
+ if (count <= 0) {
264
+ if (!InternalUsageTrackerPlugin.isLoading(object)) {
265
+ if (trackUsageParam)
266
+ console.warn(`🔴 Removed all user of "${object["type"]}"`, object);
267
+ if (autoDispose())
268
+ disposeObjectResources(object);
269
+ }
270
+ }
105
271
  }
106
- return null;
107
- }
108
-
109
- /** @deprecated */
110
- public async registerGltf(_gltf: Gltf) {
111
- // if (debug)
112
- // console.log("register gltf", gltf.scene.name, gltf);
113
- // const parser = gltf.parser;
114
- // const json = parser.json;
115
- // const textures = json.textures;
116
- // const associations = parser.associations;
117
- // const alreadyLoaded = new Set<string>();
118
- // associations.forEach((value, key) => {
119
- // // when minified instanceOf doesnt work but the texture type is 1009
120
- // if (key instanceof THREE.Texture || key.type === 1009) {
121
- // const index = value.textures;
122
- // const textureInfo = textures[index];
123
- // // TODO: a lot of information is gone when compressing with ktx2
124
- // // this.registerTexture(parser, index, textureInfo, key, alreadyLoaded);
125
- // }
126
- // else if (key instanceof THREE.Mesh || key.type == "Mesh") {
127
- // this.registerAsset(key);
128
-
129
- // // saving materials,
130
- // // FIXME: this is unlike the other things by name here as a hack for forma, it should probably saved by name and by guid just like anything else here
131
- // if(key.material){
132
- // this._materials.set(key.material.name, key.material);
133
- // }
134
- // }
135
- // });
136
-
137
- // // for (const ti in textures) {
138
- // // const textureInfo = textures[ti];
139
- // // await this.registerTexture(parser, ti, textureInfo, null, alreadyLoaded);
140
- // // }
141
-
142
- // if (debug)
143
- // console.log(this);
144
- }
145
-
146
- /** @deprecated */
147
- public registerAsset(_asset: any) {
148
- // if (debug) console.log("register asset", asset);
149
- // console.assert(asset, "Asset is null or undefined");
150
- // const guid: string = asset.userData?.guid;
151
- // if (guid === null || guid === undefined || guid.length === 0) {
152
- // // asset has no guid, this can happen e.g. when using multi material meshes
153
- // // should we ask the parent for the guid if it's a group?
154
- // // we need a more stable way to preserve ids anyways
155
- // return;
156
- // }
157
- // if (asset instanceof THREE.Texture || asset.type === 1009) {
158
- // if (this._textures.has(guid) && this._textures.get(guid) !== asset) {
159
- // if (debug)
160
- // console.warn("found duplicate texture " + guid, asset);
161
- // return;
162
- // }
163
- // if (debug)
164
- // console.log("register texture", guid, asset);
165
- // // should we check if an asset has been registered already?
166
- // // should not matter as long as we only export guid from unity?
167
- // this._textures.set(guid, asset);
168
- // }
169
- // else if (asset instanceof THREE.Mesh || asset.type == "Mesh") {
170
- // this._meshes.set(guid, asset);
171
- // }
172
- }
173
-
174
-
175
- private _materials: Map<string, THREE.Material> = new Map<string, THREE.Material>();
176
- private _meshes: Map<string, THREE.Mesh> = new Map();
177
- // private async registerMesh(parser: GltfParser, mesh : THREE.Mesh){
178
- // const guid = mesh?.userData?.guid;
179
- // }
180
-
181
-
182
- private _textures: Map<string, THREE.Texture> = new Map();
183
-
184
- // private async registerTexture(parser: GltfParser, index: number | string, textureInfo: TextureInfo, texture: THREE.Texture | null, alreadyLoaded: Set<string>) {
185
-
186
- // // const guid = textureInfo?.extras?.guid || texture?.userData?.guid;
187
- // // if (!guid) {
188
- // // if (debug) console.warn("missing guid", texture, textureInfo)
189
- // // return;
190
- // // }
191
- // // console.assert(guid !== null && guid !== undefined && guid.length > 0, "Texture has no guid in userData", texture);
192
- // // if (guid) {
193
- // // if (alreadyLoaded.has(guid)) {
194
- // // // console.warn("texture already loaded", textureInfo.name, guid);
195
- // // return;
196
- // // }
197
- // // alreadyLoaded.add(guid);
198
- // // }
199
-
200
- // // if (!texture) {
201
- // // texture = await parser.loadTexture(index);
202
- // // if (!texture) {
203
- // // if (debug)
204
- // // console.warn("failed to load texture", guid);
205
- // // return;
206
- // // }
207
- // // }
208
-
209
- // // if (textureInfo.extras) {
210
- // // texture.userData = { ...texture.userData, ...textureInfo.extras };
211
- // // }
212
- // // this.registerAsset(texture);
213
- // }
214
-
215
- }
272
+ }
273
+ object[symbol] = users;
274
+ }
275
+
276
+
277
+
278
+
279
+ // We dont want to update users during rendering
280
+
281
+ const $renderMethod = Symbol("render-method");
282
+
283
+ Object.defineProperty(WebGLRenderer.prototype, "render", {
284
+ set: function (this: WebGLRenderer, value: Function) {
285
+ this[$renderMethod] = wrapMethod(value);
286
+ },
287
+ get: function (this: WebGLRenderer) {
288
+ return this[$renderMethod];
289
+ }
290
+ });
291
+
292
+
293
+ function wrapMethod(fn: Function) {
294
+ return function (this: WebGLRenderer, ...args) {
295
+ noUpdateScope++;
296
+ const result = fn.apply(this, args);
297
+ noUpdateScope--;
298
+ return result;
299
+ }
300
+ }
301
+
302
+
303
+
304
+ // addGltfLoadEventListener(GltfLoadEventType.BeforeLoad, (_) => {
305
+ // noUpdateScope++;
306
+ // });
307
+ // addGltfLoadEventListener(GltfLoadEventType.AfterLoaded, (_) => {
308
+ // noUpdateScope--;
309
+ // });
310
+
311
+
312
+
313
+
314
+ // addPatch(Object3D.prototype, "add", (obj: Object3D) => {
315
+ // });
316
+
317
+
318
+ // addPatch(Object3D.prototype, "remove", (obj: Object3D) => {
319
+ // if(obj instanceof Mesh) {
320
+ // }
321
+ // });
322
+
@@ -5,10 +5,16 @@ import { getParam } from "./engine_utils";
5
5
  import { removeScriptFromContext, updateActiveInHierarchyWithoutEventCall } from "./engine_mainloop_utils";
6
6
  import { activeInHierarchyFieldName } from "./engine_constants";
7
7
  import { apply } from "../engine-components/js-extensions/Object3D";
8
+ import { InstantiateIdProvider } from "./engine_networking_instantiate";
9
+ import { ComponentEvents, __internalDispatchComponentLifecycleEvent } from "./engine_components_internal";
8
10
 
9
11
  const debug = getParam("debuggetcomponent");
10
12
 
11
13
 
14
+
15
+
16
+
17
+
12
18
  function tryGetObject(obj) {
13
19
  if (obj === null || obj === undefined) return obj;
14
20
  if (obj.isObject3D) return obj;
@@ -23,6 +29,9 @@ export function removeComponent(go: Object3D, componentInstance: IComponent) {
23
29
  if (!go.userData.components) return;
24
30
  const index = go.userData.components.indexOf(componentInstance);
25
31
  if (index < 0) return;
32
+
33
+ __internalDispatchComponentLifecycleEvent(ComponentEvents.Removing, componentInstance);
34
+
26
35
  //@ts-ignore
27
36
  componentInstance.gameObject = null;
28
37
  go.userData.components.splice(index, 1);
@@ -35,6 +44,8 @@ export function getOrAddComponent<T extends IComponent>(go: Object3D, typeName:
35
44
  return addNewComponent(go, newInstance) as unknown as T;
36
45
  }
37
46
 
47
+ const idProvider = new InstantiateIdProvider("addComponentIdProvider");
48
+
38
49
  export function addNewComponent<T extends IComponent>(obj: Object3D, componentInstance: T, callAwake = true): IComponent {
39
50
  if (!obj) {
40
51
  new Error("Can not add componet to null object");
@@ -43,14 +54,19 @@ export function addNewComponent<T extends IComponent>(obj: Object3D, componentIn
43
54
  if (!obj.userData.components) obj.userData.components = [];
44
55
  obj.userData.components.push(componentInstance);
45
56
  componentInstance.gameObject = obj as IGameObject;
57
+ // TODO: currently add component does not ensure a new component instance has a guid
58
+ if (componentInstance.guid === undefined || componentInstance.guid === "invalid") {
59
+ componentInstance.guid = idProvider.generateUUID();
60
+ }
46
61
  apply(obj);
47
62
  // componentInstance.transform = obj;
48
63
  registerComponent(componentInstance);
49
64
  try {
50
- if (componentInstance.__internalAwake && callAwake) {
65
+ if (callAwake && componentInstance.__internalAwake) {
51
66
  updateActiveInHierarchyWithoutEventCall(obj);
52
67
  componentInstance.__internalAwake();
53
68
  }
69
+ __internalDispatchComponentLifecycleEvent(ComponentEvents.Added, componentInstance);
54
70
  }
55
71
  catch (err) {
56
72
  console.error(err);
@@ -67,8 +83,11 @@ export function moveComponentInstance(obj: Object3D, componentInstance: ICompone
67
83
  }
68
84
  if (!obj.userData.components) obj.userData.components = [];
69
85
  else if (obj.userData.components.includes(componentInstance)) return;
86
+ // TODO: do we want to disable and enable when moving?
87
+ // componentInstance.__internalDisable();
70
88
  obj.userData.components.push(componentInstance);
71
89
  componentInstance.gameObject = obj as IGameObject;
90
+ // componentInstance.__internalEnable();
72
91
  // componentInstance.transform = obj;
73
92
  }
74
93
 
@@ -0,0 +1,30 @@
1
+ import { IComponent } from "./engine_types";
2
+
3
+
4
+ const eventListeners = new Map<string, ((data: IComponent) => void)[]>();
5
+
6
+ export enum ComponentEvents {
7
+ Added = "component-added",
8
+ Removing = "removing-component"
9
+ }
10
+
11
+ export function __internalAddComponentLifecycleEventListener(evt: string, cb: (data: IComponent) => void) {
12
+ if (!eventListeners.has(evt)) eventListeners.set(evt, []);
13
+ eventListeners.get(evt)?.push(cb);
14
+ }
15
+
16
+ export function __internalRemoveComponentLifecycleEventListener(evt: string, cb: (data: IComponent) => void) {
17
+ const listeners = eventListeners.get(evt);
18
+ if (!listeners) return;
19
+ const index = listeners.indexOf(cb);
20
+ if (index < 0) return;
21
+ listeners.splice(index, 1);
22
+ }
23
+
24
+ export function __internalDispatchComponentLifecycleEvent(evt: string, data: IComponent) {
25
+ const listeners = eventListeners.get(evt);
26
+ if (!listeners) return;
27
+ for (const listener of listeners) {
28
+ listener(data);
29
+ }
30
+ }
@@ -1,3 +1,6 @@
1
1
 
2
2
  export const activeInHierarchyFieldName = Symbol("isActiveInHierarchy");
3
- export const builtinComponentKeyName = "builtin_components";
3
+ export const builtinComponentKeyName = "builtin_components";
4
+
5
+
6
+ export const $originalGuid = Symbol("originalGuid");
@@ -47,4 +47,11 @@ export class ContextRegistry {
47
47
  const args = { event: evt, context }
48
48
  this._callbacks[evt].forEach(cb => cb(args));
49
49
  }
50
+
51
+ static addContextCreatedCallback(callback: ContextCallback) {
52
+ this.registerCallback(ContextEvent.ContextCreated, callback);
53
+ }
54
+ static addContextDestroyedCallback(callback: ContextCallback) {
55
+ this.registerCallback(ContextEvent.ContextDestroyed, callback);
56
+ }
50
57
  }
@@ -0,0 +1,21 @@
1
+
2
+
3
+
4
+
5
+ export declare type EditorModification = {
6
+ guid: string,
7
+ propertyName: string,
8
+ value: any
9
+ }
10
+
11
+ export interface IEditorModification {
12
+ onEditorModification(modification: EditorModification): void | undefined | boolean;
13
+ }
14
+
15
+ // let editorCache = new Map<string, EditorModification>();
16
+ // export function setEditorModificationCache(cache: Map<string, EditorModification>) {
17
+ // cache = editorCache;
18
+ // }
19
+ export function getEditorModificationCache() {
20
+ return globalThis["NeedleEditorSync.ModificationCache"] as null | undefined | Map<string, EditorModification>;
21
+ }