lecodes-sdk 2.4.1 → 2.4.3

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 (58) 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/browser/sdk/browser.d.ts +2 -1
  21. package/dist/types/plugins/gen/camera/contract.d.ts +27 -0
  22. package/dist/types/plugins/gen/geolocation/contract.d.ts +52 -0
  23. package/dist/types/plugins/gen/map/contract.d.ts +144 -0
  24. package/dist/types/plugins/gen/push/contract.d.ts +83 -0
  25. package/dist/types/plugins/gen/qr-scanner/contract.d.ts +16 -0
  26. package/dist/types/plugins/gen/speech/contract.d.ts +67 -0
  27. package/dist/types/plugins/gen/webrtc/contract.d.ts +342 -0
  28. package/dist/types/version.d.ts +1 -1
  29. package/dist/types.json +1 -1
  30. package/package.json +1 -1
  31. package/src/animate/tween/Timeline.ts +175 -175
  32. package/src/bridges/gl.d.ts +5 -3
  33. package/src/compile/compileProject.ts +45 -10
  34. package/src/compile/index.ts +7 -0
  35. package/src/compile/webHalf.ts +255 -0
  36. package/src/core/Aspect.ts +118 -35
  37. package/src/g2/OneWay2D.ts +0 -2
  38. package/src/g2/Physics2D.ts +8 -16
  39. package/src/g2/Scene2D.ts +1 -1
  40. package/src/g2/Shape2D.ts +51 -22
  41. package/src/gl/CameraPlace.ts +52 -52
  42. package/src/gl/Light.ts +257 -257
  43. package/src/gl/Mesh.ts +120 -120
  44. package/src/gl/Model.ts +3 -2
  45. package/src/gl/Scene.ts +1 -1
  46. package/src/gl/animation/DynamicBone.ts +549 -486
  47. package/src/gl/animation/IK.ts +0 -2
  48. package/src/gl/nav/NavAgent.ts +14 -12
  49. package/src/gl/physics/Physics.ts +4 -5
  50. package/src/gl/physics/Shape.ts +49 -23
  51. package/src/gl/scenarios.ts +291 -291
  52. package/src/gl/vehicle/Vehicle.ts +102 -58
  53. package/src/gl/vehicle/Wheel.ts +45 -11
  54. package/src/plugins/gen/ar/contract.d.ts +35 -1
  55. package/src/plugins/gen/ar/sdk/ar.gen.ts +25 -6
  56. package/src/plugins/gen/ar/sdk/ar.ts +102 -35
  57. package/src/plugins/gen/browser/sdk/browser.ts +11 -1
  58. package/src/version.ts +1 -1
@@ -79,8 +79,6 @@ abstract class Chain<Name extends string> extends Aspect<Name, Node> {
79
79
  this._ik = 0
80
80
  this._rig = undefined
81
81
  }
82
- onReconfigure(): void { this.push() }
83
-
84
82
  protected params(): Float32Array {
85
83
  const p = new Float32Array(P.COUNT)
86
84
  p[P.WEIGHT] = this._weight
@@ -74,26 +74,26 @@ export class NavAgent extends Aspect<"agent", Node, NavAgentEvents> {
74
74
 
75
75
  /** Agent radius (metres). Defaults to the navmesh's. */
76
76
  get radius(): number { return this._radius }
77
- set radius(v: number) { this._radius = v; this._dirty = true }
77
+ set radius(v: number) { this._radius = v; this.dirty() }
78
78
  get height(): number { return this._height }
79
- set height(v: number) { this._height = v; this._dirty = true }
79
+ set height(v: number) { this._height = v; this.dirty() }
80
80
  /** Top speed (m/s). */
81
81
  get speed(): number { return this._speed }
82
- set speed(v: number) { this._speed = v; this._dirty = true }
82
+ set speed(v: number) { this._speed = v; this.dirty() }
83
83
  get acceleration(): number { return this._acceleration }
84
- set acceleration(v: number) { this._acceleration = v; this._dirty = true }
84
+ set acceleration(v: number) { this._acceleration = v; this.dirty() }
85
85
  /** Local (agent-vs-agent) avoidance quality. */
86
86
  get avoidance(): NavAgentAvoidance { return this._avoidance }
87
- set avoidance(v: NavAgentAvoidance) { this._avoidance = v; this._dirty = true }
87
+ set avoidance(v: NavAgentAvoidance) { this._avoidance = v; this.dirty() }
88
88
  /** Separation force weight (0 = none). */
89
89
  get separation(): number { return this._separation }
90
- set separation(v: number) { this._separation = v; this._dirty = true }
90
+ set separation(v: number) { this._separation = v; this.dirty() }
91
91
  /** Area names this agent may walk (default: all). */
92
92
  get include(): string[] | undefined { return this._include }
93
- set include(v: string[] | undefined) { this._include = v; this._dirty = true }
93
+ set include(v: string[] | undefined) { this._include = v; this.dirty() }
94
94
  /** Area names this agent never enters. */
95
95
  get exclude(): string[] | undefined { return this._exclude }
96
- set exclude(v: string[] | undefined) { this._exclude = v; this._dirty = true }
96
+ set exclude(v: string[] | undefined) { this._exclude = v; this.dirty() }
97
97
 
98
98
  state: NavAgentState = "idle"
99
99
  /** The current velocity after avoidance (m/s). */
@@ -111,7 +111,6 @@ export class NavAgent extends Aspect<"agent", Node, NavAgentEvents> {
111
111
  private _target: Vec3 | null = null
112
112
  /** velocity-driven (`move`) rather than target-driven */
113
113
  private _steering = false
114
- private _dirty = false
115
114
  private _faceX = 0
116
115
  private _faceZ = -1
117
116
  private _retryAt = 0
@@ -125,7 +124,12 @@ export class NavAgent extends Aspect<"agent", Node, NavAgentEvents> {
125
124
  this._join()
126
125
  }
127
126
 
128
- onReconfigure(): void { this._dirty = true }
127
+ /** A parameter changed: push the agent's params to the crowd (a no-op until it has a slot —
128
+ * `_join` sends them with the add). */
129
+ protected flush(): void {
130
+ const crowd = this._crowd
131
+ if (crowd && this._slot >= 0 && crowd._mesh === NavMesh.active) _creatorNav.crowdSetParams(crowd._id, this._slot, this.params())
132
+ }
129
133
 
130
134
  onDetach(): void {
131
135
  this._leave()
@@ -216,7 +220,6 @@ export class NavAgent extends Aspect<"agent", Node, NavAgentEvents> {
216
220
  if (slot < 0) { this._retryAt = crowd._step + JOIN_RETRY_STEPS; return false }
217
221
  this._crowd = crowd
218
222
  this._slot = slot
219
- this._dirty = false
220
223
  this._lastSeen = -1
221
224
  crowd._agents.add(this)
222
225
  if (this._target && !_creatorNav.crowdSetTarget(crowd._id, slot, this._target.x, this._target.y, this._target.z)) this._target = null
@@ -253,7 +256,6 @@ export class NavAgent extends Aspect<"agent", Node, NavAgentEvents> {
253
256
  }
254
257
  const crowd = this._crowd!
255
258
  if (crowd._mesh !== NavMesh.active) { this._leave(); return }
256
- if (this._dirty) { this._dirty = false; _creatorNav.crowdSetParams(crowd._id, this._slot, this.params()) }
257
259
  if (crowd._step === this._lastSeen) return // the crowd has not advanced since (a frame with no step)
258
260
  this._lastSeen = crowd._step
259
261
  const b = crowd._buf
@@ -72,11 +72,10 @@ export class Physics extends Aspect<"physics", Node> implements CompWriter {
72
72
  * `1`, ice `0.02`. A Vehicle's tires read the GROUND body's value, so this is the single number
73
73
  * that decides how well a car corners.
74
74
  *
75
- * Change it at runtime by re-configuring — `floor.aspect(Physics, { friction: 0.02 })` (an ice
76
- * patch) — or by assigning `floor.physics.friction = 0.02`; either way the setter pushes the new
77
- * surface to the live body at once. (chisel keeps an instance setter whose name appears as an
78
- * object-literal key anywhere in the bundle, so the config-object route survives tree-shaking
79
- * even when no code reads `.friction`.)
75
+ * Live: `floor.physics.friction = 0.02` (an ice patch) pushes the new surface to the body at
76
+ * once. (chisel keeps an instance setter whose name appears as an object-literal key anywhere in
77
+ * the bundle, so `aspect(Physics, { friction })` at build survives tree-shaking even when no code
78
+ * reads `.friction`.)
80
79
  */
81
80
  get friction(): number { return this._friction }
82
81
  set friction(v: number) {
@@ -18,6 +18,7 @@
18
18
  // (which follows the sim), rather than relying on the pick body.
19
19
 
20
20
  import { Aspect } from "../../core/Aspect"
21
+ import type { FieldMeta } from "../../core/fields"
21
22
  import { cx, cy, cz, type Vec3Like } from "../../math/vec"
22
23
  import type { Node } from "../Node"
23
24
 
@@ -51,23 +52,42 @@ const dim = (v: number): number => Math.max(MIN_HALF, r4(v))
51
52
  export class Shape extends Aspect<"shape", Node> {
52
53
  static readonly aspect = "shape"
53
54
 
55
+ // Every dimension is LIVE and applies AT ONCE: a write rebuilds the geometry in place, the body
56
+ // keeping its id, velocity and place (a crouch, a live editor edit) — synchronous, because the
57
+ // caller reads the result back right away (`controller.resizing`, the node's height). A write that
58
+ // leaves the geometry's signature unchanged does nothing. `fit()` writes every field and rebuilds once.
59
+ private _box?: Vec3Like
60
+ private _sphere?: number
61
+ private _cylinder?: { halfHeight: number, radius: number }
62
+ private _capsule?: { halfHeight: number, radius: number }
63
+ private _mesh?: boolean | "convex"
64
+ private _heightfield?: boolean
65
+ private _origin?: Vec3Like
66
+ private _raycast = true
67
+
54
68
  /** Box half-extents [hx, hy, hz] (world units). */
55
- box?: Vec3Like
69
+ get box(): Vec3Like | undefined { return this._box }
70
+ set box(v: Vec3Like | undefined) { this._box = v; this._changed() }
56
71
  /** Sphere radius. */
57
- sphere?: number
72
+ get sphere(): number | undefined { return this._sphere }
73
+ set sphere(v: number | undefined) { this._sphere = v; this._changed() }
58
74
  /** Cylinder aligned on Y: half-height + radius. */
59
- cylinder?: { halfHeight: number, radius: number }
75
+ get cylinder(): { halfHeight: number, radius: number } | undefined { return this._cylinder }
76
+ set cylinder(v: { halfHeight: number, radius: number } | undefined) { this._cylinder = v; this._changed() }
60
77
  /** Capsule aligned on Y: half-height of the cylinder section + radius. */
61
- capsule?: { halfHeight: number, radius: number }
78
+ get capsule(): { halfHeight: number, radius: number } | undefined { return this._capsule }
79
+ set capsule(v: { halfHeight: number, radius: number } | undefined) { this._capsule = v; this._changed() }
62
80
  /** The node's own triangles (a Mesh's geometry or a Model's GLB, world scale applied).
63
81
  * `true` = exact triangle mesh — static/kinematic bodies, triggers, characters' ground and picking
64
82
  * only (a dynamic body can't be a triangle mesh; Physics throws). `'convex'` = convex hull of the
65
83
  * vertices, works for dynamic bodies too. A Model uses its bind pose (skinned parts skipped). */
66
- mesh?: boolean | "convex"
84
+ get mesh(): boolean | "convex" | undefined { return this._mesh }
85
+ set mesh(v: boolean | "convex" | undefined) { this._mesh = v; this._changed() }
67
86
  /** The node's terrain (`Terrain.create(...).node`) as a Jolt height field — the exact drawn grid,
68
87
  * holes included (docs/terrain-plan.md). Static / kinematic / picking / character ground only,
69
88
  * like `mesh: true`. `terrain.commit()` pushes edits into the live shape. */
70
- heightfield?: boolean
89
+ get heightfield(): boolean | undefined { return this._heightfield }
90
+ set heightfield(v: boolean | undefined) { this._heightfield = v; this._changed() }
71
91
  /**
72
92
  * The shape's centre, relative to the node's origin — world units in the node's ROTATED frame
73
93
  * (the node's scale is ignored, exactly like the explicit dimensions above). Default [0, 0, 0].
@@ -81,15 +101,22 @@ export class Shape extends Aspect<"shape", Node> {
81
101
  * you would expect. With no `origin` an auto shape (`{}`) still centres itself on the node's own
82
102
  * mesh bounds — only explicit dimensions sit on the pivot by default.
83
103
  */
84
- origin?: Vec3Like
85
- /** Whether pointer rays can hit this shape (click / touchstart). Default true. */
86
- raycast = true
104
+ get origin(): Vec3Like | undefined { return this._origin }
105
+ set origin(v: Vec3Like | undefined) { this._origin = v; this._changed() }
106
+ /** Whether pointer rays can hit this shape (click / touchstart). Default true. Live, at once. */
107
+ get raycast(): boolean { return this._raycast }
108
+ set raycast(v: boolean) { this._raycast = v; if (this._bodyId) _creator.physicsSetPickable(this._bodyId, v) }
109
+
110
+ /** Scene-editor inspector: the geometry fields (accessors, so they are listed here by name). */
111
+ static fields: FieldMeta<Shape> = {
112
+ box: {}, sphere: {}, cylinder: {}, capsule: {}, mesh: {}, heightfield: {}, origin: {}, raycast: {},
113
+ }
87
114
 
88
115
  private _shapeId = 0
89
116
  private _bodyId = 0
90
117
  /** Centre the "auto" box measured for itself — used when `origin` isn't set explicitly. */
91
118
  private _autoOrigin: [number, number, number] | null = null
92
- /** Geometry props as of the last build (see onReconfigure). */
119
+ /** Geometry props as of the last build (see _changed). */
93
120
  private _sig = ""
94
121
 
95
122
  /** @internal native shape id (0 if the build has no physics). */
@@ -110,11 +137,10 @@ export class Shape extends Aspect<"shape", Node> {
110
137
  this.node._xfKind = 0
111
138
  }
112
139
 
113
- /** Re-configuring (`node.aspect(Shape, { origin })`) rebuilds the geometry when a dimension, the
114
- * kind or the origin changed, and re-applies pickability. The body keeps its id and velocity. */
115
- onReconfigure(): void {
116
- if (this._signature() !== this._sig) this._rebuild()
117
- if (this._bodyId) _creator.physicsSetPickable(this._bodyId, this.raycast)
140
+ /** A dimension, the kind or the origin was written: rebuild the geometry when it actually changed.
141
+ * The body keeps its id and velocity. */
142
+ private _changed(): void {
143
+ if (this._shapeId && this._signature() !== this._sig) this._rebuild()
118
144
  }
119
145
 
120
146
  /**
@@ -134,14 +160,14 @@ export class Shape extends Aspect<"shape", Node> {
134
160
  console.warn(`Shape.fit: "${this.node.name}" has no geometry to measure yet (a model still loading, or a node with no mesh)`)
135
161
  return this
136
162
  }
137
- this.box = f.box
138
- this.sphere = f.sphere
139
- this.cylinder = f.cylinder
140
- this.capsule = f.capsule
141
- if (kind === "mesh") this.mesh = true
142
- else if (kind === "convex") this.mesh = "convex"
143
- else if (kind !== undefined) this.mesh = undefined
144
- this.origin = f.origin
163
+ this._box = f.box
164
+ this._sphere = f.sphere
165
+ this._cylinder = f.cylinder
166
+ this._capsule = f.capsule
167
+ if (kind === "mesh") this._mesh = true
168
+ else if (kind === "convex") this._mesh = "convex"
169
+ else if (kind !== undefined) this._mesh = undefined
170
+ this._origin = f.origin
145
171
  this._rebuild()
146
172
  return this
147
173
  }