@needle-tools/engine 5.1.0-canary.fbdfce3 → 5.1.0-experimental.03e8105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/SKILL.md +4 -1
  3. package/components.needle.json +1 -1
  4. package/dist/{needle-engine.bundle-BFSj2Fz8.js → needle-engine.bundle-BNqUjnSQ.js} +19180 -18386
  5. package/dist/needle-engine.bundle-Bt8ULD7E.umd.cjs +1733 -0
  6. package/dist/needle-engine.bundle-DF6ovbwD.min.js +1733 -0
  7. package/dist/needle-engine.d.ts +1487 -356
  8. package/dist/needle-engine.js +544 -542
  9. package/dist/needle-engine.min.js +1 -1
  10. package/dist/needle-engine.umd.cjs +1 -1
  11. package/dist/three.js +1 -0
  12. package/dist/three.min.js +21 -21
  13. package/dist/three.umd.cjs +16 -16
  14. package/lib/engine/api.d.ts +8 -1
  15. package/lib/engine/api.js +7 -1
  16. package/lib/engine/api.js.map +1 -1
  17. package/lib/engine/codegen/register_types.js +10 -18
  18. package/lib/engine/codegen/register_types.js.map +1 -1
  19. package/lib/engine/engine_audio.d.ts +68 -0
  20. package/lib/engine/engine_audio.js +172 -0
  21. package/lib/engine/engine_audio.js.map +1 -1
  22. package/lib/engine/engine_camera.fit.js +16 -4
  23. package/lib/engine/engine_camera.fit.js.map +1 -1
  24. package/lib/engine/engine_components.js +1 -1
  25. package/lib/engine/engine_components.js.map +1 -1
  26. package/lib/engine/engine_context.d.ts +21 -8
  27. package/lib/engine/engine_context.js +32 -16
  28. package/lib/engine/engine_context.js.map +1 -1
  29. package/lib/engine/engine_context_eventbus.d.ts +47 -0
  30. package/lib/engine/engine_context_eventbus.js +47 -0
  31. package/lib/engine/engine_context_eventbus.js.map +1 -0
  32. package/lib/engine/engine_disposable.d.ts +172 -0
  33. package/lib/engine/engine_disposable.js +136 -0
  34. package/lib/engine/engine_disposable.js.map +1 -0
  35. package/lib/engine/engine_gameobject.d.ts +1 -10
  36. package/lib/engine/engine_gameobject.js +22 -120
  37. package/lib/engine/engine_gameobject.js.map +1 -1
  38. package/lib/engine/engine_gltf_builtin_components.js +7 -69
  39. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  40. package/lib/engine/engine_init.js +7 -7
  41. package/lib/engine/engine_init.js.map +1 -1
  42. package/lib/engine/engine_input.d.ts +24 -5
  43. package/lib/engine/engine_input.js +3 -2
  44. package/lib/engine/engine_input.js.map +1 -1
  45. package/lib/engine/engine_instantiate_resolve.d.ts +42 -0
  46. package/lib/engine/engine_instantiate_resolve.js +372 -0
  47. package/lib/engine/engine_instantiate_resolve.js.map +1 -0
  48. package/lib/engine/engine_license.d.ts +7 -7
  49. package/lib/engine/engine_license.js +183 -57
  50. package/lib/engine/engine_license.js.map +1 -1
  51. package/lib/engine/engine_mainloop_utils.js +7 -4
  52. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  53. package/lib/engine/engine_networking.d.ts +51 -37
  54. package/lib/engine/engine_networking.js +132 -82
  55. package/lib/engine/engine_networking.js.map +1 -1
  56. package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
  57. package/lib/engine/engine_networking.transport.websocket.js +38 -0
  58. package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
  59. package/lib/engine/engine_networking_blob.js +4 -4
  60. package/lib/engine/engine_networking_blob.js.map +1 -1
  61. package/lib/engine/engine_networking_instantiate.js +2 -2
  62. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  63. package/lib/engine/engine_networking_types.d.ts +39 -1
  64. package/lib/engine/engine_networking_types.js +7 -0
  65. package/lib/engine/engine_networking_types.js.map +1 -1
  66. package/lib/engine/engine_physics_rapier.d.ts +21 -3
  67. package/lib/engine/engine_physics_rapier.js +94 -25
  68. package/lib/engine/engine_physics_rapier.js.map +1 -1
  69. package/lib/engine/engine_scenedata.js +2 -2
  70. package/lib/engine/engine_scenedata.js.map +1 -1
  71. package/lib/engine/engine_serialization_builtin_serializer.js +28 -5
  72. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  73. package/lib/engine/engine_serialization_core.d.ts +1 -0
  74. package/lib/engine/engine_serialization_core.js +7 -0
  75. package/lib/engine/engine_serialization_core.js.map +1 -1
  76. package/lib/engine/engine_types.d.ts +29 -11
  77. package/lib/engine/engine_types.js +1 -1
  78. package/lib/engine/engine_types.js.map +1 -1
  79. package/lib/engine/engine_util_decorator.js +7 -2
  80. package/lib/engine/engine_util_decorator.js.map +1 -1
  81. package/lib/engine/engine_utils.d.ts +1 -1
  82. package/lib/engine/engine_utils.js +19 -5
  83. package/lib/engine/engine_utils.js.map +1 -1
  84. package/lib/engine/engine_utils_qrcode.js +2 -2
  85. package/lib/engine/engine_utils_qrcode.js.map +1 -1
  86. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  87. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
  88. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
  89. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  90. package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +1 -1
  91. package/lib/engine/webcomponents/needle menu/needle-menu.js +6 -6
  92. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  93. package/lib/engine/webcomponents/needle-engine.d.ts +10 -4
  94. package/lib/engine/webcomponents/needle-engine.js +3 -3
  95. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  96. package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
  97. package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
  98. package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
  99. package/lib/engine/xr/NeedleXRSession.js +50 -14
  100. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  101. package/lib/engine/xr/TempXRContext.js +2 -2
  102. package/lib/engine/xr/TempXRContext.js.map +1 -1
  103. package/lib/engine/xr/events.d.ts +1 -1
  104. package/lib/engine/xr/events.js.map +1 -1
  105. package/lib/engine-components/Animation.js +17 -16
  106. package/lib/engine-components/Animation.js.map +1 -1
  107. package/lib/engine-components/AnimationBuilder.d.ts +158 -0
  108. package/lib/engine-components/AnimationBuilder.js +305 -0
  109. package/lib/engine-components/AnimationBuilder.js.map +1 -0
  110. package/lib/engine-components/Animator.d.ts +6 -0
  111. package/lib/engine-components/Animator.js +23 -13
  112. package/lib/engine-components/Animator.js.map +1 -1
  113. package/lib/engine-components/AnimatorController.builder.d.ts +191 -0
  114. package/lib/engine-components/AnimatorController.builder.js +263 -0
  115. package/lib/engine-components/AnimatorController.builder.js.map +1 -0
  116. package/lib/engine-components/AnimatorController.d.ts +2 -119
  117. package/lib/engine-components/AnimatorController.js +33 -232
  118. package/lib/engine-components/AnimatorController.js.map +1 -1
  119. package/lib/engine-components/AudioSource.d.ts +19 -3
  120. package/lib/engine-components/AudioSource.js +121 -68
  121. package/lib/engine-components/AudioSource.js.map +1 -1
  122. package/lib/engine-components/Collider.d.ts +18 -9
  123. package/lib/engine-components/Collider.js +61 -14
  124. package/lib/engine-components/Collider.js.map +1 -1
  125. package/lib/engine-components/Component.d.ts +72 -9
  126. package/lib/engine-components/Component.js +114 -10
  127. package/lib/engine-components/Component.js.map +1 -1
  128. package/lib/engine-components/ContactShadows.d.ts +1 -0
  129. package/lib/engine-components/ContactShadows.js +14 -1
  130. package/lib/engine-components/ContactShadows.js.map +1 -1
  131. package/lib/engine-components/DragControls.d.ts +7 -0
  132. package/lib/engine-components/DragControls.js +19 -7
  133. package/lib/engine-components/DragControls.js.map +1 -1
  134. package/lib/engine-components/DropListener.js +3 -0
  135. package/lib/engine-components/DropListener.js.map +1 -1
  136. package/lib/engine-components/EventList.d.ts +31 -9
  137. package/lib/engine-components/EventList.js +37 -76
  138. package/lib/engine-components/EventList.js.map +1 -1
  139. package/lib/engine-components/Joints.d.ts +4 -2
  140. package/lib/engine-components/Joints.js +19 -3
  141. package/lib/engine-components/Joints.js.map +1 -1
  142. package/lib/engine-components/Light.js +9 -1
  143. package/lib/engine-components/Light.js.map +1 -1
  144. package/lib/engine-components/Networking.d.ts +1 -1
  145. package/lib/engine-components/Networking.js +1 -1
  146. package/lib/engine-components/OrbitControls.d.ts +0 -2
  147. package/lib/engine-components/OrbitControls.js +30 -12
  148. package/lib/engine-components/OrbitControls.js.map +1 -1
  149. package/lib/engine-components/RigidBody.d.ts +12 -4
  150. package/lib/engine-components/RigidBody.js +18 -4
  151. package/lib/engine-components/RigidBody.js.map +1 -1
  152. package/lib/engine-components/SceneSwitcher.js +3 -0
  153. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  154. package/lib/engine-components/SeeThrough.js +2 -2
  155. package/lib/engine-components/SeeThrough.js.map +1 -1
  156. package/lib/engine-components/api.d.ts +2 -1
  157. package/lib/engine-components/api.js +2 -1
  158. package/lib/engine-components/api.js.map +1 -1
  159. package/lib/engine-components/codegen/components.d.ts +7 -13
  160. package/lib/engine-components/codegen/components.js +7 -13
  161. package/lib/engine-components/codegen/components.js.map +1 -1
  162. package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
  163. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  164. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
  165. package/lib/engine-components/timeline/PlayableDirector.d.ts +21 -11
  166. package/lib/engine-components/timeline/PlayableDirector.js +75 -67
  167. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  168. package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
  169. package/lib/engine-components/timeline/SignalAsset.js +1 -0
  170. package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
  171. package/lib/engine-components/timeline/TimelineBuilder.d.ts +413 -0
  172. package/lib/engine-components/timeline/TimelineBuilder.js +506 -0
  173. package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
  174. package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
  175. package/lib/engine-components/timeline/TimelineModels.js +3 -0
  176. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  177. package/lib/engine-components/timeline/TimelineTracks.d.ts +37 -6
  178. package/lib/engine-components/timeline/TimelineTracks.js +92 -26
  179. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  180. package/lib/engine-components/timeline/index.d.ts +2 -1
  181. package/lib/engine-components/timeline/index.js +2 -0
  182. package/lib/engine-components/timeline/index.js.map +1 -1
  183. package/lib/engine-components/ui/Canvas.d.ts +1 -1
  184. package/lib/engine-components/ui/Canvas.js +2 -8
  185. package/lib/engine-components/ui/Canvas.js.map +1 -1
  186. package/lib/engine-components/ui/Text.d.ts +1 -0
  187. package/lib/engine-components/ui/Text.js +10 -7
  188. package/lib/engine-components/ui/Text.js.map +1 -1
  189. package/lib/engine-components/web/CursorFollow.d.ts +0 -1
  190. package/lib/engine-components/web/CursorFollow.js +21 -13
  191. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  192. package/lib/engine-components/webxr/WebXRImageTracking.js +4 -0
  193. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  194. package/package.json +2 -83
  195. package/plugins/common/cloud.js +6 -1
  196. package/plugins/common/license.js +31 -10
  197. package/plugins/common/worker.js +9 -4
  198. package/plugins/vite/asap.js +17 -8
  199. package/plugins/vite/dependencies.js +29 -10
  200. package/plugins/vite/dependency-watcher.js +2 -2
  201. package/plugins/vite/editor-connection.js +3 -3
  202. package/plugins/vite/license.js +46 -7
  203. package/plugins/vite/local-files-core.js +3 -3
  204. package/plugins/vite/local-files-utils.d.ts +3 -1
  205. package/plugins/vite/local-files-utils.js +29 -5
  206. package/plugins/vite/reload.js +1 -1
  207. package/plugins/vite/server.js +2 -1
  208. package/src/engine/api.ts +11 -1
  209. package/src/engine/codegen/register_types.ts +10 -18
  210. package/src/engine/engine_audio.ts +184 -0
  211. package/src/engine/engine_camera.fit.ts +15 -4
  212. package/src/engine/engine_components.ts +1 -1
  213. package/src/engine/engine_context.ts +34 -18
  214. package/src/engine/engine_context_eventbus.ts +73 -0
  215. package/src/engine/engine_disposable.ts +214 -0
  216. package/src/engine/engine_gameobject.ts +54 -159
  217. package/src/engine/engine_gltf_builtin_components.ts +7 -76
  218. package/src/engine/engine_init.ts +7 -7
  219. package/src/engine/engine_input.ts +28 -7
  220. package/src/engine/engine_instantiate_resolve.ts +407 -0
  221. package/src/engine/engine_license.ts +197 -55
  222. package/src/engine/engine_mainloop_utils.ts +7 -4
  223. package/src/engine/engine_networking.transport.websocket.ts +45 -0
  224. package/src/engine/engine_networking.ts +161 -137
  225. package/src/engine/engine_networking_blob.ts +4 -4
  226. package/src/engine/engine_networking_instantiate.ts +2 -2
  227. package/src/engine/engine_networking_types.ts +41 -1
  228. package/src/engine/engine_physics_rapier.ts +102 -33
  229. package/src/engine/engine_scenedata.ts +3 -3
  230. package/src/engine/engine_serialization_builtin_serializer.ts +32 -9
  231. package/src/engine/engine_serialization_core.ts +9 -0
  232. package/src/engine/engine_types.ts +46 -27
  233. package/src/engine/engine_util_decorator.ts +7 -2
  234. package/src/engine/engine_utils.ts +16 -5
  235. package/src/engine/engine_utils_qrcode.ts +2 -2
  236. package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  237. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
  238. package/src/engine/webcomponents/needle menu/needle-menu.ts +6 -6
  239. package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
  240. package/src/engine/webcomponents/needle-engine.ts +12 -6
  241. package/src/engine/xr/NeedleXRSession.ts +48 -13
  242. package/src/engine/xr/TempXRContext.ts +2 -2
  243. package/src/engine/xr/events.ts +1 -1
  244. package/src/engine-components/Animation.ts +19 -16
  245. package/src/engine-components/AnimationBuilder.ts +472 -0
  246. package/src/engine-components/Animator.ts +24 -12
  247. package/src/engine-components/AnimatorController.builder.ts +387 -0
  248. package/src/engine-components/AnimatorController.ts +20 -291
  249. package/src/engine-components/AudioSource.ts +130 -79
  250. package/src/engine-components/Collider.ts +66 -18
  251. package/src/engine-components/Component.ts +118 -20
  252. package/src/engine-components/ContactShadows.ts +15 -1
  253. package/src/engine-components/DragControls.ts +18 -11
  254. package/src/engine-components/DropListener.ts +3 -0
  255. package/src/engine-components/EventList.ts +45 -83
  256. package/src/engine-components/Joints.ts +20 -4
  257. package/src/engine-components/Light.ts +10 -2
  258. package/src/engine-components/Networking.ts +1 -1
  259. package/src/engine-components/OrbitControls.ts +34 -14
  260. package/src/engine-components/RigidBody.ts +18 -4
  261. package/src/engine-components/SceneSwitcher.ts +3 -0
  262. package/src/engine-components/SeeThrough.ts +2 -2
  263. package/src/engine-components/api.ts +2 -1
  264. package/src/engine-components/codegen/components.ts +7 -13
  265. package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
  266. package/src/engine-components/timeline/PlayableDirector.ts +83 -81
  267. package/src/engine-components/timeline/SignalAsset.ts +4 -1
  268. package/src/engine-components/timeline/TimelineBuilder.ts +824 -0
  269. package/src/engine-components/timeline/TimelineModels.ts +5 -1
  270. package/src/engine-components/timeline/TimelineTracks.ts +96 -27
  271. package/src/engine-components/timeline/index.ts +2 -1
  272. package/src/engine-components/ui/Canvas.ts +2 -8
  273. package/src/engine-components/ui/Text.ts +12 -8
  274. package/src/engine-components/web/CursorFollow.ts +21 -14
  275. package/src/engine-components/webxr/WebXRImageTracking.ts +2 -0
  276. package/dist/needle-engine.bundle-CmxIO5uH.min.js +0 -1732
  277. package/dist/needle-engine.bundle-tJIZukCz.umd.cjs +0 -1732
  278. package/lib/engine-components/AvatarLoader.d.ts +0 -80
  279. package/lib/engine-components/AvatarLoader.js +0 -232
  280. package/lib/engine-components/AvatarLoader.js.map +0 -1
  281. package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
  282. package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
  283. package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
  284. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
  285. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
  286. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
  287. package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
  288. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
  289. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
  290. package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
  291. package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
  292. package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
  293. package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
  294. package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
  295. package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
  296. package/plugins/dts-generator/dts.codegen.js +0 -334
  297. package/plugins/dts-generator/dts.scan.js +0 -99
  298. package/plugins/dts-generator/dts.writer.js +0 -59
  299. package/plugins/dts-generator/glb.discovery.js +0 -279
  300. package/plugins/dts-generator/glb.extractor.js +0 -215
  301. package/plugins/dts-generator/glb.reader.js +0 -167
  302. package/plugins/dts-generator/index.js +0 -36
  303. package/plugins/dts-generator/manifest.types.js +0 -174
  304. package/plugins/gltf-packer.mjs +0 -1
  305. package/src/engine-components/AvatarLoader.ts +0 -264
  306. package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
  307. package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
  308. package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
  309. package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
  310. package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
  311. package/src/vite-env.d.ts +0 -16
@@ -1,36 +0,0 @@
1
- // @ts-check
2
- /**
3
- * Needle Engine — HTML binding DTS generator
4
- *
5
- * Scans all GLB/glTF files in the project's assets directory, extracts
6
- * NEEDLE_components data, and emits a `needle-bindings.d.ts` virtual-module
7
- * declaration so that TypeScript can type-check HTML ↔ 3D component bindings.
8
- *
9
- * Typical generated output:
10
- *
11
- * declare module "needle-bindings" {
12
- * interface SceneData {
13
- * Sphere: {
14
- * MyBall: { speed: number; label: string; };
15
- * };
16
- * }
17
- * }
18
- *
19
- * How component field types are resolved:
20
- * - For built-in Needle Engine components, types are read from
21
- * `components.needle.json` which lists only @serializable fields with
22
- * their proper TypeScript types.
23
- * - For user-defined components (not in the manifest), types are inferred
24
- * from the JSON value in the GLB (number/string/boolean → typed, else → unknown).
25
- * - Known Three.js types (Color, Vector3, Object3D, …) are emitted as
26
- * `import("three").TypeName` and known Needle types (RGBAColor, AssetReference, …)
27
- * as `import("@needle-tools/engine").TypeName`.
28
- * - Truly unknown types fall back to `unknown`.
29
- */
30
-
31
- export { resolveEntrypointGlbs, collectSceneFiles } from './glb.discovery.js';
32
- export { readGlbJsonChunk, readGltfJsonFile, readRemoteGlbJsonChunk } from './glb.reader.js';
33
- export { extractComponentBindings, sanitizeNodeName, inferNodeThreeType, inferTsType } from './glb.extractor.js';
34
- export { scanBindings } from './dts.scan.js';
35
- export { generateDts, generateHtmlCustomData } from './dts.codegen.js';
36
- export { generateBindingsDts } from './dts.writer.js';
@@ -1,174 +0,0 @@
1
- // @ts-check
2
- /**
3
- * Type tables and components.needle.json manifest loader.
4
- *
5
- * Knows about primitive TS types, known Three.js types, known Needle Engine
6
- * types, and how to resolve field types from the manifest.
7
- */
8
-
9
- import { existsSync, readFileSync } from 'fs';
10
- import { join, dirname } from 'path';
11
- import { fileURLToPath } from 'url';
12
-
13
- const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
15
-
16
- /** Primitive TS type strings that can safely appear in an ambient declaration. */
17
- export const PRIMITIVE_TYPES = new Set(["number", "string", "boolean"]);
18
-
19
- /**
20
- * Known Three.js types → import("three").TypeName
21
- * @type {Record<string, string>}
22
- */
23
- export const THREE_TYPES = {
24
- Color: `import("three").Color`,
25
- ColorRepresentation: `import("three").ColorRepresentation`,
26
- Euler: `import("three").Euler`,
27
- Texture: `import("three").Texture`,
28
- // Materials
29
- Material: `import("three").Material`,
30
- MeshStandardMaterial: `import("three").MeshStandardMaterial`,
31
- // Objects
32
- Object3D: `import("three").Object3D`,
33
- Mesh: `import("three").Mesh`,
34
- SkinnedMesh: `import("three").SkinnedMesh`,
35
- // Other
36
- Vector2: `import("three").Vector2`,
37
- Vector3: `import("three").Vector3`,
38
- Vector4: `import("three").Vector4`,
39
- Matrix3: `import("three").Matrix3`,
40
- Matrix4: `import("three").Matrix4`,
41
- Quaternion: `import("three").Quaternion`,
42
- // Animation
43
- AnimationClip: `import("three").AnimationClip`,
44
- AnimationMixer: `import("three").AnimationMixer`,
45
- };
46
-
47
- /**
48
- * Known Needle Engine types → import("@needle-tools/engine").TypeName
49
- * @type {Record<string, string>}
50
- */
51
- export const NEEDLE_TYPES = {
52
- AssetReference: `import("@needle-tools/engine").AssetReference`,
53
- EventList: `import("@needle-tools/engine").EventList`,
54
- GameObject: `import("@needle-tools/engine").GameObject`,
55
- LookAtConstraint: `import("@needle-tools/engine").LookAtConstraint`,
56
- RGBAColor: `import("@needle-tools/engine").RGBAColor`,
57
- RenderTexture: `import("@needle-tools/engine").RenderTexture`,
58
- Renderer: `import("@needle-tools/engine").Renderer`,
59
- Rigidbody: `import("@needle-tools/engine").Rigidbody`,
60
- Sprite: `import("@needle-tools/engine").Sprite`,
61
- Vec2: `import("@needle-tools/engine").Vec2`,
62
- };
63
-
64
- /**
65
- * Map a single non-array, non-primitive type token to its TS representation.
66
- * Returns null if unknown.
67
- * @param {string} token
68
- * @returns {string | null}
69
- */
70
- function mapKnownType(token) {
71
- if (token in THREE_TYPES) return THREE_TYPES[token];
72
- if (token in NEEDLE_TYPES) return NEEDLE_TYPES[token];
73
- return null;
74
- }
75
-
76
- /**
77
- * Convert a manifest type string to a safe ambient TS type.
78
- * Primitives and known Three.js/Needle types are resolved precisely.
79
- * For unknown types on a manifest component, falls back to
80
- * `import("@needle-tools/engine").ComponentName["fieldName"]`.
81
- * Truly unresolvable types → "unknown".
82
- *
83
- * @param {string} typeStr
84
- * @param {string} [componentName] The manifest component class name (enables indexed-access fallback)
85
- * @param {string} [fieldName] The field name on that component
86
- * @returns {string}
87
- */
88
- export function manifestTypeToTs(typeStr, componentName, fieldName) {
89
- const parts = typeStr.split(" | ").map(p => p.trim());
90
- const safeParts = parts.map(p => {
91
- if (p === "undefined" || p === "null") return p;
92
- const arrayMatch = p.match(/^(number|string|boolean)\[\]$/);
93
- if (arrayMatch) return p;
94
- if (PRIMITIVE_TYPES.has(p)) return p;
95
- const arrayTypeMatch = p.match(/^(\w+)\[\]$/);
96
- if (arrayTypeMatch) {
97
- const base = arrayTypeMatch[1];
98
- const mapped = mapKnownType(base);
99
- if (mapped) return `${mapped}[]`;
100
- }
101
- const known = mapKnownType(p);
102
- if (known) return known;
103
- return null;
104
- });
105
- if (safeParts.every(p => p !== null)) {
106
- return /** @type {string[]} */ (safeParts).join(" | ");
107
- }
108
- if (componentName && fieldName) {
109
- return `import("@needle-tools/engine").${componentName}["${fieldName}"]`;
110
- }
111
- return "unknown";
112
- }
113
-
114
- /**
115
- * Load components.needle.json and build a lookup:
116
- * componentName → Map<fieldName, tsType>
117
- * Inherited fields are flattened (inheritedFrom chain is resolved).
118
- *
119
- * @returns {Map<string, Map<string, string>>}
120
- */
121
- export function loadComponentsManifest() {
122
- /** @type {Map<string, Map<string, string>>} */
123
- const manifest = new Map();
124
- const manifestPath = join(__dirname, "../../components.needle.json");
125
- if (!existsSync(manifestPath)) return manifest;
126
- try {
127
- /** @type {Array<{name: string, inheritedFrom?: string, children?: Array<{name: string, kind: string, type: string}>}>} */
128
- const entries = JSON.parse(readFileSync(manifestPath, "utf8"));
129
-
130
- /** @type {Map<string, Map<string, string>>} */
131
- const ownFields = new Map();
132
- /** @type {Map<string, string>} */
133
- const inheritedFrom = new Map();
134
- for (const entry of entries) {
135
- if (!entry.name) continue;
136
- inheritedFrom.set(entry.name, entry.inheritedFrom || "");
137
- /** @type {Map<string, string>} */
138
- const fields = new Map();
139
- if (Array.isArray(entry.children)) {
140
- for (const child of entry.children) {
141
- if (child.kind === "property" && child.name && child.type) {
142
- fields.set(child.name, manifestTypeToTs(child.type, entry.name, child.name));
143
- }
144
- }
145
- }
146
- ownFields.set(entry.name, fields);
147
- }
148
-
149
- /** @param {string} name @returns {Map<string, string>} */
150
- function resolveFields(name) {
151
- if (manifest.has(name)) return /** @type {Map<string, string>} */ (manifest.get(name));
152
- const own = ownFields.get(name) ?? new Map();
153
- const parent = inheritedFrom.get(name);
154
- if (parent && ownFields.has(parent)) {
155
- const parentFields = resolveFields(parent);
156
- const merged = new Map([...parentFields, ...own]);
157
- manifest.set(name, merged);
158
- return merged;
159
- }
160
- manifest.set(name, own);
161
- return own;
162
- }
163
-
164
- for (const name of ownFields.keys()) {
165
- resolveFields(name);
166
- }
167
- } catch (e) {
168
- console.warn("[needle:dts-generator] Failed to load components.needle.json:", (/** @type {any} */ (e))?.message ?? e);
169
- }
170
- return manifest;
171
- }
172
-
173
- /** @type {Map<string, Map<string, string>>} */
174
- export const componentsManifest = loadComponentsManifest();
@@ -1 +0,0 @@
1
- console.error('ERR: this is an old version of the gltf packer, please update gltf-pack in your package.json. The pack-gltf script should now look something like this: "npm run pack-gltf --prefix node_modules/@needle-tools/engine" \nSee the ExportInfo component for more info.');
@@ -1,264 +0,0 @@
1
- import { Box3, Object3D, Vector3 } from "three";
2
- 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";
6
- import * as loaders from "../engine/engine_loaders.gltf.js"
7
- import { Context } from "../engine/engine_setup.js";
8
- import * as utils from "../engine/engine_utils.js"
9
- import { GameObject } from "./Component.js";
10
-
11
- const debug = utils.getParam("debugavatar");
12
-
13
- /**
14
- * Represents an avatar model with head and hands references.
15
- * Used for representing characters in 3D space.
16
- */
17
- export class AvatarModel {
18
- /** The root object of the avatar model */
19
- root: Object3D;
20
- /** The head object of the avatar model */
21
- head: Object3D;
22
- /** The left hand object of the avatar model, if available */
23
- leftHand: Object3D | null;
24
- /** The right hand object of the avatar model, if available */
25
- rigthHand: Object3D | null;
26
-
27
-
28
- /**
29
- * Checks if the avatar model has a valid configuration.
30
- * An avatar is considered valid if it has a head.
31
- * @returns Whether the avatar has a valid setup
32
- */
33
- get isValid(): boolean {
34
- return this.head !== null && this.head !== undefined;
35
- }
36
-
37
- /**
38
- * Creates a new avatar model.
39
- * @param root The root object of the avatar
40
- * @param head The head object of the avatar
41
- * @param leftHand The left hand object of the avatar
42
- * @param rigthHand The right hand object of the avatar
43
- */
44
- constructor(root: Object3D, head: Object3D, leftHand: Object3D | null, rigthHand: Object3D | null) {
45
- this.root = root;
46
- this.head = head;
47
- this.leftHand = leftHand;
48
- this.rigthHand = rigthHand;
49
- this.root?.traverse(h => h.layers.set(2));
50
- // this.head?.traverse(h => h.layers.set(2));
51
- // this.leftHand?.traverse(h => h.layers.set(2));
52
- // this.rigthHand?.traverse(h => h.layers.set(2));
53
- }
54
- }
55
-
56
- /**
57
- * Handles loading and instantiating avatar models from various sources.
58
- * Provides functionality to find and extract important parts of an avatar (head, hands).
59
- *
60
- * Debug mode can be enabled with the URL parameter `?debugavatar`,
61
- * which will log detailed information about avatar loading and configuration.
62
- */
63
- export class AvatarLoader {
64
-
65
- private readonly avatarRegistryUrl: string | null = null;
66
- // private loader: GLTFLoader | null;
67
- // private avatarModelCache: Map<string, AvatarModel | null> = new Map<string, AvatarModel | null>();
68
-
69
- /**
70
- * Retrieves or creates a new avatar instance from an ID or existing Object3D.
71
- * @param context The application context
72
- * @param avatarId Either a string ID to load an avatar or an existing Object3D to use as avatar
73
- * @returns Promise resolving to an AvatarModel if successful, or null if failed
74
- */
75
- public async getOrCreateNewAvatarInstance(context: Context, avatarId: string | Object3D): Promise<AvatarModel | null> {
76
-
77
- if (!avatarId) {
78
- console.error("Can not create avatar: failed to provide id or root object");
79
- return null;
80
- }
81
-
82
- let root: Object3D | null = null;
83
- if (typeof avatarId === "string") {
84
- root = await this.loadAvatar(context, avatarId);
85
- if (!root) {
86
- const opts = new InstantiateOptions();
87
- // opts.parent = context.scene.uuid;
88
- root = GameObject.instantiate(utils.tryFindObject(avatarId, context.scene) as Object3D, opts);
89
- }
90
- }
91
- else root = avatarId;
92
-
93
- if (!root) {
94
- return null;
95
- }
96
- const model = this.findAvatar(root);
97
- // model.assignRandomColors();
98
- // this.cacheModel(avatarId, model);
99
-
100
- if (model.isValid) {
101
- if (debug)
102
- console.log("[Custom Avatar] valid config", avatarId, debug ? model : "");
103
- return model;
104
- }
105
- else {
106
- console.warn("[Custom Avatar] config isn't valid", avatarId, debug ? model : "");
107
- return null;
108
- }
109
- }
110
-
111
-
112
- /**
113
- * Loads an avatar model from a file or registry using the provided ID.
114
- * @param context The engine context
115
- * @param avatarId The ID of the avatar to load
116
- * @returns Promise resolving to the loaded avatar's Object3D, or null if failed
117
- */
118
- private async loadAvatar(context: Context, avatarId: string): Promise<Object3D | null> {
119
-
120
- console.assert(avatarId !== undefined && avatarId !== null && typeof avatarId === "string", "Avatar id must not be null");
121
- if (avatarId.length <= 0) return null;
122
- if (!avatarId) return null;
123
-
124
- if (debug)
125
- console.log("[Custom Avatar] " + avatarId + ", loading...");
126
- // should probably be done by the server?!
127
- if (!avatarId.endsWith(".glb"))
128
- avatarId += ".glb";
129
-
130
-
131
- // for the demo we use the storage backend we uploaded the avatar to (by file drop)
132
- if (this.avatarRegistryUrl === null) {
133
- // try loading avatar from local file
134
- const download_res = await fetch("./" + avatarId);
135
- let bin: ArrayBuffer | null = null;
136
- if (download_res.ok) {
137
- const blob = await download_res.blob();
138
- if (blob) bin = await blob.arrayBuffer();
139
- }
140
- if (!bin) {
141
- // bin = await BlobStorage.download(avatarId, avatarId, 0, "no url here go away", true);
142
- return null;
143
- }
144
-
145
- const gltf = await getLoader().parseSync(context, bin, null!, 0);
146
- return gltf?.scene ?? null;
147
- }
148
-
149
-
150
- // if (this.avatarModelCache.has(avatarId)) {
151
- // console.log("[Custom Avatar] " + avatarId + ", found in cache");
152
- // return new Promise((res, _) => {
153
- // var model = this.avatarModelCache.get(avatarId)?.createNewInstance();
154
- // res(model);
155
- // });
156
- // }
157
- // return null;
158
-
159
- const loader = new GLTFLoader();
160
- loaders.addDracoAndKTX2Loaders(loader, context);
161
-
162
- // TODO: cache binary (fetch finary from model gallery and use binary method)
163
- return new Promise((resolve, _reject) => {
164
- const url = this.avatarRegistryUrl + "/" + avatarId;
165
- loader.load(url,
166
- async gltf => {
167
- await getLoader().createBuiltinComponents(context, url, gltf, null, undefined);
168
- resolve(gltf.scene);
169
- },
170
- progress => {
171
- if (debug)
172
- console.log("[Custom Avatar] " + (progress.loaded / progress.total * 100) + '% loaded of ' + (progress.total / 1024) + "kB");
173
- },
174
- error => {
175
- console.error("[Custom Avatar] " + "Error when loading: " + error);
176
- resolve(null);
177
- }
178
- );
179
- });
180
- }
181
-
182
- /**
183
- * Caches an avatar model for reuse.
184
- * @param _id The ID to associate with the model
185
- * @param _model The avatar model to cache
186
- */
187
- private cacheModel(_id: string, _model: AvatarModel) {
188
- // this.avatarModelCache.set(id, model);
189
- }
190
-
191
- /**
192
- * Analyzes an Object3D to find avatar parts (head, hands) based on naming conventions.
193
- * @param obj The Object3D to search for avatar parts
194
- * @returns A structured AvatarModel with references to found parts
195
- */
196
- private findAvatar(obj: Object3D): AvatarModel {
197
-
198
- const root: Object3D = obj;
199
- let searchIn = root;
200
- // some GLTFs have a "scene" root it seems, others don't, we skip the root here if there's only one child
201
- if (searchIn.children.length == 1)
202
- searchIn = obj.children[0];
203
- let head = this.findAvatarPart(searchIn, ["head"]);
204
-
205
- const leftHand = this.findAvatarPart(searchIn, ["left", "hand"]);
206
- const rightHand = this.findAvatarPart(searchIn, ["right", "hand"]);
207
-
208
- if (!head) {
209
- // very last fallback, entire root is used as head
210
- head = root;
211
-
212
- // normalize size, if the object isn't properly setup the scale might be totally off
213
- const boundsSize = new Vector3();
214
- new Box3().setFromObject(head).getSize(boundsSize);
215
- const maxAxis = Math.max(boundsSize.x, boundsSize.y, boundsSize.z);
216
- console.warn("[Custom Avatar] " + "Normalizing head scale, it's too big: " + maxAxis + " meters! Should be < 0.3m");
217
- if (maxAxis > 0.3) {
218
- head.scale.multiplyScalar(1.0 / maxAxis * 0.3);
219
- }
220
- }
221
-
222
- const model = new AvatarModel(root, head, leftHand, rightHand);
223
- return model;
224
- }
225
-
226
- /**
227
- * Recursively searches for an avatar part by name within an Object3D hierarchy.
228
- * @param obj The Object3D to search within
229
- * @param searchString Array of strings that should all be present in the object name
230
- * @returns The found Object3D part or null if not found
231
- */
232
- private findAvatarPart(obj: Object3D, searchString: string[]): Object3D | null {
233
-
234
- const name = obj.name.toLowerCase();
235
- let matchesAll = true;
236
- for (const str of searchString) {
237
- if (!matchesAll) break;
238
- if (name.indexOf(str) === -1)
239
- matchesAll = false;
240
- }
241
- if (matchesAll) return obj;
242
-
243
- if (obj.children) {
244
- for (const child of obj.children) {
245
- const found = this.findAvatarPart(child, searchString);
246
- if (found) return found;
247
- }
248
- }
249
- return null;
250
- }
251
-
252
- /**
253
- * Handles HTTP response errors from avatar loading operations.
254
- * @param response The fetch API response to check
255
- * @returns The response if it was ok
256
- * @throws Error with status text if response was not ok
257
- */
258
- private handleCustomAvatarErrors(response) {
259
- if (!response.ok) {
260
- throw Error(response.statusText);
261
- }
262
- return response;
263
- }
264
- }
@@ -1,70 +0,0 @@
1
- import { Object3D } from "three";
2
-
3
- import { serializable } from "../../engine/engine_serialization_decorator.js";
4
- import { Behaviour, GameObject } from "../Component.js";
5
- import { XRFlag } from "../webxr/XRFlag.js";
6
-
7
-
8
- /** @internal */
9
- export class AvatarBlink_Simple extends Behaviour {
10
-
11
- @serializable(Object3D)
12
- private eyes: Object3D[] = [];
13
- @serializable()
14
- private lastBlinkTime: number = 0;
15
- @serializable()
16
- private blinkLength: number = 0;
17
- @serializable()
18
- private eyesOpen: boolean = true;
19
-
20
- private state : XRFlag | null = null;
21
-
22
- awake(){
23
- this.state = GameObject.getComponentInParent(this.gameObject, XRFlag);
24
- // console.log(this.state, this.activeAndEnabled, this.gameObject);
25
- }
26
-
27
- public update() {
28
- if (!this.gameObject || !this.gameObject.visible) return;
29
- if(!this.eyes || !Array.isArray(this.eyes) || this.eyes.length === 0) return;
30
-
31
- const needsUpdate = this.context.time.time - this.lastBlinkTime > this.blinkLength;
32
-
33
- if (needsUpdate) {
34
- this.lastBlinkTime = this.context.time.time;
35
-
36
- // workaround until we propagate active state to all child components
37
- if(this.state && !this.state.isOn) return;
38
- if(!this.activeAndEnabled) return;
39
-
40
- // console.log(this.state?.isOn, this.activeAndEnabled);
41
-
42
- this.eyesOpen = !this.eyesOpen;
43
- this.blinkLength = Math.random();
44
- if (!this.eyesOpen) {
45
- this.blinkLength *= Math.random() * .2;
46
- this.blinkLength += .1;
47
- }
48
- else {
49
- // eyes are open
50
- this.blinkLength *= 3;
51
- this.blinkLength += .5;
52
- if (Math.random() < .1) this.blinkLength = .1 + Math.random() * .2;
53
- }
54
- if (Math.random() < .1) this.blinkLength *= 3;
55
-
56
- // if(time.time - this.lastMouthChangeTime < .5 && Math.random() > .5){
57
- // this.blinkLength *= 1-(100/this.lastMouthChangeFrequency);
58
- // }
59
-
60
- this.blinkLength = Math.max(.2, this.blinkLength);
61
- this.blinkLength = Math.min(3, this.blinkLength);
62
- if (this.eyes) {
63
- for (const eye of this.eyes) {
64
- if (eye)
65
- eye.visible = this.eyesOpen;
66
- }
67
- }
68
- }
69
- }
70
- }
@@ -1,64 +0,0 @@
1
- import { Object3D, Vector3 } from "three";
2
-
3
- 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
- import { Avatar_Brain_LookAt } from "./Avatar_Brain_LookAt.js";
7
-
8
- /** @internal */
9
- export class AvatarEyeLook_Rotation extends Behaviour {
10
-
11
- @serializable(Object3D)
12
- public head: GameObject | null = null;
13
- @serializable(Object3D)
14
- public eyes: GameObject[] | null = null;
15
- @serializable(Object3D)
16
- public target: Object3D | null = null;
17
-
18
- private brain: Avatar_Brain_LookAt | null = null;
19
-
20
- awake(): void {
21
- if (!this.brain) {
22
- this.brain = GameObject.getComponentInParent(this.gameObject, Avatar_Brain_LookAt);
23
- }
24
- if (!this.brain) {
25
- this.brain = GameObject.addComponent(this.gameObject, Avatar_Brain_LookAt);
26
- }
27
- if (this.brain && this.target) {
28
- this.brain.controlledTarget = this.target;
29
- }
30
- }
31
-
32
-
33
- private vec: Vector3 = new Vector3();
34
- private static forward: Vector3 = new Vector3(0, 0, 1);
35
- private currentTargetPoint: Vector3 = new Vector3();
36
-
37
- update(): void {
38
- // if(!this.activeAndEnabled) return;
39
- const target = this.target;
40
- // console.log(target);
41
- if (target && this.head) {
42
- const eyes = this.eyes;
43
- if (eyes) {
44
- const worldTarget = utils.getWorldPosition(target);
45
- this.currentTargetPoint.lerp(worldTarget, this.context.time.deltaTime / .1);
46
-
47
- const headPosition = utils.getWorldPosition(this.head);
48
- const direction = this.vec.copy(this.currentTargetPoint).sub(headPosition).normalize();
49
- if (direction.length() < .1) return;
50
- const forward = AvatarEyeLook_Rotation.forward;
51
- forward.set(0, 0, 1);
52
- forward.applyQuaternion(utils.getWorldQuaternion(this.head));
53
- const dot = forward.dot(direction);
54
- if (dot > .45) {
55
- // console.log(dot);
56
- for (let i = 0; i < eyes.length; i++) {
57
- const eye = eyes[i];
58
- eye.lookAt(this.currentTargetPoint);
59
- }
60
- }
61
- }
62
- }
63
- }
64
- }