Needle Engine

Changes between version 3.32.18-alpha.1 and 3.31.6
Files changed (236) hide show
  1. src/engine-schemes/vrUserStateBuffer.fbs +0 -0
  2. plugins/common/buildinfo.js +0 -56
  3. plugins/vite/buildinfo.js +0 -23
  4. plugins/vite/config.js +0 -1
  5. plugins/vite/copyfiles.js +1 -4
  6. plugins/vite/defines.js +1 -4
  7. plugins/vite/dependency-watcher.js +17 -23
  8. plugins/vite/index.js +0 -4
  9. plugins/vite/meta.js +0 -2
  10. src/engine-schemes/README.md +0 -2
  11. src/engine-components/export/usdz/extensions/behavior/Actions.ts +2 -3
  12. src/engine-components/AlignmentConstraint.ts +2 -3
  13. src/engine-components/Animation.ts +3 -4
  14. src/engine-components/export/usdz/extensions/Animation.ts +4 -5
  15. src/engine-components/AnimationCurve.ts +2 -18
  16. src/engine-components/AnimationUtils.ts +3 -4
  17. src/engine-components/export/usdz/utils/animationutils.ts +4 -5
  18. src/engine-components/Animator.ts +5 -6
  19. src/engine-components/AnimatorController.ts +12 -21
  20. src/engine-components/postprocessing/Effects/Antialiasing.ts +0 -1
  21. src/engine-components/api.ts +9 -7
  22. src/engine/api.ts +22 -21
  23. src/engine-components/export/usdz/extensions/behavior/AudioExtension.ts +2 -3
  24. src/engine-components/AudioListener.ts +1 -2
  25. src/engine-components/AudioSource.ts +41 -103
  26. src/engine-components/avatar/Avatar_Brain_LookAt.ts +4 -5
  27. src/engine-components/avatar/Avatar_MouthShapes.ts +3 -4
  28. src/engine-components/webxr/Avatar.ts +0 -232
  29. src/engine-components/avatar/AvatarBlink_Simple.ts +2 -3
  30. src/engine-components/avatar/AvatarEyeLook_Rotation.ts +4 -5
  31. src/engine-components/AvatarLoader.ts +5 -6
  32. src/engine-components/AxesHelper.ts +2 -3
  33. src/engine-components/ui/BaseUIComponent.ts +25 -27
  34. src/engine-components/BasicIKConstraint.ts +2 -3
  35. src/engine-components/export/usdz/extensions/behavior/Behaviour.ts +1 -1
  36. src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +13 -12
  37. src/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.ts +2 -2
  38. src/engine-components/postprocessing/Effects/Bloom.ts +0 -1
  39. src/engine-components/BoxHelperComponent.ts +3 -4
  40. src/engine-components/ui/Button.ts +15 -17
  41. src/engine-components/Camera.ts +13 -12
  42. src/engine-components/CameraUtils.ts +7 -8
  43. src/engine-components/ui/Canvas.ts +20 -45
  44. src/engine-components/ui/CanvasGroup.ts +4 -3
  45. src/engine-components/CharacterController.ts +4 -5
  46. src/engine-components/postprocessing/Effects/ChromaticAberration.ts +0 -1
  47. src/engine-components/Collider.ts +5 -12
  48. src/engine-components/postprocessing/Effects/ColorAdjustments.ts +1 -2
  49. src/engine-components/Component.ts +21 -114
  50. src/engine-components/codegen/components.ts +15 -10
  51. src/engine-components/ContactShadows.ts +3 -3
  52. src/engine/debug/debug_console.ts +4 -8
  53. src/engine/debug/debug_overlay.ts +7 -8
  54. src/engine/debug/debug.ts +2 -6
  55. src/engine-components/DeleteBox.ts +0 -1
  56. src/engine-components/postprocessing/Effects/DepthOfField.ts +1 -2
  57. src/engine-components/DeviceFlag.ts +1 -1
  58. src/engine-components/DragControls.ts +182 -949
  59. src/engine-components/DropListener.ts +4 -5
  60. src/engine-components/Duplicatable.ts +91 -74
  61. src/engine/engine_addressables.ts +6 -7
  62. src/engine/engine_assetdatabase.ts +1 -2
  63. src/engine/engine_camera.ts +1 -2
  64. src/engine/engine_components.ts +6 -7
  65. src/engine/engine_constants.ts +2 -5
  66. src/engine/engine_context.ts +74 -115
  67. src/engine/engine_create_objects.ts +1 -13
  68. src/engine/engine_element_loading.ts +16 -41
  69. src/engine/engine_element_overlay.ts +0 -17
  70. src/engine/engine_element.ts +13 -66
  71. src/engine/engine_gameobject.ts +44 -56
  72. src/engine/engine_gizmos.ts +26 -68
  73. src/engine/engine_gltf_builtin_components.ts +9 -11
  74. src/engine/engine_gltf.ts +3 -4
  75. src/engine/engine_hot_reload.ts +2 -2
  76. src/engine/engine_input.ts +185 -480
  77. src/engine/engine_license.ts +12 -26
  78. src/engine/engine_lifecycle_api.ts +4 -28
  79. src/engine/engine_lifecycle_functions_internal.ts +2 -2
  80. src/engine/engine_lightdata.ts +3 -4
  81. src/engine/engine_loaders.ts +3 -3
  82. src/engine/engine_mainloop_utils.ts +7 -34
  83. src/engine/engine_networking_auto.ts +1 -1
  84. src/engine/engine_networking_files_default_components.ts +1 -2
  85. src/engine/engine_networking_files.ts +7 -8
  86. src/engine/engine_networking_instantiate.ts +12 -17
  87. src/engine/engine_networking_peer.ts +1 -2
  88. src/engine/engine_networking_streams.ts +7 -8
  89. src/engine/engine_networking.ts +8 -12
  90. src/engine/engine_physics_rapier.ts +47 -62
  91. src/engine/engine_physics.ts +18 -23
  92. src/engine/engine_playerview.ts +1 -2
  93. src/engine/engine_scenelighting.ts +4 -5
  94. src/engine/engine_scenetools.ts +8 -9
  95. src/engine/engine_serialization_builtin_serializer.ts +8 -18
  96. src/engine/engine_serialization_core.ts +8 -8
  97. src/engine/engine_serialization.ts +5 -4
  98. src/engine/engine_shaders.ts +3 -4
  99. src/engine/engine_texture.ts +1 -2
  100. src/engine/engine_three_utils.ts +4 -18
  101. src/engine/engine_time.ts +3 -4
  102. src/engine/engine_types.ts +4 -27
  103. src/engine/engine_util_decorator.ts +2 -3
  104. src/engine/engine_utils_screenshot.ts +1 -2
  105. src/engine/engine_utils.ts +6 -70
  106. src/engine/engine_xr.ts +0 -2
  107. src/engine/engine.ts +3 -3
  108. src/engine-components/ui/EventSystem.ts +185 -281
  109. src/engine-components/EventTrigger.ts +2 -2
  110. src/engine/extensions/EXT_texture_exr.ts +2 -3
  111. src/engine/extensions/extension_utils.ts +1 -2
  112. src/engine-components/export/usdz/Extension.ts +1 -2
  113. src/engine/extensions/extensions.ts +11 -12
  114. src/engine-components/js-extensions/ExtensionUtils.ts +0 -1
  115. src/engine-components/FlyControls.ts +1 -2
  116. src/engine-components/Fog.ts +1 -2
  117. src/engine-components/Gizmos.ts +4 -5
  118. src/engine-components/export/gltf/GltfExport.ts +6 -6
  119. src/engine-components/ui/Graphic.ts +7 -8
  120. src/engine-components/GridHelper.ts +3 -4
  121. src/engine-components/GroundProjection.ts +5 -11
  122. src/engine-components/ui/Image.ts +1 -2
  123. src/engine-components/export/usdz/index.ts +3 -3
  124. src/engine-components/postprocessing/index.ts +2 -2
  125. src/engine-components/timeline/index.ts +2 -2
  126. src/engine-components/webxr/index.ts +3 -2
  127. src/engine/extensions/index.ts +2 -2
  128. src/engine/xr/index.ts +0 -5
  129. src/engine-components/ui/InputField.ts +4 -4
  130. src/engine-components/Interactable.ts +14 -6
  131. src/engine/xr/internal.ts +0 -35
  132. src/engine-components/Joints.ts +0 -1
  133. src/engine-components/ui/Layout.ts +3 -3
  134. src/engine-components/Light.ts +13 -10
  135. src/engine-components/LODGroup.ts +4 -5
  136. src/engine-components/debug/LogStats.ts +1 -1
  137. src/engine-components/utils/LookAt.ts +4 -4
  138. src/engine-components/LookAtConstraint.ts +2 -3
  139. src/engine/extensions/NEEDLE_animator_controller_model.ts +2 -3
  140. src/engine/extensions/NEEDLE_components.ts +6 -7
  141. src/engine/extensions/NEEDLE_gameobject_data.ts +3 -3
  142. src/engine/extensions/NEEDLE_lighting_settings.ts +6 -7
  143. src/engine/extensions/NEEDLE_lightmaps.ts +7 -8
  144. src/engine/extensions/NEEDLE_persistent_assets.ts +2 -3
  145. src/engine/extensions/NEEDLE_progressive.ts +3 -5
  146. src/engine/extensions/NEEDLE_render_objects.ts +18 -18
  147. src/engine/extensions/NEEDLE_techniques_webgl.ts +5 -8
  148. src/needle-engine.ts +3 -0
  149. src/engine/xr/NeedleXRController.ts +0 -785
  150. src/engine/xr/NeedleXRSession.ts +0 -1290
  151. src/engine/xr/NeedleXRSync.ts +0 -221
  152. src/engine-components/NestedGltf.ts +4 -4
  153. src/engine-components/Networking.ts +1 -1
  154. src/engine-components/js-extensions/Object3D.ts +12 -11
  155. src/engine-components/OffsetConstraint.ts +3 -4
  156. src/engine-components/utils/OpenURL.ts +40 -8
  157. src/engine-components/OrbitControls.ts +15 -15
  158. src/engine-components/ui/Outline.ts +2 -3
  159. src/engine-components/ParticleSystem.ts +34 -39
  160. src/engine-components/ParticleSystemModules.ts +24 -205
  161. src/engine-components/ParticleSystemSubEmitter.ts +3 -4
  162. src/engine-components/postprocessing/Effects/Pixelation.ts +3 -4
  163. src/engine-components/timeline/PlayableDirector.ts +9 -10
  164. src/engine-components/PlayerColor.ts +14 -19
  165. src/engine-components-experimental/networking/PlayerSync.ts +26 -119
  166. src/engine-components/ui/PointerEvents.ts +30 -118
  167. src/engine-components/postprocessing/PostProcessingEffect.ts +4 -5
  168. src/engine-components/postprocessing/PostProcessingHandler.ts +4 -5
  169. src/engine-components-experimental/Presentation.ts +1 -1
  170. src/engine-components/ui/Raycaster.ts +8 -27
  171. src/engine-components/ui/RaycastUtils.ts +1 -2
  172. src/engine-components/ui/RectTransform.ts +5 -6
  173. src/engine-components/ReflectionProbe.ts +2 -3
  174. src/engine/codegen/register_types.ts +28 -17
  175. src/engine-components/Renderer.ts +38 -60
  176. src/engine-components/RendererLightmap.ts +2 -3
  177. src/engine-components/js-extensions/RGBAColor.ts +1 -2
  178. src/engine-components/RigidBody.ts +6 -15
  179. src/engine-components/SceneSwitcher.ts +12 -13
  180. src/engine/xr/SceneTransition.ts +0 -79
  181. src/engine-schemes/schemes.ts +1 -2
  182. src/engine-components/ScreenCapture.ts +8 -9
  183. src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.ts +0 -1
  184. src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.ts +2 -3
  185. src/engine-components/ShadowCatcher.ts +3 -4
  186. src/engine-components/timeline/SignalAsset.ts +2 -2
  187. src/engine-components/Skybox.ts +9 -10
  188. src/engine-components/SmoothFollow.ts +4 -5
  189. src/engine-components/ui/SpatialHtml.ts +0 -1
  190. src/engine-components/SpatialTrigger.ts +3 -4
  191. src/engine-components/SpectatorCamera.ts +33 -23
  192. src/engine-components/SpriteRenderer.ts +3 -4
  193. src/engine-components/SyncedCamera.ts +13 -13
  194. src/engine-components/SyncedRoom.ts +2 -2
  195. src/engine-components/SyncedTransform.ts +7 -25
  196. src/engine-components/webxr/TeleportTarget.ts +0 -9
  197. src/engine/xr/TempXRContext.ts +0 -183
  198. src/engine/tests/test_utils.ts +1 -1
  199. src/engine-components/TestRunner.ts +5 -6
  200. src/engine-components/ui/Text.ts +8 -9
  201. src/engine-components/export/usdz/ThreeUSDZExporter.ts +33 -36
  202. src/engine-components/postprocessing/Effects/TiltShiftEffect.ts +3 -4
  203. src/engine-components/timeline/TimelineTracks.ts +22 -60
  204. src/engine-components/postprocessing/Effects/Tonemapping.ts +0 -1
  205. src/engine-components/TransformGizmo.ts +5 -6
  206. src/engine-components/webxr/types.ts +0 -4
  207. src/engine/extensions/usage_tracker.ts +1 -2
  208. src/engine-components/export/usdz/USDZExporter.ts +94 -41
  209. src/engine-components/export/usdz/extensions/USDZText.ts +5 -6
  210. src/engine-components/export/usdz/extensions/USDZUI.ts +9 -13
  211. plugins/types/userconfig.d.ts +0 -3
  212. src/engine-components/ui/Utils.ts +2 -4
  213. src/engine/xr/utils.ts +0 -40
  214. src/engine-components/js-extensions/Vector.ts +1 -2
  215. src/engine-components/VideoPlayer.ts +9 -12
  216. src/engine-components/postprocessing/Effects/Vignette.ts +2 -3
  217. src/engine-components/Voip.ts +5 -6
  218. src/engine-components/postprocessing/Volume.ts +6 -7
  219. src/engine-schemes/vr-user-state-buffer.ts +30 -37
  220. src/engine-components/webxr/WebARCameraBackground.ts +53 -46
  221. src/engine-components/webxr/WebARSessionRoot.ts +164 -390
  222. src/engine-components/webxr/WebXR.ts +672 -211
  223. src/engine-components/webxr/WebXRAvatar.ts +300 -10
  224. src/engine-components/webxr/WebXRButtons.ts +0 -348
  225. src/engine-components/webxr/WebXRImageTracking.ts +78 -70
  226. src/engine-components/webxr/WebXRPlaneTracking.ts +49 -56
  227. src/engine-components/webxr/WebXRRig.ts +8 -45
  228. src/engine-components/webxr/controllers/XRControllerFollow.ts +0 -67
  229. src/engine-components/webxr/controllers/XRControllerModel.ts +0 -307
  230. src/engine-components/webxr/controllers/XRControllerMovement.ts +0 -340
  231. src/engine-components/webxr/XRFlag.ts +0 -143
  232. src/engine/xr/XRRig.ts +0 -9
  233. src/engine-components/webxr/WebXRController.ts +1168 -0
  234. src/engine-components/webxr/WebXRGrabRendering.ts +151 -0
  235. src/engine-components/webxr/WebXRSync.ts +463 -0
  236. src/engine-components/XRFlag.ts +139 -0
src/engine-schemes/vrUserStateBuffer.fbs CHANGED
File without changes
plugins/common/buildinfo.js DELETED
@@ -1,56 +0,0 @@
1
- import fs from 'fs';
2
-
3
-
4
- /** Create a file containing information about the build inside the build directory
5
- * @param {String} buildDirectory
6
- */
7
- export function createBuildInfoFile(buildDirectory) {
8
- if (!buildDirectory) {
9
- console.warn("WARN: Can not create build info file because \"buildDirectory\" is not defined");
10
- return;
11
- }
12
- // start creating the buildinfo
13
- const buildInfo = {
14
- time: new Date().toISOString(),
15
- totalsize: 0,
16
- files: []
17
- };
18
- console.log("[needle-buildinfo] - Collect files in " + buildDirectory);
19
- recursivelyCollectFiles(buildDirectory, "", buildInfo);
20
- const buildInfoPath = `${buildDirectory}/needle.buildinfo.json`;
21
- const totalSizeInMB = buildInfo.totalsize / 1024 / 1024;
22
- console.log(`[needle-buildinfo] - Collected ${buildInfo.files.length} files (${totalSizeInMB.toFixed(2)} MB). Write info to \"${buildInfoPath}\"`);
23
- fs.writeFileSync(buildInfoPath, JSON.stringify(buildInfo));
24
- }
25
-
26
- /** Recursively collect all files in a directory
27
- * @param {String} directory to search
28
- * @param {{ files: Array<string>, totalsize:number }} info
29
- */
30
- function recursivelyCollectFiles(directory, path, info) {
31
- const entries = fs.readdirSync(directory, { withFileTypes: true });
32
- for (const entry of entries) {
33
- if (entry.isDirectory()) {
34
- // make sure we never collect files inside node_modules
35
- if (entry.name === "node_modules") {
36
- console.warn("WARN: Skipping node_modules directory at " + path);
37
- continue;
38
- }
39
- const newPath = path?.length <= 0 ? entry.name : `${path}/${entry.name}`;
40
- const newDirectory = `${directory}/${entry.name}`;
41
- console.log("[needle-buildinfo] - Collect files in " + newPath);
42
- recursivelyCollectFiles(newDirectory, newPath, info);
43
- } else {
44
- const relpath = `${path}/${entry.name}`;
45
- info.files.push(relpath);
46
- try {
47
- const fullpath = `${directory}/${entry.name}`;
48
- const stats = fs.statSync(fullpath);
49
- info.totalsize += stats.size;
50
- }
51
- catch {
52
- //ignore
53
- }
54
- }
55
- }
56
- }
plugins/vite/buildinfo.js DELETED
@@ -1,23 +0,0 @@
1
- import { createBuildInfoFile } from '../common/buildinfo.js';
2
- import { getOutputDirectory } from './config.js';
3
-
4
-
5
-
6
- /** Create a buildinfo file in the build directory
7
- * @param {import('../types').userSettings} userSettings
8
- * @returns {import('vite').Plugin}
9
- */
10
- export const needleBuildInfo = (command, config, userSettings) => {
11
-
12
- if (userSettings?.noBuildInfo) return;
13
-
14
- return {
15
- name: 'needle-buildinfo',
16
- apply: "build",
17
- enforce: "post",
18
- closeBundle: () => {
19
- const buildDirectory = getOutputDirectory();
20
- createBuildInfoFile(buildDirectory);
21
- }
22
- }
23
- }
plugins/vite/config.js CHANGED
@@ -68,7 +68,6 @@
68
68
  return "assets";
69
69
  }
70
70
 
71
- /** @returns the fullpath of the build */
72
71
  export function getOutputDirectory() {
73
72
  const projectConfig = tryLoadProjectConfig();
74
73
  return process.cwd() + "/" + (projectConfig?.buildDirectory || "dist");
plugins/vite/copyfiles.js CHANGED
@@ -36,10 +36,7 @@
36
36
  const needleConfig = tryLoadProjectConfig();
37
37
  if (needleConfig) {
38
38
  assetsDirName = needleConfig.assetsDirectory;
39
- while (assetsDirName.startsWith('/')) assetsDirName = assetsDirName.substring(1);
40
-
41
- if (needleConfig.buildDirectory)
42
- outdirName = needleConfig.buildDirectory;
39
+ while(assetsDirName.startsWith('/')) assetsDirName = assetsDirName.substring(1);
43
40
  }
44
41
 
45
42
  if (copyIncludesFromEngine !== false) {
plugins/vite/defines.js CHANGED
@@ -26,7 +26,7 @@
26
26
  // console.log("Update vite defines -------------------------------------------");
27
27
  if (!viteConfig.define) viteConfig.define = {};
28
28
  const version = tryGetNeedleEngineVersion();
29
- console.log("Needle Engine Version: " + version, needleEngineConfig?.generator ?? "(unknown generator)");
29
+ console.log("Needle Engine Version:", version, needleEngineConfig?.generator);
30
30
  if (version)
31
31
  viteConfig.define.NEEDLE_ENGINE_VERSION = "\"" + version + "\"";
32
32
  if (needleEngineConfig)
@@ -42,9 +42,6 @@
42
42
  if (viteConfig.define.NEEDLE_USE_RAPIER === undefined) {
43
43
  viteConfig.define.NEEDLE_USE_RAPIER = useRapier;
44
44
  }
45
-
46
- // this gives a timestamp containing the timezone
47
- viteConfig.define.NEEDLE_PROJECT_BUILD_TIME = "\"" + new Date().toString() + "\"";
48
45
  }
49
46
  }
50
47
  }
plugins/vite/dependency-watcher.js CHANGED
@@ -39,14 +39,11 @@
39
39
  });
40
40
  }
41
41
 
42
- async function triggerReloadOnClients() {
43
- log(`Triggering reload on ${currentClients.size} clients...`)
44
- for (const client of currentClients) {
45
- client.send(JSON.stringify({ type: "full-reload" }));
46
- }
47
- return new Promise((resolve) => {
48
- setTimeout(resolve, 100);
49
- });
42
+ function triggerReloadOnClients() {
43
+ log("Triggering reload on clients (todo)", currentClients.size)
44
+ // for (const client of currentClients) {
45
+ // client.send(JSON.stringify({ type: "full-reload" }));
46
+ // }
50
47
  }
51
48
 
52
49
 
@@ -84,6 +81,9 @@
84
81
  modified = true;
85
82
  }
86
83
  if (modified || requireInstall) {
84
+ if (modified) {
85
+ log("package.json has changed. Require install?", requireInstall)
86
+ }
87
87
 
88
88
  let requireReload = false;
89
89
  if (!requireInstall) {
@@ -95,7 +95,7 @@
95
95
  if (newPackageJson.dependencies) {
96
96
  for (const key in newPackageJson.dependencies) {
97
97
  if (packageJson.dependencies[key] !== newPackageJson.dependencies[key] && newPackageJson.dependencies[key] !== undefined) {
98
- log("Detected new dependency: " + key)
98
+ log("Dependency added", key)
99
99
  requireReload = true;
100
100
  requireInstall = true;
101
101
  }
@@ -104,16 +104,13 @@
104
104
  if (packageJson.devDependencies) {
105
105
  for (const key in packageJson.devDependencies) {
106
106
  if (packageJson.devDependencies[key] !== newPackageJson.devDependencies[key] && newPackageJson.devDependencies[key] !== undefined) {
107
- log("Detected new devDependency: " + key)
107
+ log("DevDependency added", key)
108
108
  requireReload = true;
109
109
  requireInstall = true;
110
110
  }
111
111
  }
112
112
  }
113
113
 
114
- if (modified) {
115
- log("package.json has changed. Require install: " + (requireInstall ? "yes" : "no"))
116
- }
117
114
 
118
115
  packageJsonSize = packageJsonStat.size;
119
116
  lastEditTime = packageJsonStat.mtime;
@@ -122,7 +119,7 @@
122
119
  restart(server, projectDir, cachePath);
123
120
  }
124
121
  }
125
- }, 2000);
122
+ }, 1000);
126
123
  }
127
124
 
128
125
  function testIfInstallIsRequired(projectDir, packageJson) {
@@ -145,7 +142,7 @@
145
142
  }
146
143
  }
147
144
  }
148
- log("Dependency not installed: " + key)
145
+ log("Dependency not installed", key)
149
146
  return true;
150
147
  }
151
148
  else {
@@ -164,11 +161,9 @@
164
161
  const isRange = expectedVersion.includes("^") || expectedVersion.includes(">") || expectedVersion.includes("<");
165
162
  if (!isRange) {
166
163
  const packageJsonPath = path.join(depPath, "package.json");
167
- /** @type {String} */
168
164
  const installedVersion = JSON.parse(readFileSync(packageJsonPath, "utf8")).version;
169
- // fix check for cases where the version contains a alias e.g. npm:[email protected]
170
- if (expectedVersion.trimEnd().endsWith(installedVersion.trim()) == false) {
171
- log(`Dependency ${key} is installed but version is not the right one. Expected \"${expectedVersion}/" but got \"${installedVersion}\"`)
165
+ if (expectedVersion !== installedVersion) {
166
+ log(`Dependency ${key} is installed but version is not correct. Expected ${expectedVersion} but got ${installedVersion}`)
172
167
  return true;
173
168
  }
174
169
  }
@@ -199,13 +194,13 @@
199
194
  }
200
195
 
201
196
  if (id !== restartId) return;
202
- if (Date.now() - lastRestartTime < 3000) return;
197
+ if (Date.now() - lastRestartTime < 1000) return;
203
198
  log("Restarting server...")
204
199
  lastRestartTime = Date.now();
205
200
  requireInstall = false;
206
201
  if (existsSync(cachePath))
207
202
  rmSync(cachePath, { recursive: true, force: true });
208
- await triggerReloadOnClients();
203
+ triggerReloadOnClients();
209
204
 
210
205
  // touch vite config to trigger reload
211
206
  // const viteConfigPath = path.join(projectDir, "vite.config.js");
@@ -217,9 +212,8 @@
217
212
  // }
218
213
 
219
214
  // check if server is running
220
- if (server.httpServer.listening) {
215
+ if (server.httpServer.listening)
221
216
  server.restart();
222
- }
223
217
  isRunningRestart = false;
224
218
  console.log("-----------------------------------------------")
225
219
  }
plugins/vite/index.js CHANGED
@@ -42,7 +42,6 @@
42
42
 
43
43
  import { vite_4_4_hack } from "./vite-4.4-hack.js";
44
44
  import { needleImportsLogger } from "./imports-logger.js";
45
- import { needleBuildInfo } from "./buildinfo.js";
46
45
 
47
46
 
48
47
  export * from "./gzip.js";
@@ -58,8 +57,6 @@
58
57
  */
59
58
  export const needlePlugins = async (command, config, userSettings) => {
60
59
 
61
- if(!config) config = {}
62
-
63
60
  // ensure we have user settings initialized with defaults
64
61
  userSettings = { ...defaultUserSettings, ...userSettings }
65
62
  const array = [
@@ -70,7 +67,6 @@
70
67
  needlePoster(command, config, userSettings),
71
68
  needleReload(command, config, userSettings),
72
69
  needleBuild(command, config, userSettings),
73
- needleBuildInfo(command, config, userSettings),
74
70
  needleCopyFiles(command, config, userSettings),
75
71
  needleTransformCodegen(command, config, userSettings),
76
72
  needleDrop(command, config, userSettings),
plugins/vite/meta.js CHANGED
@@ -109,8 +109,6 @@
109
109
  }
110
110
  else console.log("WARN: could not find needle engine package.json")
111
111
 
112
- tags.push({ tag: 'meta', attrs: { name: 'needle:buildtime', content: new Date().toISOString() } });
113
-
114
112
  return { html, tags }
115
113
  },
116
114
  }
src/engine-schemes/README.md DELETED
@@ -1,2 +0,0 @@
1
- Using flatbuffer compiler 2.0
2
- https://github.com/google/flatbuffers/releases/tag/v2.0.0
src/engine-components/export/usdz/extensions/behavior/Actions.ts CHANGED
@@ -1,7 +1,6 @@
1
- import { BufferGeometry,Material, Matrix4, Object3D } from "three";
2
-
3
- import { USDDocument,USDObject } from "../../ThreeUSDZExporter.js";
1
+ import { Object3D, Matrix4, Material, BufferGeometry } from "three";
4
2
  import { ActionBuilder, ActionModel } from "./BehavioursBuilder.js";
3
+ import { USDObject, USDDocument } from "../../ThreeUSDZExporter.js";
5
4
 
6
5
  export abstract class DocumentAction {
7
6
 
src/engine-components/AlignmentConstraint.ts CHANGED
@@ -1,8 +1,7 @@
1
+ import { Behaviour, GameObject } from "./Component.js";
2
+ import * as utils from "./../engine/engine_three_utils.js";
1
3
  import { Vector3 } from "three";
2
-
3
4
  import { serializable } from "../engine/engine_serialization_decorator.js";
4
- import * as utils from "./../engine/engine_three_utils.js";
5
- import { Behaviour, GameObject } from "./Component.js";
6
5
 
7
6
  export class AlignmentConstraint extends Behaviour {
8
7
 
src/engine-components/Animation.ts CHANGED
@@ -1,11 +1,10 @@
1
+ import { Behaviour } from "./Component.js";
1
2
  import { AnimationAction, AnimationClip, AnimationMixer, LoopOnce, LoopRepeat } from "three";
2
-
3
+ import { MixerEvent } from "./Animator.js";
4
+ import { serializable } from "../engine/engine_serialization_decorator.js";
3
5
  import { Mathf } from "../engine/engine_math.js";
4
- import { serializable } from "../engine/engine_serialization_decorator.js";
5
6
  import type { Vec2 } from "../engine/engine_types.js";
6
7
  import { getParam } from "../engine/engine_utils.js";
7
- import { MixerEvent } from "./Animator.js";
8
- import { Behaviour } from "./Component.js";
9
8
 
10
9
  const debug = getParam("debuganimation");
11
10
 
src/engine-components/export/usdz/extensions/Animation.ts CHANGED
@@ -1,10 +1,9 @@
1
- import { AnimationClip, Bone,Interpolant, KeyframeTrack, Matrix4, Object3D, PropertyBinding, Quaternion, Vector3 } from "three";
2
-
1
+ import { GameObject } from "../../../Component.js";
3
2
  import { getParam } from "../../../../engine/engine_utils.js";
3
+ import { USDObject, buildMatrix, findStructuralNodesInBoneHierarchy, usdNumberFormatting as fn, getPathToSkeleton } from "../ThreeUSDZExporter.js";
4
+ import type { IUSDExporterExtension } from "../Extension.js";
5
+ import { Object3D, Matrix4, Vector3, Quaternion, Interpolant, AnimationClip, KeyframeTrack, PropertyBinding, Bone } from "three";
4
6
  import { Animator } from "../../../Animator.js";
5
- import { GameObject } from "../../../Component.js";
6
- import type { IUSDExporterExtension } from "../Extension.js";
7
- import { buildMatrix, findStructuralNodesInBoneHierarchy, getPathToSkeleton,usdNumberFormatting as fn, USDObject } from "../ThreeUSDZExporter.js";
8
7
 
9
8
  const debug = getParam("debugusdzanimation");
10
9
  const debugSerialization = getParam("debugusdzanimationserialization");
src/engine-components/AnimationCurve.ts CHANGED
@@ -23,22 +23,6 @@
23
23
  @serializable(Keyframe)
24
24
  keys!: Array<Keyframe>;
25
25
 
26
- clone() {
27
- const curve = new AnimationCurve();
28
- curve.keys = this.keys?.map(k => {
29
- const key = new Keyframe();
30
- key.time = k.time;
31
- key.value = k.value;
32
- key.inTangent = k.inTangent;
33
- key.inWeight = k.inWeight;
34
- key.outTangent = k.outTangent;
35
- key.outWeight = k.outWeight;
36
- key.weightedMode = k.weightedMode;
37
- return key;
38
- }) || [];
39
- return curve;
40
- }
41
-
42
26
  get duration(): number {
43
27
  if (!this.keys || this.keys.length == 0) return 0;
44
28
  return this.keys[this.keys.length - 1].time;
@@ -54,9 +38,9 @@
54
38
  for (let i = 0; i < this.keys.length; i++) {
55
39
  const kf = this.keys[i];
56
40
  if (kf.time <= time) {
57
- const hasNextKeyframe = i + 1 < this.keys.length;
41
+ const hasNextKeyframe = i+1 < this.keys.length;
58
42
  if (hasNextKeyframe) {
59
- const nextKf = this.keys[i + 1];
43
+ const nextKf = this.keys[i+1];
60
44
  // if the next
61
45
  if (nextKf.time < time) continue;
62
46
  // tangents are set to Infinity if interpolation is set to constant - in that case we should always return the floored value
src/engine-components/AnimationUtils.ts CHANGED
@@ -1,12 +1,11 @@
1
- import { Object3D } from "three";
2
1
  import type { GLTF } from "three/examples/jsm/loaders/GLTFLoader.js";
3
-
2
+ import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
4
3
  import { addNewComponent } from "../engine/engine_components.js";
5
- import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
4
+ import { Animator } from "./Animator.js";
6
5
  import { Animation } from "./Animation.js";
7
- import { Animator } from "./Animator.js";
8
6
  import { GameObject } from "./Component.js";
9
7
  import { PlayableDirector } from "./timeline/PlayableDirector.js";
8
+ import { Object3D } from "three";
10
9
 
11
10
 
12
11
  const $objectAnimationKey = Symbol("objectIsAnimatedData");
src/engine-components/export/usdz/utils/animationutils.ts CHANGED
@@ -1,10 +1,9 @@
1
- import { AnimationClip,Object3D } from "three";
2
-
3
- import { getParam } from "../../../../engine/engine_utils.js";
1
+ import { Animator } from "../../../Animator.js";
4
2
  import { Animation } from "../../../Animation.js";
5
- import { Animator } from "../../../Animator.js";
3
+ import { Object3D, AnimationClip } from "three";
4
+ import { AnimationExtension } from "../extensions/Animation.js";
6
5
  import { Behaviour, GameObject } from "../../../Component.js";
7
- import { AnimationExtension } from "../extensions/Animation.js";
6
+ import { getParam } from "../../../../engine/engine_utils.js";
8
7
  import { PlayAnimationOnClick } from "../extensions/behavior/BehaviourComponents.js";
9
8
 
10
9
  const debug = getParam("debugusdz");
src/engine-components/Animator.ts CHANGED
@@ -1,12 +1,11 @@
1
- import type { AnimationAction, AnimationActionLoopStyles, AnimationMixer } from "three";
2
-
3
- import { Mathf } from "../engine/engine_math.js";
4
- import { serializable } from "../engine/engine_serialization_decorator.js";
1
+ import { Behaviour } from "./Component.js";
2
+ import type { AnimationActionLoopStyles, AnimationAction, AnimationMixer } from "three";
5
3
  import { getParam } from "../engine/engine_utils.js";
6
4
  import type { AnimatorControllerModel } from "../engine/extensions/NEEDLE_animator_controller_model.js";
5
+ import { AnimatorController } from "./AnimatorController.js";
6
+ import { serializable } from "../engine/engine_serialization_decorator.js";
7
+ import { Mathf } from "../engine/engine_math.js";
7
8
  import { getObjectAnimated } from "./AnimationUtils.js";
8
- import { AnimatorController } from "./AnimatorController.js";
9
- import { Behaviour } from "./Component.js";
10
9
 
11
10
  const debug = getParam("debuganimator");
12
11
 
src/engine-components/AnimatorController.ts CHANGED
@@ -1,16 +1,15 @@
1
+ import { Animator } from "./Animator.js";
2
+ import type { AnimatorControllerModel, Condition, State, Transition } from "../engine/extensions/NEEDLE_animator_controller_model.js";
3
+ import { AnimatorConditionMode, AnimatorControllerParameterType, AnimatorStateInfo, createMotion, StateMachineBehaviour } from "../engine/extensions/NEEDLE_animator_controller_model.js";
1
4
  import { AnimationAction, AnimationClip, AnimationMixer, AxesHelper, Euler, KeyframeTrack, LoopOnce, Object3D, Quaternion, Vector3 } from "three";
2
-
5
+ import { deepClone, getParam } from "../engine/engine_utils.js";
6
+ import { Context } from "../engine/engine_setup.js";
7
+ import { TypeStore } from "../engine/engine_typestore.js";
8
+ import { SerializationContext, TypeSerializer, assign } from "../engine/engine_serialization_core.js";
9
+ import { Mathf } from "../engine/engine_math.js";
10
+ import { isAnimationAction } from "../engine/engine_three_utils.js";
3
11
  import { isDevEnvironment } from "../engine/debug/index.js";
4
- import { Mathf } from "../engine/engine_math.js";
5
12
  import { InstantiateIdProvider } from "../engine/engine_networking_instantiate.js";
6
- import { assign,SerializationContext, TypeSerializer } from "../engine/engine_serialization_core.js";
7
- import { Context } from "../engine/engine_setup.js";
8
- import { isAnimationAction } from "../engine/engine_three_utils.js";
9
- import { TypeStore } from "../engine/engine_typestore.js";
10
- import { deepClone, getParam } from "../engine/engine_utils.js";
11
- import type { AnimatorControllerModel, Condition, State, Transition } from "../engine/extensions/NEEDLE_animator_controller_model.js";
12
- import { AnimatorConditionMode, AnimatorControllerParameterType, AnimatorStateInfo, createMotion, StateMachineBehaviour } from "../engine/extensions/NEEDLE_animator_controller_model.js";
13
- import { Animator } from "./Animator.js";
14
13
 
15
14
  const debug = getParam("debuganimatorcontroller");
16
15
  const debugRootMotion = getParam("debugrootmotion");
@@ -213,7 +212,6 @@
213
212
  console.warn("AnimatorController has not been resolved, can not create model from string", this.model);
214
213
  return null;
215
214
  }
216
- if (debug) console.warn("AnimatorController clone()", this.model);
217
215
  // clone runtime controller but dont clone clip or action
218
216
  const clonedModel = deepClone(this.model, (_owner, _key, _value) => {
219
217
  if (_value === null || _value === undefined) return true;
@@ -226,8 +224,6 @@
226
224
  }
227
225
  // dont clone AnimationClip
228
226
  if (_value["tracks"] !== undefined) return false;
229
- // when assigned __concreteInstance during serialization
230
- if (_value instanceof AnimatorController) return false;
231
227
  return true;
232
228
  }) as AnimatorControllerModel;
233
229
  console.assert(clonedModel !== this.model);
@@ -585,7 +581,7 @@
585
581
  }
586
582
 
587
583
  private createActions(_animator: Animator) {
588
- if (debug) console.log("AnimatorController createActions", this.model);
584
+ // console.trace(this.model, _animator);
589
585
  for (const layer of this.model.layers) {
590
586
  const sm = layer.stateMachine;
591
587
  for (let index = 0; index < sm.states.length; index++) {
@@ -612,13 +608,8 @@
612
608
  if (this.animator && state.motion.clips) {
613
609
  // TODO: we have to compare by name because on instantiate we clone objects but not the node object
614
610
  const mapping = state.motion.clips?.find(e => e.node.name === this.animator?.gameObject?.name);
615
- if (!mapping) {
616
- if (debug || isDevEnvironment()) {
617
- console.warn("Could not find clip for animator \"" + this.animator?.gameObject?.name + "\"", state.motion.clips.map(c => c.node.name));
618
- }
619
- }
620
- else
621
- state.motion.clip = mapping.clip;
611
+ // console.log(state.name, mapping?.clip);
612
+ state.motion.clip = mapping?.clip;
622
613
  }
623
614
 
624
615
  // ensure we have a clip to blend to
src/engine-components/postprocessing/Effects/Antialiasing.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { EdgeDetectionMode, SMAAEffect, SMAAPreset } from "postprocessing";
2
-
3
2
  import { serializable } from "../../../engine/engine_serialization.js";
4
3
  import { type EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect.js";
5
4
  import { VolumeParameter } from "../VolumeParameter.js";
src/engine-components/api.ts CHANGED
@@ -1,20 +1,22 @@
1
+ export { Behaviour, Component, GameObject } from "./Component.js"
1
2
  export * from "./codegen/components.js";
2
- export { Behaviour, Component, GameObject } from "./Component.js"
3
3
 
4
4
  // We dont want to export everything in the extensions
5
- export { ClearFlags } from "./Camera.js"
5
+ export * from "./js-extensions/RGBAColor.js";
6
+ export * from "./js-extensions/Object3D.js";
7
+ export * from "./XRFlag.js"
8
+
6
9
  export * from "./export/index.js"
7
- export * from "./js-extensions/Object3D.js";
8
- export * from "./js-extensions/RGBAColor.js";
9
10
  export * from "./postprocessing/index.js"
10
- export { type ISceneEventListener } from "./SceneSwitcher.js";
11
11
  export * from "./timeline/index.js"
12
12
  export * from "./ui/index.js"
13
13
  export * from "./webxr/index.js"
14
- export * from "./webxr/XRFlag.js"
15
14
 
15
+ export { ClearFlags } from "./Camera.js"
16
+ export { type ISceneEventListener } from "./SceneSwitcher.js";
17
+
16
18
  import "./CameraUtils.js"
17
19
  import "./AnimationUtils.js"
18
20
 
19
21
  export { ParticleSystemBaseBehaviour, type QParticle, type QParticleBehaviour } from "./ParticleSystem.js"
20
- export { ParticleSystemShapeType } from "./ParticleSystemModules.js"
22
+
src/engine/api.ts CHANGED
@@ -1,42 +1,42 @@
1
1
 
2
- export * from "./debug/index.js";
2
+ export * from "./extensions/index.js";
3
3
  export * from "./engine_addressables.js";
4
4
  export * from "./engine_application.js";
5
5
  export * from "./engine_assetdatabase.js";
6
+ export * from "./engine_create_objects.js";
7
+ export * from "./engine_components_internal.js";
6
8
  export * from "./engine_components.js";
7
9
  export * from "./engine_components_internal.js";
8
- export * from "./engine_components_internal.js";
9
- export * from "./engine_constants.js";
10
+ export * from "./engine_context_registry.js";
10
11
  export * from "./engine_context.js";
11
- export * from "./engine_context_registry.js";
12
12
  export * from "./engine_coroutine.js"
13
- export * from "./engine_create_objects.js";
13
+ export * from "./engine_constants.js";
14
+ export * from "./debug/index.js";
14
15
  export * from "./engine_element.js";
16
+ export * from "./engine_element_loading.js";
15
17
  export * from "./engine_element_attributes.js";
16
- export * from "./engine_element_loading.js";
17
- export * from "./engine_gameobject.js";
18
18
  export { Gizmos } from "./engine_gizmos.js"
19
19
  export * from "./engine_gltf.js";
20
20
  export * from "./engine_hot_reload.js";
21
- export * from "./engine_input.js";
22
- export { InstancingUtil } from "./engine_instancing.js";
23
- export { hasIndieLicense,hasProLicense } from "./engine_license.js";
24
- export * from "./engine_lifecycle_api.js";
25
- export * from "./engine_math.js";
21
+ export * from "./engine_gameobject.js";
26
22
  export * from "./engine_networking.js";
23
+ export * from "./engine_networking_types.js";
27
24
  export { syncField } from "./engine_networking_auto.js";
28
25
  export * from "./engine_networking_files.js";
29
26
  export * from "./engine_networking_instantiate.js";
30
- export * from "./engine_networking_peer.js";
31
27
  export * from "./engine_networking_streams.js";
32
- export * from "./engine_networking_types.js";
33
28
  export * from "./engine_networking_utils.js";
29
+ export * from "./engine_networking_peer.js";
34
30
  export * from "./engine_patcher.js";
31
+ export * from "./engine_playerview.js";
35
32
  export * from "./engine_physics.js";
36
33
  export * from "./engine_physics.types.js";
37
34
  export * from "./engine_physics_rapier.js";
38
- export * from "./engine_playerview.js";
39
35
  export * from "./engine_scenelighting.js";
36
+ export * from "./engine_input.js";
37
+ export * from "./engine_lifecycle_api.js";
38
+ export * from "./engine_math.js";
39
+ export * from "./js-extensions/index.js";
40
40
  export * from "./engine_scenetools.js";
41
41
  export * from "./engine_serialization.js";
42
42
  export { type ISerializable } from "./engine_serialization_core.js";
@@ -44,11 +44,12 @@
44
44
  export * from "./engine_three_utils.js";
45
45
  export * from "./engine_time.js";
46
46
  export * from "./engine_types.js";
47
- export { registerType,TypeStore } from "./engine_typestore.js";
48
- export { prefix,validate } from "./engine_util_decorator.js";
49
- export * from "./engine_utils.js";
50
47
  export * from "./engine_utils_screenshot.js";
51
48
  export * from "./engine_web_api.js";
52
- export * from "./engine_xr.js";
53
- export * from "./extensions/index.js";
54
- export * from "./js-extensions/index.js";
49
+ export * from "./engine_utils.js";
50
+
51
+ export { TypeStore, registerType } from "./engine_typestore.js";
52
+
53
+ export { InstancingUtil } from "./engine_instancing.js";
54
+ export { validate, prefix } from "./engine_util_decorator.js";
55
+ export { hasProLicense, hasIndieLicense } from "./engine_license.js";
src/engine-components/export/usdz/extensions/behavior/AudioExtension.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { Object3D } from "three";
2
-
3
- import { AudioSource } from "../../../../AudioSource.js";
4
1
  import { GameObject } from "../../../../Component.js";
5
2
  import type { IUSDExporterExtension } from "../../Extension.js";
6
3
  import { USDObject, USDWriter, USDZExporterContext } from "../../ThreeUSDZExporter.js";
4
+ import { Object3D } from "three";
5
+ import { AudioSource } from "../../../../AudioSource.js";
7
6
 
8
7
  export class AudioExtension implements IUSDExporterExtension {
9
8
 
src/engine-components/AudioListener.ts CHANGED
@@ -1,8 +1,7 @@
1
+ import { Behaviour, GameObject } from "./Component.js";
1
2
  import { AudioListener as ThreeAudioListener } from "three";
2
-
3
3
  import { AudioSource } from "./AudioSource.js";
4
4
  import { Camera } from "./Camera.js";
5
- import { Behaviour, GameObject } from "./Component.js";
6
5
 
7
6
 
8
7
  export class AudioListener extends Behaviour {
src/engine-components/AudioSource.ts CHANGED
@@ -1,14 +1,11 @@
1
- import { Audio, AudioContext, AudioLoader, PositionalAudio, Vector3 } from "three";
1
+ import { Behaviour, GameObject } from "./Component.js";
2
2
  import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js';
3
-
3
+ import { AudioListener } from "./AudioListener.js";
4
+ import * as utils from "../engine/engine_utils.js";
5
+ import { serializable } from "../engine/engine_serialization_decorator.js";
6
+ import { ApplicationEvents } from "../engine/engine_application.js";
7
+ import { Audio, AudioContext, AudioLoader, PositionalAudio } from "three";
4
8
  import { isDevEnvironment } from "../engine/debug/index.js";
5
- import { ApplicationEvents } from "../engine/engine_application.js";
6
- import { Mathf } from "../engine/engine_math.js";
7
- import { serializable } from "../engine/engine_serialization_decorator.js";
8
- import { getTempVector } from "../engine/engine_three_utils.js";
9
- import * as utils from "../engine/engine_utils.js";
10
- import { AudioListener } from "./AudioListener.js";
11
- import { Behaviour, GameObject } from "./Component.js";
12
9
 
13
10
 
14
11
  const debug = utils.getParam("debugaudio");
@@ -68,9 +65,6 @@
68
65
  playOnAwake: boolean = false;
69
66
 
70
67
  @serializable()
71
- preload: boolean = false;
72
-
73
- @serializable()
74
68
  get loop(): boolean {
75
69
  if (this.sound) this._loop = this.sound.getLoop();
76
70
  return this._loop;
@@ -146,69 +140,23 @@
146
140
  if (!listener && this.context.mainCamera) listener = GameObject.addNewComponent(this.context.mainCamera, AudioListener);
147
141
  if (listener?.listener) {
148
142
  this.sound = new PositionalAudio(listener.listener);
149
- this.gameObject?.add(this.sound);
150
-
151
- // this._listener = listener;
152
- // this._originalSoundMatrixWorldFunction = this.sound.updateMatrixWorld;
153
- // this.sound.updateMatrixWorld = this._onSoundMatrixWorld;
143
+ this.gameObject.add(this.sound);
154
144
  }
155
145
  else if (debug) console.warn("No audio listener found in scene - can not play audio");
156
146
  }
157
147
  return this.sound;
158
148
  }
159
149
 
160
- // This is a hacky workaround to get the PositionalAudio behave like a 2D audio source
161
- // private _listener: AudioListener | null = null;
162
- // private _originalSoundMatrixWorldFunction: Function | null = null;
163
- // private _onSoundMatrixWorld = (force: boolean) => {
164
- // if (this._spatialBlend > .05) {
165
- // if (this._originalSoundMatrixWorldFunction) {
166
- // this._originalSoundMatrixWorldFunction.call(this.sound, force);
167
- // }
168
- // }
169
- // else {
170
- // // we use another object's matrix world function (but bound to the positional audio)
171
- // // this is just a little trick to prevent calling the PositionalAudio's updateMatrixWorld function
172
- // this.gameObject.updateMatrixWorld?.call(this.sound, force);
173
- // if (this.sound && this._listener) {
174
- // this.sound.gain.connect(this._listener.listener.getInput());
175
- // // const pos = getTempVector().setFromMatrixPosition(this._listener.gameObject.matrixWorld);
176
- // // const ctx = this.sound.context;
177
- // // const delay = this._listener.listener.timeDelta;
178
- // // const time = ctx.currentTime ;
179
- // // this.sound.panner.positionX.setValueAtTime(pos.x, time);
180
- // // this.sound.panner.positionY.setValueAtTime(pos.y, time);
181
- // // this.sound.panner.positionZ.setValueAtTime(pos.z, time);
182
- // // this.sound.panner.orientationX.setValueAtTime(0, time);
183
- // // this.sound.panner.orientationY.setValueAtTime(0, time);
184
- // // this.sound.panner.orientationZ.setValueAtTime(-1, time);
185
- // }
186
- // }
187
- // }
188
-
189
150
  public get ShouldPlay(): boolean { return this.shouldPlay; }
190
151
 
191
- /** Get the audio context from the Sound */
192
- public get audioContext() {
193
- return this.sound?.context;
194
- }
195
152
 
196
153
  awake() {
197
- if (debug) console.log(this);
154
+ if(debug) console.log(this);
198
155
  this.audioLoader = new AudioLoader();
199
156
  if (this.playOnAwake) this.shouldPlay = true;
200
-
201
- if (this.preload) {
202
- if (typeof this.clip === "string") {
203
- this.audioLoader.load(this.clip, this.createAudio, () => { }, console.error);
204
- }
205
- }
206
157
  }
207
158
 
208
159
  onEnable(): void {
209
- if (this.sound)
210
- this.gameObject.add(this.sound);
211
-
212
160
  if (!AudioSource.userInteractionRegistered) {
213
161
  AudioSource.registerWaitForAllowAudio(() => {
214
162
  if (this.enabled && !this.destroyed && this.shouldPlay)
@@ -254,56 +202,50 @@
254
202
  this.sound?.setVolume(this.volume);
255
203
  }
256
204
 
205
+ private lerp = (x, y, a) => x * (1 - a) + y * a;
206
+
257
207
  private createAudio = (buffer?: AudioBuffer) => {
258
- if (debug) console.log("AudioBuffer finished loading", buffer);
208
+ if (debug) console.log("audio buffer loaded");
209
+ AudioSource.registerWaitForAllowAudio(() => {
210
+ if (debug)
211
+ console.log("finished loading", buffer);
259
212
 
260
- const sound = this.Sound;
261
- if (!sound) {
262
- if (debug) console.warn("Failed getting sound?", this.name);
263
- return;
264
- }
213
+ const sound = this.Sound;
214
+ if (!sound) {
215
+ console.warn("Failed getting sound", this.name);
216
+ return;
217
+ }
218
+ if (sound.isPlaying)
219
+ sound.stop();
265
220
 
266
- if (sound.isPlaying)
267
- sound.stop();
221
+ if (buffer)
222
+ sound.setBuffer(buffer);
223
+ sound.loop = this._loop;
224
+ if (this.context.application.muted) sound.setVolume(0);
225
+ else sound.setVolume(this.volume);
226
+ sound.autoplay = this.shouldPlay;
227
+ // sound.setDistanceModel('linear');
228
+ // sound.setRolloffFactor(1);
229
+ this.applySpatialDistanceSettings();
230
+ // sound.setDirectionalCone(180, 360, 0.1);
231
+ if (sound.isPlaying)
232
+ sound.stop();
268
233
 
269
- if (buffer) sound.setBuffer(buffer);
270
- sound.loop = this._loop;
271
- if (this.context.application.muted) sound.setVolume(0);
272
- else sound.setVolume(this.volume);
273
- sound.autoplay = this.shouldPlay && AudioSource.userInteractionRegistered;
234
+ if (debug) console.log(this.name, this.shouldPlay, AudioSource.userInteractionRegistered, this);
274
235
 
275
- this.applySpatialDistanceSettings();
276
-
277
- if (sound.isPlaying)
278
- sound.stop();
279
-
280
- // const src = sound.context.createBufferSource();
281
- // src.buffer = sound.buffer;
282
- // src.connect(sound.panner);
283
- // src.start(this.audioContext?.currentTime);
284
- // const gain = sound.context.createGain();
285
- // gain.gain.value = 1 - this.spatialBlend;
286
- // src.connect(gain);
287
-
288
- // make sure we only play the sound if the user has interacted with the page
289
- AudioSource.registerWaitForAllowAudio(this.__onAllowAudioCallback);
236
+ if (this.shouldPlay && AudioSource.userInteractionRegistered)
237
+ this.play();
238
+ });
290
239
  }
291
- private __onAllowAudioCallback = () => {
292
- if (this.shouldPlay)
293
- this.play();
294
- }
295
240
 
296
241
  private applySpatialDistanceSettings() {
297
242
  const sound = this.sound;
298
243
  if (!sound) return;
299
244
  this._needUpdateSpatialDistanceSettings = false;
300
- const dist = Mathf.lerp(10 * this._maxDistance / Math.max(0.0001, this.spatialBlend), this._minDistance, this.spatialBlend);
245
+ const dist = this.lerp(10 * this._maxDistance / Math.max(0.0001, this.spatialBlend), this._minDistance, this.spatialBlend);
301
246
  if (debug) console.log(this.name, this._minDistance, this._maxDistance, this.spatialBlend, "Ref distance=" + dist);
302
247
  sound.setRefDistance(dist);
303
248
  sound.setMaxDistance(Math.max(0.01, this._maxDistance));
304
- // sound.setRolloffFactor(this.spatialBlend);
305
- // sound.panner.positionZ.automationRate
306
-
307
249
  // https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel
308
250
  switch (this.rollOffMode) {
309
251
  case AudioRolloffMode.Logarithmic:
@@ -327,7 +269,7 @@
327
269
  }
328
270
  }
329
271
 
330
- private async onNewClip(clip?: string | MediaStream) {
272
+ private onNewClip(clip?: string | MediaStream) {
331
273
  if (clip) this.clip = clip;
332
274
  if (typeof clip === "string") {
333
275
  if (debug)
@@ -343,10 +285,7 @@
343
285
  this._lastClipStartedLoading = clip;
344
286
  if (debug)
345
287
  console.log("load audio", clip);
346
- const buffer = await this.audioLoader.loadAsync(clip).catch(console.error);
347
- this._lastClipStartedLoading = null;
348
- if (buffer)
349
- this.createAudio(buffer);
288
+ this.audioLoader.load(clip, this.createAudio, () => { }, console.error);
350
289
  }
351
290
  else console.warn("Unsupported audio clip type", clip)
352
291
  }
@@ -389,7 +328,6 @@
389
328
  if (this.sound && !this.sound.isPlaying) {
390
329
  const muted = this.context.application.muted;
391
330
  if (muted) this.sound.setVolume(0);
392
- this.gameObject?.add(this.sound);
393
331
 
394
332
  if (this.clip instanceof MediaStream) {
395
333
 
@@ -473,7 +411,7 @@
473
411
  this._hasEnded = true;
474
412
  if (debug)
475
413
  console.log("Audio clip ended", this.clip);
476
- this.dispatchEvent(new CustomEvent("ended", { detail: this }));
414
+ this.sound.dispatchEvent({ type: 'ended', target: this });
477
415
  }
478
416
 
479
417
  // this.gameObject.position.x = Math.sin(time.time) * 2;
src/engine-components/avatar/Avatar_Brain_LookAt.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import * as THREE from "three";
2
-
3
- import { OwnershipModel } from "../../engine/engine_networking.js";
4
- import type { IModel } from "../../engine/engine_networking_types.js";
5
- import { Context } from "../../engine/engine_setup.js";
6
- import * as utils from "../../engine/engine_three_utils.js";
7
2
  import { TypeStore } from "../../engine/engine_typestore.js";
8
3
  import { Behaviour, GameObject } from "../Component.js";
9
4
  import { AvatarMarker } from "../webxr/WebXRAvatar.js";
5
+ import * as utils from "../../engine/engine_three_utils.js";
6
+ import { OwnershipModel } from "../../engine/engine_networking.js";
7
+ import { Context } from "../../engine/engine_setup.js";
8
+ import type { IModel } from "../../engine/engine_networking_types.js";
10
9
 
11
10
  export class Avatar_POI {
12
11
 
src/engine-components/avatar/Avatar_MouthShapes.ts CHANGED
@@ -1,10 +1,9 @@
1
- import { Object3D } from "three";
2
-
3
- import { serializable } from "../../engine/engine_serialization_decorator.js";
4
- import * as utils from "../../engine/engine_utils.js";
5
1
  import { Behaviour, GameObject } from "../Component.js";
6
2
  import { Voip } from "../Voip.js";
7
3
  import { AvatarMarker } from "../webxr/WebXRAvatar.js";
4
+ import * as utils from "../../engine/engine_utils.js";
5
+ import { Object3D } from "three";
6
+ import { serializable } from "../../engine/engine_serialization_decorator.js";
8
7
 
9
8
  const debug = utils.getParam("debugmouth");
10
9
 
src/engine-components/webxr/Avatar.ts DELETED
@@ -1,232 +0,0 @@
1
- import { Object3D, Quaternion, Vector3 } from "three";
2
-
3
- import { AssetReference } from "../../engine/engine_addressables.js";
4
- import { ObjectUtils, PrimitiveType } from "../../engine/engine_create_objects.js";
5
- import { serializable } from "../../engine/engine_serialization_decorator.js";
6
- import { IGameObject } from "../../engine/engine_types.js";
7
- import { getParam,PromiseAllWithErrors } from "../../engine/engine_utils.js";
8
- import { NeedleXREventArgs, NeedleXRSession, NeedleXRUtils } from "../../engine/xr/index.js";
9
- import { PlayerState } from "../../engine-components-experimental/networking/PlayerSync.js";
10
- import { Behaviour, GameObject } from "../Component.js";
11
- import { SyncedTransform } from "../SyncedTransform.js";
12
- import { AvatarMarker } from "./WebXRAvatar.js";
13
- import { XRFlag } from "./XRFlag.js";
14
-
15
- const debug = getParam("debugwebxr");
16
-
17
- const flipForwardQuaternion = new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), Math.PI);
18
-
19
- export class Avatar extends Behaviour {
20
-
21
- @serializable(AssetReference)
22
- head?: AssetReference;
23
-
24
- @serializable(AssetReference)
25
- leftHand?: AssetReference;
26
-
27
- @serializable(AssetReference)
28
- rightHand?: AssetReference;
29
-
30
- private _syncTransforms?: SyncedTransform[];
31
-
32
- async onEnterXR(_args: NeedleXREventArgs) {
33
- if (!this.activeAndEnabled) return;
34
- if (debug) console.warn("AVATAR ENTER XR", this.guid, this.sourceId, this, this.activeAndEnabled)
35
- if (this._syncTransforms)
36
- this._syncTransforms.length = 0;
37
- await this.prepareAvatar();
38
-
39
- const playerstate = PlayerState.getFor(this);
40
- if (playerstate?.owner) {
41
- const marker = this.gameObject.addNewComponent(AvatarMarker)!;
42
- marker.avatar = this.gameObject;
43
- marker.connectionId = playerstate.owner;
44
- }
45
- else if (this.context.connection.isConnected) console.error("No player state found for avatar", this);
46
- // don't destroy the avatar when entering XR and not connected to a networking backend
47
- else if (playerstate && !this.context.connection.isConnected) playerstate.dontDestroy = true;
48
- }
49
-
50
- onLeaveXR(_args: NeedleXREventArgs): void {
51
- const marker = this.gameObject.getComponent(AvatarMarker);
52
- if (marker) {
53
- marker.destroy();
54
- }
55
- }
56
-
57
- onUpdateXR(args: NeedleXREventArgs): void {
58
- if (!this.activeAndEnabled) return;
59
-
60
- const isLocalPlayer = PlayerState.isLocalPlayer(this);
61
- if (!isLocalPlayer) return;
62
-
63
- const xr = args.xr;
64
- // make sure the avatar is inside the active rig
65
- if (xr.rig && xr.rig.gameObject !== this.gameObject.parent) {
66
- this.gameObject.position.set(0, 0, 0);
67
- this.gameObject.rotation.set(0, 0, 0);
68
- this.gameObject.scale.set(1, 1, 1);
69
- xr.rig.gameObject.add(this.gameObject);
70
- }
71
- // this.gameObject.position.copy(xr.rig!.gameObject.position);
72
- // this.gameObject.quaternion.copy(xr.rig!.gameObject.quaternion);
73
- // this.gameObject.scale.set(1, 1, 1);
74
-
75
-
76
- if (this._syncTransforms && isLocalPlayer) {
77
- for (const sync of this._syncTransforms) {
78
- sync.fastMode = true;
79
- if (!sync.isOwned())
80
- sync.requestOwnership();
81
- }
82
- }
83
-
84
-
85
- // synchronize head
86
- if (this.head && this.context.mainCamera) {
87
- const headObj = this.head.asset as IGameObject;
88
- headObj.position.copy(this.context.mainCamera.position);
89
- headObj.quaternion.copy(this.context.mainCamera.quaternion);
90
- headObj.quaternion.x *= -1;
91
-
92
- // HACK: XRFlag limitation workaround to make sure first person user head is never rendered
93
- if (this.context.time.frameCount % 10 === 0) {
94
- const xrflags = GameObject.getComponentsInChildren(this.head.asset, XRFlag);
95
- for (const flag of xrflags) {
96
- flag.enabled = false;
97
- flag.gameObject.visible = false;
98
- }
99
- }
100
- }
101
-
102
- // synchronize hands
103
- const leftCtrl = args.xr.leftController;
104
- const leftObj = this.leftHand?.asset as Object3D;
105
- if (leftCtrl && leftObj) {
106
- leftObj.position.copy(leftCtrl.gripPosition);
107
- leftObj.quaternion.copy(leftCtrl.gripQuaternion);
108
- leftObj.quaternion.multiply(flipForwardQuaternion);
109
- leftObj.visible = leftCtrl.isTracking;
110
- }
111
-
112
- const right = args.xr.rightController;
113
- if (right && this.rightHand?.asset) {
114
- const rightObj = this.rightHand.asset as Object3D;
115
- rightObj.position.copy(right.gripPosition);
116
- rightObj.quaternion.copy(right.gripQuaternion);
117
- rightObj.quaternion.multiply(flipForwardQuaternion);
118
- rightObj.visible = right.isTracking;
119
- }
120
- }
121
-
122
- onBeforeRender(): void {
123
- if (this.context.time.frame % 10 === 0)
124
- this.updateRemoteAvatarVisibility();
125
- }
126
-
127
-
128
- private updateRemoteAvatarVisibility() {
129
- if (this.context.connection.isConnected) {
130
- const state = PlayerState.getFor(this);
131
- if (state && state.isLocalPlayer == false) {
132
-
133
- const sync = NeedleXRSession.getXRSync(this.context);
134
- if (sync) {
135
- if (sync.hasState(state.owner)) {
136
- this.tryFindAvatarObjectsIfMissing();
137
-
138
- const leftObj = this.leftHand?.asset as Object3D;
139
- if (leftObj) {
140
- leftObj.visible = sync?.isTracking(state.owner, "left") ?? false;
141
- }
142
- const rightObj = this.rightHand?.asset as Object3D;
143
- if (rightObj) {
144
- rightObj.visible = sync?.isTracking(state.owner, "right") ?? false;
145
- }
146
- }
147
- }
148
-
149
- // HACK: XRFlag limitation workaround to make sure first person user head of OTHER users is ALWAYS rendered
150
- if (this.head?.asset) {
151
- const xrflags = GameObject.getComponentsInChildren(this.head.asset, XRFlag);
152
- for (const flag of xrflags) {
153
- flag.enabled = false;
154
- flag.gameObject.visible = true;
155
- }
156
- }
157
- }
158
- }
159
- }
160
-
161
-
162
-
163
- private tryFindAvatarObjectsIfMissing() {
164
- // if no avatar objects are set, try to find them
165
- if (!this.head || !this.leftHand || !this.rightHand) {
166
- const res = { head: this.head, leftHand: this.leftHand, rightHand: this.rightHand };
167
- NeedleXRUtils.tryFindAvatarObjects(this.gameObject, this.sourceId || "", res);
168
- if (res.head) this.head = res.head;
169
- if (res.leftHand) this.leftHand = res.leftHand;
170
- if (res.rightHand) this.rightHand = res.rightHand;
171
- }
172
- }
173
-
174
- private async prepareAvatar() {
175
- // if no avatar objects are set, try to find them
176
- this.tryFindAvatarObjectsIfMissing();
177
-
178
- if (!this.head) {
179
- const head = new Object3D();
180
- head.name = "Head";
181
- const cube = ObjectUtils.createPrimitive(PrimitiveType.Cube);
182
- head.add(cube);
183
- this.gameObject.add(head);
184
- this.head = new AssetReference("", this.sourceId, head);
185
- if (debug) console.log("Create head", head);
186
- }
187
- else if (this.head instanceof Object3D) {
188
- this.head = new AssetReference("", this.sourceId, this.head);
189
- }
190
-
191
- if (!this.rightHand) {
192
- const rightHand = new Object3D();
193
- rightHand.name = "Right Hand";
194
- this.gameObject.add(rightHand);
195
- this.rightHand = new AssetReference("", this.sourceId, rightHand);
196
- if (debug) console.log("Create right hand", rightHand);
197
- }
198
- else if (this.rightHand instanceof Object3D) {
199
- this.rightHand = new AssetReference("", this.sourceId, this.rightHand);
200
- }
201
-
202
- if (!this.leftHand) {
203
- const leftHand = new Object3D();
204
- leftHand.name = "Left Hand";
205
- this.gameObject.add(leftHand);
206
- this.leftHand = new AssetReference("", this.sourceId, leftHand);
207
- if (debug) console.log("Create left hand", leftHand);
208
- }
209
- else if (this.leftHand instanceof Object3D) {
210
- this.leftHand = new AssetReference("", this.sourceId, this.leftHand);
211
- }
212
-
213
- await this.loadAvatarObjects(this.head, this.leftHand, this.rightHand);
214
-
215
- if (PlayerState.isLocalPlayer(this.gameObject)) {
216
- this._syncTransforms = GameObject.getComponentsInChildren(this.gameObject, SyncedTransform);
217
- }
218
- }
219
-
220
-
221
- private async loadAvatarObjects(head: AssetReference, left: AssetReference, right: AssetReference) {
222
- const pHead = head.loadAssetAsync();
223
- const pHandLeft = left.loadAssetAsync();
224
- const pHandRight = right.loadAssetAsync();
225
- const promises = new Array<Promise<any>>();
226
- if (pHead) promises.push(pHead);
227
- if (pHandLeft) promises.push(pHandLeft);
228
- if (pHandRight) promises.push(pHandRight);
229
- const res = await PromiseAllWithErrors(promises);
230
- if (debug) console.log("Avatar loaded results:", res);
231
- }
232
- }
src/engine-components/avatar/AvatarBlink_Simple.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { Object3D } from "three";
2
-
2
+ import { Behaviour, GameObject } from "../Component.js";
3
+ import { XRFlag, XRState } from "../XRFlag.js";
3
4
  import { serializable } from "../../engine/engine_serialization_decorator.js";
4
- import { Behaviour, GameObject } from "../Component.js";
5
- import { XRFlag, XRState } from "../webxr/XRFlag.js";
6
5
 
7
6
 
8
7
  export class AvatarBlink_Simple extends Behaviour {
src/engine-components/avatar/AvatarEyeLook_Rotation.ts CHANGED
@@ -1,11 +1,10 @@
1
+ import { Behaviour, GameObject } from "../Component.js";
2
+ import * as utils from "../../engine/engine_three_utils.js"
1
3
  import * as THREE from "three";
4
+ import { Avatar_Brain_LookAt } from "./Avatar_Brain_LookAt.js";
5
+ import { serializable } from "../../engine/engine_serialization_decorator.js";
2
6
  import { Object3D } from "three";
3
7
 
4
- import { serializable } from "../../engine/engine_serialization_decorator.js";
5
- import * as utils from "../../engine/engine_three_utils.js"
6
- import { Behaviour, GameObject } from "../Component.js";
7
- import { Avatar_Brain_LookAt } from "./Avatar_Brain_LookAt.js";
8
-
9
8
  export class AvatarEyeLook_Rotation extends Behaviour {
10
9
 
11
10
  @serializable(Object3D)
src/engine-components/AvatarLoader.ts CHANGED
@@ -1,13 +1,12 @@
1
- import { Box3, Object3D, Vector3 } from "three";
2
1
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
3
-
4
- import { InstantiateOptions } from "../engine/engine_gameobject.js";
5
- import { getLoader } from "../engine/engine_gltf.js";
2
+ import * as utils from "../engine/engine_utils.js"
6
3
  import * as loaders from "../engine/engine_loaders.js"
7
4
  import { Context } from "../engine/engine_setup.js";
8
- import * as utils from "../engine/engine_utils.js"
5
+ import { GameObject } from "./Component.js";
9
6
  import { download_file } from "../engine/engine_web_api.js";
10
- import { GameObject } from "./Component.js";
7
+ import { getLoader } from "../engine/engine_gltf.js";
8
+ import { InstantiateOptions } from "../engine/engine_gameobject.js";
9
+ import { Box3, Object3D, Vector3 } from "three";
11
10
 
12
11
  const debug = utils.getParam("debugavatar");
13
12
 
src/engine-components/AxesHelper.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { AxesHelper as _AxesHelper } from "three";
2
-
1
+ import { Behaviour } from "./Component.js";
3
2
  import * as params from "../engine/engine_default_parameters.js";
4
3
  import { serializable } from "../engine/engine_serialization_decorator.js";
5
- import { Behaviour } from "./Component.js";
4
+ import { AxesHelper as _AxesHelper } from "three";
6
5
 
7
6
  export class AxesHelper extends Behaviour {
8
7
  @serializable()
src/engine-components/ui/BaseUIComponent.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  // import { Canvas } from './Canvas.js';
2
- import { AxesHelper, Object3D } from 'three';
3
2
  import * as ThreeMeshUI from 'three-mesh-ui';
4
-
5
- import { showGizmos } from '../../engine/engine_default_parameters.js';
6
- import { getParam } from '../../engine/engine_utils.js';
7
3
  import { Behaviour, GameObject } from "../Component.js";
8
4
  import { EventSystem } from "./EventSystem.js";
5
+ import { showGizmos } from '../../engine/engine_default_parameters.js';
6
+ import { AxesHelper, Object3D } from 'three';
9
7
  import type { ICanvas } from './Interfaces.js';
8
+ import { getParam } from '../../engine/engine_utils.js';
10
9
  export const includesDir = "./include";
11
10
 
12
11
  const debug = getParam("debugshadowcomponents");
@@ -25,38 +24,22 @@
25
24
 
26
25
  export const $shadowDomOwner = Symbol("shadowDomOwner");
27
26
 
28
- /** Derive from this class if you want to implement your own UI components
29
- * It provides utility methods and simplifies managing the underlying three-mesh-ui hierarchy
30
- */
31
27
  export class BaseUIComponent extends Behaviour {
32
28
 
33
- /** Is this object on the root of the UI hierarchy ? */
34
29
  isRoot() { return this.Root?.gameObject === this.gameObject; }
35
30
 
36
- /** Access the parent canvas component */
37
31
  get canvas() {
38
32
  const cv = this.Root as any as ICanvas;
39
33
  if (cv?.isCanvas) return cv;
40
34
  return null;
41
35
  }
42
- /** @deprecated use `canvas` */
43
- protected get Canvas() {
44
- return this.canvas;
45
- }
46
36
 
47
- /** Mark the UI dirty which will trigger an THREE-Mesh-UI update */
48
37
  markDirty() {
49
38
  EventSystem.markUIDirty(this.context);
50
39
  }
51
40
 
52
- /** the underlying three-mesh-ui */
53
- get shadowComponent() { return this._shadowComponent }
54
- private set shadowComponent(val: Object3D | null) {
55
- this._shadowComponent = val;
56
- }
41
+ shadowComponent: ThreeMeshUI.Block | null = null;
57
42
 
58
- private _shadowComponent: Object3D | null = null;
59
-
60
43
  private _controlsChildLayout = true;
61
44
  get controlsChildLayout(): boolean { return this._controlsChildLayout; }
62
45
  set controlsChildLayout(val: boolean) {
@@ -75,6 +58,11 @@
75
58
  return this._root;
76
59
  }
77
60
 
61
+ // TODO: rename to canvas
62
+ protected get Canvas() {
63
+ return this.canvas;
64
+ }
65
+
78
66
  // private _intermediate?: Object3D;
79
67
  protected _parentComponent?: BaseUIComponent | null = undefined;
80
68
 
@@ -89,10 +77,7 @@
89
77
  super.onEnable();
90
78
  }
91
79
 
92
- /** Add a three-mesh-ui object to the UI hierarchy
93
- * @param container the three-mesh-ui object to add
94
- * @param parent the parent component to add the object to
95
- */
80
+ //@ts-ignore
96
81
  protected addShadowComponent(container: any, parent?: BaseUIComponent) {
97
82
 
98
83
  this.removeShadowComponent();
@@ -149,7 +134,21 @@
149
134
  if(debug) console.log(this.shadowComponent)
150
135
  }
151
136
 
152
- protected setShadowComponentOwner(current: ThreeMeshUI.MeshUIBaseElement | Object3D | null | undefined) {
137
+
138
+ set(_state: object) {
139
+ // if (!this.shadowComponent) return;
140
+ // this.traverseOwnedShadowComponents(this.shadowComponent, this, o => {
141
+ // for (const ch of o.children) {
142
+ // console.log(this, ch);
143
+ // if (ch.isUI && typeof ch.set === "function") {
144
+ // // ch.set(state);
145
+ // // ch.update(true, true, true);
146
+ // }
147
+ // }
148
+ // })
149
+ }
150
+
151
+ protected setShadowComponentOwner(current: Object3D | null | undefined) {
153
152
  if (!current) return;
154
153
  // TODO: only traverse our own hierarchy, we can stop if we find another owner
155
154
  if (current[$shadowDomOwner] === undefined || current[$shadowDomOwner] === this) {
@@ -172,7 +171,6 @@
172
171
  }
173
172
  }
174
173
 
175
- /** Remove the underlying UI object from the hierarchy */
176
174
  protected removeShadowComponent() {
177
175
  if (this.shadowComponent) {
178
176
  this.shadowComponent.removeFromParent();
src/engine-components/BasicIKConstraint.ts CHANGED
@@ -1,8 +1,7 @@
1
+ import { Behaviour, GameObject } from "./Component.js";
2
+ import * as utils from "./../engine/engine_three_utils.js";
1
3
  import { Vector3 } from "three";
2
4
 
3
- import * as utils from "./../engine/engine_three_utils.js";
4
- import { Behaviour, GameObject } from "./Component.js";
5
-
6
5
  export class BasicIKConstraint extends Behaviour {
7
6
 
8
7
  private from!: GameObject;
src/engine-components/export/usdz/extensions/behavior/Behaviour.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { getParam } from "../../../../../engine/engine_utils.js";
2
1
  import { GameObject } from "../../../../Component.js";
3
2
  import type { IUSDExporterExtension } from "../../Extension.js";
4
3
  import { USDObject, USDWriter, USDZExporterContext } from "../../ThreeUSDZExporter.js";
5
4
  import { BehaviorModel } from "./BehavioursBuilder.js";
5
+ import { getParam } from "../../../../../engine/engine_utils.js";
6
6
 
7
7
  const debug = getParam("debugusdz");
8
8
 
src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts CHANGED
@@ -1,20 +1,21 @@
1
- import { Group,Material, Mesh, Object3D, Quaternion, Vector3 } from "three";
2
-
3
- import { isDevEnvironment, showBalloonWarning } from "../../../../../engine/debug/index.js";
4
- import { serializable } from "../../../../../engine/engine_serialization_decorator.js";
5
- import { getWorldPosition, getWorldQuaternion, getWorldScale, setWorldPosition, setWorldQuaternion, setWorldScale } from "../../../../../engine/engine_three_utils.js";
6
- import type { State } from "../../../../../engine/extensions/NEEDLE_animator_controller_model.js";
7
- import { NEEDLE_progressive } from "../../../../../engine/extensions/NEEDLE_progressive.js";
1
+ import { Behaviour, GameObject } from "../../../../Component.js";
8
2
  import { Animator } from "../../../../Animator.js";
9
- import { AudioSource } from "../../../../AudioSource.js";
10
- import { Behaviour, GameObject } from "../../../../Component.js";
11
3
  import { Renderer } from "../../../../Renderer.js";
4
+ import { serializable } from "../../../../../engine/engine_serialization_decorator.js";
12
5
  import type { IPointerClickHandler, PointerEventData } from "../../../../ui/PointerEvents.js";
13
- import { ObjectRaycaster,Raycaster } from "../../../../ui/Raycaster.js";
6
+ import { AnimationExtension, RegisteredAnimationInfo, type UsdzAnimation } from "../Animation.js";
7
+ import { getWorldPosition, getWorldQuaternion, getWorldScale, setWorldPosition, setWorldQuaternion, setWorldScale } from "../../../../../engine/engine_three_utils.js";
8
+
9
+ import { Object3D, Material, Vector3, Quaternion, Mesh, Group } from "three";
14
10
  import { USDDocument, USDObject, USDZExporterContext } from "../../ThreeUSDZExporter.js";
15
- import { AnimationExtension, RegisteredAnimationInfo, type UsdzAnimation } from "../Animation.js";
11
+
16
12
  import type { BehaviorExtension, UsdzBehaviour } from "./Behaviour.js";
17
- import { ActionBuilder, ActionModel, AuralMode, BehaviorModel, GroupActionModel, type IBehaviorElement, MotionType, MultiplePerformOperation,PlayAction, Space, TriggerBuilder } from "./BehavioursBuilder.js";
13
+ import { ActionBuilder, ActionModel, AuralMode, BehaviorModel, type IBehaviorElement, MotionType, PlayAction, Space, TriggerBuilder, GroupActionModel, MultiplePerformOperation } from "./BehavioursBuilder.js";
14
+ import { AudioSource } from "../../../../AudioSource.js";
15
+ import { NEEDLE_progressive } from "../../../../../engine/extensions/NEEDLE_progressive.js";
16
+ import { isDevEnvironment, showBalloonWarning } from "../../../../../engine/debug/index.js";
17
+ import { Raycaster, ObjectRaycaster } from "../../../../ui/Raycaster.js";
18
+ import type { State } from "../../../../../engine/extensions/NEEDLE_animator_controller_model.js";
18
19
 
19
20
  function ensureRaycaster(obj: GameObject) {
20
21
  if (!obj) return;
src/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Object3D } from "three";
2
+ import { USDDocument, USDObject, USDWriter, makeNameSafeForUSD } from "../../ThreeUSDZExporter.js";
2
3
 
4
+ import { BehaviorExtension } from "./Behaviour.js";
3
5
  import { getParam } from "../../../../../engine/engine_utils.js";
4
- import { makeNameSafeForUSD,USDDocument, USDObject, USDWriter } from "../../ThreeUSDZExporter.js";
5
- import { BehaviorExtension } from "./Behaviour.js";
6
6
 
7
7
  const debug = getParam("debugusdz");
8
8
 
src/engine-components/postprocessing/Effects/Bloom.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { BlendFunction, BloomEffect, SelectiveBloomEffect } from "postprocessing";
2
-
3
2
  import { serializable } from "../../../engine/engine_serialization.js";
4
3
  import { PostProcessingEffect } from "../PostProcessingEffect.js";
5
4
  import { VolumeParameter } from "../VolumeParameter.js";
src/engine-components/BoxHelperComponent.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { Box3, Color, type ColorRepresentation, LineSegments, Object3D, Vector3 } from "three";
2
-
1
+ import { Behaviour } from "./Component.js";
2
+ import { getParam } from "../engine/engine_utils.js";
3
3
  import { CreateWireCube, Gizmos } from "../engine/engine_gizmos.js";
4
4
  import { getWorldPosition, getWorldScale } from "../engine/engine_three_utils.js";
5
- import { getParam } from "../engine/engine_utils.js";
6
- import { Behaviour } from "./Component.js";
5
+ import { Box3, Color, type ColorRepresentation, LineSegments, Object3D, Vector3 } from "three";
7
6
 
8
7
  const gizmos = getParam("gizmos");
9
8
  const debug = getParam("debugboxhelper");
src/engine-components/ui/Button.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { showBalloonMessage } from "../../engine/debug/index.js";
2
- import { Gizmos } from "../../engine/engine_gizmos.js";
3
- import { PointerType } from "../../engine/engine_input.js";
4
- import { serializable } from "../../engine/engine_serialization_decorator.js";
5
- import { getParam } from "../../engine/engine_utils.js";
6
- import { Animator } from "../Animator.js";
7
1
  import { Behaviour, GameObject } from "../Component.js";
8
2
  import { EventList } from "../EventList.js";
3
+ import type { IPointerClickHandler, IPointerEnterHandler, IPointerEventHandler, IPointerExitHandler, PointerEventData } from "./PointerEvents.js";
4
+ import { Image } from "./Image.js";
9
5
  import { RGBAColor } from "../js-extensions/RGBAColor.js";
10
- import { Image } from "./Image.js";
11
- import type { IPointerClickHandler, IPointerEnterHandler, IPointerEventHandler, IPointerExitHandler, PointerEventData } from "./PointerEvents.js";
6
+ import { serializable } from "../../engine/engine_serialization_decorator.js";
7
+ import { Animator } from "../Animator.js";
8
+ import { getParam } from "../../engine/engine_utils.js";
9
+ import { showBalloonMessage } from "../../engine/debug/index.js";
12
10
  import { GraphicRaycaster, ObjectRaycaster, Raycaster } from "./Raycaster.js";
11
+ import { PointerType } from "../../engine/engine_input.js";
12
+ import { Gizmos } from "../../engine/engine_gizmos.js";
13
13
 
14
14
  const debug = getParam("debugbutton");
15
15
 
@@ -65,12 +65,12 @@
65
65
  @serializable(EventList)
66
66
  onClick?: EventList;
67
67
 
68
- private _isHovered: number = 0;
68
+ private _isHovered: boolean = false;
69
69
 
70
70
  onPointerEnter(_) {
71
- this._isHovered += 1;
72
71
  if (debug)
73
- console.warn("Button Enter", this._isHovered, this.animationTriggers?.highlightedTrigger, this.animator);
72
+ console.log("Button Enter", this.animationTriggers?.highlightedTrigger, this.animator);
73
+ this._isHovered = true;
74
74
  if (!this.interactable) return;
75
75
  if (this.transition == Transition.Animation && this.animationTriggers && this.animator) {
76
76
  this.animator.setTrigger(this.animationTriggers.highlightedTrigger);
@@ -82,12 +82,10 @@
82
82
  }
83
83
 
84
84
  onPointerExit() {
85
- this._isHovered -= 1;
86
85
  if (debug)
87
- console.log("Button Exit", this._isHovered, this.animationTriggers?.highlightedTrigger, this.animator);
86
+ console.log("Button Exit", this.animationTriggers?.highlightedTrigger, this.animator);
87
+ this._isHovered = false;
88
88
  if (!this.interactable) return;
89
- if (this._isHovered > 0) return;
90
- this._isHovered = 0;
91
89
  if (this.transition == Transition.Animation && this.animationTriggers && this.animator) {
92
90
  this.animator.setTrigger(this.animationTriggers.normalTrigger);
93
91
  }
@@ -122,10 +120,10 @@
122
120
  }
123
121
 
124
122
  onPointerClick(args: PointerEventData) {
125
- if (!this.interactable) return;
123
+ if (!this.interactable || args.pointerId !== 0) return;
126
124
 
127
- if (args.button !== 0 && args.event.pointerType === PointerType.Mouse) return;
128
125
  // Button clicks should only run with left mouse button while using mouse
126
+ if(args.pointerId !== 0 && this.context.input.getIsMouse(args.pointerId)) return;
129
127
  if (debug) {
130
128
  console.warn("Button Click", this.onClick);
131
129
  showBalloonMessage("CLICKED button " + this.name + " at " + this.context.time.frameCount);
src/engine-components/Camera.ts CHANGED
@@ -1,17 +1,17 @@
1
- import { EquirectangularReflectionMapping, OrthographicCamera, PerspectiveCamera, Ray, SRGBColorSpace, Vector3 } from "three";
2
- import { Texture } from "three";
3
-
1
+ import { Behaviour, GameObject } from "./Component.js";
2
+ import { getParam } from "../engine/engine_utils.js";
3
+ import { serializable } from "../engine/engine_serialization_decorator.js";
4
+ import { RGBAColor } from "./js-extensions/RGBAColor.js";
5
+ import { Context, XRSessionMode } from "../engine/engine_setup.js";
6
+ import type { ICamera } from "../engine/engine_types.js"
4
7
  import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../engine/debug/index.js";
8
+ import { getWorldPosition } from "../engine/engine_three_utils.js";
5
9
  import { Gizmos } from "../engine/engine_gizmos.js";
6
- import { serializable } from "../engine/engine_serialization_decorator.js";
7
- import { Context } from "../engine/engine_setup.js";
10
+
11
+ import { EquirectangularReflectionMapping, OrthographicCamera, PerspectiveCamera, Ray, SRGBColorSpace, Vector3 } from "three";
12
+ import { OrbitControls } from "./OrbitControls.js";
8
13
  import { RenderTexture } from "../engine/engine_texture.js";
9
- import { getWorldPosition } from "../engine/engine_three_utils.js";
10
- import type { ICamera } from "../engine/engine_types.js"
11
- import { getParam } from "../engine/engine_utils.js";
12
- import { Behaviour, GameObject } from "./Component.js";
13
- import { RGBAColor } from "./js-extensions/RGBAColor.js";
14
- import { OrbitControls } from "./OrbitControls.js";
14
+ import { Texture } from "three";
15
15
 
16
16
  export enum ClearFlags {
17
17
  Skybox = 1,
@@ -350,6 +350,7 @@
350
350
  if (this._backgroundBlurriness !== undefined)
351
351
  this.context.scene.backgroundBlurriness = this._backgroundBlurriness;
352
352
  if (this._backgroundIntensity !== undefined)
353
+ //@ts-ignore
353
354
  this.context.scene.backgroundIntensity = this._backgroundIntensity;
354
355
 
355
356
  break;
@@ -391,7 +392,7 @@
391
392
  if (debug)
392
393
  showBalloonMessage("Environment blend mode: " + environmentBlendMode + " on " + navigator.userAgent);
393
394
  let transparent = environmentBlendMode === 'additive' || environmentBlendMode === 'alpha-blend';
394
- if (context.isInAR) {
395
+ if (context.xrSessionMode === XRSessionMode.ImmersiveAR) {
395
396
  if (environmentBlendMode === "opaque") {
396
397
  // workaround for Quest 2 returning opaque when it should be alpha-blend
397
398
  // check user agent if this is the Quest browser and return true if so
src/engine-components/CameraUtils.ts CHANGED
@@ -1,15 +1,14 @@
1
+ import { OrbitControls } from "./OrbitControls.js";
2
+ import { addNewComponent, getOrAddComponent } from "../engine/engine_components.js";
1
3
  import { Object3D } from "three";
2
-
4
+ import type { ICamera, IContext } from "../engine/engine_types.js";
5
+ import { RGBAColor } from "./js-extensions/RGBAColor.js";
6
+ import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
3
7
  import { getCameraController } from "../engine/engine_camera.js";
4
- import { addNewComponent, getOrAddComponent } from "../engine/engine_components.js";
5
- import { Context } from "../engine/engine_context.js";
6
- import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
8
+ import { Camera, ClearFlags } from "./Camera.js";
7
9
  import { NeedleEngineHTMLElement } from "../engine/engine_element.js";
8
- import type { ICamera, IContext } from "../engine/engine_types.js";
9
10
  import { getParam } from "../engine/engine_utils.js";
10
- import { Camera, ClearFlags } from "./Camera.js";
11
- import { RGBAColor } from "./js-extensions/RGBAColor.js";
12
- import { OrbitControls } from "./OrbitControls.js";
11
+ import { Context } from "../engine/engine_context.js";
13
12
 
14
13
  const debug = getParam("debugmissingcamera");
15
14
 
src/engine-components/ui/Canvas.ts CHANGED
@@ -1,19 +1,17 @@
1
- import { Matrix4, Object3D } from "three";
2
- import * as ThreeMeshUI from 'three-mesh-ui'
3
-
4
- import { Mathf } from "../../engine/engine_math.js";
1
+ import { updateRenderSettings as updateRenderSettingsRecursive } from "./Utils.js";
5
2
  import { serializable } from "../../engine/engine_serialization_decorator.js";
6
3
  import { FrameEvent } from "../../engine/engine_setup.js";
7
- import { delayForFrames, getParam } from "../../engine/engine_utils.js";
8
- import { NeedleXREventArgs } from "../../engine/xr/index.js";
4
+ import { BaseUIComponent, UIRootComponent } from "./BaseUIComponent.js";
5
+ import { GameObject } from "../Component.js";
6
+ import { Matrix4, Object3D } from "three";
7
+ import { RectTransform } from "./RectTransform.js";
8
+ import type { ICanvas, ICanvasEventReceiver, ILayoutGroup, IRectTransform } from "./Interfaces.js";
9
9
  import { Camera } from "../Camera.js";
10
- import { GameObject } from "../Component.js";
11
- import { BaseUIComponent, UIRootComponent } from "./BaseUIComponent.js";
12
10
  import { EventSystem } from "./EventSystem.js";
13
- import type { ICanvas, ICanvasEventReceiver, ILayoutGroup, IRectTransform } from "./Interfaces.js";
11
+ import * as ThreeMeshUI from 'three-mesh-ui'
12
+ import { getParam } from "../../engine/engine_utils.js";
14
13
  import { LayoutGroup } from "./Layout.js";
15
- import { RectTransform } from "./RectTransform.js";
16
- import { updateRenderSettings as updateRenderSettingsRecursive } from "./Utils.js";
14
+ import { Mathf } from "../../engine/engine_math.js";
17
15
 
18
16
  export enum RenderMode {
19
17
  ScreenSpaceOverlay = 0,
@@ -202,37 +200,19 @@
202
200
  }
203
201
  }
204
202
 
205
- async onEnterXR(args: NeedleXREventArgs) {
206
- // workaround for https://linear.app/needle/issue/NE-4114
207
- if (this.screenspace) {
208
- if (args.xr.isVR || args.xr.isPassThrough) {
209
- this.gameObject.visible = false;
210
- }
211
- }
212
- else {
213
- this.gameObject.visible = false;
214
- await delayForFrames(1).then(()=>{
215
- this.gameObject.visible = true;
216
- });
217
- }
218
- }
219
- onLeaveXR(args: NeedleXREventArgs): void {
220
- if (this.screenspace) {
221
- if (args.xr.isVR || args.xr.isPassThrough) {
222
- this.gameObject.visible = true;
223
- }
224
- }
225
- }
226
-
227
203
  onBeforeRenderRoutine = () => {
228
- this.previousParent = this.gameObject.parent;
229
- if ((this.context.xr?.isVR || this.context.xr?.isPassThrough) && this.screenspace) {
230
- // see https://linear.app/needle/issue/NE-4114
231
- this.gameObject.visible = false;
232
- this.gameObject.removeFromParent();
204
+ if (this.context.isInVR) {
205
+ this.onUpdateRenderMode();
206
+ this.handleLayoutUpdates();
207
+ // TODO TMUI @swingingtom - For VR this is so we don't have text clipping
208
+ this.shadowComponent?.updateMatrixWorld(true);
209
+ this.shadowComponent?.updateWorldMatrix(true, true);
210
+ this.invokeBeforeRenderEvents();
211
+ EventSystem.ensureUpdateMeshUI(ThreeMeshUI, this.context, true);
233
212
  return;
234
213
  }
235
214
 
215
+ this.previousParent = this.gameObject.parent;
236
216
  // console.log(this.previousParent?.name + "/" + this.gameObject.name);
237
217
 
238
218
  if (this.renderOnTop || this.screenspace) {
@@ -251,12 +231,7 @@
251
231
  }
252
232
 
253
233
  onAfterRenderRoutine = () => {
254
- if ((this.context.xr?.isVR || this.context.xr?.isPassThrough) && this.screenspace) {
255
- this.previousParent?.add(this.gameObject);
256
- // this is currently causing an error during XR (https://linear.app/needle/issue/NE-4114)
257
- // this.gameObject.visible = true;
258
- return;
259
- }
234
+ if(this.context.isInVR) return;
260
235
  if ((this.screenspace || this.renderOnTop) && this.previousParent && this.context.mainCamera) {
261
236
  if (this.screenspace) {
262
237
  const camObj = this.context.mainCamera;
@@ -301,7 +276,7 @@
301
276
  for (const ch of this._rectTransforms) {
302
277
  if (matrixWorldChanged) ch.markDirty();
303
278
  let layout = this._layoutGroups.get(ch.gameObject);
304
- if (ch.isDirty && !layout) {
279
+ if(ch.isDirty && !layout){
305
280
  layout = ch.gameObject.getComponentInParent(LayoutGroup) as LayoutGroup;
306
281
  }
307
282
  if (ch.isDirty || layout?.isDirty) {
src/engine-components/ui/CanvasGroup.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { serializable } from "../../engine/engine_serialization_decorator.js";
1
+ import { Graphic } from "./Graphic.js";
2
2
  import { FrameEvent } from "../../engine/engine_setup.js";
3
3
  import { Behaviour, GameObject } from "../Component.js";
4
+ import { type ICanvasGroup, type IHasAlphaFactor } from "./Interfaces.js";
5
+ import { serializable } from "../../engine/engine_serialization_decorator.js";
4
6
  import { BaseUIComponent } from "./BaseUIComponent.js";
5
- import { Graphic } from "./Graphic.js";
6
- import { type ICanvasGroup, type IHasAlphaFactor } from "./Interfaces.js";
7
7
 
8
8
 
9
9
  export class CanvasGroup extends Behaviour implements ICanvasGroup {
@@ -41,6 +41,7 @@
41
41
 
42
42
  private _buffer: Graphic[] = [];
43
43
  private applyChangesNow() {
44
+ this._buffer.length = 0;
44
45
  for (const ch of GameObject.getComponentsInChildren(this.gameObject, BaseUIComponent, this._buffer)) {
45
46
  const hasAlphaFactor = ch as any as IHasAlphaFactor;
46
47
  if (hasAlphaFactor.setAlphaFactor)
src/engine-components/CharacterController.ts CHANGED
@@ -1,15 +1,14 @@
1
1
  import { Quaternion, Ray, Vector2, Vector3 } from "three";
2
-
3
2
  import { Mathf } from "../engine/engine_math.js";
4
- import { RaycastOptions } from "../engine/engine_physics.js";
5
3
  import { serializable } from "../engine/engine_serialization.js";
6
- import { getWorldPosition } from "../engine/engine_three_utils.js";
7
4
  import { Collision } from "../engine/engine_types.js";
8
- import { getParam } from "../engine/engine_utils.js";
9
- import { Animator } from "./Animator.js"
10
5
  import { CapsuleCollider } from "./Collider.js";
11
6
  import { Behaviour, GameObject } from "./Component.js";
12
7
  import { Rigidbody } from "./RigidBody.js";
8
+ import { Animator } from "./Animator.js"
9
+ import { RaycastOptions } from "../engine/engine_physics.js";
10
+ import { getWorldPosition } from "../engine/engine_three_utils.js";
11
+ import { getParam } from "../engine/engine_utils.js";
13
12
 
14
13
  const debug = getParam("debugcharactercontroller");
15
14
 
src/engine-components/postprocessing/Effects/ChromaticAberration.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ChromaticAberrationEffect } from "postprocessing";
2
2
  import { Vector2 } from "three";
3
-
4
3
  import { serializable } from "../../../engine/engine_serialization.js";
5
4
  import { type EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect.js";
6
5
  import { VolumeParameter } from "../VolumeParameter.js";
src/engine-components/Collider.ts CHANGED
@@ -1,14 +1,13 @@
1
+ import { Behaviour } from "./Component.js";
2
+ import { Rigidbody } from "./RigidBody.js";
3
+ import { serializable } from "../engine/engine_serialization_decorator.js";
1
4
  import { Group, Mesh, Vector3 } from "three"
2
-
3
- import type { PhysicsMaterial } from "../engine/engine_physics.types.js";
4
- import { serializable } from "../engine/engine_serialization_decorator.js";
5
- import { getWorldScale } from "../engine/engine_three_utils.js";
6
5
  // import { IColliderProvider, registerColliderProvider } from "../engine/engine_physics.js";
7
6
  import type { IBoxCollider, ICollider, ISphereCollider } from "../engine/engine_types.js";
7
+ import { getWorldScale } from "../engine/engine_three_utils.js";
8
+ import type { PhysicsMaterial } from "../engine/engine_physics.types.js";
8
9
  import { validate } from "../engine/engine_util_decorator.js";
9
10
  import { unwatchWrite, watchWrite } from "../engine/engine_utils.js";
10
- import { Behaviour } from "./Component.js";
11
- import { Rigidbody } from "./RigidBody.js";
12
11
 
13
12
 
14
13
  export class Collider extends Behaviour implements ICollider {
@@ -106,14 +105,8 @@
106
105
  onEnable() {
107
106
  super.onEnable();
108
107
  this.context.physics.engine?.addBoxCollider(this, this.size);
109
- watchWrite(this.gameObject.scale, this.updateProperties);
110
108
  }
111
109
 
112
- onDisable(): void {
113
- super.onDisable();
114
- unwatchWrite(this.gameObject.scale, this.updateProperties);
115
- }
116
-
117
110
  onValidate(): void {
118
111
  this.updateProperties();
119
112
  }
src/engine-components/postprocessing/Effects/ColorAdjustments.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  import { BrightnessContrastEffect, HueSaturationEffect } from "postprocessing";
2
- import { LinearToneMapping, NoToneMapping } from "three";
3
-
4
2
  import { serializable } from "../../../engine/engine_serialization.js";
5
3
  import { type EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect.js";
6
4
  import { VolumeParameter } from "../VolumeParameter.js";
7
5
  import { registerCustomEffectType } from "../VolumeProfile.js";
6
+ import { LinearToneMapping, NoToneMapping } from "three";
8
7
 
9
8
 
10
9
  export class ColorAdjustments extends PostProcessingEffect {
src/engine-components/Component.ts CHANGED
@@ -1,17 +1,15 @@
1
- import { Euler, Object3D, Quaternion, Scene, Vector3 } from "three";
2
-
3
- import { isDevEnvironment } from "../engine/debug/index.js";
4
- import { addNewComponent, destroyComponentInstance, findObjectOfType, findObjectsOfType, getComponent, getComponentInChildren, getComponentInParent, getComponents, getComponentsInChildren, getComponentsInParent, getOrAddComponent, moveComponentInstance, removeComponent } from "../engine/engine_components.js";
1
+ import { Mathf } from "../engine/engine_math.js";
2
+ import * as threeutils from "../engine/engine_three_utils.js";
5
3
  import { activeInHierarchyFieldName } from "../engine/engine_constants.js";
6
- import { destroy, findByGuid, foreachComponent, HideFlags, IInstantiateOptions, instantiate, isActiveInHierarchy, isActiveSelf, isDestroyed, isUsingInstancing, markAsInstancedRendered, setActive } from "../engine/engine_gameobject.js";
4
+ import { Context, FrameEvent } from "../engine/engine_setup.js";
7
5
  import * as main from "../engine/engine_mainloop_utils.js";
8
6
  import { syncDestroy, syncInstantiate } from "../engine/engine_networking_instantiate.js";
9
- import { Context, FrameEvent } from "../engine/engine_setup.js";
10
- import * as threeutils from "../engine/engine_three_utils.js";
11
- import type { Collision, Constructor, ConstructorConcrete, GuidsMap, ICollider, IComponent, IGameObject, SourceIdentifier } from "../engine/engine_types.js";
12
- import { INeedleXRSessionEventReceiver, NeedleXRControllerEventArgs, NeedleXREventArgs } from "../engine/engine_xr.js";
13
- import { IPointerEventHandler, PointerEventData } from "./ui/PointerEvents.js";
7
+ import type { ConstructorConcrete, SourceIdentifier, IComponent, IGameObject, Constructor, GuidsMap, Collision, ICollider } from "../engine/engine_types.js";
8
+ import { addNewComponent, destroyComponentInstance, findObjectOfType, findObjectsOfType, getComponent, getComponentInChildren, getComponentInParent, getComponents, getComponentsInChildren, getComponentsInParent, getOrAddComponent, moveComponentInstance, removeComponent } from "../engine/engine_components.js";
9
+ import { findByGuid, destroy, InstantiateOptions, instantiate, HideFlags, foreachComponent, markAsInstancedRendered, isActiveInHierarchy, isActiveSelf, isUsingInstancing, setActive, isDestroyed, IInstantiateOptions } from "../engine/engine_gameobject.js";
14
10
 
11
+ import { Euler, Object3D, Quaternion, Scene, Vector3 } from "three";
12
+ import { showBalloonWarning, isDevEnvironment } from "../engine/debug/index.js";
15
13
 
16
14
  // export interface ISerializationCallbackReceiver {
17
15
  // onBeforeSerialize?(): object | void;
@@ -83,8 +81,8 @@
83
81
  * @param instance object to instantiate
84
82
  * @param opts options for the instantiation (e.g. with what parent, position, etc.)
85
83
  */
86
- public static instantiate(instance: GameObject | Object3D, opts: IInstantiateOptions | null = null): GameObject {
87
- return instantiate(instance, opts) as GameObject;
84
+ public static instantiate(instance: GameObject | Object3D | null, opts: IInstantiateOptions | null = null): GameObject | null {
85
+ return instantiate(instance, opts) as GameObject | null;
88
86
  }
89
87
 
90
88
  /** Destroys a object on all connected clients (if you are in a networked session)
@@ -125,7 +123,7 @@
125
123
  main.addScriptToArrays(comp, context!);
126
124
  if (comp.__internalDidAwakeAndStart) return;
127
125
  if (context!.new_script_start.includes(comp) === false) {
128
- context!.new_script_start.push(comp as Component);
126
+ context!.new_script_start.push(comp as Behaviour);
129
127
  }
130
128
  }, true);
131
129
  }
@@ -256,7 +254,7 @@
256
254
  return getComponentsInParent(go, typeName, arr);
257
255
  }
258
256
 
259
- public static getAllComponents(go: IGameObject | Object3D): Component[] {
257
+ public static getAllComponents(go: IGameObject | Object3D): Behaviour[] {
260
258
  const componentsList = go.userData?.components;
261
259
  const newList = [...componentsList];
262
260
  return newList;
@@ -296,7 +294,7 @@
296
294
  abstract set worldQuaternion(val: Quaternion);
297
295
  abstract get worldQuaternion(): Quaternion;
298
296
  abstract set worldRotation(val: Vector3);
299
- abstract get worldRotation(): Vector3;
297
+ abstract get worldRotation(): Vector3;
300
298
  abstract set worldScale(val: Vector3);
301
299
  abstract get worldScale(): Vector3;
302
300
 
@@ -307,28 +305,17 @@
307
305
 
308
306
 
309
307
 
310
- /** Needle Engine component base class. Derive from this component to implement your own using the provided lifecycle methods. Components can be added to threejs objects using `GameObject.addComponent`.
311
- *
312
- * The most common lifecycle methods are `awake`, `start`, `onEanble`, `onDisable` `update` and `onDestroy`.
313
- * XR specific callbacks include `onEnterXR`, `onLeaveXR`, `onUpdateXR`, `onControllerAdded` and `onControllerRemoved`.
314
- * To receive pointer events implement `onPointerDown`, `onPointerUp`, `onPointerEnter`, `onPointerExit` and `onPointerMove`.
315
- */
316
- export abstract class Component implements IComponent, EventTarget,
317
- Partial<INeedleXRSessionEventReceiver>,
318
- Partial<IPointerEventHandler>
319
- {
308
+ export class Component implements IComponent, EventTarget {
320
309
 
321
310
  get isComponent(): boolean { return true; }
322
311
 
323
312
  private __context: Context | undefined;
324
- /** Use the context to get access to many Needle Engine features and use physics, timing, access the camera or scene */
325
313
  get context(): Context {
326
314
  return this.__context ?? Context.Current;
327
315
  }
328
316
  set context(context: Context) {
329
317
  this.__context = context;
330
318
  }
331
- /** shorthand for `this.context.scene` */
332
319
  get scene(): Scene { return this.context.scene; }
333
320
 
334
321
  get layer(): number {
@@ -368,7 +355,7 @@
368
355
  return this.gameObject?.userData.hideFlags;
369
356
  }
370
357
 
371
- /** @returns true if the object is enabled and active in the hierarchy */
358
+
372
359
  get activeAndEnabled(): boolean {
373
360
  if (this.destroyed) return false;
374
361
  if (this.__isEnabled === false) return false;
@@ -398,27 +385,19 @@
398
385
  this.gameObject[activeInHierarchyFieldName] = val;
399
386
  }
400
387
 
401
- /** the object this component is attached to. Note that this is a threejs Object3D with some additional features */
402
388
  gameObject!: GameObject;
403
- /** the unique identifier for this component */
404
389
  guid: string = "invalid";
405
- /** holds the source identifier this object was created with/from (e.g. if it was part of a glTF file the sourceId holds the url to the glTF) */
406
390
  sourceId?: SourceIdentifier;
407
391
  // transform: Object3D = nullObject;
408
392
 
409
393
  /** called on a component with a map of old to new guids (e.g. when instantiate generated new guids and e.g. timeline track bindings needs to remape them) */
410
394
  resolveGuids?(guidsMap: GuidsMap): void;
411
395
 
412
- /** called once when the component becomes active for the first time (once per component)
413
- * This is the first callback to be called */
396
+ /** called once when the component becomes active for the first time */
414
397
  awake() { }
415
- /** called every time when the component gets enabled (this is invoked after awake and before start)
416
- * or when it becomes active in the hierarchy (e.g. if a parent object or this.gameObject gets set to visible)
417
- */
398
+ /** called every time when the component gets enabled (this is invoked after awake and before start) */
418
399
  onEnable() { }
419
- /** called every time the component gets disabled or if a parent object (or this.gameObject) gets set to invisible */
420
400
  onDisable() { }
421
- /** Called when the component gets destroyed */
422
401
  onDestroy() {
423
402
  this.__destroyed = true;
424
403
  }
@@ -430,17 +409,11 @@
430
409
  /** Called for all scripts when the context gets paused or unpaused */
431
410
  onPausedChanged?(isPaused: boolean, wasPaused: boolean): void;
432
411
 
433
- /** called at the beginning of a frame (once per component) */
434
412
  start?(): void;
435
- /** first callback in a frame (called every frame when implemented) */
436
413
  earlyUpdate?(): void;
437
- /** regular callback in a frame (called every frame when implemented) */
438
414
  update?(): void;
439
- /** late callback in a frame (called every frame when implemented) */
440
415
  lateUpdate?(): void;
441
- /** called before the scene gets rendered in the main update loop */
442
416
  onBeforeRender?(frame: XRFrame | null): void;
443
- /** called after the scene was rendered */
444
417
  onAfterRender?(): void;
445
418
 
446
419
  onCollisionEnter?(col: Collision);
@@ -451,79 +424,18 @@
451
424
  onTriggerStay?(col: ICollider);
452
425
  onTriggerExit?(col: ICollider);
453
426
 
454
-
455
- /** Optional callback, you can implement this to only get callbacks for VR or AR sessions if necessary.
456
- * @returns true if the mode is supported (if false the mode is not supported by this component and it will not receive XR callbacks for this mode)
457
- */
458
- supportsXR?(mode: XRSessionMode): boolean;
459
- /** Called before the XR session is requested. Use this callback if you want to modify the session init features */
460
- onBeforeXR?(mode: XRSessionMode, args: XRSessionInit): void;
461
- /** Callback when this component joins a xr session (or becomes active in a running XR session) */
462
- onEnterXR?(args: NeedleXREventArgs): void;
463
- /** Callback when a xr session updates (while it is still active in XR session) */
464
- onUpdateXR?(args: NeedleXREventArgs): void;
465
- /** Callback when this component exists a xr session (or when it becomes inactive in a running XR session) */
466
- onLeaveXR?(args: NeedleXREventArgs): void;
467
- /** Callback when a controller is connected/added while in a XR session
468
- * OR when the component joins a running XR session that has already connected controllers
469
- * OR when the component becomes active during a running XR session that has already connected controllers */
470
- onXRControllerAdded?(args: NeedleXRControllerEventArgs): void;
471
- /** callback when a controller is removed while in a XR session
472
- * OR when the component becomes inactive during a running XR session
473
- */
474
- onXRControllerRemoved?(args: NeedleXRControllerEventArgs): void;
475
-
476
-
477
- /* IPointerEventReceiver */
478
- /* @inheritdoc */
479
- onPointerEnter?(args: PointerEventData);
480
- onPointerMove?(args: PointerEventData);
481
- onPointerExit?(args: PointerEventData);
482
- onPointerDown?(args: PointerEventData);
483
- onPointerUp?(args: PointerEventData);
484
- onPointerClick?(args: PointerEventData);
485
-
486
-
487
- /** starts a coroutine (javascript generator function)
488
- * `yield` will wait for the next frame:
489
- * - Use `yield WaitForSeconds(1)` to wait for 1 second.
490
- * - Use `yield WaitForFrames(10)` to wait for 10 frames.
491
- * - Use `yield new Promise(...)` to wait for a promise to resolve.
492
- * @param routine generator function to start
493
- * @param evt event to register the coroutine for (default: FrameEvent.Update). Note that all coroutine FrameEvent callbacks are invoked after the matching regular component callbacks. For example `FrameEvent.Update` will be called after regular component `update()` methods)
494
- * @returns the generator function (use it to stop the coroutine with `stopCoroutine`)
495
- * @example
496
- * ```ts
497
- * onEnable() { this.startCoroutine(this.myCoroutine()); }
498
- * private *myCoroutine() {
499
- * while(this.activeAndEnabled) {
500
- * console.log("Hello World", this.context.time.frame);
501
- * // wait for 5 frames
502
- * for(let i = 0; i < 5; i++) yield;
503
- * }
504
- * }
505
- * ```
506
- */
507
427
  startCoroutine(routine: Generator, evt: FrameEvent = FrameEvent.Update): Generator {
508
428
  return this.context.registerCoroutineUpdate(this, routine, evt);
509
429
  }
510
- /**
511
- * Stop a coroutine that was previously started with `startCoroutine`
512
- * @param routine the routine to be stopped
513
- * @param evt the frame event to unregister the routine from (default: FrameEvent.Update)
514
- */
430
+
515
431
  stopCoroutine(routine: Generator, evt: FrameEvent = FrameEvent.Update): void {
516
432
  this.context.unregisterCoroutineUpdate(routine, evt);
517
433
  }
518
434
 
519
- /** @returns true if this component was destroyed (`this.destroy()`) or the whole object this component was part of */
520
435
  public get destroyed(): boolean {
521
436
  return this.__destroyed;
522
437
  }
523
438
 
524
- /**
525
- * Destroys this component (and removes it from the object)
526
- */
527
439
  public destroy() {
528
440
  if (this.__destroyed) return;
529
441
  this.__internalDestroy();
@@ -552,11 +464,7 @@
552
464
 
553
465
  /** @internal */
554
466
  constructor() {
555
- this.__didAwake = false;
556
- this.__didStart = false;
557
- this.__didEnable = false;
558
- this.__isEnabled = undefined;
559
- this.__destroyed = false;
467
+ this.__internalNewInstanceCreated();
560
468
  }
561
469
 
562
470
 
@@ -758,6 +666,5 @@
758
666
  }
759
667
  }
760
668
 
761
- // For legacy reasons we need to export this as well
762
- // (and we don't use extend to inherit the component docs)
763
- export { Component as Behaviour };
669
+ export class Behaviour extends Component {
670
+ }
src/engine-components/codegen/components.ts CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint-disable */
2
1
  // Export types
3
2
  export class __Ignore {}
4
3
  export { ActionBuilder } from "../export/usdz/extensions/behavior/BehavioursBuilder.js";
@@ -12,11 +11,11 @@
12
11
  export { Animator } from "../Animator.js";
13
12
  export { AnimatorController } from "../AnimatorController.js";
14
13
  export { Antialiasing } from "../postprocessing/Effects/Antialiasing.js";
14
+ export { AttachedObject } from "../webxr/WebXRController.js";
15
15
  export { AudioExtension } from "../export/usdz/extensions/behavior/AudioExtension.js";
16
16
  export { AudioListener } from "../AudioListener.js";
17
17
  export { AudioSource } from "../AudioSource.js";
18
18
  export { AudioTrackHandler } from "../timeline/TimelineTracks.js";
19
- export { Avatar } from "../webxr/Avatar.js";
20
19
  export { Avatar_Brain_LookAt } from "../avatar/Avatar_Brain_LookAt.js";
21
20
  export { Avatar_MouthShapes } from "../avatar/Avatar_MouthShapes.js";
22
21
  export { Avatar_MustacheShake } from "../avatar/Avatar_MustacheShake.js";
@@ -31,6 +30,7 @@
31
30
  export { BasicIKConstraint } from "../BasicIKConstraint.js";
32
31
  export { BehaviorExtension } from "../export/usdz/extensions/behavior/Behaviour.js";
33
32
  export { BehaviorModel } from "../export/usdz/extensions/behavior/BehavioursBuilder.js";
33
+ export { Behaviour } from "../Component.js";
34
34
  export { Bloom } from "../postprocessing/Effects/Bloom.js";
35
35
  export { BoxCollider } from "../Collider.js";
36
36
  export { BoxGizmo } from "../Gizmos.js";
@@ -51,6 +51,7 @@
51
51
  export { ColorAdjustments } from "../postprocessing/Effects/ColorAdjustments.js";
52
52
  export { ColorBySpeedModule } from "../ParticleSystemModules.js";
53
53
  export { ColorOverLifetimeModule } from "../ParticleSystemModules.js";
54
+ export { Component } from "../Component.js";
54
55
  export { ContactShadows } from "../ContactShadows.js";
55
56
  export { ControlTrackHandler } from "../timeline/TimelineTracks.js";
56
57
  export { CustomBranding } from "../export/usdz/USDZExporter.js";
@@ -87,6 +88,7 @@
87
88
  export { Image } from "../ui/Image.js";
88
89
  export { InheritVelocityModule } from "../ParticleSystemModules.js";
89
90
  export { InputField } from "../ui/InputField.js";
91
+ export { Interactable } from "../Interactable.js";
90
92
  export { Light } from "../Light.js";
91
93
  export { LimitVelocityOverLifetimeModule } from "../ParticleSystemModules.js";
92
94
  export { LODGroup } from "../LODGroup.js";
@@ -100,7 +102,6 @@
100
102
  export { MeshRenderer } from "../Renderer.js";
101
103
  export { MinMaxCurve } from "../ParticleSystemModules.js";
102
104
  export { MinMaxGradient } from "../ParticleSystemModules.js";
103
- export { NeedleWebXRHtmlElement } from "../webxr/WebXRButtons.js";
104
105
  export { NestedGltf } from "../NestedGltf.js";
105
106
  export { Networking } from "../Networking.js";
106
107
  export { NoiseModule } from "../ParticleSystemModules.js";
@@ -124,6 +125,7 @@
124
125
  export { PreliminaryAction } from "../export/usdz/extensions/behavior/BehaviourComponents.js";
125
126
  export { PreliminaryTrigger } from "../export/usdz/extensions/behavior/BehaviourComponents.js";
126
127
  export { RawImage } from "../ui/Image.js";
128
+ export { Raycaster } from "../ui/Raycaster.js";
127
129
  export { Rect } from "../ui/RectTransform.js";
128
130
  export { RectTransform } from "../ui/RectTransform.js";
129
131
  export { ReflectionProbe } from "../ReflectionProbe.js";
@@ -151,7 +153,6 @@
151
153
  export { SizeOverLifetimeModule } from "../ParticleSystemModules.js";
152
154
  export { SkinnedMeshRenderer } from "../Renderer.js";
153
155
  export { SmoothFollow } from "../SmoothFollow.js";
154
- export { SpatialGrabRaycaster } from "../ui/Raycaster.js";
155
156
  export { SpatialHtml } from "../ui/SpatialHtml.js";
156
157
  export { SpatialTrigger } from "../SpatialTrigger.js";
157
158
  export { SpatialTriggerReceiver } from "../SpatialTrigger.js";
@@ -166,7 +167,7 @@
166
167
  export { SyncedRoom } from "../SyncedRoom.js";
167
168
  export { SyncedTransform } from "../SyncedTransform.js";
168
169
  export { TapGestureTrigger } from "../export/usdz/extensions/behavior/BehaviourComponents.js";
169
- export { TeleportTarget } from "../webxr/TeleportTarget.js";
170
+ export { TeleportTarget } from "../webxr/WebXRController.js";
170
171
  export { TestRunner } from "../TestRunner.js";
171
172
  export { TestSimulateUserData } from "../TestRunner.js";
172
173
  export { Text } from "../ui/Text.js";
@@ -196,16 +197,20 @@
196
197
  export { Volume } from "../postprocessing/Volume.js";
197
198
  export { VolumeParameter } from "../postprocessing/VolumeParameter.js";
198
199
  export { VolumeProfile } from "../postprocessing/VolumeProfile.js";
200
+ export { VRUserState } from "../webxr/WebXRSync.js";
201
+ export { WebAR } from "../webxr/WebXR.js";
199
202
  export { WebARCameraBackground } from "../webxr/WebARCameraBackground.js";
200
203
  export { WebARSessionRoot } from "../webxr/WebARSessionRoot.js";
201
204
  export { WebXR } from "../webxr/WebXR.js";
205
+ export { WebXRAvatar } from "../webxr/WebXRAvatar.js";
206
+ export { WebXRController } from "../webxr/WebXRController.js";
202
207
  export { WebXRImageTracking } from "../webxr/WebXRImageTracking.js";
203
208
  export { WebXRImageTrackingModel } from "../webxr/WebXRImageTracking.js";
204
209
  export { WebXRPlaneTracking } from "../webxr/WebXRPlaneTracking.js";
210
+ export { WebXRSync } from "../webxr/WebXRSync.js";
205
211
  export { WebXRTrackedImage } from "../webxr/WebXRImageTracking.js";
206
- export { XRControllerFollow } from "../webxr/controllers/XRControllerFollow.js";
207
- export { XRControllerModel } from "../webxr/controllers/XRControllerModel.js";
208
- export { XRControllerMovement } from "../webxr/controllers/XRControllerMovement.js";
209
- export { XRFlag } from "../webxr/XRFlag.js";
212
+ export { XRFlag } from "../XRFlag.js";
213
+ export { XRGrabModel } from "../webxr/WebXRGrabRendering.js";
214
+ export { XRGrabRendering } from "../webxr/WebXRGrabRendering.js";
210
215
  export { XRRig } from "../webxr/WebXRRig.js";
211
- export { XRState } from "../webxr/XRFlag.js";
216
+ export { XRState } from "../XRFlag.js";
src/engine-components/ContactShadows.ts CHANGED
@@ -1,11 +1,11 @@
1
+ import { Behaviour } from "./Component.js";
2
+ import { serializable } from "../engine/engine_serialization_decorator.js";
3
+
1
4
  import { CustomBlending, DoubleSide, Group, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MinEquation, OrthographicCamera, PlaneGeometry, ShaderMaterial, WebGLRenderTarget } from "three";
2
5
  import { HorizontalBlurShader } from 'three/examples/jsm/shaders/HorizontalBlurShader.js';
3
6
  import { VerticalBlurShader } from 'three/examples/jsm/shaders/VerticalBlurShader.js';
4
-
5
- import { serializable } from "../engine/engine_serialization_decorator.js";
6
7
  import { getParam } from "../engine/engine_utils.js"
7
8
  import { setCustomVisibility } from "../engine/js-extensions/Layers.js";
8
- import { Behaviour } from "./Component.js";
9
9
 
10
10
  const debug = getParam("debugcontactshadows");
11
11
 
src/engine/debug/debug_console.ts CHANGED
@@ -1,7 +1,6 @@
1
+ import { getErrorCount } from "./debug_overlay.js";
2
+ import { getParam, isMobileDevice } from "../engine_utils.js";
1
3
  import { isLocalNetwork } from "../engine_networking_utils.js";
2
- import { getParam, isMobileDevice, isQuest } from "../engine_utils.js";
3
- import { isDevEnvironment } from "./debug.js";
4
- import { getErrorCount, makeErrorsVisibleForDevelopment } from "./debug_overlay.js";
5
4
 
6
5
  let consoleInstance: any = null;
7
6
  let consoleHtmlElement: HTMLElement | null = null;
@@ -23,11 +22,8 @@
23
22
  currentUrl.searchParams.set("console", "1");
24
23
  console.log("🌵 Tip: You can add the \"?console\" query parameter to the url to show the debug console (on mobile it will automatically open in the bottom right corner when your get errors during development)", "\nOpen this page console: " + currentUrl.toString());
25
24
  }
26
- const isMobile = isMobileDevice() || (isQuest() && isDevEnvironment());
25
+ const isMobile = isMobileDevice();
27
26
  if (isMobile) {
28
- // we need to invoke this here - otherwise we will miss errors that happen after the console is loaded
29
- // and calling the method from the root needle-engine.ts import is evaluated later (if we import the method from the toplevel file and then invoke it)
30
- makeErrorsVisibleForDevelopment();
31
27
  beginWatchingLogs();
32
28
  createConsole(true);
33
29
  if (isMobile) {
@@ -195,7 +191,7 @@
195
191
  }
196
192
  `;
197
193
  consoleHtmlElement?.prepend(styles);
198
- if (startHidden === true && getErrorCount() <= 0)
194
+ if (startHidden === true)
199
195
  hideDebugConsole();
200
196
  console.log("🌵 Debug console has loaded");
201
197
  }
src/engine/debug/debug_overlay.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { getParam } from "../engine_utils.js";
2
+ import { isLocalNetwork } from "../engine_networking_utils.js";
1
3
  import { ContextRegistry } from "../engine_context_registry.js";
2
- import { isLocalNetwork } from "../engine_networking_utils.js";
3
- import { getParam } from "../engine_utils.js";
4
4
 
5
5
  const debug = getParam("debugdebug");
6
6
  let hide = false;
@@ -15,7 +15,7 @@
15
15
  }
16
16
 
17
17
  export function getErrorCount() {
18
- return _errorCount;
18
+ return errorCount;
19
19
  }
20
20
 
21
21
  const originalConsoleError = console.error;
@@ -37,10 +37,9 @@
37
37
  if (hide) return;
38
38
  const isLocal = isLocalNetwork();
39
39
  if (debug) console.log("Is this a local network?", isLocal);
40
- if (isLocal)
41
- {
40
+ if (isLocal) {
42
41
  if (debug)
43
- console.warn("Patch console", window.location.hostname);
42
+ console.log(window.location.hostname);
44
43
  console.error = patchedConsoleError;
45
44
  window.addEventListener("error", (event) => {
46
45
  if (hide) return;
@@ -67,10 +66,10 @@
67
66
  }
68
67
 
69
68
 
70
- let _errorCount = 0;
69
+ let errorCount = 0;
71
70
 
72
71
  function onReceivedError() {
73
- _errorCount += 1;
72
+ errorCount += 1;
74
73
  }
75
74
 
76
75
  function onParseError(args: Array<any>) {
src/engine/debug/debug.ts CHANGED
@@ -1,13 +1,10 @@
1
+ import { addLog, LogType, setAllowOverlayMessages } from "./debug_overlay.js";
2
+ import { showDebugConsole } from "./debug_console.js";
1
3
  import { isLocalNetwork } from "../engine_networking_utils.js";
2
- import { getParam } from "../engine_utils.js";
3
- import { showDebugConsole } from "./debug_console.js";
4
- import { addLog, LogType, setAllowOverlayMessages } from "./debug_overlay.js";
5
4
 
6
5
  export { showDebugConsole }
7
6
  export { LogType, setAllowOverlayMessages };
8
7
 
9
- const noDevLogs = getParam("nodevlogs");
10
-
11
8
  /** Displays a debug message on screen for a certain amount of time */
12
9
  export function showBalloonMessage(text: string, logType: LogType = LogType.Log): void {
13
10
  addLog(logType, text);
@@ -25,7 +22,6 @@
25
22
 
26
23
  /** True when the application runs on a local url */
27
24
  export function isDevEnvironment(): boolean {
28
- if (noDevLogs) return false;
29
25
  if (_manuallySetDevEnvironment !== undefined) return _manuallySetDevEnvironment;
30
26
  return isLocalNetwork();
31
27
  }
src/engine-components/DeleteBox.ts CHANGED
@@ -1,6 +1,5 @@
1
1
 
2
2
  import * as THREE from "three";
3
-
4
3
  import { syncDestroy } from "../engine/engine_networking_instantiate.js";
5
4
  import { getParam } from "../engine/engine_utils.js";
6
5
  import { BoxHelperComponent } from "./BoxHelperComponent.js";
src/engine-components/postprocessing/Effects/DepthOfField.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { DepthOfFieldEffect } from "postprocessing";
2
-
2
+ import { serializable } from "../../../engine/engine_serialization.js";
3
3
  import { Mathf } from "../../../engine/engine_math.js";
4
- import { serializable } from "../../../engine/engine_serialization.js";
5
4
  import { getParam, isMobileDevice } from "../../../engine/engine_utils.js";
6
5
  import { PostProcessingEffect } from "../PostProcessingEffect.js";
7
6
  import { VolumeParameter } from "../VolumeParameter.js";
src/engine-components/DeviceFlag.ts CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
+ import { isMobileDevice } from "../engine/engine_utils.js";
2
3
  import { serializable } from "../engine/engine_serialization_decorator.js";
3
- import { isMobileDevice } from "../engine/engine_utils.js";
4
4
  import { Behaviour, GameObject } from "./Component.js";
5
5
 
6
6
 
src/engine-components/DragControls.ts CHANGED
@@ -1,126 +1,104 @@
1
- import { AxesHelper, Box3, BufferGeometry, Camera, Color, Event, Line, LineBasicMaterial, Matrix3, Matrix4, Mesh, MeshBasicMaterial, Object3D, Plane, PlaneHelper, Quaternion, Ray, Raycaster, SphereGeometry, Vector3 } from "three";
2
-
3
- import { Gizmos } from "../engine/engine_gizmos.js";
4
- import { InstancingUtil } from "../engine/engine_instancing.js";
5
- import { Mathf } from "../engine/engine_math.js";
1
+ import { GameObject } from "./Component.js";
2
+ import { SyncedTransform } from "./SyncedTransform.js";
3
+ import type { IPointerDownHandler, IPointerEnterHandler, IPointerEventHandler, IPointerExitHandler, IPointerUpHandler, PointerEventData } from "./ui/PointerEvents.js";
4
+ import { Context } from "../engine/engine_setup.j