lecodes-sdk 0.19.0

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 (367) hide show
  1. package/README.md +114 -0
  2. package/dist/global.d.ts +503 -0
  3. package/dist/host.d.ts +61 -0
  4. package/dist/inject.js +4730 -0
  5. package/dist/types/animate/animate.d.ts +20 -0
  6. package/dist/types/animate/bezier.d.ts +2 -0
  7. package/dist/types/animate/easings.d.ts +21 -0
  8. package/dist/types/canvas/Canvas.d.ts +168 -0
  9. package/dist/types/core/Aspect.d.ts +171 -0
  10. package/dist/types/core/InspectorUI.d.ts +88 -0
  11. package/dist/types/core/StateMachine.d.ts +81 -0
  12. package/dist/types/core/color.d.ts +13 -0
  13. package/dist/types/core/compWrite.d.ts +11 -0
  14. package/dist/types/core/events.d.ts +11 -0
  15. package/dist/types/core/fields.d.ts +58 -0
  16. package/dist/types/core/registry.d.ts +7 -0
  17. package/dist/types/core/signals.d.ts +29 -0
  18. package/dist/types/core/time.d.ts +31 -0
  19. package/dist/types/g2/Camera2D.d.ts +19 -0
  20. package/dist/types/g2/CharacterController2D.d.ts +134 -0
  21. package/dist/types/g2/Node2D.d.ts +91 -0
  22. package/dist/types/g2/OneWay2D.d.ts +24 -0
  23. package/dist/types/g2/Physics2D.d.ts +147 -0
  24. package/dist/types/g2/Scene2D.d.ts +72 -0
  25. package/dist/types/g2/Shape2D.d.ts +58 -0
  26. package/dist/types/g2/Sprite.d.ts +51 -0
  27. package/dist/types/g2/SpriteAnimation.d.ts +50 -0
  28. package/dist/types/g2/SpriteSheet.d.ts +69 -0
  29. package/dist/types/g2/Texture2D.d.ts +16 -0
  30. package/dist/types/g2/Tilemap.d.ts +20 -0
  31. package/dist/types/g2/Tileset.d.ts +32 -0
  32. package/dist/types/g2/Trigger2D.d.ts +20 -0
  33. package/dist/types/g2/autotile.d.ts +133 -0
  34. package/dist/types/g2/cells.d.ts +14 -0
  35. package/dist/types/g2/defineScene2d.d.ts +141 -0
  36. package/dist/types/g2/groups2d.d.ts +16 -0
  37. package/dist/types/g2/loop.d.ts +4 -0
  38. package/dist/types/g2/scenarios2d.d.ts +30 -0
  39. package/dist/types/g2/touch.d.ts +2 -0
  40. package/dist/types/gl/Camera.d.ts +79 -0
  41. package/dist/types/gl/CameraPlace.d.ts +26 -0
  42. package/dist/types/gl/CharacterController.d.ts +98 -0
  43. package/dist/types/gl/Gearbox.d.ts +86 -0
  44. package/dist/types/gl/Geometry.d.ts +39 -0
  45. package/dist/types/gl/IK.d.ts +53 -0
  46. package/dist/types/gl/InstancedMesh.d.ts +46 -0
  47. package/dist/types/gl/Light.d.ts +73 -0
  48. package/dist/types/gl/Lightmap.d.ts +85 -0
  49. package/dist/types/gl/Locomotion.d.ts +279 -0
  50. package/dist/types/gl/Material.d.ts +100 -0
  51. package/dist/types/gl/Mesh.d.ts +33 -0
  52. package/dist/types/gl/Model.d.ts +53 -0
  53. package/dist/types/gl/NavAgent.d.ts +99 -0
  54. package/dist/types/gl/NavMesh.d.ts +169 -0
  55. package/dist/types/gl/Node.d.ts +99 -0
  56. package/dist/types/gl/Noise.d.ts +20 -0
  57. package/dist/types/gl/Particles.d.ts +277 -0
  58. package/dist/types/gl/Physics.d.ts +91 -0
  59. package/dist/types/gl/Plane.d.ts +19 -0
  60. package/dist/types/gl/Ragdoll.d.ts +86 -0
  61. package/dist/types/gl/Ray.d.ts +8 -0
  62. package/dist/types/gl/Scene.d.ts +221 -0
  63. package/dist/types/gl/Shape.d.ts +122 -0
  64. package/dist/types/gl/Terrain.d.ts +280 -0
  65. package/dist/types/gl/Texture.d.ts +27 -0
  66. package/dist/types/gl/Trigger.d.ts +10 -0
  67. package/dist/types/gl/Vehicle.d.ts +191 -0
  68. package/dist/types/gl/Wheel.d.ts +95 -0
  69. package/dist/types/gl/animation/AnimationClip.d.ts +60 -0
  70. package/dist/types/gl/animation/Animator.d.ts +219 -0
  71. package/dist/types/gl/animation/Layer.d.ts +31 -0
  72. package/dist/types/gl/animation/Loop.d.ts +17 -0
  73. package/dist/types/gl/animation/Playback.d.ts +36 -0
  74. package/dist/types/gl/animation/core.d.ts +367 -0
  75. package/dist/types/gl/controls.d.ts +19 -0
  76. package/dist/types/gl/physicsEvents.d.ts +1 -0
  77. package/dist/types/gl/scenarios.d.ts +98 -0
  78. package/dist/types/gl/state.d.ts +5 -0
  79. package/dist/types/gl/terrainMesh.d.ts +46 -0
  80. package/dist/types/gl/touch.d.ts +2 -0
  81. package/dist/types/inject.d.ts +123 -0
  82. package/dist/types/math/Mathf.d.ts +39 -0
  83. package/dist/types/math/mat4.d.ts +66 -0
  84. package/dist/types/math/quat.d.ts +53 -0
  85. package/dist/types/math/vec.d.ts +129 -0
  86. package/dist/types/net/codec.d.ts +25 -0
  87. package/dist/types/net/core.d.ts +106 -0
  88. package/dist/types/net/index.d.ts +80 -0
  89. package/dist/types/net/replication.d.ts +101 -0
  90. package/dist/types/plugins/camera.d.ts +25 -0
  91. package/dist/types/plugins/geolocation.d.ts +39 -0
  92. package/dist/types/plugins/oauth.d.ts +25 -0
  93. package/dist/types/plugins/permission.d.ts +1 -0
  94. package/dist/types/plugins/push.d.ts +46 -0
  95. package/dist/types/plugins/qr.d.ts +21 -0
  96. package/dist/types/plugins/service.d.ts +33 -0
  97. package/dist/types/runtime/app.d.ts +67 -0
  98. package/dist/types/runtime/appEvents.d.ts +7 -0
  99. package/dist/types/runtime/channel.d.ts +1 -0
  100. package/dist/types/runtime/clipboard.d.ts +7 -0
  101. package/dist/types/runtime/datetime.d.ts +80 -0
  102. package/dist/types/runtime/device.d.ts +126 -0
  103. package/dist/types/runtime/fetch.d.ts +31 -0
  104. package/dist/types/runtime/files.d.ts +33 -0
  105. package/dist/types/runtime/input.d.ts +121 -0
  106. package/dist/types/runtime/media.d.ts +46 -0
  107. package/dist/types/runtime/misc.d.ts +11 -0
  108. package/dist/types/runtime/net.d.ts +15 -0
  109. package/dist/types/runtime/rpc.d.ts +44 -0
  110. package/dist/types/runtime/service.d.ts +1 -0
  111. package/dist/types/runtime/share.d.ts +2 -0
  112. package/dist/types/runtime/storage.d.ts +5 -0
  113. package/dist/types/runtime/touch.d.ts +56 -0
  114. package/dist/types/scene/defineScene.d.ts +296 -0
  115. package/dist/types/scene/editorPlugins.d.ts +82 -0
  116. package/dist/types/scene/gizmos.d.ts +56 -0
  117. package/dist/types/scene/grammar.d.ts +56 -0
  118. package/dist/types/scene/level.d.ts +98 -0
  119. package/dist/types/scene/material.d.ts +76 -0
  120. package/dist/types/server/auth/appConfig.d.ts +16 -0
  121. package/dist/types/server/auth/global.d.ts +56 -0
  122. package/dist/types/server/auth/models.d.ts +164 -0
  123. package/dist/types/server/auth/types.d.ts +56 -0
  124. package/dist/types/server/channel.d.ts +28 -0
  125. package/dist/types/server/context.d.ts +27 -0
  126. package/dist/types/server/db/defineDb.d.ts +36 -0
  127. package/dist/types/server/db/fields.d.ts +146 -0
  128. package/dist/types/server/db/index.d.ts +6 -0
  129. package/dist/types/server/db/marci/query.d.ts +326 -0
  130. package/dist/types/server/db/types.d.ts +163 -0
  131. package/dist/types/server/errors.d.ts +8 -0
  132. package/dist/types/server/inject.d.ts +5 -0
  133. package/dist/types/ui/NativeView.d.ts +38 -0
  134. package/dist/types/ui/UI.d.ts +27 -0
  135. package/dist/types/ui/UIBottomSheet.d.ts +71 -0
  136. package/dist/types/ui/UIButton.d.ts +30 -0
  137. package/dist/types/ui/UIContainer.d.ts +33 -0
  138. package/dist/types/ui/UIImage.d.ts +35 -0
  139. package/dist/types/ui/UIInput.d.ts +110 -0
  140. package/dist/types/ui/UIModal.d.ts +70 -0
  141. package/dist/types/ui/UINode.d.ts +363 -0
  142. package/dist/types/ui/UIPager.d.ts +123 -0
  143. package/dist/types/ui/UIPopover.d.ts +39 -0
  144. package/dist/types/ui/UIScreen.d.ts +57 -0
  145. package/dist/types/ui/UIScrollable.d.ts +40 -0
  146. package/dist/types/ui/UISpacer.d.ts +9 -0
  147. package/dist/types/ui/UITabs.d.ts +96 -0
  148. package/dist/types/ui/UIText.d.ts +19 -0
  149. package/dist/types/ui/UIVideo.d.ts +28 -0
  150. package/dist/types/ui/UIVirtualizedList.d.ts +97 -0
  151. package/dist/types/ui/UIWidget.d.ts +65 -0
  152. package/dist/types/ui/fonts.d.ts +9 -0
  153. package/dist/types/ui/presentable.d.ts +68 -0
  154. package/dist/types/ui/router.d.ts +40 -0
  155. package/dist/types/ui/theme.d.ts +26 -0
  156. package/dist/types.json +1 -0
  157. package/package.json +46 -0
  158. package/prompts/2d.md +395 -0
  159. package/prompts/3d-scene-files.md +113 -0
  160. package/prompts/3d-scene.md +119 -0
  161. package/prompts/3d.md +303 -0
  162. package/prompts/README.md +142 -0
  163. package/prompts/ar.md +109 -0
  164. package/prompts/canvas.md +27 -0
  165. package/prompts/compose.ts +46 -0
  166. package/prompts/concept.md +49 -0
  167. package/prompts/core-design.md +75 -0
  168. package/prompts/core.md +264 -0
  169. package/prompts/design.md +218 -0
  170. package/prompts/dist/2d-game.md +1530 -0
  171. package/prompts/dist/3d-app.md +1672 -0
  172. package/prompts/dist/ar-app.md +1548 -0
  173. package/prompts/dist/concept.md +49 -0
  174. package/prompts/dist/design.md +498 -0
  175. package/prompts/dist/ui-app.md +1134 -0
  176. package/prompts/index.md +37 -0
  177. package/prompts/intake-prompt.md +33 -0
  178. package/prompts/namer-prompt.md +12 -0
  179. package/prompts/router-prompt.md +50 -0
  180. package/prompts/select.ts +111 -0
  181. package/prompts/ui-design.md +203 -0
  182. package/prompts/ui.md +803 -0
  183. package/src/animate/animate.ts +238 -0
  184. package/src/animate/bezier.ts +138 -0
  185. package/src/animate/easings.ts +126 -0
  186. package/src/bridges.d.ts +1345 -0
  187. package/src/canvas/Canvas.ts +305 -0
  188. package/src/compile/__tests__/assetIconMacro.test.ts +219 -0
  189. package/src/compile/__tests__/assetMacro.test.ts +74 -0
  190. package/src/compile/__tests__/assetName.test.ts +55 -0
  191. package/src/compile/__tests__/compile.test.ts +287 -0
  192. package/src/compile/__tests__/detectEntry.test.ts +132 -0
  193. package/src/compile/__tests__/fontMacro.test.ts +199 -0
  194. package/src/compile/aspectMacro.ts +86 -0
  195. package/src/compile/assetIconMacro.ts +384 -0
  196. package/src/compile/assetMacro.ts +146 -0
  197. package/src/compile/assetName.ts +50 -0
  198. package/src/compile/bundler.ts +287 -0
  199. package/src/compile/compileProject.ts +127 -0
  200. package/src/compile/detectEntry.ts +128 -0
  201. package/src/compile/fontMacro.ts +459 -0
  202. package/src/compile/fontRegistry.ts +78 -0
  203. package/src/compile/header.ts +67 -0
  204. package/src/compile/index.ts +100 -0
  205. package/src/compile/libraryImports.ts +52 -0
  206. package/src/compile/liteMaterial.ts +247 -0
  207. package/src/compile/sceneEditor.ts +88 -0
  208. package/src/compile/serverSplit.ts +233 -0
  209. package/src/compile/serverTypes.ts +227 -0
  210. package/src/compile/sfnt.ts +98 -0
  211. package/src/compile/shaderSchema.ts +202 -0
  212. package/src/compile/shaderTargets.ts +77 -0
  213. package/src/compile/sourcemap.ts +25 -0
  214. package/src/core/Aspect.ts +568 -0
  215. package/src/core/InspectorUI.ts +212 -0
  216. package/src/core/StateMachine.ts +308 -0
  217. package/src/core/__tests__/stateMachine.test.ts +132 -0
  218. package/src/core/color.ts +66 -0
  219. package/src/core/compWrite.ts +42 -0
  220. package/src/core/events.ts +38 -0
  221. package/src/core/fields.ts +120 -0
  222. package/src/core/registry.ts +23 -0
  223. package/src/core/signals.ts +277 -0
  224. package/src/core/time.ts +84 -0
  225. package/src/g2/Camera2D.ts +40 -0
  226. package/src/g2/CharacterController2D.ts +276 -0
  227. package/src/g2/Node2D.ts +267 -0
  228. package/src/g2/OneWay2D.ts +66 -0
  229. package/src/g2/Physics2D.ts +346 -0
  230. package/src/g2/Scene2D.ts +209 -0
  231. package/src/g2/Shape2D.ts +259 -0
  232. package/src/g2/Sprite.ts +89 -0
  233. package/src/g2/SpriteAnimation.ts +171 -0
  234. package/src/g2/SpriteSheet.ts +166 -0
  235. package/src/g2/Texture2D.ts +47 -0
  236. package/src/g2/Tilemap.ts +41 -0
  237. package/src/g2/Tileset.ts +71 -0
  238. package/src/g2/Trigger2D.ts +77 -0
  239. package/src/g2/autotile.ts +433 -0
  240. package/src/g2/cells.ts +91 -0
  241. package/src/g2/defineScene2d.ts +381 -0
  242. package/src/g2/groups2d.ts +106 -0
  243. package/src/g2/loop.ts +50 -0
  244. package/src/g2/scenarios2d.ts +69 -0
  245. package/src/g2/touch.ts +83 -0
  246. package/src/gl/Camera.ts +160 -0
  247. package/src/gl/CameraPlace.ts +52 -0
  248. package/src/gl/CharacterController.ts +238 -0
  249. package/src/gl/Gearbox.ts +212 -0
  250. package/src/gl/Geometry.ts +279 -0
  251. package/src/gl/IK.ts +193 -0
  252. package/src/gl/InstancedMesh.ts +132 -0
  253. package/src/gl/Light.ts +135 -0
  254. package/src/gl/Lightmap.ts +402 -0
  255. package/src/gl/Locomotion.ts +498 -0
  256. package/src/gl/Material.ts +279 -0
  257. package/src/gl/Mesh.ts +83 -0
  258. package/src/gl/Model.ts +124 -0
  259. package/src/gl/NavAgent.ts +337 -0
  260. package/src/gl/NavMesh.ts +397 -0
  261. package/src/gl/Node.ts +350 -0
  262. package/src/gl/Noise.ts +30 -0
  263. package/src/gl/Particles.ts +676 -0
  264. package/src/gl/Physics.ts +222 -0
  265. package/src/gl/Plane.ts +53 -0
  266. package/src/gl/Ragdoll.ts +270 -0
  267. package/src/gl/Ray.ts +16 -0
  268. package/src/gl/Scene.ts +505 -0
  269. package/src/gl/Shape.ts +409 -0
  270. package/src/gl/Terrain.ts +1092 -0
  271. package/src/gl/Texture.ts +63 -0
  272. package/src/gl/Trigger.ts +45 -0
  273. package/src/gl/Vehicle.ts +473 -0
  274. package/src/gl/Wheel.ts +240 -0
  275. package/src/gl/animation/AnimationClip.ts +204 -0
  276. package/src/gl/animation/Animator.ts +329 -0
  277. package/src/gl/animation/Layer.ts +39 -0
  278. package/src/gl/animation/Loop.ts +31 -0
  279. package/src/gl/animation/Playback.ts +52 -0
  280. package/src/gl/animation/core.ts +670 -0
  281. package/src/gl/controls.ts +95 -0
  282. package/src/gl/physicsEvents.ts +20 -0
  283. package/src/gl/scenarios.ts +291 -0
  284. package/src/gl/state.ts +6 -0
  285. package/src/gl/terrainMesh.ts +219 -0
  286. package/src/gl/touch.ts +68 -0
  287. package/src/host.d.ts +61 -0
  288. package/src/inject.ts +203 -0
  289. package/src/math/Mathf.ts +118 -0
  290. package/src/math/mat4.ts +278 -0
  291. package/src/math/quat.ts +232 -0
  292. package/src/math/vec.ts +255 -0
  293. package/src/net/codec.ts +119 -0
  294. package/src/net/core.ts +384 -0
  295. package/src/net/index.ts +181 -0
  296. package/src/net/replication.ts +622 -0
  297. package/src/plugins/camera.ts +81 -0
  298. package/src/plugins/geolocation.ts +123 -0
  299. package/src/plugins/oauth.ts +61 -0
  300. package/src/plugins/permission.ts +7 -0
  301. package/src/plugins/push.ts +132 -0
  302. package/src/plugins/qr.ts +73 -0
  303. package/src/plugins/service.ts +47 -0
  304. package/src/runtime/app.ts +101 -0
  305. package/src/runtime/appEvents.ts +54 -0
  306. package/src/runtime/channel.ts +61 -0
  307. package/src/runtime/clipboard.ts +20 -0
  308. package/src/runtime/datetime.ts +329 -0
  309. package/src/runtime/device.ts +293 -0
  310. package/src/runtime/fetch.ts +77 -0
  311. package/src/runtime/files.ts +108 -0
  312. package/src/runtime/input.ts +175 -0
  313. package/src/runtime/media.ts +111 -0
  314. package/src/runtime/misc.ts +16 -0
  315. package/src/runtime/net.ts +36 -0
  316. package/src/runtime/rpc.ts +218 -0
  317. package/src/runtime/service.ts +83 -0
  318. package/src/runtime/share.ts +9 -0
  319. package/src/runtime/storage.ts +13 -0
  320. package/src/runtime/touch.ts +76 -0
  321. package/src/scene/defineScene.ts +1396 -0
  322. package/src/scene/editorPlugins.ts +110 -0
  323. package/src/scene/gizmos.ts +148 -0
  324. package/src/scene/grammar.ts +120 -0
  325. package/src/scene/level.ts +296 -0
  326. package/src/scene/material.ts +188 -0
  327. package/src/server/auth/appConfig.ts +12 -0
  328. package/src/server/auth/global.ts +80 -0
  329. package/src/server/auth/host.ts +318 -0
  330. package/src/server/auth/models.ts +83 -0
  331. package/src/server/auth/types.ts +50 -0
  332. package/src/server/channel.ts +56 -0
  333. package/src/server/context.ts +36 -0
  334. package/src/server/db/defineDb.ts +237 -0
  335. package/src/server/db/fields.ts +132 -0
  336. package/src/server/db/httpTransport.ts +93 -0
  337. package/src/server/db/index.ts +7 -0
  338. package/src/server/db/marci/query.ts +412 -0
  339. package/src/server/db/types.ts +202 -0
  340. package/src/server/errors.ts +12 -0
  341. package/src/server/host.ts +74 -0
  342. package/src/server/inject.ts +13 -0
  343. package/src/server/runtime.ts +133 -0
  344. package/src/server/validate.ts +87 -0
  345. package/src/ui/NativeView.ts +142 -0
  346. package/src/ui/UI.ts +39 -0
  347. package/src/ui/UIBottomSheet.ts +139 -0
  348. package/src/ui/UIButton.ts +101 -0
  349. package/src/ui/UIContainer.ts +60 -0
  350. package/src/ui/UIImage.ts +83 -0
  351. package/src/ui/UIInput.ts +185 -0
  352. package/src/ui/UIModal.ts +139 -0
  353. package/src/ui/UINode.ts +830 -0
  354. package/src/ui/UIPager.ts +362 -0
  355. package/src/ui/UIPopover.ts +100 -0
  356. package/src/ui/UIScreen.ts +123 -0
  357. package/src/ui/UIScrollable.ts +87 -0
  358. package/src/ui/UISpacer.ts +14 -0
  359. package/src/ui/UITabs.ts +236 -0
  360. package/src/ui/UIText.ts +51 -0
  361. package/src/ui/UIVideo.ts +88 -0
  362. package/src/ui/UIVirtualizedList.ts +241 -0
  363. package/src/ui/UIWidget.ts +127 -0
  364. package/src/ui/fonts.ts +13 -0
  365. package/src/ui/presentable.ts +117 -0
  366. package/src/ui/router.ts +132 -0
  367. package/src/ui/theme.ts +84 -0
@@ -0,0 +1,280 @@
1
+ import { Node } from "./Node";
2
+ import { Material } from "./Material";
3
+ import { Texture } from "./Texture";
4
+ import { Geometry } from "./Geometry";
5
+ import { type ColorInput } from "../core/color";
6
+ import { Vec3, type Vec3Like } from "../math/vec";
7
+ export type TerrainLayer = {
8
+ /** Albedo texture (a URL / `asset()` handle, or a loaded Texture). Unset = white. */
9
+ albedo?: string | Texture;
10
+ /** Metres per texture repeat. Default 8. */
11
+ tiling?: number;
12
+ /** Perceptual roughness of the layer. Default 1. */
13
+ roughness?: number;
14
+ /** Normal-map strength (0 = the layer's slot of the pack is not read). Default 0 — set 1 when the
15
+ * layer has a normal map in `normals`. */
16
+ normalScale?: number;
17
+ /** Sample this layer triplanar in world space (cliff rock): no stretching on steep slopes; its
18
+ * normal map is then skipped. Default false. */
19
+ triplanar?: boolean;
20
+ };
21
+ export type TerrainOptions = {
22
+ /** Samples per side (square). 257 / 513 / 1025 are the usual sizes. Default 129. */
23
+ size?: number;
24
+ sizeX?: number;
25
+ sizeZ?: number;
26
+ /** Metres between samples. Default 1. */
27
+ cellSize?: number;
28
+ /** Cells per chunk side (≤ 255). Default 64. */
29
+ chunk?: number;
30
+ /** Heights in metres: an array of sizeX × sizeZ (row-major, z rows), or a function of the sample's
31
+ * LOCAL position in metres. Default flat 0. */
32
+ heights?: Float32Array | ((x: number, z: number) => number);
33
+ /** A byte per sample, 1 = hole (a triangle needs its three samples valid). */
34
+ holes?: Uint8Array;
35
+ /** RGBA layer weights per sample (normalised in the shader). Default: all layer 0. */
36
+ control?: Uint8Array;
37
+ layers?: TerrainLayer[];
38
+ /** The two normal-map packs: `[layers 0+1, layers 2+3]` — XY of the even layer in RG, the odd in BA. */
39
+ normals?: [string | Texture | undefined, (string | Texture)?];
40
+ /** Multiplier on every layer's albedo. */
41
+ tint?: ColorInput;
42
+ name?: string;
43
+ /** A material to use instead of `Material.terrain()` (a custom terrain shader with the same uniforms). */
44
+ material?: Material;
45
+ };
46
+ /** A region of the terrain in LOCAL metres (XZ). `node` = the XZ footprint of a node's triangles. */
47
+ export type TerrainRegion = {
48
+ circle: {
49
+ x: number;
50
+ z: number;
51
+ r: number;
52
+ };
53
+ } | {
54
+ rect: {
55
+ x: number;
56
+ z: number;
57
+ w: number;
58
+ h: number;
59
+ };
60
+ } | {
61
+ polygon: readonly (readonly [number, number])[];
62
+ } | {
63
+ node: Node;
64
+ };
65
+ export type ConformOptions = {
66
+ /** How far below the target surface the ground sits (keeps bilinear terrain strictly under a
67
+ * curved road between samples). Default 0.05. */
68
+ offset?: number;
69
+ /** Metres over which the surrounding ground blends back to its old height. Default 4; 0 = hard edge. */
70
+ falloff?: number;
71
+ /** `both` (default) cuts and fills; `lower` only cuts; `raise` only fills. */
72
+ mode?: "both" | "lower" | "raise";
73
+ };
74
+ export type RibbonOptions = {
75
+ /** Width in metres. */
76
+ width: number;
77
+ /** Metres of ribbon per texture repeat along its length. Default = width. */
78
+ uvScale?: number;
79
+ };
80
+ /** A brush dab for `sculpt` — LOCAL metres. */
81
+ export type SculptOptions = {
82
+ x: number;
83
+ z: number;
84
+ /** Brush radius in metres. */
85
+ radius: number;
86
+ /** `raise` / `lower` by `amount` metres at full weight; `smooth` blends toward the 3×3 average
87
+ * (`amount` 0…1 = how far); `flatten` pulls toward `target` (default: the height under the
88
+ * centre) by `amount` 0…1. Default raise. */
89
+ mode?: "raise" | "lower" | "smooth" | "flatten";
90
+ amount?: number;
91
+ /** 0…1 — the share of the radius at full weight; the rest feathers out (default 0.5). */
92
+ hardness?: number;
93
+ target?: number;
94
+ };
95
+ /** `snapshot()` — the three sample arrays, copied; `restore()` puts them back (undo, a level reset). */
96
+ export type TerrainSnapshot = {
97
+ heights: Float32Array;
98
+ holes: Uint8Array;
99
+ control: Uint8Array;
100
+ };
101
+ /** A ray hit on the terrain (`raycast` local, `raycastWorld` world). */
102
+ export type TerrainHit = {
103
+ point: Vec3;
104
+ normal: Vec3;
105
+ distance: number;
106
+ };
107
+ export type AutoPaintRules = {
108
+ /** The layer everything starts as. Default 0. */
109
+ base?: number;
110
+ /** Slope rule: the layer takes over between `from` and `to` degrees of slope. */
111
+ slope?: {
112
+ layer: number;
113
+ from: number;
114
+ to: number;
115
+ };
116
+ /** Height rule: the layer takes over between `from` and `to` metres (snow line). */
117
+ height?: {
118
+ layer: number;
119
+ from: number;
120
+ to: number;
121
+ };
122
+ /** Low rule: the layer takes over BELOW `to` metres, fading in from `from` (valley floors). */
123
+ low?: {
124
+ layer: number;
125
+ from: number;
126
+ to: number;
127
+ };
128
+ };
129
+ /** What Shape { heightfield } reads off a terrain node (`node._terrain`). */
130
+ export type TerrainData = {
131
+ sizeX: number;
132
+ sizeZ: number;
133
+ cellSize: number;
134
+ heights: Float32Array;
135
+ holes: Uint8Array | null;
136
+ };
137
+ export declare class Terrain {
138
+ /** The node the terrain hangs off: transform it to place the ground; add it to the scene. */
139
+ readonly node: Node;
140
+ readonly sizeX: number;
141
+ readonly sizeZ: number;
142
+ readonly cellSize: number;
143
+ readonly chunk: number;
144
+ /** sizeX × sizeZ heights in metres, row-major (z rows). Edit, then `commit()`. */
145
+ readonly heights: Float32Array;
146
+ /** A byte per sample, 1 = hole. */
147
+ readonly holes: Uint8Array;
148
+ /** RGBA layer weights per sample. */
149
+ readonly control: Uint8Array;
150
+ /** The splat material (`Material.terrain()` unless one was passed). */
151
+ readonly material: Material;
152
+ /** Resolves when every layer texture has loaded (the terrain renders white until then). */
153
+ readonly ready: Promise<void>;
154
+ layers: TerrainLayer[];
155
+ private _native;
156
+ private _chunkMeshes;
157
+ private _controlTex;
158
+ private _dirty;
159
+ private _holesTouched;
160
+ private _controlDirty;
161
+ private _anyHole;
162
+ private _cast;
163
+ private _receive;
164
+ private constructor();
165
+ /** Build a terrain from data / a generator (synchronous; `ready` resolves once its textures loaded). */
166
+ static create(opts?: TerrainOptions): Terrain;
167
+ /** The terrain a node carries (the node `Terrain.create` returned), or null. */
168
+ static of(node: Node | null | undefined): Terrain | null;
169
+ /** Load a `.terrain` file (`Terrain.serialize` / the editor / `lecodes terrain import`); layer textures
170
+ * are not in the file — pass them in `opts` (they are asset handles the file cannot hold). */
171
+ static load(url: string, opts?: Omit<TerrainOptions, "size" | "sizeX" | "sizeZ" | "heights" | "holes" | "control">): Promise<Terrain>;
172
+ private get _grid();
173
+ /** Height at a local (x, z) on the drawn triangles; NaN in a hole or outside the grid. */
174
+ heightAt(x: number, z: number): number;
175
+ /** The drawn triangle's normal at a local (x, z) (unit Vec3, +Y up). */
176
+ normalAt(x: number, z: number): Vec3;
177
+ /** The smooth (vertex) normal at integer sample (ix, iz). */
178
+ sampleNormal(ix: number, iz: number): Vec3;
179
+ /** Extent in local metres: `[width, depth]`. */
180
+ get extent(): [number, number];
181
+ /** Min / max height over the grid. */
182
+ get heightRange(): [number, number];
183
+ /** A world-space point into the terrain's local frame. */
184
+ toLocal(p: Vec3Like): Vec3;
185
+ /** A local point into world space. */
186
+ toWorld(p: Vec3Like): Vec3;
187
+ /** The ground's WORLD height under a world (x, z): NaN off the grid / in a hole. */
188
+ worldHeightAt(x: number, z: number): number;
189
+ /** Nearest hit of a LOCAL ray on the drawn triangles (holes let it through), null on a miss.
190
+ * Exact against what is rendered — the editor's brush and a host without physics pick with it. */
191
+ raycast(origin: Vec3Like, dir: Vec3Like, maxDistance?: number): TerrainHit | null;
192
+ /** `raycast` in WORLD space — through the node's transform (rotation + uniform scale). */
193
+ raycastWorld(origin: Vec3Like, dir: Vec3Like, maxDistance?: number): TerrainHit | null;
194
+ /** Write a rectangle of samples (`src` = w × h heights, row-major). */
195
+ setHeights(x0: number, z0: number, w: number, h: number, src: ArrayLike<number>): this;
196
+ /** Apply `fn(oldHeight, weight, x, z)` over a region; `weight` is 1 inside, fading to 0 over
197
+ * `falloff` metres outside it. The building block of flatten / raise / hole. */
198
+ shape(region: TerrainRegion, fn: (h: number, w: number, x: number, z: number) => number, falloff?: number): this;
199
+ /** Flatten a region to `height` (a plateau / a building pad), blending over `falloff` metres. */
200
+ flatten(region: TerrainRegion, height: number, opts?: {
201
+ falloff?: number;
202
+ }): this;
203
+ /** Raise (or lower, negative) a region by `delta` metres, blending over `falloff` metres. */
204
+ raise(region: TerrainRegion, delta: number, opts?: {
205
+ falloff?: number;
206
+ }): this;
207
+ /** Copies of heights / holes / control — an undo point or a level reset. */
208
+ snapshot(): TerrainSnapshot;
209
+ /** Put a `snapshot()` back (same grid size) — everything marked dirty for the next `commit()`. */
210
+ restore(s: TerrainSnapshot): this;
211
+ /** One brush dab: raise / lower / smooth / flatten a disc of `radius` metres around (x, z), feathered
212
+ * by `hardness` — the editor's sculpt tool and runtime deformation (craters, digging) share it. */
213
+ sculpt(opts: SculptOptions): this;
214
+ /** Cut a hole (no triangles, no collision, no navmesh) — or fill one back with `on = false`. */
215
+ hole(region: TerrainRegion, on?: boolean): this;
216
+ /**
217
+ * Conform the ground to a mesh — the terrain takes the target's TOP surface minus `offset` under
218
+ * its footprint (a road sits exactly on it, nothing pokes through), and blends back to the old
219
+ * ground over `falloff` metres around it. `target` = a node (a Mesh, a Model, or a node holding
220
+ * them — every triangle in the subtree counts), a Geometry in local coordinates, or a raw soup
221
+ * (9 floats per triangle, local). Call again after the target moves.
222
+ */
223
+ conform(target: Node | Geometry | Float32Array, opts?: ConformOptions): this;
224
+ /** `conform` to a ribbon along `points` (world/local metres, see `ribbon`) — the road stamp. */
225
+ conformPath(points: readonly Vec3Like[], opts: ConformOptions & RibbonOptions): this;
226
+ /**
227
+ * A flat ribbon Geometry along a polyline (the road mesh AND the conform target): `width` metres,
228
+ * vertices take the points' own Y, UV0 = (across 0…1, along / uvScale). Build it from heights you
229
+ * sampled with `heightAt` and smoothed, then `Mesh.from(geometry, { material })` + `conform`.
230
+ * It also carries a lightmap UV (uv1: along 0…1 × across 0…width/length — the strip's true aspect,
231
+ * so `lecodes lightmap bake` gives it uniform texels), which makes the road a bake receiver.
232
+ */
233
+ static ribbon(points: readonly Vec3Like[], opts: RibbonOptions): Geometry;
234
+ /** Write RGBA layer weights for a rectangle of samples (`rgba` = w × h × 4 bytes). */
235
+ paint(x0: number, z0: number, w: number, h: number, rgba: ArrayLike<number>): this;
236
+ /** Paint `layer` over a region with `strength` (0…1), feathered over `falloff` metres. */
237
+ paintLayer(region: TerrainRegion, layer: number, strength?: number, falloff?: number): this;
238
+ /** Paint the whole terrain from slope / height rules (grass on the flats, rock on cliffs, snow on
239
+ * the peaks, dirt in the valleys) — the CPU pass a procedural level starts from. */
240
+ paintAuto(rules?: AutoPaintRules): this;
241
+ private _blendLayer;
242
+ /** Push every pending edit to the engine: chunk renderables + the height-field collider for the
243
+ * dirty rectangle, the control texture. Call once after a batch of edits. */
244
+ commit(): this;
245
+ set castShadows(v: boolean);
246
+ get castShadows(): boolean;
247
+ set receiveShadows(v: boolean);
248
+ get receiveShadows(): boolean;
249
+ /** The whole terrain as a `.terrain` file (LTER: heights quantised to 16 bits, holes, control). */
250
+ serialize(): ArrayBuffer;
251
+ /** Decode a `.terrain` file into create() options (heights back in metres). */
252
+ static parse(buf: ArrayBuffer): {
253
+ sizeX: number;
254
+ sizeZ: number;
255
+ cellSize: number;
256
+ chunk: number;
257
+ heights: Float32Array;
258
+ holes: Uint8Array;
259
+ control: Uint8Array;
260
+ layers: TerrainLayer[];
261
+ };
262
+ private _build;
263
+ private _buildFallbackChunk;
264
+ private _rebuildFallbackChunks;
265
+ private _applyShadows;
266
+ private _uploadControl;
267
+ private _applyLayers;
268
+ /** Re-push layer scalars after editing `layers` (textures given as Texture apply too). */
269
+ applyLayers(): Promise<void>;
270
+ private _touch;
271
+ private _touchControl;
272
+ /** The sample rectangle a region (+ falloff) touches, or null when it misses the grid. */
273
+ private _regionRect;
274
+ /** Per-sample weights over `r`: 1 inside the region, smooth 1→0 across `falloff` metres outside. */
275
+ private _regionWeights;
276
+ /** World matrix of the node (column-major). */
277
+ private _world;
278
+ /** A target's triangles in the terrain's LOCAL frame, 9 floats per triangle. */
279
+ private _triangles;
280
+ }
@@ -0,0 +1,27 @@
1
+ import { type FetchResponse, type File } from "../runtime/fetch";
2
+ export declare class Texture {
3
+ readonly width: number;
4
+ readonly height: number;
5
+ /** Horizontal wrap mode (U). */
6
+ wrapS: number;
7
+ /** Vertical wrap mode (V). */
8
+ wrapT: number;
9
+ constructor(width: number, height: number, id: number);
10
+ static fromCanvas(canvas: {
11
+ _bakeSurface(): number;
12
+ width: number;
13
+ height: number;
14
+ pixelRatio: number;
15
+ _tex3dId: number;
16
+ }): Texture;
17
+ /** A texture from raw pixels: `channels` (1–4, default 4) UBYTE per pixel, row-major, `width ×
18
+ * height × channels` bytes; `srgb` (default true for colour) picks the sRGB internal format —
19
+ * pass false for data (a heightmap, a mask). No mips. Throws on a host without the call. */
20
+ static fromPixels(width: number, height: number, data: Uint8Array, opts?: {
21
+ channels?: 1 | 2 | 3 | 4;
22
+ srgb?: boolean;
23
+ }): Texture;
24
+ /** Re-upload a rectangle of a `fromPixels` texture (same channel count). */
25
+ update(x: number, y: number, width: number, height: number, data: Uint8Array): void;
26
+ static load(source: string | FetchResponse | File): Promise<Texture>;
27
+ }
@@ -0,0 +1,10 @@
1
+ import { Aspect } from "../core/Aspect";
2
+ import type { Node } from "./Node";
3
+ export declare class Trigger extends Aspect<"trigger", Node> {
4
+ static readonly aspect = "trigger";
5
+ private _bodyId;
6
+ /** Native body id (0 if no physics support). */
7
+ get id(): number;
8
+ onAttach(): void;
9
+ onDetach(): void;
10
+ }
@@ -0,0 +1,191 @@
1
+ import { Aspect } from "../core/Aspect";
2
+ import type { FieldMeta } from "../core/fields";
3
+ import { Vec3, type Vec3Like } from "../math/vec";
4
+ import { type QuatLike } from "../math/quat";
5
+ import { Node } from "./Node";
6
+ import { Wheel } from "./Wheel";
7
+ /** Which axle the engine drives. A wheel's own `drive` overrides it. */
8
+ export type DriveLayout = "rear" | "front" | "all";
9
+ /**
10
+ * How an axle's two wheels share torque.
11
+ * - `lsd` — limited slip (Jolt's 1.4 ratio), the sane default.
12
+ * - `open` — fully open: a lifted or spinning wheel takes ALL the torque.
13
+ * - `locked` — both wheels forced to the same speed. Breaks traction predictably: the drift diff.
14
+ * A number is the raw max/min wheel-speed ratio (> 1; smaller is more locked).
15
+ */
16
+ export type DifferentialMode = "lsd" | "open" | "locked";
17
+ export interface EngineConfig {
18
+ /** Peak torque in N·m (default 500). The single biggest "how fast is it" knob. */
19
+ torque?: number;
20
+ /** Redline in RPM (default 6000). */
21
+ maxRpm?: number;
22
+ /** Idle RPM (default 1000) — the engine never falls below it. */
23
+ idleRpm?: number;
24
+ /**
25
+ * The engine's CHARACTER: a flat list `[rpm, torque, rpm, torque, …]` in NORMALISED units — x is
26
+ * a fraction of the redline, y a fraction of `torque`. Left out, Jolt's own broad curve is used.
27
+ *
28
+ * `[0, 0.8, 0.66, 1, 1, 0.8]` is an ordinary petrol engine (peak two thirds up, falling to the
29
+ * redline); `[0, 1, 1, 1]` is flat, which is what an electric motor feels like.
30
+ */
31
+ curve?: number[];
32
+ /** Moment of inertia in kg·m² (default 0.5) — how eagerly it revs when the clutch is out. */
33
+ inertia?: number;
34
+ /** Engine braking: angular damping of the engine itself (default 0.2). */
35
+ braking?: number;
36
+ }
37
+ export interface SteeringConfig {
38
+ /** Steering lock in degrees at a standstill (default 35). */
39
+ lock?: number;
40
+ /**
41
+ * The lock still available, in degrees, once the car reaches `speed` (default 10) — what stops a
42
+ * car over-driving its own front tires.
43
+ *
44
+ * A tire makes its peak grip at a few degrees of slip angle, and the steering angle a corner needs
45
+ * falls with the SQUARE of speed. Holding full lock at 100 km/h therefore asks the front for
46
+ * several times what it can give: the tires saturate, the car ploughs on, and the wheel stops
47
+ * answering. In between the lock eases on `(1 − v/speed)²`, which tracks the real curve closely.
48
+ * `0` turns the taper off — full lock at any speed.
49
+ */
50
+ atSpeed?: number;
51
+ /** The speed in m/s at which the lock has fallen to `atSpeed` (default 30 ≈ 108 km/h). */
52
+ speed?: number;
53
+ /** How fast the front wheels may turn, in degrees per second (default 220). A keyboard asks for
54
+ * full lock in one frame, which no steering wheel can do, and that step alone snaps a tire past
55
+ * its peak. `0` = instantly. */
56
+ rate?: number;
57
+ }
58
+ /**
59
+ * Aerodynamics. Both numbers are quoted the same way — **a fraction of the car's own weight at
60
+ * 30 m/s (108 km/h)** — and both grow with the SQUARE of speed from there, so `0.5` at 30 m/s is
61
+ * `2.0` at 60 m/s. One mental model for both, and no drag coefficients or frontal areas to invent.
62
+ */
63
+ export interface AeroConfig {
64
+ /**
65
+ * Downforce (default 0 — a car with no wing). The knob that decides whether a car corners better
66
+ * or worse the faster it goes: tire grip is a constant, but the force a corner demands grows with
67
+ * v², so with no downforce every car runs out of road at speed. `0.6` roughly doubles a car's
68
+ * cornering at 150 km/h; a road car is nearer `0.1`, a race car well past `1`.
69
+ *
70
+ * It presses along the CHASSIS' own down axis (that is what keeps a car planted over a crest) and
71
+ * only while a wheel is on the ground — a car on its roof is never launched by its own wing.
72
+ */
73
+ downforce?: number;
74
+ /** Air resistance (default 0.03 — an ordinary car). What gives a car a top speed at all. */
75
+ drag?: number;
76
+ }
77
+ export declare class Vehicle extends Aspect<"vehicle", Node> {
78
+ static readonly aspect = "vehicle";
79
+ /** Chassis mass in kg (default 1200). Wheels are massless in this model. */
80
+ mass: number;
81
+ /** Centre of mass height in chassis space (metres, negative = lower). Left out, it drops to halfway
82
+ * down the chassis shape — a car with its mass at the shape's centre tips over. */
83
+ centerOfMass?: number;
84
+ /** Which axle the engine drives (default "rear"). A wheel's own `drive` overrides it. */
85
+ driveAxle: DriveLayout;
86
+ /** Differential lock across each driven axle. `locked` is the drift setup — both wheels turn
87
+ * together, so the pair lets go as a pair. Live: re-configure the aspect to switch it mid-drive. */
88
+ differential: DifferentialMode | number;
89
+ /**
90
+ * Anti-roll bars between each axle's wheels — what stops a car rolling onto its inside wheels in a
91
+ * fast corner. `true` (default) is a bar 0.01 as stiff as the wheel's own spring; a number is that
92
+ * ratio directly, and `0` / `false` removes the bars.
93
+ *
94
+ * **The numbers are far smaller than they look and the gain is steep** — Jolt's bar feeds
95
+ * `lengthDifference × stiffness × dt` as a bias into the suspension's own soft constraint, so 4%
96
+ * of the spring already flattens the body. Measured on a 1250 kg car: `0` → 1.3° of roll at 0.86 g,
97
+ * `0.01` → 0.6°, `0.15` → 0.2° (flat), `0.5` → the car HOPS.
98
+ *
99
+ * This is the knob for how much a car visibly LEANS, not for wheel lift: bars change how far the
100
+ * body tips, not how much load transfers. For lift, lower `centerOfMass`.
101
+ */
102
+ antiRoll: boolean | number;
103
+ /** Pitch/roll limit in degrees (default 60) before the constraint rights the car. 180 turns it off. */
104
+ maxTilt: number;
105
+ /** Friction of the CHASSIS body itself — how it slides when it lands on its roof or side. Nothing
106
+ * to do with the tires; those are the `Wheel`'s `tire.grip` × the ground's friction. */
107
+ friction: number;
108
+ /** Strength of the clutch when fully engaged (default 10). Small values slip; large ones weld the
109
+ * engine to the wheels. The `Gearbox` scales it 0..1 while shifting. */
110
+ clutchStrength: number;
111
+ engine: EngineConfig;
112
+ steering: SteeringConfig;
113
+ aero: AeroConfig;
114
+ /** Scene-editor inspector: the flat, tunable half. The grouped objects are edited in code. */
115
+ static fields: FieldMeta<Vehicle>;
116
+ static editor: {
117
+ rebuild: boolean;
118
+ };
119
+ private _id;
120
+ private _bodyId;
121
+ private _builtMass;
122
+ private _wheels;
123
+ private _state;
124
+ private _stateFrame;
125
+ private _throttle;
126
+ private _steer;
127
+ private _brake;
128
+ private _handbrake;
129
+ onAttach(): void;
130
+ onDetach(): void;
131
+ /**
132
+ * Re-configuring an attached vehicle retunes it in place — the way a drift button switches the
133
+ * differential without the car so much as blinking:
134
+ *
135
+ * car.aspect(Vehicle, { differential: drift ? 'locked' : 'lsd' })
136
+ *
137
+ * Live: `differential`, `engine`, `steering`, `aero`, `maxTilt`, `friction`, `clutchStrength`, and
138
+ * every `Wheel`'s `tire.grip` and brake torques. Everything else describes the car's STRUCTURE —
139
+ * `mass`, `centerOfMass`, which wheels exist and where, their suspension, `driveAxle`, `antiRoll` — and
140
+ * is baked into the constraint at attach; to change one of those, re-attach the aspect.
141
+ */
142
+ onReconfigure(): void;
143
+ /** Native vehicle id (0 until attached / no physics support). */
144
+ get id(): number;
145
+ /** The chassis rigid-body id — the same handle the plain body calls take. */
146
+ get bodyId(): number;
147
+ /** The wheels, in blob order (front axle first). */
148
+ get wheels(): readonly Wheel[];
149
+ /**
150
+ * The driver's controls, all in [-1, 1] (brakes in [0, 1]). Sticky: the last values keep applying
151
+ * until the next call, so a held key does not need re-sending. `forward < 0` asks for reverse; the
152
+ * `Gearbox` engages it once the car has stopped.
153
+ */
154
+ drive(forward: number, steer?: number, brake?: number, handbrake?: number): this;
155
+ /** Teleport upright and clear all motion (velocity, engine, gearbox, wheel spin). Defaults to the
156
+ * chassis node's current pose — `reset()` alone un-flips a car where it lies. */
157
+ reset(position?: Vec3Like, rotation?: QuatLike): this;
158
+ /** Push the chassis (a boost pad, an explosion) — an instantaneous impulse in kg·m/s. */
159
+ applyImpulse(v: Vec3Like): this;
160
+ private _read;
161
+ /** Speed along the car's forward axis in m/s — negative when reversing (× 3.6 for km/h). */
162
+ get speed(): number;
163
+ /** Engine revolutions per minute. */
164
+ get rpm(): number;
165
+ /** How many wheels are touching the ground. */
166
+ get wheelsOnGround(): number;
167
+ /** Any wheel on the ground — false while airborne. */
168
+ get grounded(): boolean;
169
+ /** Chassis velocity in world units/s (fresh Vec3). */
170
+ get velocity(): Vec3;
171
+ /** The last throttle handed to `drive()` — what the gearbox reads to know which way you want to go. */
172
+ get throttle(): number;
173
+ /** The last steer input handed to `drive()`, [-1, 1]. */
174
+ get steerInput(): number;
175
+ /** The last foot-brake input handed to `drive()`, [0, 1] — the pedal, not the resulting force. */
176
+ get brake(): number;
177
+ /** The last handbrake input handed to `drive()`, [0, 1]. */
178
+ get handbrake(): number;
179
+ /** Current gear from the attached `Gearbox`: −1 reverse, 0 neutral, 1… forward. */
180
+ get gear(): number;
181
+ /** The steering lock, in degrees, the car is allowed at its current speed — the full lock at rest,
182
+ * falling to `steering.atSpeed`. The same curve the engine applies; useful on a HUD. */
183
+ get steerLock(): number;
184
+ /** Every Wheel under the chassis, ordered front axle first, with its axle group resolved. */
185
+ private _collectWheels;
186
+ /** Pack the whole configuration into the one blob the host ABI takes (see bridges.d.ts). */
187
+ private _buildSettings;
188
+ /** Edit mode: which way the chassis faces. Each wheel draws its own circle and travel range — see
189
+ * `Wheel.rebuild()`. Play mode never calls this. */
190
+ rebuild(): void;
191
+ }
@@ -0,0 +1,95 @@
1
+ import { Aspect } from "../core/Aspect";
2
+ import type { FieldMeta } from "../core/fields";
3
+ import { type Vec3Like } from "../math/vec";
4
+ import { Node } from "./Node";
5
+ /** Floats `vehicleGetState` writes before the per-wheel block: speed, rpm, contacts, vx, vy, vz. */
6
+ export declare const STATE_HEADER = 6;
7
+ /** Floats per wheel: contact, slip, slipAngle, suspensionLength, steerDeg, spin. */
8
+ export declare const WHEEL_STATE = 6;
9
+ /** How a tire behaves past its grip peak. `road` is Jolt's own curve — grip falls off after the peak,
10
+ * so the car can be made to let go. `arcade` holds the peak all the way out: much harder to spin. */
11
+ export type TireCurve = "road" | "arcade";
12
+ export interface WheelSuspension {
13
+ /** Total travel in metres, full droop to fully compressed (default 0.4). */
14
+ travel?: number;
15
+ /** Spring frequency in Hz — bigger is stiffer (default 1.4; a race car ~2.5, a truck ~1). It also
16
+ * sets the ride-height sag, and the sag is how far the wheel can still extend DOWN. */
17
+ stiffness?: number;
18
+ /** Damping ratio 0..1 (default 0.5). Low values pogo. */
19
+ damping?: number;
20
+ }
21
+ export interface WheelTire {
22
+ /** Grip multiplier on the friction curves (default 1). The grip a wheel actually gets is combined
23
+ * with the ground it stands on as `sqrt(tire × groundFriction)`, and a body's friction defaults to
24
+ * 0.6 — so a road a car should really corner on wants `Physics { friction: 1 }`. */
25
+ grip?: number;
26
+ /** Which friction curve (default `road`). */
27
+ curve?: TireCurve;
28
+ }
29
+ export interface WheelVisual {
30
+ /** The MODEL's axle direction in its own space (default `[1, 0, 0]`). Set it instead of parenting
31
+ * the mesh under a corrective node when the art points another way. */
32
+ axis?: Vec3Like;
33
+ /** Drawn radius, if the art is not exactly the physical `radius` — sinks a wheel into its arch or
34
+ * lets a fat tire overhang, with no effect on the simulation. Default: the physical radius. */
35
+ radius?: number;
36
+ /** Let the model spin (default true). `false` keeps the steer angle and suspension travel but not
37
+ * the rotation — a brake caliper. */
38
+ spin?: boolean;
39
+ }
40
+ export declare class Wheel extends Aspect<"wheel", Node> {
41
+ static readonly aspect = "wheel";
42
+ /** Wheel radius in metres. Default: measured from the node's rendered bounds, else 0.35. Too small
43
+ * and the car scrapes, too large and it floats. */
44
+ radius?: number;
45
+ /** Wheel width in metres. Default: measured, else 0.25. */
46
+ width?: number;
47
+ /** Does this wheel steer? Default: the wheels on the front axle. */
48
+ steer?: boolean;
49
+ /** Does the engine drive it? Default: from the vehicle's `drive` layout. */
50
+ drive?: boolean;
51
+ /** Foot brake on this wheel. */
52
+ brake: boolean;
53
+ /** Handbrake on this wheel. Default: every non-steering wheel (locking the front wheels of a moving
54
+ * car is not a handbrake turn, it is a crash). */
55
+ handbrake?: boolean;
56
+ /** Axle group, front to back. Default: derived from Z. Set it for a car whose wheels are not in neat
57
+ * left/right pairs — an axle's wheels are paired for the differential and the anti-roll bar. */
58
+ axle?: number;
59
+ /** Foot-brake torque in N·m (default 1500); the handbrake pulls 3× on the wheels that have it. */
60
+ brakeTorque: number;
61
+ suspension: WheelSuspension;
62
+ tire: WheelTire;
63
+ visual: WheelVisual;
64
+ /** Scene-editor inspector. `steer` / `drive` / `handbrake` are deliberately absent: they are
65
+ * tri-state (undefined = derive it from the axle), which a switch cannot express. */
66
+ static fields: FieldMeta<Wheel>;
67
+ static editor: {
68
+ rebuild: boolean;
69
+ };
70
+ private _angle;
71
+ private _scale;
72
+ private _local;
73
+ onAttach(): void;
74
+ onDetach(): void;
75
+ private _state;
76
+ /** Touching the ground this step. */
77
+ get contact(): boolean;
78
+ /** Longitudinal slip RATIO: 0 = rolling in sync with the ground, ~1 = spinning up or locked.
79
+ * Unsigned — smoke, tire marks and wheelspin sound key off this. */
80
+ get slip(): number;
81
+ /** Slip ANGLE in degrees: how far the tire's travel direction is off from where it points.
82
+ * Unsigned, 0..90 — past the curve's peak (~3°) the tire is sliding sideways. Drift particles. */
83
+ get slipAngle(): number;
84
+ /** Steer angle in degrees, positive to the right. */
85
+ get steerAngle(): number;
86
+ /** Wheel spin in rad/s (× radius ≈ the speed the tire is laying down). */
87
+ get spin(): number;
88
+ /** Suspension compression, 0 = fully extended (drooping) … 1 = fully compressed. */
89
+ get compression(): number;
90
+ /** LATE phase: after the step and the transform sync, right before the frame draws. */
91
+ update(dt: number): void;
92
+ /** Edit mode: this wheel's own circle at its resting height, its travel range, and a mark when the
93
+ * engine drives it — enough to place a wheel without running the game. */
94
+ rebuild(): void;
95
+ }
@@ -0,0 +1,60 @@
1
+ import { type FetchResponse } from "../../runtime/fetch";
2
+ import type { Vec3Like } from "../../math/vec";
3
+ import type { QuatLike } from "../../math/quat";
4
+ /** A keyframe: `[time (s), value]`. */
5
+ export type ClipKey<V> = [number, V];
6
+ export type ClipInterpolation = "linear" | "step";
7
+ /** Curves for one target node (bone name), any subset of the three channels. */
8
+ export type ClipTrackDef = {
9
+ position?: ClipKey<Vec3Like | [number, number, number]>[];
10
+ rotation?: ClipKey<QuatLike | [number, number, number, number]>[];
11
+ scale?: ClipKey<Vec3Like | [number, number, number]>[];
12
+ interpolation?: ClipInterpolation;
13
+ };
14
+ export type ClipDef = {
15
+ /** Clip length in seconds — defaults to the last key time across all tracks. */
16
+ duration?: number;
17
+ /** Target node name → its curves. Names bind to bones (or any child node) at Animator attach. */
18
+ tracks: Record<string, ClipTrackDef>;
19
+ };
20
+ export type ClipInfo = {
21
+ name: string;
22
+ duration: number;
23
+ trackCount: number;
24
+ };
25
+ export declare class AnimationClip {
26
+ /** Source name (the clip's name inside its file; `"clip"` for procedural clips). Informational —
27
+ * an Animator addresses clips by the key YOU give it. */
28
+ readonly name: string;
29
+ /** Length in seconds. */
30
+ readonly duration: number;
31
+ /** Number of animated (node, channel) tracks. */
32
+ readonly trackCount: number;
33
+ private constructor();
34
+ /** Mark a moment of the clip (SECONDS from its start) with an event name: `kick.addEvent(0.4, 'hit')`
35
+ * → `anim.on('hit', (clip, layer) => …)` fires when the playhead crosses it, loops included.
36
+ * Events are part of the clip: every model playing it gets them; `slice()` keeps the ones inside
37
+ * the range, re-timed. Chainable. */
38
+ addEvent(time: number, name: string): this;
39
+ private _pushEvents;
40
+ /** Load ONE clip from a GLB: the file's only/first clip, or the one named / at the given index. */
41
+ static load(source: string | FetchResponse, clip?: string | number): Promise<AnimationClip>;
42
+ /** Load EVERY clip of a GLB (library files), keyed by clip name. */
43
+ static loadAll(source: string | FetchResponse): Promise<Record<string, AnimationClip>>;
44
+ /** Build a clip from curves in code — no DCC needed. Keys are `[time, value]`; a track binds to the
45
+ * node of that name when the clip is used by an Animator (bones, or any child node). */
46
+ static from(def: ClipDef): AnimationClip;
47
+ /** A sub-range of this clip as a NEW clip — `[start, end]` seconds of the source, re-timed to 0
48
+ * (`end` defaults to the clip's end; array-slice semantics). Cut a too-long take down to the
49
+ * action, or carve several sub-clips out of one packed timeline:
50
+ *
51
+ * clips: { Kick: kick.slice(0.2, 1.1) }
52
+ *
53
+ * Keys outside the range are dropped and exact boundary values are interpolated in, so the
54
+ * sliced clip starts and ends precisely on the source's pose at the cut points. Everything
55
+ * downstream (blend spaces, events' 0–1 times, root motion, phase sync) sees a normal clip of
56
+ * the new duration. */
57
+ slice(start: number, end?: number): AnimationClip;
58
+ private static _label;
59
+ private static _loadSet;
60
+ }