tosijs-3d 0.8.0 → 0.8.1

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 (200) hide show
  1. package/CHANGELOG.md +410 -0
  2. package/Migration.md +64 -0
  3. package/README.md +12 -0
  4. package/dist/ambient-leaves.d.ts.map +1 -1
  5. package/dist/ambient-leaves.js +8 -4
  6. package/dist/ambient-leaves.js.map +1 -1
  7. package/dist/angle-field.d.ts +44 -0
  8. package/dist/angle-field.d.ts.map +1 -0
  9. package/dist/angle-field.js +414 -0
  10. package/dist/angle-field.js.map +1 -0
  11. package/dist/arc.d.ts +95 -0
  12. package/dist/arc.d.ts.map +1 -0
  13. package/dist/arc.js +206 -0
  14. package/dist/arc.js.map +1 -0
  15. package/dist/b3d-aircraft.d.ts +35 -1
  16. package/dist/b3d-aircraft.d.ts.map +1 -1
  17. package/dist/b3d-aircraft.js +224 -13
  18. package/dist/b3d-aircraft.js.map +1 -1
  19. package/dist/b3d-ambient.d.ts +4 -0
  20. package/dist/b3d-ambient.d.ts.map +1 -1
  21. package/dist/b3d-ambient.js +27 -3
  22. package/dist/b3d-ambient.js.map +1 -1
  23. package/dist/b3d-beacon.d.ts +63 -0
  24. package/dist/b3d-beacon.d.ts.map +1 -0
  25. package/dist/b3d-beacon.js +307 -0
  26. package/dist/b3d-beacon.js.map +1 -0
  27. package/dist/b3d-clouds.d.ts +9 -0
  28. package/dist/b3d-clouds.d.ts.map +1 -1
  29. package/dist/b3d-clouds.js +32 -3
  30. package/dist/b3d-clouds.js.map +1 -1
  31. package/dist/b3d-controller.d.ts +2 -2
  32. package/dist/b3d-controller.d.ts.map +1 -1
  33. package/dist/b3d-controller.js +14 -1
  34. package/dist/b3d-controller.js.map +1 -1
  35. package/dist/b3d-destroyable.d.ts +28 -2
  36. package/dist/b3d-destroyable.d.ts.map +1 -1
  37. package/dist/b3d-destroyable.js +99 -36
  38. package/dist/b3d-destroyable.js.map +1 -1
  39. package/dist/b3d-interactive.d.ts +9 -4
  40. package/dist/b3d-interactive.d.ts.map +1 -1
  41. package/dist/b3d-interactive.js +48 -1
  42. package/dist/b3d-interactive.js.map +1 -1
  43. package/dist/b3d-launcher.d.ts +23 -0
  44. package/dist/b3d-launcher.d.ts.map +1 -1
  45. package/dist/b3d-launcher.js +71 -1
  46. package/dist/b3d-launcher.js.map +1 -1
  47. package/dist/b3d-manipulator.d.ts +85 -0
  48. package/dist/b3d-manipulator.d.ts.map +1 -0
  49. package/dist/b3d-manipulator.js +493 -0
  50. package/dist/b3d-manipulator.js.map +1 -0
  51. package/dist/b3d-planet.js +2 -2
  52. package/dist/b3d-prop.d.ts +31 -0
  53. package/dist/b3d-prop.d.ts.map +1 -0
  54. package/dist/b3d-prop.js +244 -0
  55. package/dist/b3d-prop.js.map +1 -0
  56. package/dist/b3d-skybox.d.ts +2 -0
  57. package/dist/b3d-skybox.d.ts.map +1 -1
  58. package/dist/b3d-skybox.js +32 -1
  59. package/dist/b3d-skybox.js.map +1 -1
  60. package/dist/b3d-spawner.d.ts +24 -0
  61. package/dist/b3d-spawner.d.ts.map +1 -1
  62. package/dist/b3d-spawner.js +52 -10
  63. package/dist/b3d-spawner.js.map +1 -1
  64. package/dist/b3d-svg-plane.d.ts.map +1 -1
  65. package/dist/b3d-svg-plane.js +8 -79
  66. package/dist/b3d-svg-plane.js.map +1 -1
  67. package/dist/b3d-terrain.d.ts +27 -0
  68. package/dist/b3d-terrain.d.ts.map +1 -1
  69. package/dist/b3d-terrain.js +251 -14
  70. package/dist/b3d-terrain.js.map +1 -1
  71. package/dist/b3d-turret.d.ts +16 -0
  72. package/dist/b3d-turret.d.ts.map +1 -1
  73. package/dist/b3d-turret.js +76 -0
  74. package/dist/b3d-turret.js.map +1 -1
  75. package/dist/b3d-utils.d.ts +97 -2
  76. package/dist/b3d-utils.d.ts.map +1 -1
  77. package/dist/b3d-utils.js +220 -3
  78. package/dist/b3d-utils.js.map +1 -1
  79. package/dist/b3d-warhead.d.ts +4 -1
  80. package/dist/b3d-warhead.d.ts.map +1 -1
  81. package/dist/b3d-warhead.js +43 -19
  82. package/dist/b3d-warhead.js.map +1 -1
  83. package/dist/b3d-water.d.ts +9 -0
  84. package/dist/b3d-water.d.ts.map +1 -1
  85. package/dist/b3d-water.js +74 -3
  86. package/dist/b3d-water.js.map +1 -1
  87. package/dist/color-field.d.ts +30 -0
  88. package/dist/color-field.d.ts.map +1 -0
  89. package/dist/color-field.js +351 -0
  90. package/dist/color-field.js.map +1 -0
  91. package/dist/color.d.ts +47 -0
  92. package/dist/color.d.ts.map +1 -0
  93. package/dist/color.js +216 -0
  94. package/dist/color.js.map +1 -0
  95. package/dist/destroyable-behavior.d.ts +23 -3
  96. package/dist/destroyable-behavior.d.ts.map +1 -1
  97. package/dist/destroyable-behavior.js +107 -4
  98. package/dist/destroyable-behavior.js.map +1 -1
  99. package/dist/destroyable.d.ts +50 -1
  100. package/dist/destroyable.d.ts.map +1 -1
  101. package/dist/destroyable.js +28 -4
  102. package/dist/destroyable.js.map +1 -1
  103. package/dist/icon-data.d.ts.map +1 -1
  104. package/dist/icon-data.js +11 -0
  105. package/dist/icon-data.js.map +1 -1
  106. package/dist/index.d.ts +29 -4
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +32 -3
  109. package/dist/index.js.map +1 -1
  110. package/dist/interaction.d.ts +58 -3
  111. package/dist/interaction.d.ts.map +1 -1
  112. package/dist/interaction.js +26 -10
  113. package/dist/interaction.js.map +1 -1
  114. package/dist/interactive-behavior.d.ts +71 -5
  115. package/dist/interactive-behavior.d.ts.map +1 -1
  116. package/dist/interactive-behavior.js +127 -7
  117. package/dist/interactive-behavior.js.map +1 -1
  118. package/dist/key-layout.d.ts +1 -1
  119. package/dist/key-layout.d.ts.map +1 -1
  120. package/dist/key-layout.js +30 -0
  121. package/dist/key-layout.js.map +1 -1
  122. package/dist/keyboard-gamepad.d.ts.map +1 -1
  123. package/dist/keyboard-gamepad.js +18 -0
  124. package/dist/keyboard-gamepad.js.map +1 -1
  125. package/dist/keyboard.d.ts.map +1 -1
  126. package/dist/keyboard.js +123 -22
  127. package/dist/keyboard.js.map +1 -1
  128. package/dist/library-mesh.d.ts +47 -0
  129. package/dist/library-mesh.d.ts.map +1 -0
  130. package/dist/library-mesh.js +114 -0
  131. package/dist/library-mesh.js.map +1 -0
  132. package/dist/manipulator-view.d.ts +79 -0
  133. package/dist/manipulator-view.d.ts.map +1 -0
  134. package/dist/manipulator-view.js +552 -0
  135. package/dist/manipulator-view.js.map +1 -0
  136. package/dist/manipulator.d.ts +214 -0
  137. package/dist/manipulator.d.ts.map +1 -0
  138. package/dist/manipulator.js +423 -0
  139. package/dist/manipulator.js.map +1 -0
  140. package/dist/model-transform.d.ts +24 -0
  141. package/dist/model-transform.d.ts.map +1 -1
  142. package/dist/model-transform.js +39 -0
  143. package/dist/model-transform.js.map +1 -1
  144. package/dist/panel-layer.d.ts +34 -0
  145. package/dist/panel-layer.d.ts.map +1 -0
  146. package/dist/panel-layer.js +154 -0
  147. package/dist/panel-layer.js.map +1 -0
  148. package/dist/panel-orbit.d.ts +156 -0
  149. package/dist/panel-orbit.d.ts.map +1 -0
  150. package/dist/panel-orbit.js +289 -0
  151. package/dist/panel-orbit.js.map +1 -0
  152. package/dist/picker.d.ts +40 -0
  153. package/dist/picker.d.ts.map +1 -0
  154. package/dist/picker.js +385 -0
  155. package/dist/picker.js.map +1 -0
  156. package/dist/popup-surface.d.ts +13 -0
  157. package/dist/popup-surface.d.ts.map +1 -1
  158. package/dist/popup-surface.js +4 -1
  159. package/dist/popup-surface.js.map +1 -1
  160. package/dist/scene-schemas.d.ts.map +1 -1
  161. package/dist/scene-schemas.js +188 -28
  162. package/dist/scene-schemas.js.map +1 -1
  163. package/dist/svg-icons.d.ts.map +1 -1
  164. package/dist/svg-icons.js +34 -3
  165. package/dist/svg-icons.js.map +1 -1
  166. package/dist/terrain-editor.d.ts +20 -0
  167. package/dist/terrain-editor.d.ts.map +1 -0
  168. package/dist/terrain-editor.js +295 -0
  169. package/dist/terrain-editor.js.map +1 -0
  170. package/dist/terrain-grid.d.ts +30 -0
  171. package/dist/terrain-grid.d.ts.map +1 -1
  172. package/dist/terrain-grid.js +33 -0
  173. package/dist/terrain-grid.js.map +1 -1
  174. package/dist/text-entry.d.ts +9 -0
  175. package/dist/text-entry.d.ts.map +1 -0
  176. package/dist/text-entry.js +105 -0
  177. package/dist/text-entry.js.map +1 -0
  178. package/dist/tosi-b3d.d.ts +77 -0
  179. package/dist/tosi-b3d.d.ts.map +1 -1
  180. package/dist/tosi-b3d.js +465 -20
  181. package/dist/tosi-b3d.js.map +1 -1
  182. package/dist/vector-field.d.ts +2 -10
  183. package/dist/vector-field.d.ts.map +1 -1
  184. package/dist/vector-field.js +13 -17
  185. package/dist/vector-field.js.map +1 -1
  186. package/dist/widgets3d-layout.d.ts +18 -1
  187. package/dist/widgets3d-layout.d.ts.map +1 -1
  188. package/dist/widgets3d-layout.js +27 -3
  189. package/dist/widgets3d-layout.js.map +1 -1
  190. package/dist/widgets3d.d.ts +63 -0
  191. package/dist/widgets3d.d.ts.map +1 -1
  192. package/dist/widgets3d.js +478 -77
  193. package/dist/widgets3d.js.map +1 -1
  194. package/dist/wind.d.ts +90 -0
  195. package/dist/wind.d.ts.map +1 -0
  196. package/dist/wind.js +263 -0
  197. package/dist/wind.js.map +1 -0
  198. package/package.json +3 -1
  199. package/static/attributes.json +4062 -0
  200. package/static/attributes.txt +1093 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,416 @@ All notable changes to **tosijs-3d**. This project is pre-1.0 (`0.x`), so minor
6
6
  versions may carry breaking peer-dependency changes — each is called out in a
7
7
  **⚠️ Breaking** block in its version section below, with what a consumer must do.
8
8
 
9
+ ## 0.8.1
10
+
11
+ ### ⚠️ Breaking
12
+
13
+ Nothing breaks at compile time. Two behaviours change, and
14
+ [Migration.md](./Migration.md) has the before/after for each.
15
+
16
+ - **Aircraft guns are direct-hit, not area-effect.** `gun-mode="blast"`
17
+ restores the old behaviour; `gunBlastRadius`/`gunFullRadius` are attributes
18
+ now rather than hardcoded.
19
+ - **`activationVeto` takes an optional second parameter.** Existing callers
20
+ compile unchanged, and a veto that ignores its argument behaves identically.
21
+ When the info is omitted a reach veto now **refuses** rather than passing —
22
+ see Migration.md for why that direction, and how to say otherwise.
23
+ - **`select3d` no longer draws ‹ › stepper arrows.** The popup it always had is
24
+ now the only way in, and is discoverable.
25
+
26
+ ### Changed
27
+
28
+ - **Aircraft guns damage what they pass through, instead of firing an area
29
+ effect** (#23). Blast damage resolves by distance to a destroyable's
30
+ registered point — ONE point, at the model's origin — so scaling a fighter 4×
31
+ puts its wing outside a 1.5 m blast and point-blank fire does nothing, with
32
+ no error. Direct-hit damage has no length scale in it and is immune to that
33
+ whole class. `gunMode="blast"` restores the previous behaviour, and
34
+ `gunFullRadius`/`gunBlastRadius` are attributes now rather than hardcoded.
35
+ - **A disposed mesh now takes its own materials and textures with it.**
36
+ `mesh.dispose()` leaves them behind, so every scene child that built one
37
+ leaked it on every teardown — including every RE-PARENT, since a move
38
+ disconnects the child while the scene deliberately survives. Measured:
39
+ re-parenting one scene six times took materials 3 → 15 and textures 3 → 21,
40
+ unbounded, meshes correctly flat. `disposeMeshTree` CHECKS before disposing —
41
+ a glTF file shares one material across many meshes and a disposed material
42
+ still answers `isReady()`, so a wrong sharing rule turns siblings black
43
+ silently. Textures held by the scene environment, a render target or a
44
+ light's gel are exempt, because nothing references those from a material.
45
+ - **A blast finds every destroyable, not every `<tosi-b3d-destroyable>`.**
46
+ `detonateWarhead` queried one tag name, so `b3d-loader` models — which attach
47
+ the same behaviour — were invisible to every explosion in the scene. The
48
+ registry now lives on `DestroyableBehavior`, so anything attaching one is a
49
+ target by construction.
50
+
51
+ ### Fixed
52
+
53
+ A second headset pass found the rest of these. Between the two, every one was
54
+ invisible to a green suite — and the ones on panels were all reproducible flat,
55
+ which is now written down rather than re-learned (CLAUDE.md, "A PANEL IS NOT A
56
+ HEADSET-ONLY SURFACE").
57
+
58
+ - **We were eating other people's keystrokes.** `KeyboardGamepad` listens on
59
+ `window` so you can steer without clicking the canvas first, and the on-screen
60
+ keyboard listens there so an in-scene field types with no DOM focus — the only
61
+ way that works in a headset. Both then `preventDefault` what they claim, with
62
+ no notion of where the event came from. `a` is a strafe key, so typing "lamp"
63
+ into a search box lost the character AND strafed the demo, on any page
64
+ carrying a scene. `isTextEntry(event)` is the one predicate all three
65
+ listeners consult. An input you PRESS is not typing — space on a checkbox
66
+ stays a press — and key RELEASE is deliberately unguarded, or a key pressed on
67
+ the canvas and released in a field would stay down forever.
68
+ - **A popup is a popup, not something its panel crops.** `select3d`'s menu and
69
+ `openMenu3d` went to the panel-bounded path, so a menu was squeezed into
70
+ whatever room was left under its own row. Only the keyboard called
71
+ `showLayer`, because someone knew it existed. `showPopup` now prefers a layer
72
+ and keeps the bounded path as its fallback, so the fix reaches every caller;
73
+ `boundedPopup` remains for a popup that must not escape. **Picking an option
74
+ dismisses it** — `closePopup()` is the panel's own tracking and knows nothing
75
+ about layers, so a menu set the value and stayed standing.
76
+ - **An in-scene panel's popups open on their own plane.** A panel rasterised
77
+ onto a plane is not in the document, so the DOM layer cannot auto-install and
78
+ every popup took the cropped path. `panelScene` had registered a scene layer
79
+ since the keyboard needed one; the `<tosi-b3d>` settings panel never did. The
80
+ placement maths is extracted to `panel-layer` rather than copied — a formula
81
+ at three sites, fixed at one, is a mistake this repo has already paid for.
82
+ - **A popup is drawn at its panel's scale.** It took `width * 0.95` whatever it
83
+ contained: right for a keyboard, grotesque for a 160-unit menu at twice the
84
+ text size of the thing that opened it. One viewBox unit is now the same
85
+ physical size on a panel and its popup.
86
+ - **A press aimed at a popup reaches the popup.** The XR panel's re-pick ignored
87
+ what the ray actually hit and forced a pick against itself, so a press on a
88
+ popup in FRONT of it was routed to the panel behind — close and move never saw
89
+ a thing. An occluder that is itself UI now wins.
90
+ - **No empty band above a flat popup.** 30px was reserved for the move/close
91
+ glyphs an in-scene popup draws; a DOM layer draws none. Reserved only when a
92
+ mounting host actually draws chrome.
93
+ - **The keyboard's × means "put it away".** It closed only the presentation you
94
+ pressed, leaving the other up and the field still believing it had a keyboard
95
+ open — and left the mode on, so the glyph stayed lit over nothing and the next
96
+ press flipped the preference instead of reopening. A takeover is still not a
97
+ dismissal: swapping layouts between fields must not darken the glyph.
98
+ - **`Migration.md`'s first block ran as a live example.** The doc system executes
99
+ `html` fences, which is the natural fence for illustrative markup. Now `xml`,
100
+ and `doc-examples.test.ts` — which scanned only `src/*.ts` — fails on any live
101
+ fence in a published markdown doc.
102
+
103
+ Five of these came from one headset pass on the terrain editor, which is the
104
+ argument for `RELEASING.md` step 5a in one paragraph: every one of them was
105
+ invisible to 2300 passing tests, and the first was invisible to a day of
106
+ reading the source.
107
+
108
+ - **A pinned panel header was clipped away — invisible, but still hittable.**
109
+ The header was appended inside the clipped body group, whose clip rect
110
+ necessarily starts below it, so it was clipped in full while its band stayed
111
+ reserved and the pointer router kept routing to it. Three symptoms, one cause:
112
+ the Exit VR / Re-seat / Pause buttons vanished, the panel grew a tall empty
113
+ band, and pressing where they _should_ be worked. ⚠️ It only bit a panel that
114
+ SCROLLS, because `clip-path` is only applied then — so every small panel in
115
+ the demos and tests was fine and the terrain editor was not.
116
+ - **An icon bar ran off the edge of its panel.** `layout()` ignored the width it
117
+ was handed. A scene's bar is Exit VR + Re-seat + Perf Stats + one per
118
+ registered debug source + the gadgets — ten items, 380px, in a 296px panel. It
119
+ wraps now, and the hit test reads `y` as well as `x`.
120
+ - **Noise `scale` sliders are LOGARITHMIC.** They are frequencies: on the old
121
+ linear 0.005–0.3 track the whole usable band was the first 15% and the default
122
+ sat at 3%, so every value you actually want was crushed against the left stop.
123
+ The schema has said `x-scale: 'log'` all along and `terrainEditor3d` honours
124
+ it — the hand-rolled demo panels did not, which is how it shipped.
125
+ - **A scrolling panel has a scroll RAIL.** Scrolling began on empty space, and a
126
+ panel full of controls has none, so in a headset there was no gesture that
127
+ scrolled it at all. The rail is also the only visible sign that there IS more
128
+ below — a texture on a plane has no scrollbar, no overflow shadow and no
129
+ momentum. Rows are measured twice so it never overlaps a control.
130
+ - **A slider keeps a usable track however narrow its row.** The label took a
131
+ flat 45% and the readout took whatever it needed, leaving a 53px track at
132
+ 282px wide with a unit in the format. The track reserves a minimum now and the
133
+ label yields, clipped so it cannot paint over the control it gave way to.
134
+
135
+ - **`operable` contradicted `useNearest` on the same door.** With no pointer on
136
+ it the getter knows no distance, so a reach veto blocks — while `useNearest`,
137
+ which measures the distance itself, opens that same door 1 m away. Nothing in
138
+ the behaviour knows where your actor is standing, so `operableFor(info)` is
139
+ the question to ask for a "press E" prompt; it runs the same veto pass as
140
+ `activate()`, so a check and the act cannot disagree.
141
+
142
+ - **A terrain attribute change no longer rebuilds the whole world every frame,
143
+ and a retained tile is the cell it claims to be.**
144
+ tosijs queues one render per animation frame and `slider3d` writes on every
145
+ pointer move, so an attribute-driven rebuild that cleared the tile pool and
146
+ refilled it unbounded cost a FULL rebuild per frame for as long as you dragged
147
+ — ~50 ms of noise alone at the high tier, ~6.3 ms at the quest tier inside a
148
+ 13.9 ms VR frame, before skirts, normals and the vertex uploads. It now marks
149
+ the pool stale and re-cuts under the ordinary `fillBudget`/`tileBuildMs` cap,
150
+ so the world morphs instead of blinking out. `regenerate()` keeps its
151
+ documented unbounded behaviour, and now adopts the generation key so "set the
152
+ attributes, then call `regenerate()`" stops paying for two rebuilds.
153
+
154
+ Retaining tiles rather than clearing them exposed a second thing: a tile's
155
+ key is `(level, gx, gz)` and says nothing about SIZE or PLACE, so after a
156
+ `tileSize`/`horizScale` change an old tile key-matched a desired cell that was
157
+ a different size somewhere else — and the world came out gapped and
158
+ wrong-scale while the streamer reported itself finished. A retained tile now
159
+ adopts the whole desired cell and marks itself stale when its geometry moved,
160
+ so the two rebuild paths agree about what the world is.
161
+
162
+ - **`disposeMeshTree` could dispose a texture a library model was still
163
+ drawing.** The material guard asks `scene.meshes` and was right; the texture
164
+ guard asked `scene.materials`, which cannot see a library-instantiated model's
165
+ materials — those belong to the `AssetContainer` while their meshes are in the
166
+ scene. A texture shared with a hand-made material was disposed under the
167
+ library model, which went black, silently. The in-use set is now derived from
168
+ the meshes that remain.
169
+ - **The attribute index lost three elements' documentation to one legend
170
+ table.** The generator rejects a table whose header names an identifier
171
+ (`touch-gamepad` maps `data-part` values to gamepad fields — its rows are
172
+ values, not attributes), but applied the rejection to the whole DOCUMENT on
173
+ the strength of the first table it found. `b3d-lamp` opens with a capability
174
+ matrix, so the point, spot and area lights all shipped bare attribute names
175
+ with no default and no prose. Each table is judged on its own header now.
176
+ - **`operable` and `debugState` contradicted what a pointer press actually
177
+ did.** Both were routed through the same helper as a scripted `activate()`,
178
+ which reports an unknown distance as `Infinity` so a reach veto fails closed.
179
+ That is right for an activation and wrong for an inspection: a hovered door
180
+ reported `operable: false` and `out-of-reach:blocks` at the moment a press
181
+ opened it. While the pointer is on it they now judge with the real hover, and
182
+ `debugState` prints the info it judged with — it is the only debug readout
183
+ that exists in a headset.
184
+ - **The attribute index ships inside the package.** `static/attributes.txt` and
185
+ `attributes.json` are in `files` now, so an agent already in a consumer
186
+ project reads `node_modules/tosijs-3d/static/attributes.txt` with no network
187
+ and no proxy. It was published to the doc site only, which is the one place
188
+ the actor it was built for cannot reach.
189
+
190
+ - **`b3d-destroyable` could not place a library piece properly** — three
191
+ reports from `tosijs-3d-ensemble` against one function, and one bug family:
192
+ the async load treated its callback as if nothing could change underneath it.
193
+ - **Rotation was dropped** (#48). Only x/y/z reached `instantiate`. It looks
194
+ like it should not matter, since `AbstractMesh.render()` syncs `rx/ry/rz` —
195
+ but that is a COMPONENT render, and it had already run by the time the
196
+ async callback assigned `this.mesh`. Position applied, rotation did not.
197
+ Now forwarded, and the transform is re-synced once the node exists.
198
+ - **No scale** (#47). `size` is the placeholder cube's edge length and does
199
+ nothing once `library` is set, so a placed model could not be resized at
200
+ all — ensemble measured a piece at 5.273 units for `scale` 1, 2 and 4
201
+ alike. New `scale` attribute, uniform, applied to the instance root.
202
+ - **A removed element orphaned its node permanently** (#49). Remove it inside
203
+ the load window and the disconnect handler found nothing to dispose, then
204
+ the pending callback built a node owned by no element — a ghost nothing
205
+ would ever move or free. Guarded with `loadGeneration`, the mechanism
206
+ `b3d-aircraft` already used; the retry poll stops on a stale generation too.
207
+ - **Two engines on one canvas are now impossible, and a lost context says so**
208
+ (#56). Building an engine over a live one disposed nothing and failed
209
+ silently — the first context's shader programs go invalid while every uniform
210
+ still reads back correctly, which is why it presented as four different bugs
211
+ (white meshes, dark sky, empty scene, half-loaded scene). It now disposes the
212
+ old engine and warns. Separately, `webglcontextlost` is reported to the
213
+ console and the debug ring instead of just rendering wrong.
214
+ - **The flat scene panel now closes on a background press**, like every other
215
+ transient overlay here. A press inside it, or on the gear, still does not —
216
+ the gear toggles, so closing first would make it look inert.
217
+ - **A still sky never found a late sun** (#55). `updateSky` writes
218
+ `sunPosition`, `rayleigh` and `turbidity` only when a sun element's light
219
+ exists, and the frame gate re-ran it only when `timeOfDay` moved — so
220
+ `realtimeScale: 0`, which is what a reproducible authored scene wants, ran it
221
+ once and came up dark about four loads in five. The default `realtimeScale:
222
+ 10` hid it, because a drifting clock reopens the gate until some pass catches
223
+ the sun. The retry is now gated on the OUTCOME rather than the clock, and
224
+ bounded so a scene with no sun does not retry forever.
225
+ - **A flat popup could open off-screen with no way back** (#57). The DOM layer
226
+ set `left`/`top` straight from the anchor with no bounds check, so a field in
227
+ a right-hand panel opened a keyboard 112px past the right edge — rightmost
228
+ column of keys unreachable, and unrecoverable, because the move/close chrome
229
+ is drawn by picking and picking exists only in the scene. It now places
230
+ through `placePopup`, the same pure flip/clamp the in-scene presentation
231
+ uses, **and the holder can be dragged** — which is the better fix, since only
232
+ the person typing knows what the popup is covering. A press that lands on a
233
+ widget still belongs to the widget, or you could never type.
234
+ - **`chaseDistance` / `chaseHeight` / `chaseMinHeight` / `hudSize` accepted a
235
+ write and did nothing** (#43). All four were consumed when the rig and HUD
236
+ plane were built and never read again, so a settings slider bound to any of
237
+ them read back correctly and moved nothing — ensemble measured bit-identical
238
+ framing across a 3× change. Worse than an ordinary no-op because
239
+ `chasePitchFollow` on the same element IS live, so the element looked
240
+ responsive and only some of it was. The chase geometry now comes from one
241
+ path used at build AND every frame; the HUD remounts when its geometry
242
+ changes, instead of latching on a boolean.
243
+ - **`select3d` looked like a cycler** (#37). It has opened a popup list all
244
+ along — nothing said so, so a consumer counted 23 taps to reach the 24th
245
+ option. It now draws a downward chevron, the whole control opens the list,
246
+ and the arrows are gone. Stepping survives only where a panel gives no host
247
+ and a menu is impossible.
248
+ - **An icon name colliding with `Object.prototype` threw** rather than falling
249
+ back — `iconGlyph('constructor')` and friends. 0.8.0 was the first release
250
+ where table DATA becomes an icon name, with no `catch` in the repaint path.
251
+ Fixed at all three unsafe sites, including `registerIcons`, where `__proto__`
252
+ was an assignment that would have corrupted the map rather than failing.
253
+ - **`spinner3d` leaked into a module-global ticker.** `Widget3d` gained
254
+ `dispose?()`, and `B3d` releases the widget set it replaces on each repaint.
255
+ Reaping by `el.isConnected` would have been wrong: an in-scene panel's SVG is
256
+ never attached, so a visible VR spinner would have been culled.
257
+ - Panels size to their content, the in-scene icon bar is pinned, and the theme
258
+ editor no longer follows you between demos (from the 0.8.0 headset pass).
259
+
260
+ ### Added
261
+
262
+ - **A spatial panel can be dragged, and the drag is aimed at where you POINT.**
263
+ `orbitFromAim` walks the controller ray to the sphere's radius and asks which
264
+ way that point lies from the anchor. Using the ray's DIRECTION instead treats
265
+ your hand as if it were at your eyes: the panel sat where the arithmetic said
266
+ rather than where you pointed, and hand wobble swung it by the whole
267
+ head-to-hand offset.
268
+
269
+ The seat lives on the element, so a structural refresh — pressing Pause, say —
270
+ no longer snaps the panel back to its default. A seat names an EDGE and the
271
+ pin BLENDS across the horizon: a hard switch moved the panel by its entire
272
+ height in one frame as you dragged through eye level. The grip is
273
+ `iconGlyph('move')`, the same mark a torn-off popup already uses.
274
+
275
+ - **A spatial panel can be dragged, on the sphere around its rig anchor.** Two
276
+ properties fall out rather than being built: the distance cannot drift (so it
277
+ can never be shoved into your face or out of reach) and the facing comes free.
278
+ `panel-orbit` is the pure half — no Babylon, no DOM — so the placement rule is
279
+ testable without a headset.
280
+
281
+ A drag past a limit **follows you and stiffens**, and letting go springs back:
282
+ a hard stop is the right resting behaviour and the wrong live one, because a
283
+ panel that simply stops following your hand reads as a dropped drag rather
284
+ than a limit. The band and the clamp deliberately disagree — the panel may
285
+ PASS a limit and may never come to REST past one, since out there its own Exit
286
+ VR and Re-seat buttons are hard to reach.
287
+
288
+ A seat names an EDGE, not a centre: below the equator it is bottom-relative
289
+ and above it top-relative, so a tall panel's extra height always grows back
290
+ toward eye level instead of trailing into the floor or pushing past the
291
+ ceiling it was just clamped to. The ceiling is 60°, which is the default seat
292
+ exactly, so the panel can only ever be dragged somewhere more comfortable than
293
+ where it started.
294
+
295
+ - **`budgetedReach(reach, tileSize)` and `MAX_TILES_ACROSS` are exported from
296
+ `tosijs-3d/terrain-grid`**, so a UI can clamp its own slider against the same
297
+ limit `<tosi-b3d-terrain>` enforces rather than guessing. `reach` × `tileSize`
298
+ is the footgun and neither looks dangerous alone: reach 5000 at tileSize 10 is
299
+ a million finest tiles, which is the slider that killed a tab (#66) and got
300
+ capped at "400 m" as a guess. Pure, no scene needed. The element's own
301
+ `_budgetedReach` is now a call to it, so they cannot drift.
302
+
303
+ - **A manipulator — translate, rotate and scale handles you can grab** (#38),
304
+ ported from `tosijs-3d-ensemble` where it was shaken out against real
305
+ authoring, including on a phone. Three files on the usual split:
306
+ `manipulator.ts` (pure — the five grip readings, snapping, the drag reducer),
307
+ `manipulator-view.ts` (the Babylon handles, with the two-pass pick and the
308
+ euler composition folded in so a consumer no longer writes either), and
309
+ `<tosi-b3d-manipulator>`. The flat pointer is wired; `grab`/`grabNear`/
310
+ `drag`/`release` take world rays so a controller or a hand drives the same
311
+ code. Note `move`/`turn` rather than `translate`/`rotate`: `translate` is a
312
+ real `HTMLElement` property and declaring it gives one word two owners.
313
+ - **`<tosi-b3d-beacon>`** — a clickable hull for anything with a position and
314
+ no geometry: a lamp, a positional sound, a spawn point (#70). Invisible via
315
+ `visibility = 0` rather than `isVisible = false`, which is the whole trick —
316
+ Babylon's default pick test is `isEnabled && isVisible && isPickable`, so the
317
+ obvious way to hide a hull makes it unpickable, and the failure returns
318
+ _whatever is behind it_ rather than nothing. `beaconOwner(mesh)` is the entire
319
+ reading-side API.
320
+ - **`angle3d` and `arc3d`** — dial a bearing, dial a firing arc (#71). An angle
321
+ on a linear track has ends where the quantity does not, so 359° and 1° sit at
322
+ opposite ends of the slider. `arc.ts` is the pure model, and an arc is a
323
+ CENTRE and a WIDTH rather than a start and an end — which makes "is this
324
+ bearing inside" and "does that arc contain this one" one line each, and makes
325
+ straddling north unrepresentable rather than special-cased. An envelope is
326
+ drawn, not merely clamped against, so a turret's restricted arc explains the
327
+ ship instead of silently snapping.
328
+ - **`picker3d`** — choosing one of five hundred (#37). A `table` for the
329
+ virtualized filterable list, an `inputField` for the query, a `select3d` for
330
+ the family: two levels without a tree, because a tree needs a pointer to
331
+ expand and two flat controls work from a D-pad. Filtering is AND across terms
332
+ over the whole name, so word order cannot matter.
333
+ - **`terrainEditor3d`** — a terrain editor built FROM `sceneSchemas.terrain()`
334
+ (#66), so a range cannot disagree with the element it edits. Curated, not
335
+ generated: most of the schema's thirty properties are performance internals,
336
+ and a panel showing all of them is a settings dump.
337
+ - **`FieldType: 'color'` and a swatch on `inputField`** (#72). Tolerant in,
338
+ canonical out — `#abc`, `red` and `rgb(255,128,0)` all commit as `#rrggbb`,
339
+ and a five-digit hex is valid WHILE TYPING and refused at commit rather than
340
+ silently accepted. The swatch holds the last good colour while the text does
341
+ not parse, so a half-typed value does not read as a lost one.
342
+ - **One wind for the scene** (#73) — `windSpeed`, `windBearingDeg`, `windGust`
343
+ on `<tosi-b3d>`, with `wind="scene|own"` on clouds, water and ambient.
344
+ Clouds, water and leaves each carried their own wind in three spellings and
345
+ could silently disagree. `wind.ts` is pure: Cartesian inside, degrees at the
346
+ edge, and that IS the composition rule — a valley funnelling, a lee
347
+ sheltering and a headland curling are all just contributions that add.
348
+ - **Combat attribution** (#8) — `Cause {by, kind, via, hops}` on `damaged` and
349
+ `destroyed`, threaded through chain links, `tick` and `deathBlast`, and
350
+ stored on the `Destroyable` so a reaction a frame later can still ask. `by`
351
+ is the ORIGINATOR however many hops back, because re-attributing each hop to
352
+ the thing next to it launders the credit away. Measured on the 48-drum
353
+ cascade: one hit, 48 kills, all credited, hop counts 1/3/5/7/9/11/6/6.
354
+ - **`b3d-aircraft` can be damaged and locked** (#23) — `destroyable="on"`
355
+ attaches the same behaviour `b3d-loader` uses, and `blip="on"` mounts a radar
356
+ blip, without which an enemy cannot be missile-locked and a player reports
357
+ that "missiles don't work".
358
+ - **A veto is told about the activation** (#36) — `blocks(info)` receives
359
+ `{actor, source, distance, …}`, so one door can answer differently for an NPC
360
+ holding the key and a player who is not, and can tell a hand within reach
361
+ from a ray across the room. A veto that ignores its argument is unaffected.
362
+ - **A configured terrain now draws itself** (#66). `<tosi-b3d-terrain>` built a
363
+ tile pool and filled it only when told, so a terrain with its attributes set
364
+ rendered nothing until someone called `regenerate()` — a silent failure that
365
+ every consumer worked around with their own bounded retry. Ordinary attribute
366
+ changes now regenerate on the next frame, like every other element. Keyed on
367
+ the GENERATION attributes only, so a `wireframe` toggle stays a material tweak,
368
+ and relying on tosijs's own render batching for bursts rather than
369
+ reimplementing it — five writes in a task are already one `render()`.
370
+ - **`b3d-turret` and `b3d-launcher` take a `library`** (#34), so a piece that
371
+ IS a turret no longer renders as a cylinder and a box. Which node aims is
372
+ declared by the MODEL — a `_barrel` suffix, resolved like `_centerOfGravity`
373
+ and the collider suffixes — because a rigger declares moving parts in Blender,
374
+ not in scene markup. `_muzzle` is separate and says where rounds leave: the
375
+ same node on a simple gun, a different one on a multi-barrel mount. A model
376
+ with neither still works — it yaws as a unit and the muzzle falls back to the
377
+ existing forward offset.
378
+ - **`b3d-spawner` can spawn at an authored PLACE**, not only on a ring around
379
+ the player (#40). `anchor="place"` plus `x`/`y`/`z` and `facingDeg` — a
380
+ carrier deck, a hangar door, a dungeon entrance. Mutually exclusive with the
381
+ distances by construction rather than by warning, and a placed spawn does not
382
+ consume the RNG, so adding a launchpad cannot shift the encounters in a scene
383
+ that promises "same seed, same battles".
384
+ - **`<tosi-b3d-prop>`** — a library model in the scene and nothing else (#68).
385
+ Every existing route to a library-backed mesh brought behaviour with it: a
386
+ plain prop had to be a `<tosi-b3d-destroyable>` carrying `capacity`, `armor`,
387
+ `explode` and a combat id for something nothing will ever shoot.
388
+
389
+ It matters more than a convenience element, because it is the difference
390
+ between the CDN's 5,108 models being reachable or not **from a page that
391
+ cannot run JavaScript**. Every model in those kit libraries sits at the origin
392
+ with no translation (the format is built for `clone()`), so a consumer with a
393
+ JS build reaches all of them and a consumer writing declarative HTML reached
394
+ none. `library-url` covers the one-model case without a separate
395
+ `<tosi-b3d-library>` and a `type` handshake, sharing one library element per
396
+ URL so ten props do not fetch the kit ten times.
397
+
398
+ - **Collision GROUPS** — `markCollisionGroup(mesh, 'water')` plus
399
+ `collidable(reject, { ignoreGroups: ['water'] })` (#44). The single
400
+ `b3dNoCollide` boolean answered "does anything hit this", which is one answer
401
+ for every asker — and a sea needs two, since _"the aircraft should not treat
402
+ water as ground"_ and _"shells should splash on water"_ were the same switch.
403
+ Groups move the answer to the ASKER: the mesh says what it is, each mover says
404
+ what it treats as solid, so one sea answers differently for a seaplane and a
405
+ submarine on the same frame. Additive, and composes with the existing UI
406
+ exclusion and reject hook rather than replacing either. `b3d-water` now tags
407
+ itself `'water'`.
408
+ - **`color3d` — a colour picker that exists in a headset**, and `color.ts`, the
409
+ pure model under it (parse/format, RGB↔HSV, `contrastInk`; no DOM, so a
410
+ consumer can validate a document's colours headlessly). This was the one
411
+ control the SVG UI did not have: the only two ways to pick a colour were
412
+ `<input type="color">` (which cannot express alpha) or a consumer injecting
413
+ one, and **neither exists in an immersive session** — so the theme editor, of
414
+ all things, had no colour control in the presentation this library is for.
415
+ - **Colour icons for scene concepts** — `sky`, `sun`, `water`, `terrain`,
416
+ `fog`, `mesh`, `decor` (#64). Unlike the stroked/filled sets these carry
417
+ literal colours and no `currentColor`, so they do not follow the theme.
418
+
9
419
  ## 0.8.0
10
420
 
11
421
  Lights, editors, and the schema surface `tosijs-3d-ensemble` asked for — plus
package/Migration.md CHANGED
@@ -9,6 +9,70 @@ This file ships **inside the package**, because a migration table you can only
9
9
  read on GitHub does not exist for someone who has already installed the thing
10
10
  and is staring at an error.
11
11
 
12
+ ## 0.8.0 → 0.8.1
13
+
14
+ **Nothing breaks at compile time, and one behaviour changes.** The
15
+ `activationVeto` signature grew a second parameter and it is OPTIONAL — a
16
+ required one would have been a hard TypeScript break for every caller, and the
17
+ default is chosen so that a veto reading it gets a conservative answer rather
18
+ than a permissive one.
19
+
20
+ ### 1. Aircraft guns are direct-hit, not area-effect
21
+
22
+ **What changed.** `<tosi-b3d-aircraft>`'s cannon damages the thing its shell
23
+ passes through. It used to detonate a small AOE warhead at the impact point.
24
+
25
+ **Why.** Blast damage resolves by distance to a destroyable's registered point —
26
+ one point, at the model's origin. Scale a fighter up and its wing sits outside
27
+ the blast, so point-blank fire does nothing, silently. Direct-hit damage has no
28
+ length scale in it, so it cannot break that way. Reported by an adopter who hit
29
+ it by making their world four times larger (#23).
30
+
31
+ **If you relied on the old behaviour**, say so explicitly:
32
+
33
+ <!--
34
+ `xml`, NOT `html` — the doc system RUNS a ```html fence as a live example, and
35
+ this one is illustrative markup in a reference document with no scene to mount
36
+ into. `xml` highlights the same and stays inert. See `doc-examples.test.ts`,
37
+ which now fails on any live-language fence in a published markdown file.
38
+ -->
39
+
40
+ ```xml
41
+ <tosi-b3d-aircraft
42
+ gun-mode="blast"
43
+ gun-blast-radius="1.5"
44
+ gun-full-radius="0.5"
45
+ ></tosi-b3d-aircraft>
46
+ ```
47
+
48
+ Both radii are attributes now; they used to be hardcoded. Missiles and bombs are
49
+ unchanged — AOE is right for those.
50
+
51
+ ### 2. `activationVeto`'s second parameter (optional)
52
+
53
+ `blocks(info)` now receives a description of the activation — who, how, how far.
54
+ A veto that ignores its argument is unaffected, which is every veto written
55
+ before this existed:
56
+
57
+ ```javascript
58
+ use.vetoes.push({ name: 'locked', blocks: () => !hasKey }) // unchanged
59
+ ```
60
+
61
+ Calling `activationVeto(vetoes)` directly still compiles. When you omit the
62
+ info, vetoes are told `distance: Infinity` — "we do not know that you are near"
63
+ — so a **reach veto refuses** rather than waving the activation through. If you
64
+ call it yourself and want a reach veto to pass, supply the distance:
65
+
66
+ ```javascript
67
+ activationVeto(vetoes, { source: 'near', distance: 0.4 })
68
+ ```
69
+
70
+ ### 3. `select3d` no longer draws ‹ › stepper arrows
71
+
72
+ Tapping the control opens a popup list, which it already did — the arrows were
73
+ a second way to do the same thing and made the popup undiscoverable. Nothing to
74
+ change; the control is the same size and the same tap.
75
+
12
76
  ## 0.7.8 → 0.8.0
13
77
 
14
78
  **Nothing breaks at runtime.** Both items below keep working in 0.8.x; one is an
package/README.md CHANGED
@@ -6,6 +6,18 @@
6
6
  <img style="width: 280px; height: 280px;" alt="tosijs-3d logo" src="https://3d.tosijs.net/favicon.svg">
7
7
  </div>
8
8
 
9
+ **Looking for a capability?** Search the **[attribute
10
+ index](https://3d.tosijs.net/attributes.txt)** before assuming it does not
11
+ exist — one greppable line per attribute, generated from source on every
12
+ build. There is a [JSON form](https://3d.tosijs.net/attributes.json) for
13
+ tools, and both ship **inside the package** — an agent already in a consumer
14
+ project reads `node_modules/tosijs-3d/static/attributes.txt` with no network.
15
+
16
+ It exists because the recurring adopter failure is not a missing feature, it is
17
+ a feature that ships, is documented, and cannot be found: three issues in one
18
+ week turned out to be capability that was already there. One `grep water` finds
19
+ `submersible`; reading 147 doc pages does not.
20
+
9
21
  **Upgrading?** See [Migration.md](./Migration.md) for the breaking changes and
10
22
  what to do about them, and [CHANGELOG.md](./CHANGELOG.md) for the full detail.
11
23
  Both ship inside the package, so they work from `node_modules` too.
@@ -1 +1 @@
1
- {"version":3,"file":"ambient-leaves.d.ts","sourceRoot":"","sources":["../src/ambient-leaves.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAA;AAqB1C,MAAM,WAAW,gBAAgB;IAC/B,8FAA8F;IAC9F,QAAQ,EAAE,MAAM,CAAA;IAChB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAA;IACZ,sCAAsC;IACtC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvB;AAwCD;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,GAAG,CAA2B;gBAE1B,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,gBAAgB;IAkExD,uFAAuF;IACvF,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAMjD,iEAAiE;IACjE,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAKnC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IASxC,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,WAAW;IAqBnB;oGACgG;IAChG,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,eAAe;CAmDxB"}
1
+ {"version":3,"file":"ambient-leaves.d.ts","sourceRoot":"","sources":["../src/ambient-leaves.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAA;AAqB1C,MAAM,WAAW,gBAAgB;IAC/B,8FAA8F;IAC9F,QAAQ,EAAE,MAAM,CAAA;IAChB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAA;IACZ,sCAAsC;IACtC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvB;AAwCD;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,GAAG,CAA2B;gBAE1B,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,gBAAgB;IAkExD,uFAAuF;IACvF,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAMjD,iEAAiE;IACjE,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAKnC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IASxC,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,WAAW;IAqBnB;oGACgG;IAChG,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,eAAe;CAmDxB"}
@@ -14,10 +14,14 @@ the cost is fixed no matter how big the world is, the population is what the bud
14
14
  field DRAINS rather than being switched off. `B3dAmbient` owns all of that and drives this renderer;
15
15
  this file owns only the tumble.
16
16
 
17
- > **Wind is a placeholder here.** Each leaf carries its own drift + sway + tumble, which reads fine
18
- > in isolation but doesn't AGREE with the rain or the smoke. The shared `wind(x,y,z,t)` field
19
- > (TODO) is what makes them all blow the same way — when it lands, drift/sway come from it and this
20
- > per-leaf randomness becomes just the flutter on top.
17
+ > **The shared wind has landed.** `setWind` used to be a placeholder — each leaf carried its own
18
+ > drift, which read fine in isolation and did not AGREE with the clouds or the water. It now comes
19
+ > from [[wind|the scene's wind]] via `b3d-ambient`, so leaves stream the same way the sky does, and
20
+ > the per-leaf sway is what it was always meant to be: the flutter ON TOP of a shared field rather
21
+ > than a stand-in for one.
22
+ >
23
+ > Set `wind="own"` on the ambient element to opt out — which is how you say a courtyard is
24
+ > sheltered while the scene blows.
21
25
 
22
26
  ## See it live
23
27
 
@@ -1 +1 @@
1
- {"version":3,"file":"ambient-leaves.js","sourceRoot":"","sources":["../src/ambient-leaves.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ambient-leaves.js","sourceRoot":"","sources":["../src/ambient-leaves.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type Arc } from './arc.js';
2
+ import type { Widget3d } from './widgets3d.js';
3
+ export interface AngleField extends Widget3d {
4
+ readonly value: number;
5
+ setValue: (next: number) => void;
6
+ /** Change the permitted sector — a placement decides what a gun can reach. */
7
+ setLimits: (limits: Arc) => void;
8
+ }
9
+ export interface ArcField extends Widget3d {
10
+ readonly value: Arc;
11
+ setValue: (next: Arc) => void;
12
+ setEnvelope: (envelope: Arc) => void;
13
+ }
14
+ export interface Angle3dOptions {
15
+ label?: string;
16
+ /** DEGREES. */
17
+ value?: number;
18
+ /** The permitted sector. The handle catches at a stop rather than jumping. */
19
+ limits?: Arc;
20
+ /** Ring diameter. `0` fits the row to the panel width. */
21
+ size?: number;
22
+ handleChange?: (v: number) => void;
23
+ /** @deprecated use `handleChange` — removed in 0.9. */
24
+ onChange?: (v: number) => void;
25
+ handleCommit?: (v: number) => void;
26
+ }
27
+ export interface Arc3dOptions {
28
+ label?: string;
29
+ value?: Arc;
30
+ /** The arc may only lie within this one. */
31
+ envelope?: Arc;
32
+ minWidth?: number;
33
+ maxWidth?: number;
34
+ size?: number;
35
+ handleChange?: (v: Arc) => void;
36
+ /** @deprecated use `handleChange` — removed in 0.9. */
37
+ onChange?: (v: Arc) => void;
38
+ handleCommit?: (v: Arc) => void;
39
+ }
40
+ /** Dial one direction. */
41
+ export declare function angle3d(config?: Angle3dOptions): AngleField;
42
+ /** Dial a direction and a width together. */
43
+ export declare function arc3d(config?: Arc3dOptions): ArcField;
44
+ //# sourceMappingURL=angle-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angle-field.d.ts","sourceRoot":"","sources":["../src/angle-field.ts"],"names":[],"mappings":"AAgIA,OAAO,EAWL,KAAK,GAAG,EAET,MAAM,UAAU,CAAA;AAEjB,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAO3D,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,8EAA8E;IAC9E,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,QAAS,SAAQ,QAAQ;IACxC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAA;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IAC7B,WAAW,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAA;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,eAAe;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,GAAG,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;IAC/B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;IAC3B,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;CAChC;AAkHD,0BAA0B;AAC1B,wBAAgB,OAAO,CAAC,MAAM,GAAE,cAAmB,GAAG,UAAU,CAgG/D;AAED,6CAA6C;AAC7C,wBAAgB,KAAK,CAAC,MAAM,GAAE,YAAiB,GAAG,QAAQ,CAiHzD"}