lecodes-sdk 2.4.1 → 2.4.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 (51) hide show
  1. package/dist/types/core/Aspect.d.ts +34 -5
  2. package/dist/types/g2/OneWay2D.d.ts +0 -1
  3. package/dist/types/g2/Physics2D.d.ts +8 -6
  4. package/dist/types/g2/Scene2D.d.ts +1 -1
  5. package/dist/types/g2/Shape2D.d.ts +43 -15
  6. package/dist/types/gl/Model.d.ts +3 -2
  7. package/dist/types/gl/Scene.d.ts +1 -1
  8. package/dist/types/gl/animation/DynamicBone.d.ts +99 -35
  9. package/dist/types/gl/animation/IK.d.ts +0 -1
  10. package/dist/types/gl/nav/NavAgent.d.ts +3 -2
  11. package/dist/types/gl/physics/Physics.d.ts +4 -5
  12. package/dist/types/gl/physics/Shape.d.ts +40 -15
  13. package/dist/types/gl/vehicle/Vehicle.d.ts +54 -35
  14. package/dist/types/gl/vehicle/Wheel.d.ts +31 -10
  15. package/dist/types/plugins/gen/ar/contract.d.ts +152 -0
  16. package/dist/types/plugins/gen/ar/sdk/ar.d.ts +47 -21
  17. package/dist/types/plugins/gen/ar/sdk/ar.gen.d.ts +17 -3
  18. package/dist/types/plugins/gen/audio-recorder/contract.d.ts +64 -0
  19. package/dist/types/plugins/gen/browser/contract.d.ts +108 -0
  20. package/dist/types/plugins/gen/camera/contract.d.ts +27 -0
  21. package/dist/types/plugins/gen/geolocation/contract.d.ts +52 -0
  22. package/dist/types/plugins/gen/map/contract.d.ts +144 -0
  23. package/dist/types/plugins/gen/push/contract.d.ts +83 -0
  24. package/dist/types/plugins/gen/qr-scanner/contract.d.ts +16 -0
  25. package/dist/types/plugins/gen/speech/contract.d.ts +67 -0
  26. package/dist/types/plugins/gen/webrtc/contract.d.ts +342 -0
  27. package/dist/types/version.d.ts +1 -1
  28. package/dist/types.json +1 -1
  29. package/package.json +1 -1
  30. package/src/bridges/gl.d.ts +5 -3
  31. package/src/compile/compileProject.ts +45 -10
  32. package/src/compile/index.ts +7 -0
  33. package/src/compile/webHalf.ts +255 -0
  34. package/src/core/Aspect.ts +118 -35
  35. package/src/g2/OneWay2D.ts +0 -2
  36. package/src/g2/Physics2D.ts +8 -16
  37. package/src/g2/Scene2D.ts +1 -1
  38. package/src/g2/Shape2D.ts +51 -22
  39. package/src/gl/Model.ts +3 -2
  40. package/src/gl/Scene.ts +1 -1
  41. package/src/gl/animation/DynamicBone.ts +549 -486
  42. package/src/gl/animation/IK.ts +0 -2
  43. package/src/gl/nav/NavAgent.ts +14 -12
  44. package/src/gl/physics/Physics.ts +4 -5
  45. package/src/gl/physics/Shape.ts +49 -23
  46. package/src/gl/vehicle/Vehicle.ts +102 -58
  47. package/src/gl/vehicle/Wheel.ts +45 -11
  48. package/src/plugins/gen/ar/contract.d.ts +35 -1
  49. package/src/plugins/gen/ar/sdk/ar.gen.ts +25 -6
  50. package/src/plugins/gen/ar/sdk/ar.ts +102 -35
  51. package/src/version.ts +1 -1
package/src/g2/Scene2D.ts CHANGED
@@ -132,7 +132,7 @@ export class Scene2D implements Presentable {
132
132
  * types: it is what makes a Scene2D a `SystemHost` there. */
133
133
  readonly _systems = new Map<Function, Aspect<any, any, any>>()
134
134
 
135
- /** Attach (and configure) a system, or reconfigure it if already present. Returns the scene typed
135
+ /** Build a system from `opts` (a class already on the scene is detached and built afresh). Returns the scene typed
136
136
  * as now-having it (`scene.system(Hud).hud`). A 3D `System<'x'>` (target Scene) is rejected here. */
137
137
  // `this: Self` (not `Self & Scene2D`): with the intersection TS infers Self = Scene2D and a chain
138
138
  // `scene.system(A).system(B)` loses A's accessor from the result type.
package/src/g2/Shape2D.ts CHANGED
@@ -12,11 +12,12 @@
12
12
  // a collider that wraps the art instead of one centred on the pivot (half of it underground), which
13
13
  // is why every character used to carry a hand-computed offset.
14
14
  //
15
- // RE-CONFIGURING REBUILDS IT IN PLACE: `node.aspect(Shape2D, { capsule: … })` on a live node swaps the
16
- // fixture while the body keeps its id, its velocity and its place in the world. That is what makes a
17
- // crouch (and a live editor edit) possible.
15
+ // EVERY DIMENSION IS LIVE: `node.shape.capsule = …` on a live node swaps the fixture at once while the
16
+ // body keeps its id, its velocity and its place in the world. That is what makes a crouch (and a
17
+ // live editor edit) possible.
18
18
 
19
19
  import { Aspect } from "../core/Aspect"
20
+ import type { FieldMeta } from "../core/fields"
20
21
  import { Vec2, cx, cy, type Vec2Like } from "../math/vec"
21
22
  import { ALL_GROUPS } from "./groups2d"
22
23
  import type { Node2D } from "./Node2D"
@@ -35,17 +36,36 @@ export type ShapeFixture2D = {
35
36
  export class Shape2D extends Aspect<"shape", Node2D> {
36
37
  static readonly aspect = "shape"
37
38
 
39
+ // Every dimension is LIVE and applies AT ONCE: a write swaps the fixture in place, the body keeping
40
+ // its id, its velocity and its place in the world (a crouch, a live editor edit) — synchronous,
41
+ // because the caller reads the result back right away (`controller.resizing`). A write that leaves
42
+ // the geometry's signature unchanged does nothing.
43
+ private _box?: Vec2Like
44
+ private _circle?: number
45
+ private _cap?: { from: Vec2Like, to: Vec2Like, radius: number } // `_capsule()` is the mover's view
46
+ private _segment?: { from: Vec2Like, to: Vec2Like }
47
+ private _polygon?: Vec2Like[]
48
+ private _chain?: Vec2Like[]
49
+ private _loop?: boolean
50
+ private _flip?: boolean
51
+ private _origin?: Vec2Like
52
+
38
53
  /** Box half-extents [hw, hh] (world units). */
39
- box?: Vec2Like
54
+ get box(): Vec2Like | undefined { return this._box }
55
+ set box(v: Vec2Like | undefined) { this._box = v; this._changed() }
40
56
  /** Circle radius. */
41
- circle?: number
57
+ get circle(): number | undefined { return this._circle }
58
+ set circle(v: number | undefined) { this._circle = v; this._changed() }
42
59
  /** Capsule between two local points, with a radius. */
43
- capsule?: { from: Vec2Like, to: Vec2Like, radius: number }
60
+ get capsule(): { from: Vec2Like, to: Vec2Like, radius: number } | undefined { return this._cap }
61
+ set capsule(v: { from: Vec2Like, to: Vec2Like, radius: number } | undefined) { this._cap = v; this._changed() }
44
62
  /** Thin segment (an edge) between two local points. */
45
- segment?: { from: Vec2Like, to: Vec2Like }
63
+ get segment(): { from: Vec2Like, to: Vec2Like } | undefined { return this._segment }
64
+ set segment(v: { from: Vec2Like, to: Vec2Like } | undefined) { this._segment = v; this._changed() }
46
65
  /** Convex polygon, up to 8 local points (a convex hull is computed — a CONCAVE outline silently
47
66
  * becomes its hull; use `chain` for those). */
48
- polygon?: Vec2Like[]
67
+ get polygon(): Vec2Like[] | undefined { return this._polygon }
68
+ set polygon(v: Vec2Like[] | undefined) { this._polygon = v; this._changed() }
49
69
  /**
50
70
  * A polyline of connected segments — the one shape that expresses a long CONCAVE surface (rolling
51
71
  * terrain, a cave wall) in one piece, seam-free. Pass only the points that should be solid; the
@@ -55,14 +75,23 @@ export class Shape2D extends Aspect<"shape", Node2D> {
55
75
  * must not self-intersect. It is ONE-SIDED: solid on the right of the point order — walk the points
56
76
  * so that the solid material is on your right, or set `flip`.
57
77
  */
58
- chain?: Vec2Like[]
78
+ get chain(): Vec2Like[] | undefined { return this._chain }
79
+ set chain(v: Vec2Like[] | undefined) { this._chain = v; this._changed() }
59
80
  /** `chain`: close the contour (an island / a room boundary). Needs at least 4 points. */
60
- loop?: boolean
81
+ get loop(): boolean | undefined { return this._loop }
82
+ set loop(v: boolean | undefined) { this._loop = v; this._changed() }
61
83
  /** `chain`: put the solid side on the other side of the line. */
62
- flip?: boolean
84
+ get flip(): boolean | undefined { return this._flip }
85
+ set flip(v: boolean | undefined) { this._flip = v; this._changed() }
63
86
  /** The collider's centre relative to the node, in world units. Applies to EVERY kind — it
64
87
  * translates a capsule's / segment's / polygon's / chain's points too, unlike the old `offset`. */
65
- origin?: Vec2Like
88
+ get origin(): Vec2Like | undefined { return this._origin }
89
+ set origin(v: Vec2Like | undefined) { this._origin = v; this._changed() }
90
+
91
+ /** Scene-editor inspector: the geometry fields (accessors, so they are listed here by name). */
92
+ static fields: FieldMeta<Shape2D> = {
93
+ box: {}, circle: {}, capsule: {}, segment: {}, polygon: {}, chain: {}, loop: {}, flip: {}, origin: {},
94
+ }
66
95
 
67
96
  /** @internal Geometry as of the last build — an unchanged signature means nothing to rebuild. */
68
97
  private _sig = ""
@@ -72,7 +101,7 @@ export class Shape2D extends Aspect<"shape", Node2D> {
72
101
  private _fx: ShapeFixture2D | null = null
73
102
  private _handle = 0
74
103
 
75
- /** @internal — the character claimed this shape; record the geometry so a later re-configure is
104
+ /** @internal — the character claimed this shape; record the geometry so a later write is
76
105
  * compared against it. */
77
106
  _claimedByCharacter(): void { this._sig = this._signature(); this._resizeRefused = false }
78
107
 
@@ -97,11 +126,11 @@ export class Shape2D extends Aspect<"shape", Node2D> {
97
126
  onDetach(): void { this._handle = 0; this._fx = null; this._sig = ""; this._resizeRefused = false }
98
127
 
99
128
  /**
100
- * Re-configuring the aspect swaps the fixture in place — same body, same id, same velocity, same
101
- * position. Nothing happens when the geometry is unchanged, so re-applying the same options in a
102
- * loop is free.
129
+ * A dimension was written: swap the fixture in place — same body, same id, same velocity, same
130
+ * position. Nothing happens when the signature is unchanged, so writing the same dimensions every
131
+ * frame is free.
103
132
  */
104
- onReconfigure(): void {
133
+ private _changed(): void {
105
134
  const sig = this._signature()
106
135
  if (sig === this._sig) return
107
136
 
@@ -110,9 +139,9 @@ export class Shape2D extends Aspect<"shape", Node2D> {
110
139
  if (this.node._xfKind === 1) {
111
140
  const cap = this._capsule()
112
141
  const ok = _creator2d.characterSetCapsule(this.node._xf, cap.x1, cap.y1, cap.x2, cap.y2, cap.radius)
113
- // On refusal NOTHING changed — so DON'T commit the signature. The next identical
114
- // `aspect(Shape2D, …)` then still sees a difference and retries; committing here would swallow
115
- // every retry for good, which is the whole trap in this design.
142
+ // On refusal NOTHING changed — so DON'T commit the signature. The next write of the same
143
+ // dimensions then still sees a difference and retries; committing here would swallow every
144
+ // retry for good, which is the whole trap in this design.
116
145
  this._resizeRefused = !ok
117
146
  if (ok) this._sig = sig
118
147
  return
@@ -218,7 +247,7 @@ export class Shape2D extends Aspect<"shape", Node2D> {
218
247
  _creator2d.physicsAddChain(handle, new Float32Array(p), p.length / 2, loop, fx.friction, fx.bounce, category, mask)
219
248
  }
220
249
 
221
- // Everything that changes the GEOMETRY, so a re-configure that only touches the material is free.
250
+ // Everything that changes the GEOMETRY, so a write that changed nothing is free.
222
251
  private _signature(): string {
223
252
  const o = this.origin ? `${cx(this.origin)},${cy(this.origin)}` : ""
224
253
  if (this.chain) return `chain:${this.chain.map(v => `${cx(v)},${cy(v)}`).join(";")}|${this.loop}|${this.flip}|${o}`
@@ -243,7 +272,7 @@ export class Shape2D extends Aspect<"shape", Node2D> {
243
272
  * Sprite anchor space is Y-DOWN while the world is Y-up (see docs/conventions.md), so `anchor: [.5, 1]`
244
273
  * ("feet") puts the art ABOVE the origin: its centre sits at +h/2. A node with no sprite falls back
245
274
  * to 8x8 at the origin. This is a SNAPSHOT taken when the fixture is built — growing the sprite later
246
- * does not resize the collider; re-configure the aspect to re-measure.
275
+ * does not resize the collider; write a dimension (`origin = undefined` will do) to re-measure.
247
276
  */
248
277
  private _autoBox(): { hw: number, hh: number, x: number, y: number } {
249
278
  const n = this.node as { size?: Vec2, anchor?: Vec2, scale?: Vec2 }
package/src/gl/Model.ts CHANGED
@@ -35,8 +35,9 @@ export interface TrianglePick {
35
35
  }
36
36
 
37
37
  export class Model extends Node {
38
- /** The model's Animator — always present, its clip table = the GLB's embedded clips. Configure
39
- * more (external clips, blend spaces, layers) with `model.aspect(Animator, {...})`. */
38
+ /** The model's Animator — always present, its clip table = the GLB's embedded clips. Add to it
39
+ * with `model.anim.addClip(name, clip)` (external clips), `model.anim.addLayer()`; set its fields
40
+ * (`model.anim.speed = 1.5`) — never `model.aspect(Animator, …)`, which would build a fresh one. */
40
41
  declare readonly anim: Animator
41
42
  /** @internal loaded through the lightmap material (a baked static); clones inherit it. */
42
43
  _lightmapped = false
package/src/gl/Scene.ts CHANGED
@@ -364,7 +364,7 @@ export class Scene implements Presentable {
364
364
  * types: it is what makes a Scene a `SystemHost` there. */
365
365
  readonly _systems = new Map<Function, Aspect<any, any, any>>()
366
366
 
367
- /** Attach (and configure) a system, or reconfigure it if already present. Returns the scene typed
367
+ /** Build a system from `opts` (a class already on the scene is detached and built afresh). Returns the scene typed
368
368
  * as now-having it (`scene.system(Hud).hud`). A `System<'x', Scene2D>` is rejected here. */
369
369
  // `this: Self` (not `Self & Scene`): with the intersection TS infers Self = Scene and a chain
370
370
  // `scene.system(A).system(B)` loses A's accessor from the result type.