@needle-tools/engine 2.63.3-pre.1 → 2.65.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 +24 -0
  2. package/dist/needle-engine.js +7853 -7746
  3. package/dist/needle-engine.umd.cjs +215 -214
  4. package/lib/engine/api.js.map +1 -1
  5. package/lib/engine/assets/index.js.map +1 -1
  6. package/lib/engine/assets/logo.svg +1 -0
  7. package/lib/engine/codegen/register_types.js +169 -169
  8. package/lib/engine/codegen/register_types.js.map +1 -1
  9. package/lib/engine/debug/debug.js.map +1 -1
  10. package/lib/engine/debug/debug_console.js.map +1 -1
  11. package/lib/engine/debug/debug_overlay.js.map +1 -1
  12. package/lib/engine/debug/index.js.map +1 -1
  13. package/lib/engine/engine.js.map +1 -1
  14. package/lib/engine/engine_addressables.js.map +1 -1
  15. package/lib/engine/engine_application.js.map +1 -1
  16. package/lib/engine/engine_assetdatabase.js.map +1 -1
  17. package/lib/engine/engine_camera.js.map +1 -1
  18. package/lib/engine/engine_components.js.map +1 -1
  19. package/lib/engine/engine_constants.d.ts +1 -1
  20. package/lib/engine/engine_constants.js +1 -1
  21. package/lib/engine/engine_constants.js.map +1 -1
  22. package/lib/engine/engine_context_registry.js.map +1 -1
  23. package/lib/engine/engine_coroutine.js.map +1 -1
  24. package/lib/engine/engine_create_objects.js.map +1 -1
  25. package/lib/engine/engine_default_parameters.js.map +1 -1
  26. package/lib/engine/engine_element.d.ts +6 -4
  27. package/lib/engine/engine_element.js +152 -165
  28. package/lib/engine/engine_element.js.map +1 -1
  29. package/lib/engine/engine_element_loading.js.map +1 -1
  30. package/lib/engine/engine_element_overlay.js.map +1 -1
  31. package/lib/engine/engine_fileloader.js.map +1 -1
  32. package/lib/engine/engine_gameobject.d.ts +4 -2
  33. package/lib/engine/engine_gameobject.js +34 -15
  34. package/lib/engine/engine_gameobject.js.map +1 -1
  35. package/lib/engine/engine_generic_utils.js.map +1 -1
  36. package/lib/engine/engine_gizmos.js.map +1 -1
  37. package/lib/engine/engine_gltf.d.ts +1 -1
  38. package/lib/engine/engine_gltf.js.map +1 -1
  39. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  40. package/lib/engine/engine_hot_reload.js.map +1 -1
  41. package/lib/engine/engine_input.js.map +1 -1
  42. package/lib/engine/engine_input_utils.js.map +1 -1
  43. package/lib/engine/engine_instancing.d.ts +1 -0
  44. package/lib/engine/engine_instancing.js +3 -2
  45. package/lib/engine/engine_instancing.js.map +1 -1
  46. package/lib/engine/engine_license.js +14 -13
  47. package/lib/engine/engine_license.js.map +1 -1
  48. package/lib/engine/engine_lightdata.js.map +1 -1
  49. package/lib/engine/engine_loaders.js.map +1 -1
  50. package/lib/engine/engine_mainloop_utils.js +62 -57
  51. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  52. package/lib/engine/engine_math.js.map +1 -1
  53. package/lib/engine/engine_networking.js.map +1 -1
  54. package/lib/engine/engine_networking_auto.js.map +1 -1
  55. package/lib/engine/engine_networking_files.js.map +1 -1
  56. package/lib/engine/engine_networking_files_default_components.js.map +1 -1
  57. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  58. package/lib/engine/engine_networking_peer.js.map +1 -1
  59. package/lib/engine/engine_networking_types.js.map +1 -1
  60. package/lib/engine/engine_networking_utils.js.map +1 -1
  61. package/lib/engine/engine_networking_websocket.js.map +1 -1
  62. package/lib/engine/engine_physics.d.ts +1 -0
  63. package/lib/engine/engine_physics.js +30 -0
  64. package/lib/engine/engine_physics.js.map +1 -1
  65. package/lib/engine/engine_physics.types.js.map +1 -1
  66. package/lib/engine/engine_playerview.js.map +1 -1
  67. package/lib/engine/engine_rendererdata.js.map +1 -1
  68. package/lib/engine/engine_scenetools.js.map +1 -1
  69. package/lib/engine/engine_serialization.js.map +1 -1
  70. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  71. package/lib/engine/engine_serialization_core.js.map +1 -1
  72. package/lib/engine/engine_serialization_decorator.js.map +1 -1
  73. package/lib/engine/engine_setup.d.ts +6 -3
  74. package/lib/engine/engine_setup.js +14 -5
  75. package/lib/engine/engine_setup.js.map +1 -1
  76. package/lib/engine/engine_shaders.js.map +1 -1
  77. package/lib/engine/engine_texture.js.map +1 -1
  78. package/lib/engine/engine_three_utils.js.map +1 -1
  79. package/lib/engine/engine_time.d.ts +1 -0
  80. package/lib/engine/engine_time.js +5 -1
  81. package/lib/engine/engine_time.js.map +1 -1
  82. package/lib/engine/engine_types.d.ts +12 -0
  83. package/lib/engine/engine_types.js.map +1 -1
  84. package/lib/engine/engine_typestore.js.map +1 -1
  85. package/lib/engine/engine_util_decorator.js.map +1 -1
  86. package/lib/engine/engine_utils.js.map +1 -1
  87. package/lib/engine/engine_utils_screenshot.js.map +1 -1
  88. package/lib/engine/engine_web_api.js.map +1 -1
  89. package/lib/engine/extensions/EXT_texture_exr.js.map +1 -1
  90. package/lib/engine/extensions/NEEDLE_animator_controller_model.js.map +1 -1
  91. package/lib/engine/extensions/NEEDLE_components.js.map +1 -1
  92. package/lib/engine/extensions/NEEDLE_gameobject_data.js.map +1 -1
  93. package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
  94. package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
  95. package/lib/engine/extensions/NEEDLE_persistent_assets.js.map +1 -1
  96. package/lib/engine/extensions/NEEDLE_progressive.js.map +1 -1
  97. package/lib/engine/extensions/NEEDLE_render_objects.js.map +1 -1
  98. package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
  99. package/lib/engine/extensions/extension_resolver.js.map +1 -1
  100. package/lib/engine/extensions/extension_utils.js.map +1 -1
  101. package/lib/engine/extensions/extensions.js.map +1 -1
  102. package/lib/engine/js-extensions/Camera.js.map +1 -1
  103. package/lib/engine/js-extensions/Layers.js.map +1 -1
  104. package/lib/engine/js-extensions/index.js.map +1 -1
  105. package/lib/engine/shaders/shaderData.js.map +1 -1
  106. package/lib/engine/tests/test_utils.js.map +1 -1
  107. package/lib/engine-components/AlignmentConstraint.js.map +1 -1
  108. package/lib/engine-components/Animation.js +6 -6
  109. package/lib/engine-components/Animation.js.map +1 -1
  110. package/lib/engine-components/AnimationCurve.js.map +1 -1
  111. package/lib/engine-components/Animator.js.map +1 -1
  112. package/lib/engine-components/AnimatorController.js +2 -0
  113. package/lib/engine-components/AnimatorController.js.map +1 -1
  114. package/lib/engine-components/AudioListener.js.map +1 -1
  115. package/lib/engine-components/AudioSource.js +1 -1
  116. package/lib/engine-components/AudioSource.js.map +1 -1
  117. package/lib/engine-components/AvatarLoader.js.map +1 -1
  118. package/lib/engine-components/AxesHelper.js.map +1 -1
  119. package/lib/engine-components/BasicIKConstraint.js.map +1 -1
  120. package/lib/engine-components/BoxCollider.js.map +1 -1
  121. package/lib/engine-components/BoxHelperComponent.js.map +1 -1
  122. package/lib/engine-components/Camera.d.ts +3 -1
  123. package/lib/engine-components/Camera.js +11 -10
  124. package/lib/engine-components/Camera.js.map +1 -1
  125. package/lib/engine-components/CameraUtils.js.map +1 -1
  126. package/lib/engine-components/CharacterController.js.map +1 -1
  127. package/lib/engine-components/Collider.js.map +1 -1
  128. package/lib/engine-components/Component.d.ts +2 -1
  129. package/lib/engine-components/Component.js +2 -2
  130. package/lib/engine-components/Component.js.map +1 -1
  131. package/lib/engine-components/DeleteBox.js.map +1 -1
  132. package/lib/engine-components/DeviceFlag.js.map +1 -1
  133. package/lib/engine-components/DragControls.js.map +1 -1
  134. package/lib/engine-components/DropListener.js.map +1 -1
  135. package/lib/engine-components/Duplicatable.js.map +1 -1
  136. package/lib/engine-components/EventList.js.map +1 -1
  137. package/lib/engine-components/EventTrigger.js.map +1 -1
  138. package/lib/engine-components/EventType.js.map +1 -1
  139. package/lib/engine-components/FlyControls.js.map +1 -1
  140. package/lib/engine-components/Fog.js.map +1 -1
  141. package/lib/engine-components/Gizmos.js.map +1 -1
  142. package/lib/engine-components/GridHelper.js.map +1 -1
  143. package/lib/engine-components/GroundProjection.js.map +1 -1
  144. package/lib/engine-components/Interactable.js.map +1 -1
  145. package/lib/engine-components/Joints.js.map +1 -1
  146. package/lib/engine-components/LODGroup.js.map +1 -1
  147. package/lib/engine-components/Light.d.ts +0 -2
  148. package/lib/engine-components/Light.js +22 -14
  149. package/lib/engine-components/Light.js.map +1 -1
  150. package/lib/engine-components/LookAtConstraint.js.map +1 -1
  151. package/lib/engine-components/NestedGltf.js.map +1 -1
  152. package/lib/engine-components/Networking.js.map +1 -1
  153. package/lib/engine-components/OffsetConstraint.js.map +1 -1
  154. package/lib/engine-components/OrbitControls.js.map +1 -1
  155. package/lib/engine-components/ParticleSystem.js +13 -1
  156. package/lib/engine-components/ParticleSystem.js.map +1 -1
  157. package/lib/engine-components/ParticleSystemModules.js.map +1 -1
  158. package/lib/engine-components/ParticleSystemSubEmitter.js.map +1 -1
  159. package/lib/engine-components/PlayerColor.js.map +1 -1
  160. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  161. package/lib/engine-components/Renderer.d.ts +5 -1
  162. package/lib/engine-components/Renderer.js +78 -29
  163. package/lib/engine-components/Renderer.js.map +1 -1
  164. package/lib/engine-components/RendererLightmap.js.map +1 -1
  165. package/lib/engine-components/RigidBody.js.map +1 -1
  166. package/lib/engine-components/ScreenCapture.js.map +1 -1
  167. package/lib/engine-components/ShadowCatcher.js.map +1 -1
  168. package/lib/engine-components/Skybox.d.ts +2 -0
  169. package/lib/engine-components/Skybox.js +43 -21
  170. package/lib/engine-components/Skybox.js.map +1 -1
  171. package/lib/engine-components/SmoothFollow.js.map +1 -1
  172. package/lib/engine-components/SpatialTrigger.js.map +1 -1
  173. package/lib/engine-components/SpectatorCamera.js.map +1 -1
  174. package/lib/engine-components/SphereCollider.js.map +1 -1
  175. package/lib/engine-components/SpriteRenderer.js.map +1 -1
  176. package/lib/engine-components/SyncedCamera.js.map +1 -1
  177. package/lib/engine-components/SyncedRoom.js.map +1 -1
  178. package/lib/engine-components/SyncedTransform.js.map +1 -1
  179. package/lib/engine-components/TestRunner.js.map +1 -1
  180. package/lib/engine-components/TransformGizmo.js.map +1 -1
  181. package/lib/engine-components/VideoPlayer.js.map +1 -1
  182. package/lib/engine-components/Voip.js.map +1 -1
  183. package/lib/engine-components/Volume.js +2 -0
  184. package/lib/engine-components/Volume.js.map +1 -1
  185. package/lib/engine-components/WebARSessionRoot.js.map +1 -1
  186. package/lib/engine-components/WebXR.js.map +1 -1
  187. package/lib/engine-components/WebXRAvatar.js.map +1 -1
  188. package/lib/engine-components/WebXRController.js.map +1 -1
  189. package/lib/engine-components/WebXRGrabRendering.js.map +1 -1
  190. package/lib/engine-components/WebXRRig.js.map +1 -1
  191. package/lib/engine-components/WebXRSync.js.map +1 -1
  192. package/lib/engine-components/XRFlag.js.map +1 -1
  193. package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +1 -1
  194. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +1 -1
  195. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +1 -1
  196. package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +1 -1
  197. package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +1 -1
  198. package/lib/engine-components/codegen/components.js.map +1 -1
  199. package/lib/engine-components/debug/LogStats.js.map +1 -1
  200. package/lib/engine-components/export/gltf/GltfExport.js.map +1 -1
  201. package/lib/engine-components/export/usdz/Extension.js.map +1 -1
  202. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  203. package/lib/engine-components/export/usdz/extensions/Animation.js.map +1 -1
  204. package/lib/engine-components/export/usdz/types.js.map +1 -1
  205. package/lib/engine-components/export/usdz/utils/animationutils.js.map +1 -1
  206. package/lib/engine-components/export/usdz/utils/quicklook.js.map +1 -1
  207. package/lib/engine-components/export/usdz/utils/timeutils.js.map +1 -1
  208. package/lib/engine-components/js-extensions/ExtensionUtils.js.map +1 -1
  209. package/lib/engine-components/js-extensions/Object3D.js +8 -1
  210. package/lib/engine-components/js-extensions/Object3D.js.map +1 -1
  211. package/lib/engine-components/js-extensions/RGBAColor.js.map +1 -1
  212. package/lib/engine-components/js-extensions/Vector.js.map +1 -1
  213. package/lib/engine-components/timeline/PlayableDirector.d.ts +5 -0
  214. package/lib/engine-components/timeline/PlayableDirector.js +36 -23
  215. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  216. package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
  217. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  218. package/lib/engine-components/timeline/TimelineTracks.d.ts +9 -0
  219. package/lib/engine-components/timeline/TimelineTracks.js +112 -19
  220. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  221. package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
  222. package/lib/engine-components/ui/Button.js.map +1 -1
  223. package/lib/engine-components/ui/Canvas.js +2 -2
  224. package/lib/engine-components/ui/Canvas.js.map +1 -1
  225. package/lib/engine-components/ui/CanvasGroup.js.map +1 -1
  226. package/lib/engine-components/ui/EventSystem.js.map +1 -1
  227. package/lib/engine-components/ui/Graphic.js.map +1 -1
  228. package/lib/engine-components/ui/Image.js.map +1 -1
  229. package/lib/engine-components/ui/InputField.js.map +1 -1
  230. package/lib/engine-components/ui/Interfaces.js.map +1 -1
  231. package/lib/engine-components/ui/Keyboard.js.map +1 -1
  232. package/lib/engine-components/ui/Layout.js.map +1 -1
  233. package/lib/engine-components/ui/PointerEvents.js.map +1 -1
  234. package/lib/engine-components/ui/RaycastUtils.js.map +1 -1
  235. package/lib/engine-components/ui/Raycaster.js.map +1 -1
  236. package/lib/engine-components/ui/RectTransform.js.map +1 -1
  237. package/lib/engine-components/ui/SpatialHtml.js.map +1 -1
  238. package/lib/engine-components/ui/Text.js.map +1 -1
  239. package/lib/engine-components/ui/Utils.js.map +1 -1
  240. package/lib/engine-components-experimental/Presentation.js.map +1 -1
  241. package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -1
  242. package/lib/engine-schemes/schemes.js.map +1 -1
  243. package/lib/engine-schemes/synced-camera-model.js.map +1 -1
  244. package/lib/engine-schemes/synced-transform-model.js.map +1 -1
  245. package/lib/engine-schemes/transform.js.map +1 -1
  246. package/lib/engine-schemes/vec2.js.map +1 -1
  247. package/lib/engine-schemes/vec3.js.map +1 -1
  248. package/lib/engine-schemes/vec4.js.map +1 -1
  249. package/lib/engine-schemes/vr-user-state-buffer.js.map +1 -1
  250. package/lib/include/three/ARButton.js.map +1 -1
  251. package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js.map +1 -1
  252. package/lib/include/three/VRButton.js.map +1 -1
  253. package/lib/needle-engine.js.map +1 -1
  254. package/package.json +16 -3
  255. package/plugins/generate-font.js +65 -0
  256. package/plugins/vite/poster-client.js +3 -5
  257. package/plugins/vite/reload.js +2 -2
  258. package/src/engine/codegen/register_types.js +171 -171
  259. package/src/engine/engine_constants.ts +1 -1
  260. package/src/engine/engine_element.ts +162 -178
  261. package/src/engine/engine_gameobject.ts +583 -558
  262. package/src/engine/engine_gltf.ts +1 -1
  263. package/src/engine/engine_instancing.ts +3 -3
  264. package/src/engine/engine_license.ts +14 -13
  265. package/src/engine/engine_mainloop_utils.ts +66 -63
  266. package/src/engine/engine_physics.ts +23 -0
  267. package/src/engine/engine_setup.ts +21 -8
  268. package/src/engine/engine_time.ts +9 -4
  269. package/src/engine/engine_types.ts +36 -22
  270. package/src/engine-components/Animation.ts +6 -5
  271. package/src/engine-components/AnimatorController.ts +1 -0
  272. package/src/engine-components/AudioSource.ts +1 -1
  273. package/src/engine-components/Camera.ts +14 -12
  274. package/src/engine-components/Component.ts +5 -2
  275. package/src/engine-components/Light.ts +20 -13
  276. package/src/engine-components/ParticleSystem.ts +15 -2
  277. package/src/engine-components/Renderer.ts +92 -33
  278. package/src/engine-components/Skybox.ts +49 -22
  279. package/src/engine-components/Volume.ts +1 -0
  280. package/src/engine-components/js-extensions/Object3D.ts +8 -2
  281. package/src/engine-components/timeline/PlayableDirector.ts +35 -24
  282. package/src/engine-components/timeline/TimelineTracks.ts +124 -20
  283. package/src/engine-components/ui/Canvas.ts +2 -2
  284. package/lib/tsconfig.tsbuildinfo +0 -1
  285. package/lib/vite.config.d.ts +0 -2
  286. package/lib/vite.config.js +0 -26
  287. package/lib/vite.config.js.map +0 -1
  288. package/src/engine/codegen/license.js +0 -1
  289. package/src/tsconfig.json +0 -33
@@ -9,7 +9,7 @@ export interface INeedleGltfLoader {
9
9
  createBuiltinComponents(context: Context, gltfId: SourceIdentifier, gltf, seed: number | null | UIDProvider, extension?: NEEDLE_components): Promise<void>
10
10
  writeBuiltinComponentData(comp: object, context: SerializationContext);
11
11
  parseSync(context: Context, data, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined>;
12
- loadSync(context: Context, url: string, seed: number | UIDProvider | null, _allowAddingAnimator: boolean, prog?: (ProgressEvent) => void): Promise<GLTF | undefined>
12
+ loadSync(context: Context, url: string, seed: number | UIDProvider | null, _allowAddingAnimator: boolean, prog?: (prog : ProgressEvent) => void): Promise<GLTF | undefined>
13
13
  }
14
14
 
15
15
  let gltfLoader: INeedleGltfLoader;
@@ -1,17 +1,17 @@
1
1
  export const NEED_UPDATE_INSTANCE_KEY = Symbol("NEEDLE_NEED_UPDATE_INSTANCE");
2
2
 
3
-
3
+ export const $isUsingInstancing = Symbol("isUsingInstancing");
4
4
 
5
5
  export class InstancingUtil {
6
6
 
7
- static isUsingInstancing(instance: THREE.Object3D): boolean { return instance["__isUsingInstancing"] === true; }
7
+ static isUsingInstancing(instance: THREE.Object3D): boolean { return instance[$isUsingInstancing] === true; }
8
8
 
9
9
  // TODO: change this so it does not set matrix world directly but some flag that is only used by instancing
10
10
  static markDirty(go: THREE.Object3D | null, recursive: boolean = true) {
11
11
  if (!go) return;
12
12
  // potential optimization:
13
13
  // if(go.matrixWorldNeedsUpdate) return;
14
- // console.trace(go, GameObject.isUsingInstancing(go));
14
+ // console.warn("UPDATE", go);
15
15
  if (this.isUsingInstancing(go)) {
16
16
  go[NEED_UPDATE_INSTANCE_KEY] = true;
17
17
  go.matrixWorldNeedsUpdate = true;
@@ -42,7 +42,7 @@ async function showLicenseInfo(ctx: IContext) {
42
42
 
43
43
 
44
44
  const _licenseText = "🌵 <span class=\"text\">Made with <a href=\"https://needle.tools\" target=\"_blank\">Needle</a></span>";
45
- const licenseElementClass = "needle-license-element";
45
+ const licenseElementIdentifier = "needle-license-element";
46
46
  const licenseDuration = 30000;
47
47
  const licenseDelay = 600;
48
48
 
@@ -78,6 +78,7 @@ function insertNonCommercialUseHint(ctx: IContext) {
78
78
  setTimeout(() => {
79
79
  clearInterval(interval);
80
80
  licenseElement?.remove();
81
+ style?.remove();
81
82
  }, removeDelay);
82
83
 
83
84
  }
@@ -97,8 +98,7 @@ async function logNonCommercialUse(_logo?: string) {
97
98
 
98
99
  function createLicenseElement() {
99
100
  const licenseElement = document.createElement("div");
100
- licenseElement.classList.add(licenseElementClass);
101
- licenseElement.setAttribute("data-needle_engine_license_element", "");
101
+ licenseElement.setAttribute(licenseElementIdentifier, "");
102
102
  licenseElement.style.position = "fixed";
103
103
  licenseElement.style.bottom = "12px";
104
104
  licenseElement.style.right = "15px";
@@ -112,10 +112,8 @@ function createLicenseElement() {
112
112
  // TODO: would be better to put this into a web element and use shadow dom
113
113
  function createLicenseStyle() {
114
114
  const licenseStyle = document.createElement("style");
115
- const selector = "." + licenseElementClass;
115
+ const selector = `div[${licenseElementIdentifier}]`;
116
116
  licenseStyle.innerHTML = `
117
- @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;500&display=swap');
118
-
119
117
  ${selector} {
120
118
  font-family: 'Roboto', sans-serif !important;
121
119
  font-weight: 300;
@@ -145,23 +143,26 @@ function createLicenseStyle() {
145
143
  opacity: .9;
146
144
  }
147
145
  2% {
148
- transform: translate(0, 3px);
146
+ transform: translate(0, 2.5px);
149
147
  }
150
- 6% {
148
+ 3% {
151
149
  transform: translate(0, 0px);
152
150
  pointer-events: all;
153
151
  opacity: 1;
154
152
  }
155
- 50% {
153
+ 4% {
156
154
  transform: scale(1)
157
155
  }
158
- 51% {
159
- transform: scale(1.2)
156
+ 4.5% {
157
+ transform: scale(1.3)
158
+ }
159
+ 6% {
160
+ transform: scale(1.32)
160
161
  }
161
- 53% {
162
+ 7% {
162
163
  transform: scale(1)
163
164
  }
164
- 90% {
165
+ 98% {
165
166
  opacity: 1;
166
167
  pointer-events: all;
167
168
  transform: scale(1)
@@ -7,6 +7,7 @@ import { isActiveSelf } from './engine_gameobject';
7
7
  import { ContextRegistry } from "./engine_context_registry";
8
8
 
9
9
  const debug = getParam("debugnewscripts");
10
+ const debugHierarchy = getParam("debughierarchy");
10
11
 
11
12
  // if some other script adds new scripts in onEnable or awake
12
13
  // the original array should be cleared before processing it
@@ -16,7 +17,7 @@ const new_scripts_buffer: any[] = [];
16
17
  export function processNewScripts(context: IContext) {
17
18
  if (context.new_scripts.length <= 0) return;
18
19
  if (debug)
19
- console.log("Register new components", context.new_scripts.length, context.alias ? ("element: " + context.alias) : "");
20
+ console.log("Register new components", context.new_scripts.length, [...context.new_scripts], context.alias ? ("element: " + context.alias) : context["hash"], context);
20
21
 
21
22
  // if(new_scripts_post_setup_callbacks.length > 0) console.log(new_scripts_post_setup_callbacks);
22
23
  if (context.new_scripts_pre_setup_callbacks.length > 0) {
@@ -214,8 +215,6 @@ function removeFromArray(script: any, array: any[]) {
214
215
  if (index >= 0) array.splice(index, 1);
215
216
  }
216
217
 
217
- const previousActiveMap: { [key: string]: boolean } = {};
218
- const previousActiveInHierarchyMap: { [key: string]: boolean } = {};
219
218
 
220
219
  export function updateIsActive(obj?: Object3D) {
221
220
  if (!obj) obj = ContextRegistry.Current.scene;
@@ -223,78 +222,83 @@ export function updateIsActive(obj?: Object3D) {
223
222
  console.trace("Invalid call - no current context.");
224
223
  return;
225
224
  }
226
- updateIsActiveInHierarchyRecursiveRuntime(obj, isActiveSelf(obj), true);
225
+ const wasSuccessful = updateIsActiveInHierarchyRecursiveRuntime(obj, isActiveSelf(obj), true);
226
+ if (!wasSuccessful) {
227
+ console.error("Failed to update active state in hierarchy of \"" + obj.name + "\"", obj);
228
+ console.warn(" ↑ this error might be caused by circular references. Please make sure you don't have files with circular references (e.g. one GLB 1 is loading GLB 2 which is then loading GLB 1 again).")
229
+ }
227
230
  }
228
231
 
229
- // const $wasSetVisibleBefore = Symbol("wasSetVisibleBefore");
230
-
231
- function updateIsActiveInHierarchyRecursiveRuntime(go: THREE.Object3D, activeInHierarchy: boolean, allowEventCall: boolean) {
232
- let activeStateChanged: boolean = false;
233
-
234
- const active = isActiveSelf(go);
235
-
236
- // this is a test if we dont control active state from visibility and set
237
- // active to true by default (even if the object is invisible) in engine_gameobjects:isActiveSelf
238
- // then we need to check if the object is set to visible for the first time
239
- // const visible = go.visible;
240
- // if (!active && visible) {
241
- // if (!go[$wasSetVisibleBefore]) {
242
- // go[$wasSetVisibleBefore] = true;
243
- // setActive(go, true);
244
- // }
245
- // }
246
-
247
- // if (activeInHierarchy) {
248
- // const prevActive = previousActiveMap[go.uuid];
249
- // if (prevActive !== undefined) {
250
- // if (prevActive !== active) {
251
- // activeStateChanged = true;
252
- // if (allowEventCall) {
253
- // perComponent(go, comp => {
254
- // if (active) {
255
- // utils.safeInvoke(comp.__internalAwake.bind(comp));
256
- // comp.onEnable();
257
- // }
258
- // else comp.onDisable();
259
- // });
260
- // }
261
- // }
262
- // }
263
- // }
264
- previousActiveMap[go.uuid] = active;
232
+ function updateIsActiveInHierarchyRecursiveRuntime(go: THREE.Object3D, activeInHierarchy: boolean, allowEventCall: boolean, level: number = 0) {
233
+ if (level > 1000) {
234
+ console.warn("Hierarchy is too deep (> 1000 level) - will abort updating active state");
235
+ return false;
236
+ }
265
237
 
238
+ const isActive = isActiveSelf(go);
239
+ if (activeInHierarchy) {
240
+ activeInHierarchy = isActive;
241
+ // IF we update activeInHierarchy within a disabled hierarchy we need to check the parent
242
+ if (activeInHierarchy && go.parent) {
243
+ activeInHierarchy = go.parent[constants.activeInHierarchyFieldName]
244
+ }
245
+ }
266
246
 
267
- if (activeInHierarchy) activeInHierarchy = isActiveSelf(go);
247
+ const prevActive = go[constants.activeInHierarchyFieldName];
248
+ const changed = prevActive !== activeInHierarchy;
268
249
  go[constants.activeInHierarchyFieldName] = activeInHierarchy;
269
250
 
270
251
  // only raise events here if we didnt call enable etc already
271
- if (!activeStateChanged) {
272
- const prevActiveInHierarchy = previousActiveInHierarchyMap[go.uuid];
273
- if (prevActiveInHierarchy !== undefined) {
274
- if (prevActiveInHierarchy !== activeInHierarchy) {
275
- // console.log("CHANGE", go.name, activeInHierarchy);
276
- if (allowEventCall) {
277
- perComponent(go, comp => {
278
- if (activeInHierarchy) {
279
- utils.safeInvoke(comp.__internalAwake.bind(comp));
280
- comp.enabled = true;
281
- // comp.onEnable();
282
- }
283
- else comp.enabled = false;
284
- });
252
+ if (changed) {
253
+ if (debugHierarchy)
254
+ console.warn("ACTIVE CHANGE", go.name, isActive, go.visible, activeInHierarchy, "changed?" + changed, go);
255
+ if (allowEventCall) {
256
+ perComponent(go, comp => {
257
+ if (activeInHierarchy) {
258
+ if (comp.enabled) {
259
+ utils.safeInvoke(comp.__internalAwake.bind(comp));
260
+ comp["__didEnable"] = true;
261
+ comp.onEnable();
262
+ }
285
263
  }
286
- }
264
+ else {
265
+ if (comp["__didAwake"]) {
266
+ comp["__didEnable"] = false;
267
+ comp.onDisable();
268
+ }
269
+ }
270
+ });
287
271
  }
288
272
  }
289
- previousActiveInHierarchyMap[go.uuid] = activeInHierarchy;
290
273
 
274
+ let success = true;
291
275
  if (go.children) {
276
+ const nextLevel = level + 1;
292
277
  for (const ch of go.children) {
293
- updateIsActiveInHierarchyRecursiveRuntime(ch, activeInHierarchy, allowEventCall);
278
+ const res = updateIsActiveInHierarchyRecursiveRuntime(ch, activeInHierarchy, allowEventCall, nextLevel);
279
+ if (res === false) success = false;
294
280
  }
295
281
  }
282
+ return success;
296
283
  }
297
284
 
285
+ // let isRunning = false;
286
+ // // Prevent: https://github.com/needle-tools/needle-tiny/issues/641
287
+ // const temporyChildArrayBuffer: Array<Array<THREE.Object3D>> = [];
288
+ // export function* iterateChildrenSafe(obj: Object3D) {
289
+ // if (!obj || !obj.children) yield null;
290
+ // // if(isRunning) return;
291
+ // // isRunning = true;
292
+ // const arr = temporyChildArrayBuffer.pop() || [];
293
+ // arr.push(...obj.children);
294
+ // for (const ch of arr) {
295
+ // yield ch;
296
+ // }
297
+ // // isRunning = false;
298
+ // arr.length = 0;
299
+ // temporyChildArrayBuffer.push(arr);
300
+ // }
301
+
298
302
  export function updateActiveInHierarchyWithoutEventCall(go: THREE.Object3D) {
299
303
  let activeInHierarchy = true;
300
304
  let current: THREE.Object3D | null = go;
@@ -312,7 +316,6 @@ export function updateActiveInHierarchyWithoutEventCall(go: THREE.Object3D) {
312
316
  console.error("GO is null");
313
317
  return;
314
318
  }
315
- previousActiveInHierarchyMap[go.uuid] = activeInHierarchy;
316
319
  go[constants.activeInHierarchyFieldName] = activeInHierarchy && foundScene;
317
320
  }
318
321
 
@@ -341,7 +344,7 @@ export function registerPrewarmObject(obj: Object3D, context: IContext) {
341
344
  obj[$waitingForPrewarm] = true;
342
345
  const list = prewarmList.get(context);
343
346
  list!.push(obj);
344
- if(debugPrewarm) console.debug("register prewarm", obj.name);
347
+ if (debugPrewarm) console.debug("register prewarm", obj.name);
345
348
  }
346
349
 
347
350
  let prewarmTarget: WebGLCubeRenderTarget | null = null;
@@ -355,7 +358,7 @@ export function runPrewarm(context: IContext) {
355
358
 
356
359
  const cam = context.mainCamera;
357
360
  if (cam) {
358
- if(debugPrewarm) console.log("prewarm", list.length, "objects", [...list]);
361
+ if (debugPrewarm) console.log("prewarm", list.length, "objects", [...list]);
359
362
  const renderer = context.renderer;
360
363
  const scene = context.scene;
361
364
  renderer.compile(scene, cam!)
@@ -364,10 +367,10 @@ export function runPrewarm(context: IContext) {
364
367
  prewarmCamera.update(renderer, scene);
365
368
  for (const obj of list) {
366
369
  obj[$prewarmedFlag] = true;
367
- obj[$waitingForPrewarm] = false;
370
+ obj[$waitingForPrewarm] = false;
368
371
  }
369
372
  list.length = 0;
370
- if(debugPrewarm) console.log("prewarm done");
373
+ if (debugPrewarm) console.log("prewarm done");
371
374
  }
372
375
  }
373
376
 
@@ -26,6 +26,7 @@ const debugPhysics = getParam("debugphysics");
26
26
  const debugColliderPlacement = getParam("debugphysicscolliders");
27
27
  const debugCollisions = getParam("debugcollisions");
28
28
  const showColliders = getParam("showcolliders");
29
+ const noPhysics = getParam("nophysics");
29
30
 
30
31
 
31
32
  declare type PhysicsBody = {
@@ -286,6 +287,8 @@ export class Physics {
286
287
 
287
288
  // physics simulation
288
289
 
290
+ enabled: boolean = true;
291
+
289
292
  private _tempPosition: Vector3 = new Vector3();
290
293
  private _tempQuaternion: Quaternion = new Quaternion();
291
294
  private _tempScale: Vector3 = new Vector3();
@@ -325,6 +328,7 @@ export class Physics {
325
328
  Physics._didLoadPhysicsEngine = true;
326
329
  }
327
330
  this.world = new World(this._gravity);
331
+ if (noPhysics) this.enabled = false;
328
332
  }
329
333
 
330
334
  private _gravity = { x: 0.0, y: -9.81, z: 0.0 };
@@ -347,6 +351,10 @@ export class Physics {
347
351
  }
348
352
 
349
353
  addBoxCollider(collider: ICollider, center: Vector3, size: Vector3) {
354
+ if (!this.enabled) {
355
+ if(debugPhysics) console.warn("Physics is disabled");
356
+ return;
357
+ }
350
358
  const obj = collider.gameObject;
351
359
  const scale = getWorldScale(obj, this._tempPosition).multiply(size);
352
360
  scale.multiplyScalar(0.5);
@@ -355,6 +363,10 @@ export class Physics {
355
363
  }
356
364
 
357
365
  addSphereCollider(collider: ICollider, center: Vector3, radius: number) {
366
+ if (!this.enabled) {
367
+ if(debugPhysics) console.warn("Physics is disabled");
368
+ return;
369
+ }
358
370
  const obj = collider.gameObject;
359
371
  const scale = getWorldScale(obj, this._tempPosition).multiplyScalar(radius);
360
372
  const desc = ColliderDesc.ball(scale.x);
@@ -362,6 +374,10 @@ export class Physics {
362
374
  }
363
375
 
364
376
  addCapsuleCollider(collider: ICollider, center: Vector3, height: number, radius: number) {
377
+ if (!this.enabled) {
378
+ if(debugPhysics) console.warn("Physics is disabled");
379
+ return;
380
+ }
365
381
  const obj = collider.gameObject;
366
382
  const scale = getWorldScale(obj, this._tempPosition);
367
383
  if (debugPhysics) console.log("capsule scale", scale, height, radius);
@@ -370,6 +386,10 @@ export class Physics {
370
386
  }
371
387
 
372
388
  addMeshCollider(collider: ICollider, mesh: Mesh, convex: boolean, scale: Vector3) {
389
+ if (!this.enabled) {
390
+ if(debugPhysics) console.warn("Physics is disabled");
391
+ return;
392
+ }
373
393
  const geo = mesh.geometry;
374
394
  if (!geo) {
375
395
  if (debugPhysics) console.warn("Missing mesh geometry", mesh.name);
@@ -575,6 +595,7 @@ export class Physics {
575
595
  }
576
596
 
577
597
  updateBody(comp: ICollider | IRigidbody, translation: boolean, rotation: boolean) {
598
+ if (!this.enabled) return;
578
599
  if (comp.destroyed || !comp.gameObject) return;
579
600
  if (!translation && !rotation) return;
580
601
 
@@ -637,6 +658,7 @@ export class Physics {
637
658
 
638
659
  public step(dt?: number) {
639
660
  if (!this.world) return;
661
+ if (!this.enabled) return;
640
662
  this._isUpdatingPhysicsWorld = true;
641
663
  if (!this.eventQueue) {
642
664
  this.eventQueue = new EventQueue(false);
@@ -670,6 +692,7 @@ export class Physics {
670
692
 
671
693
  public postStep() {
672
694
  if (!this.world) return;
695
+ if (!this.enabled) return;
673
696
  this._isUpdatingPhysicsWorld = true;
674
697
  this.syncObjects();
675
698
  this._isUpdatingPhysicsWorld = false;
@@ -48,8 +48,8 @@ export declare class LoadingOptions {
48
48
  }
49
49
 
50
50
  export class ContextArgs {
51
- name: string | undefined | null;
52
- alias: string | undefined | null = undefined;
51
+ name?: string;
52
+ alias?: string;
53
53
  domElement: HTMLElement | null;
54
54
  renderer?: THREE.WebGLRenderer = undefined;
55
55
  hash?: string;
@@ -227,13 +227,15 @@ export class Context implements IContext {
227
227
  lightmaps: ILightDataRegistry;
228
228
  players: PlayerViewManager;
229
229
 
230
+ get isCreated() { return this._isCreated; }
231
+
230
232
  private _sizeChanged: boolean = false;
231
233
  private _isCreated: boolean = false;
232
234
  private _isVisible: boolean = false;
233
235
 
234
236
  private _stats: Stats.default | null = stats ? Stats.default() : null;
235
237
 
236
- constructor(args: ContextArgs | undefined) {
238
+ constructor(args?: ContextArgs) {
237
239
  this.name = args?.name || "";
238
240
  this.alias = args?.alias;
239
241
  this.domElement = args?.domElement || document.body;
@@ -287,9 +289,17 @@ export class Context implements IContext {
287
289
  resizeObserver.observe(this.domElement);
288
290
  this._disposeCallbacks.push(() => resizeObserver.disconnect());
289
291
 
290
- const intersectionObserver = new IntersectionObserver(entries => { this._isVisible = entries[0].isIntersecting; });
291
- intersectionObserver.observe(this.domElement);
292
- this._disposeCallbacks.push(() => intersectionObserver.disconnect());
292
+ this._intersectionObserver = new IntersectionObserver(entries => {
293
+ this._isVisible = entries[0].isIntersecting;
294
+ });
295
+ this._disposeCallbacks.push(() => this._intersectionObserver?.disconnect());
296
+ }
297
+
298
+
299
+ private _intersectionObserver: IntersectionObserver | null = null;
300
+ private internalOnUpdateVisible() {
301
+ this._intersectionObserver?.disconnect();
302
+ this._intersectionObserver?.observe(this.domElement);
293
303
  }
294
304
 
295
305
  private _disposeCallbacks: Function[] = [];
@@ -498,6 +508,8 @@ export class Context implements IContext {
498
508
  }
499
509
  if (!prepare_succeeded) return;
500
510
 
511
+ this.internalOnUpdateVisible();
512
+
501
513
  // console.log(prepare_succeeded);
502
514
 
503
515
  if (!this.isManagedExternally)
@@ -770,14 +782,15 @@ export class Context implements IContext {
770
782
  return paused;
771
783
  }
772
784
 
773
- private evaluatePaused() {
785
+ private evaluatePaused(): boolean {
774
786
  if (this.isInXR) return false;
775
787
  if (this.isPaused) return true;
776
788
  // if the element is not visible use the runInBackground flag to determine if we should continue
777
789
  if (this.runInBackground) {
778
790
  return false;
779
791
  }
780
- return !this.isVisibleToUser;
792
+ const paused = !this.isVisibleToUser;
793
+ return paused;
781
794
  }
782
795
 
783
796
  private renderRequiredTextures() {
@@ -3,7 +3,7 @@ import { getParam } from './engine_utils';
3
3
 
4
4
  const timescaleUrl = getParam("timescale");
5
5
  let timeScale = 1;
6
- if(typeof timescaleUrl === "number") timeScale = timescaleUrl;
6
+ if (typeof timescaleUrl === "number") timeScale = timescaleUrl;
7
7
 
8
8
  export class Time {
9
9
 
@@ -28,12 +28,17 @@ export class Time {
28
28
  private _fpsSamples: number[] = [];
29
29
  private _fpsSampleIndex: number = 0;
30
30
 
31
+ constructor() {
32
+ if (typeof timeScale === "number")
33
+ this.timeScale = timeScale;
34
+ }
35
+
31
36
  update() {
32
37
  this.deltaTime = this.clock.getDelta();
33
38
  // clamp delta time because if tab is not active clock.getDelta can get pretty big
34
39
  this.deltaTime = Math.min(.1, this.deltaTime);
35
- this.deltaTime *= timeScale * this.timeScale;
36
- if(this.deltaTime <= 0) this.deltaTime = 0.000000000001;
40
+ this.deltaTime *= this.timeScale;
41
+ if (this.deltaTime <= 0) this.deltaTime = 0.000000000001;
37
42
  this.frame += 1;
38
43
  this.time += this.deltaTime;
39
44
 
@@ -42,6 +47,6 @@ export class Time {
42
47
  let sum = 0;
43
48
  for (let i = 0; i < this._fpsSamples.length; i++)
44
49
  sum += this._fpsSamples[i];
45
- this._smoothedFps = 1/(sum / this._fpsSamples.length);
50
+ this._smoothedFps = 1 / (sum / this._fpsSamples.length);
46
51
  }
47
52
  }
@@ -21,9 +21,9 @@ export interface UIDProvider {
21
21
 
22
22
 
23
23
  export declare type CoroutineData = {
24
- comp: IComponent,
25
- main: Generator,
26
- chained?: Array<Generator>
24
+ comp: IComponent,
25
+ main: Generator,
26
+ chained?: Array<Generator>
27
27
  }
28
28
 
29
29
 
@@ -37,25 +37,25 @@ export interface IContext {
37
37
  domElement: HTMLElement;
38
38
 
39
39
  scripts: IComponent[];
40
- scripts_pausedChanged: IComponent[];
41
- // scripts with update event
42
- scripts_earlyUpdate: IComponent[];
43
- scripts_update: IComponent[];
44
- scripts_lateUpdate: IComponent[];
45
- scripts_onBeforeRender: IComponent[];
46
- scripts_onAfterRender: IComponent[];
47
- scripts_WithCorroutines: IComponent[];
48
- coroutines: { [FrameEvent: number]: Array<CoroutineData> };
49
-
50
- post_setup_callbacks: Function[];
51
- pre_update_callbacks: Function[];
52
- pre_render_callbacks: Function[];
53
- post_render_callbacks: Function[];
54
-
55
- new_scripts: IComponent[];
56
- new_script_start: IComponent[];
57
- new_scripts_pre_setup_callbacks: Function[];
58
- new_scripts_post_setup_callbacks: Function[];
40
+ scripts_pausedChanged: IComponent[];
41
+ // scripts with update event
42
+ scripts_earlyUpdate: IComponent[];
43
+ scripts_update: IComponent[];
44
+ scripts_lateUpdate: IComponent[];
45
+ scripts_onBeforeRender: IComponent[];
46
+ scripts_onAfterRender: IComponent[];
47
+ scripts_WithCorroutines: IComponent[];
48
+ coroutines: { [FrameEvent: number]: Array<CoroutineData> };
49
+
50
+ post_setup_callbacks: Function[];
51
+ pre_update_callbacks: Function[];
52
+ pre_render_callbacks: Function[];
53
+ post_render_callbacks: Function[];
54
+
55
+ new_scripts: IComponent[];
56
+ new_script_start: IComponent[];
57
+ new_scripts_pre_setup_callbacks: Function[];
58
+ new_scripts_post_setup_callbacks: Function[];
59
59
 
60
60
  stopAllCoroutinesFrom(script: IComponent);
61
61
  }
@@ -71,6 +71,13 @@ export declare interface IGameObject extends Object3D {
71
71
  guid: string | undefined;
72
72
 
73
73
  activeSelf: boolean;
74
+
75
+ /** NOTE: this is just a wrapper for devs coming from Unity. Please use this.gameObject instead. In Needle Engine this.gameObject is the same as this.gameObject.transform. See the tutorial link below for more information
76
+ * @augments Object3D
77
+ * @tutorial https://fwd.needle.tools/needle-engine/docs/transform
78
+ * */
79
+ get transform(): Object3D;
80
+
74
81
  addNewComponent<T>(type: Constructor<T>): T | null;
75
82
  removeComponent(comp: IComponent): IComponent;
76
83
  getOrAddComponent<T>(typeName: Constructor<T> | null): T;
@@ -100,12 +107,19 @@ export interface IComponent {
100
107
 
101
108
  get activeAndEnabled(): boolean;
102
109
 
110
+ /** @internal */
103
111
  __internalNewInstanceCreated();
112
+ /** @internal */
104
113
  __internalAwake();
114
+ /** @internal */
105
115
  __internalStart();
116
+ /** @internal */
106
117
  __internalEnable();
118
+ /** @internal */
107
119
  __internalDisable();
120
+ /** @internal */
108
121
  __internalDestroy();
122
+ /** @internal */
109
123
  resolveGuids?(guidsMap: GuidsMap): void;
110
124
 
111
125
  /** experimental, called when the script is registered for the first time, this is called even if the component is not enabled. */
@@ -125,11 +125,12 @@ export class Animation extends Behaviour {
125
125
  update() {
126
126
  if (!this.mixer) return;
127
127
  this.mixer.update(this.context.time.deltaTime);
128
- for (const handle of this._handles) {
129
- handle._update();
130
- }
131
- if (this._handles?.length > 0)
132
- InstancingUtil.markDirty(this.gameObject);
128
+ // this is now handled via matrix auto update
129
+ // for (const handle of this._handles) {
130
+ // handle._update();
131
+ // }
132
+ // if (this._handles?.length > 0)
133
+ // InstancingUtil.markDirty(this.gameObject);
133
134
  }
134
135
 
135
136
  getAction(name: string): THREE.AnimationAction | undefined | null {
@@ -146,6 +146,7 @@ export class AnimatorController {
146
146
  if (!this.animator) return;
147
147
  this.evaluateTransitions();
148
148
  this.updateActiveStates();
149
+ if(!this._activeState) return;
149
150
  const dt = this.animator.context.time.deltaTime;
150
151
  if (this.animator.applyRootMotion) {
151
152
  this.rootMotionHandler?.onBeforeUpdate();
@@ -75,7 +75,7 @@ export class AudioSource extends Behaviour {
75
75
  }
76
76
  this.callbacks.length = 0;
77
77
  };
78
- let fn = callback.bind(this);
78
+ const fn = callback.bind(this);
79
79
  document.addEventListener('pointerdown', fn);
80
80
  document.addEventListener('click', fn);
81
81
  document.addEventListener('dragstart', fn);