lecodes-cli 0.18.2 → 0.19.2

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 (224) hide show
  1. package/dist/index.js +1866 -301
  2. package/package.json +14 -12
  3. package/runtime/scene-harness.json +1 -1
  4. package/runtime/sdk-types.json +1 -1
  5. package/src/api.ts +302 -0
  6. package/src/browserAuth.ts +87 -0
  7. package/src/cmgenTool.ts +104 -0
  8. package/src/commands/app.ts +891 -0
  9. package/src/commands/appAndroid.ts +603 -0
  10. package/src/commands/appDesktop.ts +326 -0
  11. package/src/commands/appDesktopMac.ts +470 -0
  12. package/src/commands/appIcon.ts +187 -0
  13. package/src/commands/appShared.ts +448 -0
  14. package/src/commands/appTemplates.ts +883 -0
  15. package/src/commands/appTemplatesAndroid.ts +599 -0
  16. package/src/commands/appTemplatesGradlew.ts +9 -0
  17. package/src/commands/assets.ts +28 -0
  18. package/src/commands/clone.ts +60 -0
  19. package/src/commands/compile.ts +253 -0
  20. package/src/commands/create.ts +59 -0
  21. package/src/commands/design.ts +863 -0
  22. package/src/commands/designTemplates.ts +11 -0
  23. package/src/commands/desktop.ts +122 -0
  24. package/src/commands/dev.ts +214 -0
  25. package/src/commands/diff.ts +59 -0
  26. package/src/commands/init.ts +191 -0
  27. package/src/commands/install.ts +198 -0
  28. package/src/commands/lightmap.ts +290 -0
  29. package/src/commands/link.ts +147 -0
  30. package/src/commands/login.ts +24 -0
  31. package/src/commands/navmesh.ts +225 -0
  32. package/src/commands/pn.ts +305 -0
  33. package/src/commands/projectTemplates.ts +129 -0
  34. package/src/commands/pull.ts +109 -0
  35. package/src/commands/push.ts +173 -0
  36. package/src/commands/render.ts +414 -0
  37. package/src/commands/scene.ts +148 -0
  38. package/src/commands/shaders.ts +157 -0
  39. package/src/commands/status.ts +29 -0
  40. package/src/commands/test.ts +370 -0
  41. package/src/commands/thumbs.ts +178 -0
  42. package/src/commands/types.ts +87 -0
  43. package/src/commands/update.ts +190 -0
  44. package/src/compile/assetIcons.ts +214 -0
  45. package/src/compile/collect.ts +46 -0
  46. package/src/compile/collectLocal.ts +37 -0
  47. package/src/compile/designCompile.ts +104 -0
  48. package/src/compile/fonts.ts +156 -0
  49. package/src/compile/headlessBundle.ts +129 -0
  50. package/src/compile/nativeStack.ts +21 -0
  51. package/src/compile/projectCompile.ts +109 -0
  52. package/src/compile/sceneCompile.ts +113 -0
  53. package/src/compile/screenEntry.ts +127 -0
  54. package/src/compile/shaders.ts +245 -0
  55. package/src/config.ts +42 -0
  56. package/src/designMeta.ts +35 -0
  57. package/src/desktopRenderer.ts +532 -0
  58. package/src/desktopScript.ts +276 -0
  59. package/src/dev/clientTemplates.ts +160 -0
  60. package/src/dev/devServer.ts +292 -0
  61. package/src/dev/wsServer.ts +144 -0
  62. package/src/distRoot.ts +20 -0
  63. package/src/ignore.ts +163 -0
  64. package/src/index.ts +491 -0
  65. package/src/lecodes-3d-editor.d.ts +41 -0
  66. package/src/lecodes-assets.d.ts +7 -0
  67. package/src/lecodes-design.d.ts +191 -0
  68. package/src/lecodes-renderer.d.ts +131 -0
  69. package/src/localFiles.ts +144 -0
  70. package/src/manifest.ts +46 -0
  71. package/src/matcTool.ts +137 -0
  72. package/src/peers.ts +40 -0
  73. package/src/project.ts +61 -0
  74. package/src/projectEnv.ts +94 -0
  75. package/src/qrcode-terminal.d.ts +9 -0
  76. package/src/releases.ts +125 -0
  77. package/src/serverDiff.ts +78 -0
  78. package/src/textDiff.ts +103 -0
  79. package/src/types.ts +0 -0
  80. package/src/util.ts +146 -0
  81. package/runtime/sdk/animate/animate.ts +0 -238
  82. package/runtime/sdk/animate/bezier.ts +0 -138
  83. package/runtime/sdk/animate/easings.ts +0 -126
  84. package/runtime/sdk/canvas/Canvas.ts +0 -305
  85. package/runtime/sdk/core/Aspect.ts +0 -512
  86. package/runtime/sdk/core/InspectorUI.ts +0 -212
  87. package/runtime/sdk/core/color.ts +0 -66
  88. package/runtime/sdk/core/compWrite.ts +0 -42
  89. package/runtime/sdk/core/events.ts +0 -38
  90. package/runtime/sdk/core/fields.ts +0 -120
  91. package/runtime/sdk/core/registry.ts +0 -23
  92. package/runtime/sdk/core/signals.ts +0 -277
  93. package/runtime/sdk/core/time.ts +0 -81
  94. package/runtime/sdk/g2/Camera2D.ts +0 -40
  95. package/runtime/sdk/g2/CharacterController2D.ts +0 -276
  96. package/runtime/sdk/g2/Node2D.ts +0 -267
  97. package/runtime/sdk/g2/OneWay2D.ts +0 -66
  98. package/runtime/sdk/g2/Physics2D.ts +0 -346
  99. package/runtime/sdk/g2/Scene2D.ts +0 -209
  100. package/runtime/sdk/g2/Shape2D.ts +0 -259
  101. package/runtime/sdk/g2/Sprite.ts +0 -89
  102. package/runtime/sdk/g2/SpriteAnimation.ts +0 -171
  103. package/runtime/sdk/g2/SpriteSheet.ts +0 -166
  104. package/runtime/sdk/g2/Texture2D.ts +0 -47
  105. package/runtime/sdk/g2/Tilemap.ts +0 -41
  106. package/runtime/sdk/g2/Tileset.ts +0 -71
  107. package/runtime/sdk/g2/Trigger2D.ts +0 -77
  108. package/runtime/sdk/g2/autotile.ts +0 -433
  109. package/runtime/sdk/g2/cells.ts +0 -91
  110. package/runtime/sdk/g2/defineScene2d.ts +0 -381
  111. package/runtime/sdk/g2/groups2d.ts +0 -106
  112. package/runtime/sdk/g2/loop.ts +0 -50
  113. package/runtime/sdk/g2/scenarios2d.ts +0 -69
  114. package/runtime/sdk/g2/touch.ts +0 -83
  115. package/runtime/sdk/gl/Camera.ts +0 -160
  116. package/runtime/sdk/gl/CameraPlace.ts +0 -52
  117. package/runtime/sdk/gl/CharacterController.ts +0 -238
  118. package/runtime/sdk/gl/Gearbox.ts +0 -212
  119. package/runtime/sdk/gl/Geometry.ts +0 -279
  120. package/runtime/sdk/gl/IK.ts +0 -193
  121. package/runtime/sdk/gl/InstancedMesh.ts +0 -132
  122. package/runtime/sdk/gl/Light.ts +0 -99
  123. package/runtime/sdk/gl/Lightmap.ts +0 -179
  124. package/runtime/sdk/gl/Material.ts +0 -245
  125. package/runtime/sdk/gl/Mesh.ts +0 -83
  126. package/runtime/sdk/gl/Model.ts +0 -64
  127. package/runtime/sdk/gl/Node.ts +0 -350
  128. package/runtime/sdk/gl/Noise.ts +0 -30
  129. package/runtime/sdk/gl/Particles.ts +0 -676
  130. package/runtime/sdk/gl/Physics.ts +0 -222
  131. package/runtime/sdk/gl/Plane.ts +0 -53
  132. package/runtime/sdk/gl/Ray.ts +0 -16
  133. package/runtime/sdk/gl/Scene.ts +0 -479
  134. package/runtime/sdk/gl/Shape.ts +0 -377
  135. package/runtime/sdk/gl/Texture.ts +0 -46
  136. package/runtime/sdk/gl/Trigger.ts +0 -45
  137. package/runtime/sdk/gl/Vehicle.ts +0 -473
  138. package/runtime/sdk/gl/Wheel.ts +0 -240
  139. package/runtime/sdk/gl/animation/AnimationClip.ts +0 -204
  140. package/runtime/sdk/gl/animation/Animator.ts +0 -87
  141. package/runtime/sdk/gl/animation/Layer.ts +0 -29
  142. package/runtime/sdk/gl/animation/Loop.ts +0 -25
  143. package/runtime/sdk/gl/animation/Playback.ts +0 -43
  144. package/runtime/sdk/gl/animation/core.ts +0 -294
  145. package/runtime/sdk/gl/controls.ts +0 -95
  146. package/runtime/sdk/gl/physicsEvents.ts +0 -20
  147. package/runtime/sdk/gl/scenarios.ts +0 -291
  148. package/runtime/sdk/gl/state.ts +0 -6
  149. package/runtime/sdk/gl/touch.ts +0 -68
  150. package/runtime/sdk/inject.ts +0 -186
  151. package/runtime/sdk/math/Mathf.ts +0 -118
  152. package/runtime/sdk/math/mat4.ts +0 -278
  153. package/runtime/sdk/math/quat.ts +0 -232
  154. package/runtime/sdk/math/vec.ts +0 -255
  155. package/runtime/sdk/plugins/camera.ts +0 -81
  156. package/runtime/sdk/plugins/geolocation.ts +0 -123
  157. package/runtime/sdk/plugins/oauth.ts +0 -61
  158. package/runtime/sdk/plugins/permission.ts +0 -7
  159. package/runtime/sdk/plugins/push.ts +0 -132
  160. package/runtime/sdk/plugins/qr.ts +0 -73
  161. package/runtime/sdk/plugins/service.ts +0 -47
  162. package/runtime/sdk/runtime/app.ts +0 -101
  163. package/runtime/sdk/runtime/appEvents.ts +0 -54
  164. package/runtime/sdk/runtime/channel.ts +0 -61
  165. package/runtime/sdk/runtime/clipboard.ts +0 -20
  166. package/runtime/sdk/runtime/datetime.ts +0 -329
  167. package/runtime/sdk/runtime/device.ts +0 -293
  168. package/runtime/sdk/runtime/fetch.ts +0 -77
  169. package/runtime/sdk/runtime/files.ts +0 -23
  170. package/runtime/sdk/runtime/input.ts +0 -175
  171. package/runtime/sdk/runtime/media.ts +0 -111
  172. package/runtime/sdk/runtime/misc.ts +0 -16
  173. package/runtime/sdk/runtime/net.ts +0 -36
  174. package/runtime/sdk/runtime/rpc.ts +0 -218
  175. package/runtime/sdk/runtime/service.ts +0 -83
  176. package/runtime/sdk/runtime/share.ts +0 -9
  177. package/runtime/sdk/runtime/storage.ts +0 -13
  178. package/runtime/sdk/runtime/touch.ts +0 -76
  179. package/runtime/sdk/scene/defineScene.ts +0 -1227
  180. package/runtime/sdk/scene/editorPlugins.ts +0 -92
  181. package/runtime/sdk/scene/gizmos.ts +0 -148
  182. package/runtime/sdk/scene/grammar.ts +0 -120
  183. package/runtime/sdk/scene/material.ts +0 -188
  184. package/runtime/sdk/server/auth/appConfig.ts +0 -12
  185. package/runtime/sdk/server/auth/global.ts +0 -80
  186. package/runtime/sdk/server/auth/host.ts +0 -318
  187. package/runtime/sdk/server/auth/models.ts +0 -83
  188. package/runtime/sdk/server/auth/types.ts +0 -50
  189. package/runtime/sdk/server/channel.ts +0 -56
  190. package/runtime/sdk/server/context.ts +0 -36
  191. package/runtime/sdk/server/db/defineDb.ts +0 -237
  192. package/runtime/sdk/server/db/fields.ts +0 -132
  193. package/runtime/sdk/server/db/httpTransport.ts +0 -93
  194. package/runtime/sdk/server/db/index.ts +0 -7
  195. package/runtime/sdk/server/db/marci/query.ts +0 -412
  196. package/runtime/sdk/server/db/types.ts +0 -202
  197. package/runtime/sdk/server/errors.ts +0 -12
  198. package/runtime/sdk/server/host.ts +0 -74
  199. package/runtime/sdk/server/inject.ts +0 -13
  200. package/runtime/sdk/server/runtime.ts +0 -133
  201. package/runtime/sdk/server/validate.ts +0 -87
  202. package/runtime/sdk/ui/NativeView.ts +0 -142
  203. package/runtime/sdk/ui/UI.ts +0 -39
  204. package/runtime/sdk/ui/UIBottomSheet.ts +0 -139
  205. package/runtime/sdk/ui/UIButton.ts +0 -101
  206. package/runtime/sdk/ui/UIContainer.ts +0 -60
  207. package/runtime/sdk/ui/UIImage.ts +0 -83
  208. package/runtime/sdk/ui/UIInput.ts +0 -185
  209. package/runtime/sdk/ui/UIModal.ts +0 -139
  210. package/runtime/sdk/ui/UINode.ts +0 -826
  211. package/runtime/sdk/ui/UIPager.ts +0 -362
  212. package/runtime/sdk/ui/UIPopover.ts +0 -100
  213. package/runtime/sdk/ui/UIScreen.ts +0 -123
  214. package/runtime/sdk/ui/UIScrollable.ts +0 -87
  215. package/runtime/sdk/ui/UISpacer.ts +0 -14
  216. package/runtime/sdk/ui/UITabs.ts +0 -236
  217. package/runtime/sdk/ui/UIText.ts +0 -51
  218. package/runtime/sdk/ui/UIVideo.ts +0 -88
  219. package/runtime/sdk/ui/UIVirtualizedList.ts +0 -241
  220. package/runtime/sdk/ui/UIWidget.ts +0 -127
  221. package/runtime/sdk/ui/fonts.ts +0 -13
  222. package/runtime/sdk/ui/presentable.ts +0 -117
  223. package/runtime/sdk/ui/router.ts +0 -132
  224. package/runtime/sdk/ui/theme.ts +0 -84
@@ -1,291 +0,0 @@
1
- // No-code scenario aspects: ready-made behaviors a scene builder attaches in the editor without
2
- // writing any code — move to a target, travel a waypoint path, spin, face something, start a GLB
3
- // animation. They are ordinary aspects (work from hand-written code too); in the scene editor the
4
- // movement ones double as `static editor` generators that draw their paths as editor gizmos
5
- // (`Gizmos.*` in rebuild() — overlay lines, never scene content; play mode never calls rebuild(),
6
- // so they cost nothing at runtime).
7
- //
8
- // Conventions shared by the family:
9
- // • targets/waypoints are scene nodes — place an Empty, then pick it in the inspector (`ref()`);
10
- // • times are seconds, angles degrees; all motion runs in `update(dt)` (play mode only);
11
- // • orientation is quaternion-composed — never euler-incremented (see math/quat.ts).
12
-
13
- import { Aspect } from "../core/Aspect"
14
- import type { FieldMeta } from "../core/fields"
15
- import type { InspectorUI } from "../core/InspectorUI"
16
- import { Vec3 } from "../math/vec"
17
- import { Quat } from "../math/quat"
18
- import { Node } from "./Node"
19
- import { Model } from "./Model"
20
- import type { Playback } from "./animation/Playback"
21
- import { Gizmos } from "../scene/gizmos"
22
-
23
- const MOVE_LINE = "#5b8ef0"
24
- const LOOK_LINE = "#d9a13f"
25
- const DEG2RAD = Math.PI / 180
26
-
27
- type LoopMode = "once" | "loop" | "pingpong"
28
-
29
- /** Normalized phase for elapsed time `t` over one trip of `duration`: once clamps at 1, loop
30
- * wraps, pingpong triangles 0→1→0. */
31
- const phase = (t: number, duration: number, mode: LoopMode): number => {
32
- if (duration <= 0) return 1
33
- const u = t / duration
34
- if (mode === "once") return Math.min(u, 1)
35
- if (mode === "loop") return u - Math.floor(u)
36
- const v = u % 2
37
- return v <= 1 ? v : 2 - v
38
- }
39
-
40
- const ease = (k: number, easing: "smooth" | "linear"): number =>
41
- easing === "smooth" ? k * k * (3 - 2 * k) : k
42
-
43
- /** A world point in `node`'s PARENT space — what `node.position` is expressed in. */
44
- const toParentLocal = (node: Node, world: Vec3): Vec3 => {
45
- const parent = node.parent
46
- return parent ? parent.worldMatrix.invert().transformPoint(world) : world
47
- }
48
-
49
- /** A path node's waypoints: its children in scene-FILE order (`_sceneChildOrder`, stamped by
50
- * defineScene — the engine's live child order is insertion-based and may differ), editor helper
51
- * nodes (`__`-prefixed) excluded. Runtime-added children append in engine order. */
52
- const pathWaypoints = (path: Node): Node[] => {
53
- const children = path.children.filter((c) => !(c.name ?? "").startsWith("__"))
54
- const order = (path as { _sceneChildOrder?: string[] })._sceneChildOrder
55
- if (!order) return children
56
- const byName = new Map(children.map((c) => [ c.name, c ]))
57
- const sorted: Node[] = []
58
- for (const n of order) { const c = byName.get(n); if (c) sorted.push(c) }
59
- const seen = new Set(sorted)
60
- for (const c of children) if (!seen.has(c)) sorted.push(c)
61
- return sorted
62
- }
63
-
64
- // ---- the aspects ---------------------------------------------------------------------------------
65
-
66
- /** Travel from the node's starting position to a target node in `duration` seconds. */
67
- export class MoveTo extends Aspect<"moveTo"> {
68
- /** Where to travel — place an Empty node and pick it. */
69
- target: Node | null = null
70
-
71
- /** Seconds for the full trip. */
72
- duration = 2
73
-
74
- /** Seconds to wait before starting. */
75
- delay = 0
76
-
77
- /** once = stop at the target · loop = restart from the start point · pingpong = back and forth. */
78
- mode: LoopMode = "once"
79
-
80
- /** Motion curve. */
81
- easing: "smooth" | "linear" = "smooth"
82
-
83
- static readonly aspect = "moveTo"
84
- static editor = { rebuild: true }
85
- static fields: FieldMeta<MoveTo> = {
86
- target: { editor: "node" },
87
- duration: { min: 0.05, max: 120, step: 0.05 },
88
- delay: { min: 0, max: 120, step: 0.05 },
89
- mode: { options: [ "once", "loop", "pingpong" ] },
90
- easing: { options: [ "smooth", "linear" ] },
91
- }
92
-
93
- private _t = 0
94
- private _start: Vec3 | null = null
95
-
96
- update(dt: number): void {
97
- if (!this.target) return
98
- this._start ??= this.node.position
99
- this._t += dt
100
- const k = ease(phase(Math.max(0, this._t - this.delay), this.duration, this.mode), this.easing)
101
- const end = toParentLocal(this.node, this.target.worldPosition)
102
- this.node.position = new Vec3(this._start).add(end.sub(this._start).scale(k))
103
- }
104
-
105
- /** Editor-only path line (edit mode; play mode never calls this). */
106
- rebuild(): void {
107
- if (!this.target) return
108
- // the target is an empty — its own anchored marker shows the endpoint
109
- Gizmos.line(this.node.worldPosition, this.target.worldPosition, { color: MOVE_LINE })
110
- }
111
- }
112
-
113
- /** Travel through the children of a path node (add an Empty per waypoint) in `duration` seconds.
114
- * `loop` runs the circuit closed (last → first); `pingpong` goes back and forth along the open
115
- * path; `once` stops at the last waypoint. */
116
- export class FollowPath extends Aspect<"followPath"> {
117
- /** A node whose CHILDREN are the waypoints, in file order. */
118
- path: Node | null = null
119
-
120
- /** Seconds for one full pass of the path. */
121
- duration = 6
122
-
123
- /** Seconds to wait before starting. */
124
- delay = 0
125
-
126
- mode: LoopMode = "loop"
127
-
128
- /** Turn to face the direction of travel. */
129
- orient = true
130
-
131
- /** Which local axis leads when orienting. */
132
- forward: "-z" | "z" | "x" | "-x" = "-z"
133
-
134
- static readonly aspect = "followPath"
135
- static editor = { rebuild: true }
136
- static fields: FieldMeta<FollowPath> = {
137
- path: { editor: "node" },
138
- duration: { min: 0.05, max: 300, step: 0.05 },
139
- delay: { min: 0, max: 120, step: 0.05 },
140
- mode: { options: [ "loop", "once", "pingpong" ] },
141
- forward: { options: [ "-z", "z", "x", "-x" ] },
142
- }
143
-
144
- private _t = 0
145
-
146
- private _points(): Vec3[] {
147
- if (!this.path) return []
148
- const points = pathWaypoints(this.path).map((c) => c.worldPosition)
149
- if (this.mode === "loop" && points.length > 1) points.push(points[0]!.clone())
150
- return points
151
- }
152
-
153
- update(dt: number): void {
154
- const points = this._points()
155
- if (points.length < 2) return
156
- this._t += dt
157
- const k = phase(Math.max(0, this._t - this.delay), this.duration, this.mode === "loop" ? "loop" : this.mode)
158
-
159
- const lengths: number[] = []
160
- let total = 0
161
- for (let i = 0; i < points.length - 1; i++) {
162
- const l = points[i + 1]!.sub(points[i]!).length()
163
- lengths.push(l)
164
- total += l
165
- }
166
- if (total <= 0) return
167
-
168
- let dist = k * total
169
- let i = 0
170
- while (i < lengths.length - 1 && dist > lengths[i]!) { dist -= lengths[i]!; i++ }
171
- const a = points[i]!
172
- const b = points[i + 1]!
173
- const seg = b.sub(a)
174
- const u = lengths[i]! > 0 ? Math.min(dist / lengths[i]!, 1) : 0
175
- const world = a.add(seg.scale(u))
176
- this.node.position = toParentLocal(this.node, world)
177
- if (this.orient && seg.lengthSq() > 1e-12) this.node.lookAt(world.add(seg), this.forward)
178
- }
179
-
180
- /** Editor-only waypoint polyline (edit mode; play mode never calls this). */
181
- rebuild(): void {
182
- const points = this._points() // loop mode already appends the first point again
183
- Gizmos.polyline(points, { color: MOVE_LINE }) // waypoints are empties: they carry their own markers
184
- }
185
- }
186
-
187
- /** Continuous rotation about one of the node's local axes, degrees per second. */
188
- export class Spin extends Aspect<"spin"> {
189
- /** Degrees per second. */
190
- speed = 45
191
-
192
- /** Local axis to spin around. */
193
- axis: "x" | "y" | "z" = "y"
194
-
195
- static readonly aspect = "spin"
196
- static fields: FieldMeta<Spin> = {
197
- speed: { min: -720, max: 720, step: 5 },
198
- axis: { options: [ "x", "y", "z" ] },
199
- }
200
-
201
- update(dt: number): void {
202
- const axis: [number, number, number] = this.axis === "x" ? [ 1, 0, 0 ] : this.axis === "y" ? [ 0, 1, 0 ] : [ 0, 0, 1 ]
203
- // compose in quaternion space about the LOCAL axis (q ⊗ dq) — never euler-increment
204
- this.node.quaternion = this.node.quaternion.mul(Quat.fromAxisAngle(axis, this.speed * dt * DEG2RAD))
205
- }
206
- }
207
-
208
- /** Keep the node facing a target node (a turret tracking, a signpost, a camera aimed at a hero).
209
- * Accessor `node.facing` — NOT `lookAt`, which would shadow the `Node.lookAt()` method. */
210
- export class LookAt extends Aspect<"facing"> {
211
- /** The node to face. */
212
- target: Node | null = null
213
-
214
- /** Which local axis points at the target. */
215
- forward: "-z" | "z" | "x" | "-x" = "-z"
216
-
217
- /** 0 = snap instantly; otherwise seconds of turn lag (bigger = slower, smoother). */
218
- smoothing = 0
219
-
220
- static readonly aspect = "facing"
221
- static editor = { rebuild: true }
222
- static fields: FieldMeta<LookAt> = {
223
- target: { editor: "node" },
224
- forward: { options: [ "-z", "z", "x", "-x" ] },
225
- smoothing: { min: 0, max: 5, step: 0.05 },
226
- }
227
-
228
- update(dt: number): void {
229
- if (!this.target) return
230
- const point = this.target.worldPosition
231
- if (this.smoothing <= 0) { this.node.lookAt(point, this.forward); return }
232
- const q0 = this.node.quaternion
233
- this.node.lookAt(point, this.forward)
234
- const q1 = this.node.quaternion
235
- this.node.quaternion = q0.slerp(q1, 1 - Math.exp(-dt / this.smoothing))
236
- }
237
-
238
- /** Editor-only sight line (edit mode; play mode never calls this). */
239
- rebuild(): void {
240
- if (!this.target) return
241
- Gizmos.line(this.node.worldPosition, this.target.worldPosition, { color: LOOK_LINE })
242
- }
243
- }
244
-
245
- /** Start a GLB animation clip when the scene runs. Attach to a `model:` node; the inspector card
246
- * lists the model's clips live and can preview them while editing. */
247
- export class PlayAnimation extends Aspect<"playAnimation", Model> {
248
- /** Clip name; empty = the model's first clip. */
249
- clip = ""
250
-
251
- loop = true
252
-
253
- /** Playback rate (1 = authored speed). */
254
- speed = 1
255
-
256
- static readonly aspect = "playAnimation"
257
- static fields: FieldMeta<PlayAnimation> = {
258
- speed: { min: 0.05, max: 5, step: 0.05 },
259
- }
260
-
261
- private _preview?: Playback
262
-
263
- onAttach(): void {
264
- const anim = (this.node as Model | undefined)?.anim
265
- if (!anim) return
266
- if (this.loop) anim.playLoop(this.clip === "" ? 0 : this.clip, { speed: this.speed })
267
- else anim.play(this.clip === "" ? 0 : this.clip, { speed: this.speed })
268
- }
269
-
270
- static inspector(ui: InspectorUI, a: PlayAnimation): void {
271
- const anim = (a.node as Model | undefined)?.anim
272
- const clips = anim ? anim.clips : []
273
- if (clips.length === 0) {
274
- ui.warn("No animation clips — attach this to a GLB model node")
275
- return
276
- }
277
- ui.select("clip", clips.map((c) => c.name))
278
- ui.auto("loop", "speed")
279
- if (anim) {
280
- const clip = a.clip === "" ? clips[0]?.name : a.clip
281
- const playing = a._preview?.playing === true
282
- if (ui.button(playing ? "Restart preview" : "Preview")) {
283
- if (a.loop) { anim.playLoop(clip, { speed: a.speed }); a._preview = undefined }
284
- else a._preview = anim.play(clip, { speed: a.speed, restart: true })
285
- }
286
- if (playing && ui.button("Stop")) { anim.stop(); a._preview = undefined }
287
- const duration = clips.find((c) => c.name === clip)?.duration
288
- ui.info(playing ? "previewing…" : duration !== undefined ? `${duration.toFixed(2)}s` : "")
289
- }
290
- }
291
- }
@@ -1,6 +0,0 @@
1
- // Tiny shared module to break the Node ↔ Scene ↔ touch dependency cycle. The active 3D scene is set
2
- // here by Scene.open()/close() and read by the touch dispatch system.
3
-
4
- import type { Scene } from "./Scene"
5
-
6
- export const glState: { activeScene: Scene | null, frame: number } = { activeScene: null, frame: 0 }
@@ -1,68 +0,0 @@
1
- // 3D pointer dispatch. Registers the host touch callbacks lazily (first listener) and routes hits to
2
- // the struck Node and to the active scene's listeners. Ported from worker/src/TouchEventSystem.ts.
3
-
4
- import { ClickEvent, TouchStartEvent, type TrackHandler } from "../runtime/touch"
5
- import { nodeRegistry } from "./Node"
6
- import { glState } from "./state"
7
-
8
- // Hits inside a loaded model (GLB) land on sub-entities the user never created a Node for — walk up
9
- // the transform hierarchy to the nearest entity someone actually holds (the model's Node).
10
- const resolveHitNode = (entityId: number) => {
11
- let node = nodeRegistry.get(entityId)
12
- for (let id = entityId, i = 0; !node && i < 32; i++) {
13
- id = _creator.getParent(id)
14
- if (id === 0) break
15
- node = nodeRegistry.get(id)
16
- }
17
- return node ?? null
18
- }
19
-
20
- const onTouchEnd = (pointerId: number, clientX: number, clientY: number, entityId: number): TrackHandler | null => {
21
- const scene = glState.activeScene
22
- if (!scene) return null
23
- const ev = new ClickEvent<any>(clientX, clientY, pointerId)
24
- if (entityId > 0) {
25
- const node = resolveHitNode(entityId)
26
- ev.target = node
27
- if (node) node._dispatchEvent("click", ev)
28
- } else {
29
- ev.target = null
30
- }
31
- for (const listener of scene._clickListeners.slice()) listener(ev)
32
- return null
33
- }
34
-
35
- const onTouchStart = (pointerId: number, clientX: number, clientY: number, entityId: number): TrackHandler | null => {
36
- const scene = glState.activeScene
37
- if (!scene) return null
38
- const ev = new TouchStartEvent<any>(clientX, clientY, pointerId)
39
- if (entityId > 0) {
40
- const node = resolveHitNode(entityId)
41
- ev.target = node
42
- if (node) {
43
- node._dispatchEvent("touchstart", ev)
44
- if (ev._trackHandler) return ev._trackHandler
45
- }
46
- } else {
47
- ev.target = null
48
- }
49
- for (const listener of scene._touchStartListeners.slice()) {
50
- listener(ev)
51
- if (ev._trackHandler) return ev._trackHandler
52
- }
53
- return null
54
- }
55
-
56
- let touchStartRegistered = false
57
- export const registerTouchStartEvent = (): void => {
58
- if (touchStartRegistered) return
59
- touchStartRegistered = true
60
- _creatorUI.registerTouchStartEvent(onTouchStart)
61
- }
62
-
63
- let touchEndRegistered = false
64
- export const registerTouchEndEvent = (): void => {
65
- if (touchEndRegistered) return
66
- touchEndRegistered = true
67
- _creatorUI.registerTouchEndEvent(onTouchEnd)
68
- }
@@ -1,186 +0,0 @@
1
- // THE aggregation point. Every public global the SDK provides is re-exported here under the exact
2
- // name user code uses it as. The bundler passes this file to esbuild's `inject:` option, so user
3
- // code references `Scene`, `Sprite`, `toast`, … with no imports; esbuild tree-shakes away whatever
4
- // a given project does not use (so a pure-2D project drops all 3D classes, and vice versa).
5
- //
6
- // Rule: this is the ONLY file that `export`s public names. Everything else is internal and imported
7
- // by it. Host-provided globals (setLoop, console, setTimeout, DEG2RAD, asset, …) are NOT here —
8
- // they live in src/host.d.ts as declarations and stay as free references at runtime.
9
-
10
- // ---- math ----
11
- export { Mathf } from "./math/Mathf"
12
- export { Vec2, Vec3 } from "./math/vec"
13
- export { Quat } from "./math/quat"
14
- export { Mat4 } from "./math/mat4"
15
- export { Color } from "./core/color"
16
-
17
- // ---- aspects (attachable node capabilities) ----
18
- export { Aspect, System, type With, type SystemHost } from "./core/Aspect"
19
- export { type EventMap } from "./core/events"
20
- export { Time } from "./core/time"
21
- export { InspectorUI } from "./core/InspectorUI"
22
-
23
- // ---- reactivity (signals; UI text/style props also accept `() => value` bindings) ----
24
- export { signal, computed, effect, type Signal, type Computed } from "./core/signals"
25
- export { __compWrite, __compOp, type CompAxis, type CompWriter } from "./core/compWrite"
26
-
27
- // ---- canvas (core 2D drawing that bakes to a texture; shared by 2D/3D/UI) ----
28
- export { Canvas, Bitmap } from "./canvas/Canvas"
29
-
30
- // ---- platform runtime (injected globals; the host provides the lower-level _creator* bridges) ----
31
- export { toast, openURL, SvgSource } from "./runtime/misc"
32
- export { app, type AppState, type OrientationLock } from "./runtime/app"
33
- export { clipboard } from "./runtime/clipboard"
34
- export { date, type DateValue, type DateInput, type Unit, type Locale } from "./runtime/datetime"
35
- export { fetch, fetchLocal, FormData, File, type FetchResponse } from "./runtime/fetch"
36
- export { localStorage } from "./runtime/storage"
37
- export { device, type HapticStyle, type MotionOptions } from "./runtime/device"
38
- export { Input, InputChannel, type InputKeyEvent, type InputGamepadEvent, type InputEventName, type GamepadState, type GamepadAxisName } from "./runtime/input"
39
- export { WebSocket } from "./runtime/net"
40
- // App-backend transport: the compiler-generated stubs of `*.server.ts` modules call these; user code
41
- // only ever imports its server functions (docs/backend-plan.md §4).
42
- export { __rpc, __channel, __serverOnly, RpcError, type ClientChannel } from "./runtime/rpc"
43
- export { AudioPlayer, VideoPlayer } from "./runtime/media"
44
- export { openFilePicker } from "./runtime/files"
45
- export { share } from "./runtime/share"
46
- export { ClickEvent, TouchStartEvent, LongPressEvent } from "./runtime/touch"
47
-
48
- // ---- 2D engine (creator-2d) ----
49
- export { Scene2D } from "./g2/Scene2D"
50
- export { Node2D } from "./g2/Node2D"
51
- export { Camera2D } from "./g2/Camera2D"
52
- export { Sprite } from "./g2/Sprite"
53
- export { SpriteAnimation } from "./g2/SpriteAnimation"
54
- export { Shape2D } from "./g2/Shape2D"
55
- export { Physics2D } from "./g2/Physics2D"
56
- export { Trigger2D } from "./g2/Trigger2D"
57
- export { CharacterController2D } from "./g2/CharacterController2D"
58
- export { OneWay2D } from "./g2/OneWay2D"
59
- export { PhysicsGroup2D } from "./g2/groups2d"
60
- export { Tilemap } from "./g2/Tilemap"
61
- export { Texture2D } from "./g2/Texture2D"
62
- // sprite sheets as data (.sprite.ts files — see src/g2/SpriteSheet.ts)
63
- export { SpriteSheet, defineSpriteSheet } from "./g2/SpriteSheet"
64
- export type { SpriteSheetDef, SheetSprite, SpriteMakeOptions } from "./g2/SpriteSheet"
65
- // tilesets as data (.tiles.ts files — autotile materials, see src/g2/Tileset.ts + autotile.ts)
66
- export { Tileset, defineTileset, Autotile2D } from "./g2/Tileset"
67
- export { rawCell, isRawCell, rawIndex } from "./g2/autotile"
68
- export { rot90, rot180, rot270, flipX, packTile, tileIndex, tileTurns, tileFlip, tileOriented } from "./g2/autotile"
69
- export type {
70
- TilesetDef, TileMaterial, PatchMaterial, PathMaterial, PatchSlots, EdgeSlot, FillBlock, BlockEntry,
71
- TileBlock, TilePart,
72
- } from "./g2/autotile"
73
- // 2D scenes as data (.scene2d.ts files — see src/g2/defineScene2d.ts) + the cells('…') payload
74
- export { defineScene2d, Scene2dHandle } from "./g2/defineScene2d"
75
- export type { Scene2dDef, Scene2dNodeDef, Scene2dEnv, SpriteSourceDef, TilemapSourceDef, Camera2dNodeDef, LoadedScene2d } from "./g2/defineScene2d"
76
- export { cells, encodeCells, type CellsData } from "./g2/cells"
77
- // no-code 2D scenario aspects (attachable in scene files — see src/g2/scenarios2d.ts)
78
- export { CameraFollow } from "./g2/scenarios2d"
79
-
80
- // ---- UI (creator-ui) ----
81
- export {
82
- UIScreen, type UIScreenStyle,
83
- UIRow, UIColumn, UIBox, type UIContainerStyle,
84
- UIText, type UITextStyle,
85
- UIButton, type UIButtonStyle,
86
- UIImage, type UIImageStyle,
87
- UIVideo, type UIVideoStyle,
88
- UIInput, UITextArea, type UIInputStyle,
89
- UIScrollable, type UIScrollableStyle,
90
- UIPager, type UIPagerStyle,
91
- UITabs, type UITabDef,
92
- defineTabs, type TabDef, type TabsHandle,
93
- UIWidget, type UIWidgetStyle,
94
- UIModal, type UIModalStyle,
95
- UIBottomSheet, type UIBottomSheetStyle,
96
- UIPopover, type UIPopoverStyle,
97
- UISpacer, type UISpacerStyle,
98
- UIVirtualizedList,
99
- Router,
100
- NativeView, type UINativeViewStyle,
101
- registerFont,
102
- __uiMap,
103
- __UIColumn, __UIRow, __UIBox, __UIButton, __UIScreen, __UIScrollable, __UIWidget,
104
- } from "./ui/UI"
105
- // The Presentable navigation contract (docs/navigation-presentable-plan.md). `Presentable` is
106
- // interface + runtime companion (declaration merging): `Presentable.current` = what's on screen.
107
- export { Presentable } from "./ui/UI"
108
- export type { PresentOptions, Transition, TransitionName, TransitionSpec, TransitionTransform } from "./ui/UI"
109
- // The base node type + the union a container accepts as children — documented as the signature of
110
- // UIColumn/UIRow/append/etc., so they must be global (type-only; erased at runtime).
111
- export type { UINode, UINodeChild } from "./ui/UINode"
112
- // App theme variables (docs/ui-theme-plan.md): theme({...}) merges + returns typed var()
113
- // accessors; system vars are static props (theme.primaryColor, theme["comfort-top"], …).
114
- export { theme, type ThemeValues, type ThemeAccessors } from "./ui/theme"
115
-
116
- // ---- animate ----
117
- export { animate, animateMat4, stopAnimation, pauseAnimation, resumeAnimation } from "./animate/animate"
118
- export { cubicBezier } from "./animate/bezier"
119
- export { easeIn, easeOut, easeInOut } from "./animate/easings"
120
-
121
- // ---- plugins (optional, host-provided capabilities — typed NativeView/service wrappers, see src/plugins/) ----
122
- export { QRScanner } from "./plugins/qr"
123
- export { CameraView, type CameraFacing } from "./plugins/camera"
124
- export { Geolocation, type GeoPosition, type GeoOptions, type GeoWatch } from "./plugins/geolocation"
125
- export { Push, type PushPayload, type PushStatus, type PushRegisterOptions, type PushEvent } from "./plugins/push"
126
- export { OAuth, type OAuthCredential, type OAuthProviderName } from "./plugins/oauth"
127
- export { Service } from "./plugins/service"
128
-
129
- // ---- scenes as data (.scene.ts files — see src/scene/defineScene.ts) ----
130
- export { defineScene, use, ref, make, SceneHandle, applyEditorPose as __applyEditorPose } from "./scene/defineScene"
131
- export {
132
- defineMaterial, MaterialHandle,
133
- // editor-harness helpers (the scene editor's live material paths — not app API)
134
- assignMaterialDef as __assignMaterialDef, applyMaterialParam as __applyMaterialParam,
135
- } from "./scene/material"
136
- export type { MaterialData, MaterialParamValue, ShaderMaterialDef, LitMaterialDef, UnlitMaterialDef } from "./scene/material"
137
- export type { SceneDef, SceneNodeDef, MeshDef, LightDef, MaterialDef, CameraNodeDef, AspectEntry, MakeEntry, LoadedScene, SceneInstance } from "./scene/defineScene"
138
- export { CameraPlace } from "./gl/CameraPlace"
139
- export type { FieldMeta } from "./core/fields"
140
- // Editor-only line drawing from generator rebuild() / make() factories / tool hooks — drawn by the
141
- // scene editor's viewport overlay, a no-op everywhere else (see src/scene/gizmos.ts).
142
- export { Gizmos, GizmoBuffer as __GizmoBuffer, withGizmoScope as __withGizmoScope } from "./scene/gizmos"
143
- export type { GizmoStyle, GizmoAnchor } from "./scene/gizmos"
144
-
145
- // ---- no-code scenario aspects (attachable in the scene editor — see src/gl/scenarios.ts) ----
146
- export { MoveTo, FollowPath, Spin, LookAt, PlayAnimation } from "./gl/scenarios"
147
-
148
- // ---- editor plugins (called from `*.editor.ts` files — editor bundles only; DCE'd from apps) ----
149
- export { registerEditorWindow, registerEditorTool, __editorPlugins } from "./scene/editorPlugins"
150
- export type { EditorApi, EditorRayHit, EditorToolHooks, EditorWindowFn } from "./scene/editorPlugins"
151
-
152
- // ---- 3D engine (creator-gl) ----
153
- export { Scene, ARScene, VRScene } from "./gl/Scene"
154
- export { Node } from "./gl/Node"
155
- export { Mesh } from "./gl/Mesh"
156
- export { Model } from "./gl/Model"
157
- export { Shape } from "./gl/Shape"
158
- export { Physics } from "./gl/Physics"
159
- export { Trigger } from "./gl/Trigger"
160
- export { CharacterController } from "./gl/CharacterController"
161
- export { Vehicle } from "./gl/Vehicle"
162
- export type { DriveLayout, DifferentialMode, EngineConfig, SteeringConfig, AeroConfig } from "./gl/Vehicle"
163
- export { Wheel } from "./gl/Wheel"
164
- export type { TireCurve, WheelSuspension, WheelTire, WheelVisual } from "./gl/Wheel"
165
- export { Gearbox } from "./gl/Gearbox"
166
- export { AnimationClip } from "./gl/animation/AnimationClip"
167
- export type { ClipDef, ClipTrackDef, ClipKey } from "./gl/animation/AnimationClip"
168
- export { Animator } from "./gl/animation/Animator"
169
- export { Playback } from "./gl/animation/Playback"
170
- export { Loop } from "./gl/animation/Loop"
171
- export { Layer } from "./gl/animation/Layer"
172
- export type { PlayOptions, StopOptions, LayerOptions, LoopOptions, LoopDef, BlendPosition } from "./gl/animation/core"
173
- export { IK } from "./gl/IK"
174
- export type { IKTwoBone, IKLookAt } from "./gl/IK"
175
- export { Light } from "./gl/Light"
176
- export { Lightmap } from "./gl/Lightmap"
177
- export { Material } from "./gl/Material"
178
- export { Geometry } from "./gl/Geometry"
179
- export { InstancedMesh } from "./gl/InstancedMesh"
180
- export type { InstanceTransform } from "./gl/InstancedMesh"
181
- export { Texture } from "./gl/Texture"
182
- export { Camera } from "./gl/Camera"
183
- export { Ray } from "./gl/Ray"
184
- export { Plane } from "./gl/Plane"
185
- export { Noise } from "./gl/Noise"
186
- export { Particles, Trail, curve, colorCurve } from "./gl/Particles"
@@ -1,118 +0,0 @@
1
- // Scalar / general math helpers, exposed to user code as the `Mathf` global. Vector & quaternion
2
- // helpers live with the engine that uses them (vec2 in g2/, vec3+quat in gl/). `smoothDamp` works on
3
- // both numbers and numeric arrays here (no gl-matrix), which covers 2D (vec2) and 3D position damping.
4
-
5
- export type Damper<T extends number | number[]> = ((target: T, dt: number) => T) & {
6
- /** Snap the damper's internal current value (e.g. on teleport). */
7
- setValue(value: T): void
8
- }
9
-
10
- const clamp = (v: number, min: number, max: number): number => (v < min ? min : v > max ? max : v)
11
-
12
- const smoothDampNumber = (initial: number, smoothTime: number, maxSpeed: number): Damper<number> => {
13
- let current = initial
14
- let velocity = 0
15
- const damp = ((target: number, dt: number): number => {
16
- smoothTime = Math.max(0.0001, smoothTime)
17
- const omega = 2 / smoothTime
18
- const x = omega * dt
19
- const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x)
20
- const maxDelta = maxSpeed * smoothTime
21
- let delta = clamp(current - target, -maxDelta, maxDelta)
22
- const newTarget = current - delta
23
- const temp = (velocity + omega * delta) * dt
24
- velocity = (velocity - omega * temp) * exp
25
- current = newTarget + (delta + temp) * exp
26
- return current
27
- }) as Damper<number>
28
- damp.setValue = (v) => { current = v; velocity = 0 }
29
- return damp
30
- }
31
-
32
- function smoothDamp(initial: number, smoothTime: number, maxSpeed?: number): Damper<number>
33
- function smoothDamp(initial: number[], smoothTime: number, maxSpeed?: number): Damper<number[]>
34
- function smoothDamp(initial: any, smoothTime: number, maxSpeed = Infinity): any {
35
- return typeof initial === "number"
36
- ? smoothDampNumber(initial, smoothTime, maxSpeed)
37
- : smoothDampArray(initial, smoothTime, maxSpeed)
38
- }
39
-
40
- const smoothDampArray = (initial: number[], smoothTime: number, maxSpeed: number): Damper<number[]> => {
41
- const n = initial.length
42
- let current = initial.slice()
43
- const velocity = new Array(n).fill(0)
44
- const damp = ((target: number[], dt: number): number[] => {
45
- smoothTime = Math.max(0.0001, smoothTime)
46
- const omega = 2 / smoothTime
47
- const x = omega * dt
48
- const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x)
49
- const maxDelta = maxSpeed * smoothTime
50
-
51
- const delta = new Array(n)
52
- let mag = 0
53
- for (let i = 0; i < n; i++) { delta[i] = current[i] - target[i]; mag += delta[i] * delta[i] }
54
- mag = Math.sqrt(mag)
55
- if (mag > maxDelta && mag > 0) {
56
- const s = maxDelta / mag
57
- for (let i = 0; i < n; i++) delta[i] *= s
58
- }
59
-
60
- const out = new Array(n)
61
- for (let i = 0; i < n; i++) {
62
- const newTarget = current[i] - delta[i]
63
- const temp = (velocity[i] + omega * delta[i]) * dt
64
- velocity[i] = (velocity[i] - omega * temp) * exp
65
- out[i] = newTarget + (delta[i] + temp) * exp
66
- }
67
- current = out
68
- return out.slice()
69
- }) as Damper<number[]>
70
- damp.setValue = (v) => { current = v.slice(); velocity.fill(0) }
71
- return damp
72
- }
73
-
74
- export const Mathf = {
75
- PI: Math.PI,
76
- TAU: Math.PI * 2,
77
- EPSILON: 1e-6,
78
- DEG2RAD: Math.PI / 180,
79
- RAD2DEG: 180 / Math.PI,
80
-
81
- deg2rad: (deg: number): number => deg * (Math.PI / 180),
82
- rad2deg: (rad: number): number => rad * (180 / Math.PI),
83
-
84
- clamp,
85
- clamp01: (v: number): number => clamp(v, 0, 1),
86
- lerp: (a: number, b: number, t: number): number => a + (b - a) * t,
87
- inverseLerp: (a: number, b: number, v: number): number => (a === b ? 0 : (v - a) / (b - a)),
88
- remap: (v: number, inMin: number, inMax: number, outMin: number, outMax: number): number =>
89
- outMin + ((v - inMin) / (inMax - inMin)) * (outMax - outMin),
90
-
91
- /** Move `a` toward `b` by at most `maxDelta`. */
92
- moveTowards: (a: number, b: number, maxDelta: number): number => {
93
- const d = b - a
94
- return Math.abs(d) <= maxDelta ? b : a + Math.sign(d) * maxDelta
95
- },
96
- /** Frame-rate-independent exponential approach (good default: lambda 5..15). */
97
- damp: (a: number, b: number, lambda: number, dt: number): number => a + (b - a) * (1 - Math.exp(-lambda * dt)),
98
-
99
- sign: Math.sign,
100
- /** Loop a value into [0, length). */
101
- repeat: (t: number, length: number): number => clamp(t - Math.floor(t / length) * length, 0, length),
102
- /** Ping-pong a value in [0, length]. */
103
- pingPong: (t: number, length: number): number => {
104
- const r = clamp(t - Math.floor(t / (length * 2)) * (length * 2), 0, length * 2)
105
- return length - Math.abs(r - length)
106
- },
107
-
108
- random: (min = 0, max = 1): number => min + Math.random() * (max - min),
109
- randomInt: (min: number, max: number): number => Math.floor(min + Math.random() * (max - min + 1)),
110
-
111
- /**
112
- * Critically-damped follow (Unity SmoothDamp). Returns a stateful damper you call every frame:
113
- * const d = Mathf.smoothDamp([x, y], 0.15)
114
- * pos = d(targetPos, dt)
115
- * Works on a number or a numeric array (vec2 / vec3).
116
- */
117
- smoothDamp,
118
- }