tosijs-3d 0.7.8 → 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.
- package/CHANGELOG.md +598 -0
- package/Migration.md +112 -0
- package/README.md +12 -0
- package/dist/ambient-budget.d.ts +1 -1
- package/dist/ambient-budget.d.ts.map +1 -1
- package/dist/ambient-leaves.d.ts.map +1 -1
- package/dist/ambient-leaves.js +8 -4
- package/dist/ambient-leaves.js.map +1 -1
- package/dist/angle-field.d.ts +44 -0
- package/dist/angle-field.d.ts.map +1 -0
- package/dist/angle-field.js +414 -0
- package/dist/angle-field.js.map +1 -0
- package/dist/arc.d.ts +95 -0
- package/dist/arc.d.ts.map +1 -0
- package/dist/arc.js +206 -0
- package/dist/arc.js.map +1 -0
- package/dist/b3d-aircraft.d.ts +40 -6
- package/dist/b3d-aircraft.d.ts.map +1 -1
- package/dist/b3d-aircraft.js +230 -19
- package/dist/b3d-aircraft.js.map +1 -1
- package/dist/b3d-ambient.d.ts +8 -4
- package/dist/b3d-ambient.d.ts.map +1 -1
- package/dist/b3d-ambient.js +31 -7
- package/dist/b3d-ambient.js.map +1 -1
- package/dist/b3d-beacon.d.ts +63 -0
- package/dist/b3d-beacon.d.ts.map +1 -0
- package/dist/b3d-beacon.js +307 -0
- package/dist/b3d-beacon.js.map +1 -0
- package/dist/b3d-biped.d.ts +5 -5
- package/dist/b3d-biped.d.ts.map +1 -1
- package/dist/b3d-biped.js +8 -8
- package/dist/b3d-biped.js.map +1 -1
- package/dist/b3d-black-hole.d.ts +2 -2
- package/dist/b3d-black-hole.d.ts.map +1 -1
- package/dist/b3d-black-hole.js +1 -1
- package/dist/b3d-black-hole.js.map +1 -1
- package/dist/b3d-button.d.ts +2 -2
- package/dist/b3d-button.d.ts.map +1 -1
- package/dist/b3d-button.js +1 -1
- package/dist/b3d-button.js.map +1 -1
- package/dist/b3d-car.d.ts +4 -4
- package/dist/b3d-car.d.ts.map +1 -1
- package/dist/b3d-car.js +2 -2
- package/dist/b3d-car.js.map +1 -1
- package/dist/b3d-clouds.d.ts +11 -2
- package/dist/b3d-clouds.d.ts.map +1 -1
- package/dist/b3d-clouds.js +36 -7
- package/dist/b3d-clouds.js.map +1 -1
- package/dist/b3d-collisions.d.ts +2 -2
- package/dist/b3d-collisions.d.ts.map +1 -1
- package/dist/b3d-collisions.js +2 -2
- package/dist/b3d-collisions.js.map +1 -1
- package/dist/b3d-controllable.d.ts +4 -4
- package/dist/b3d-controllable.d.ts.map +1 -1
- package/dist/b3d-controllable.js +2 -2
- package/dist/b3d-controllable.js.map +1 -1
- package/dist/b3d-controller.d.ts +5 -5
- package/dist/b3d-controller.d.ts.map +1 -1
- package/dist/b3d-controller.js +18 -5
- package/dist/b3d-controller.js.map +1 -1
- package/dist/b3d-death.d.ts +5 -5
- package/dist/b3d-death.d.ts.map +1 -1
- package/dist/b3d-death.js +11 -10
- package/dist/b3d-death.js.map +1 -1
- package/dist/b3d-destroyable.d.ts +31 -5
- package/dist/b3d-destroyable.d.ts.map +1 -1
- package/dist/b3d-destroyable.js +103 -40
- package/dist/b3d-destroyable.js.map +1 -1
- package/dist/b3d-exploder.js +2 -2
- package/dist/b3d-exploder.js.map +1 -1
- package/dist/b3d-fog.d.ts +2 -2
- package/dist/b3d-fog.d.ts.map +1 -1
- package/dist/b3d-fog.js +1 -1
- package/dist/b3d-fog.js.map +1 -1
- package/dist/b3d-galaxy.d.ts +3 -3
- package/dist/b3d-galaxy.d.ts.map +1 -1
- package/dist/b3d-galaxy.js +3 -3
- package/dist/b3d-galaxy.js.map +1 -1
- package/dist/b3d-hud.d.ts +3 -3
- package/dist/b3d-hud.d.ts.map +1 -1
- package/dist/b3d-hud.js +5 -5
- package/dist/b3d-hud.js.map +1 -1
- package/dist/b3d-input-focus.d.ts +4 -4
- package/dist/b3d-input-focus.d.ts.map +1 -1
- package/dist/b3d-input-focus.js +4 -4
- package/dist/b3d-input-focus.js.map +1 -1
- package/dist/b3d-interactive.d.ts +13 -8
- package/dist/b3d-interactive.d.ts.map +1 -1
- package/dist/b3d-interactive.js +50 -3
- package/dist/b3d-interactive.js.map +1 -1
- package/dist/b3d-lamp.d.ts +102 -3
- package/dist/b3d-lamp.d.ts.map +1 -1
- package/dist/b3d-lamp.js +264 -15
- package/dist/b3d-lamp.js.map +1 -1
- package/dist/b3d-launcher.d.ts +28 -5
- package/dist/b3d-launcher.d.ts.map +1 -1
- package/dist/b3d-launcher.js +77 -7
- package/dist/b3d-launcher.js.map +1 -1
- package/dist/b3d-library.d.ts +3 -3
- package/dist/b3d-library.d.ts.map +1 -1
- package/dist/b3d-library.js +5 -5
- package/dist/b3d-library.js.map +1 -1
- package/dist/b3d-light.d.ts +2 -2
- package/dist/b3d-light.d.ts.map +1 -1
- package/dist/b3d-light.js +1 -1
- package/dist/b3d-light.js.map +1 -1
- package/dist/b3d-loader.d.ts +3 -3
- package/dist/b3d-loader.d.ts.map +1 -1
- package/dist/b3d-loader.js +2 -2
- package/dist/b3d-loader.js.map +1 -1
- package/dist/b3d-manipulator.d.ts +85 -0
- package/dist/b3d-manipulator.d.ts.map +1 -0
- package/dist/b3d-manipulator.js +493 -0
- package/dist/b3d-manipulator.js.map +1 -0
- package/dist/b3d-panel.d.ts +1 -1
- package/dist/b3d-panel.d.ts.map +1 -1
- package/dist/b3d-particles.d.ts +2 -2
- package/dist/b3d-particles.d.ts.map +1 -1
- package/dist/b3d-particles.js +1 -1
- package/dist/b3d-particles.js.map +1 -1
- package/dist/b3d-physics.d.ts +3 -3
- package/dist/b3d-physics.d.ts.map +1 -1
- package/dist/b3d-physics.js +5 -5
- package/dist/b3d-physics.js.map +1 -1
- package/dist/b3d-planet.d.ts +4 -4
- package/dist/b3d-planet.d.ts.map +1 -1
- package/dist/b3d-planet.js +7 -7
- package/dist/b3d-planet.js.map +1 -1
- package/dist/b3d-primitives.d.ts +2 -2
- package/dist/b3d-primitives.d.ts.map +1 -1
- package/dist/b3d-primitives.js +1 -1
- package/dist/b3d-primitives.js.map +1 -1
- package/dist/b3d-probe.d.ts +1 -1
- package/dist/b3d-probe.d.ts.map +1 -1
- package/dist/b3d-probe.js +3 -3
- package/dist/b3d-probe.js.map +1 -1
- package/dist/b3d-prop.d.ts +31 -0
- package/dist/b3d-prop.d.ts.map +1 -0
- package/dist/b3d-prop.js +244 -0
- package/dist/b3d-prop.js.map +1 -0
- package/dist/b3d-quality.d.ts +1 -1
- package/dist/b3d-quality.d.ts.map +1 -1
- package/dist/b3d-quality.js +1 -1
- package/dist/b3d-quality.js.map +1 -1
- package/dist/b3d-radar-blip.d.ts +2 -2
- package/dist/b3d-radar-blip.d.ts.map +1 -1
- package/dist/b3d-radar-blip.js +1 -1
- package/dist/b3d-radar-blip.js.map +1 -1
- package/dist/b3d-radar.d.ts +3 -3
- package/dist/b3d-radar.d.ts.map +1 -1
- package/dist/b3d-radar.js +2 -2
- package/dist/b3d-radar.js.map +1 -1
- package/dist/b3d-reflections.d.ts +2 -2
- package/dist/b3d-reflections.d.ts.map +1 -1
- package/dist/b3d-reflections.js +3 -3
- package/dist/b3d-reflections.js.map +1 -1
- package/dist/b3d-shadows.d.ts +2 -2
- package/dist/b3d-shadows.d.ts.map +1 -1
- package/dist/b3d-shadows.js +2 -2
- package/dist/b3d-shadows.js.map +1 -1
- package/dist/b3d-skybox.d.ts +4 -2
- package/dist/b3d-skybox.d.ts.map +1 -1
- package/dist/b3d-skybox.js +33 -2
- package/dist/b3d-skybox.js.map +1 -1
- package/dist/b3d-sound.d.ts +2 -2
- package/dist/b3d-sound.d.ts.map +1 -1
- package/dist/b3d-sound.js +3 -3
- package/dist/b3d-sound.js.map +1 -1
- package/dist/b3d-spawner.d.ts +27 -3
- package/dist/b3d-spawner.d.ts.map +1 -1
- package/dist/b3d-spawner.js +55 -13
- package/dist/b3d-spawner.js.map +1 -1
- package/dist/b3d-star-system.d.ts +3 -3
- package/dist/b3d-star-system.d.ts.map +1 -1
- package/dist/b3d-star-system.js +3 -3
- package/dist/b3d-star-system.js.map +1 -1
- package/dist/b3d-star.d.ts +2 -2
- package/dist/b3d-star.d.ts.map +1 -1
- package/dist/b3d-star.js +2 -2
- package/dist/b3d-star.js.map +1 -1
- package/dist/b3d-svg-plane.d.ts +3 -3
- package/dist/b3d-svg-plane.d.ts.map +1 -1
- package/dist/b3d-svg-plane.js +12 -83
- package/dist/b3d-svg-plane.js.map +1 -1
- package/dist/b3d-terrain.d.ts +31 -4
- package/dist/b3d-terrain.d.ts.map +1 -1
- package/dist/b3d-terrain.js +261 -24
- package/dist/b3d-terrain.js.map +1 -1
- package/dist/b3d-trigger.d.ts +6 -2
- package/dist/b3d-trigger.d.ts.map +1 -1
- package/dist/b3d-trigger.js +28 -4
- package/dist/b3d-trigger.js.map +1 -1
- package/dist/b3d-turret.d.ts +20 -4
- package/dist/b3d-turret.d.ts.map +1 -1
- package/dist/b3d-turret.js +80 -4
- package/dist/b3d-turret.js.map +1 -1
- package/dist/b3d-utils.d.ts +97 -2
- package/dist/b3d-utils.d.ts.map +1 -1
- package/dist/b3d-utils.js +220 -3
- package/dist/b3d-utils.js.map +1 -1
- package/dist/b3d-warhead.d.ts +7 -4
- package/dist/b3d-warhead.d.ts.map +1 -1
- package/dist/b3d-warhead.js +45 -21
- package/dist/b3d-warhead.js.map +1 -1
- package/dist/b3d-water.d.ts +11 -2
- package/dist/b3d-water.d.ts.map +1 -1
- package/dist/b3d-water.js +77 -6
- package/dist/b3d-water.js.map +1 -1
- package/dist/biome-chart.js +3 -3
- package/dist/box.d.ts +6 -2
- package/dist/box.d.ts.map +1 -1
- package/dist/box.js +19 -10
- package/dist/box.js.map +1 -1
- package/dist/carve.d.ts +1 -1
- package/dist/carve.d.ts.map +1 -1
- package/dist/carve.js +1 -1
- package/dist/carve.js.map +1 -1
- package/dist/color-field.d.ts +30 -0
- package/dist/color-field.d.ts.map +1 -0
- package/dist/color-field.js +351 -0
- package/dist/color-field.js.map +1 -0
- package/dist/color.d.ts +47 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/color.js +216 -0
- package/dist/color.js.map +1 -0
- package/dist/curve-field.d.ts +8 -2
- package/dist/curve-field.d.ts.map +1 -1
- package/dist/curve-field.js +79 -44
- package/dist/curve-field.js.map +1 -1
- package/dist/curve-program.d.ts +2 -2
- package/dist/curve-program.d.ts.map +1 -1
- package/dist/curve-program.js +68 -37
- package/dist/curve-program.js.map +1 -1
- package/dist/curve.d.ts +1 -1
- package/dist/curve.d.ts.map +1 -1
- package/dist/curve.js +1 -1
- package/dist/curve.js.map +1 -1
- package/dist/demo-utils.d.ts +4 -4
- package/dist/demo-utils.d.ts.map +1 -1
- package/dist/demo-utils.js +1 -1
- package/dist/demo-utils.js.map +1 -1
- package/dist/destroyable-behavior.d.ts +24 -4
- package/dist/destroyable-behavior.d.ts.map +1 -1
- package/dist/destroyable-behavior.js +109 -6
- package/dist/destroyable-behavior.js.map +1 -1
- package/dist/destroyable.d.ts +51 -2
- package/dist/destroyable.d.ts.map +1 -1
- package/dist/destroyable.js +29 -5
- package/dist/destroyable.js.map +1 -1
- package/dist/footprint-field.d.ts +7 -2
- package/dist/footprint-field.d.ts.map +1 -1
- package/dist/footprint-field.js +8 -4
- package/dist/footprint-field.js.map +1 -1
- package/dist/frame-panel.d.ts +1 -1
- package/dist/frame-panel.d.ts.map +1 -1
- package/dist/frame-panel.js +4 -4
- package/dist/frame-panel.js.map +1 -1
- package/dist/galaxy-data.d.ts +1 -1
- package/dist/galaxy-data.d.ts.map +1 -1
- package/dist/galaxy-data.js +1 -1
- package/dist/galaxy-data.js.map +1 -1
- package/dist/game-controller.d.ts +3 -3
- package/dist/game-controller.d.ts.map +1 -1
- package/dist/game-controller.js +2 -2
- package/dist/game-controller.js.map +1 -1
- package/dist/gamepad-focus.d.ts +1 -1
- package/dist/gamepad-focus.d.ts.map +1 -1
- package/dist/glass-gamepad.d.ts +1 -1
- package/dist/glass-gamepad.d.ts.map +1 -1
- package/dist/glass-gamepad.js +3 -3
- package/dist/glass-gamepad.js.map +1 -1
- package/dist/gradient-editor.d.ts +1 -1
- package/dist/gradient-editor.d.ts.map +1 -1
- package/dist/gradient-editor.js +1 -1
- package/dist/gradient-editor.js.map +1 -1
- package/dist/handler-of.d.ts +14 -0
- package/dist/handler-of.d.ts.map +1 -0
- package/dist/handler-of.js +65 -0
- package/dist/handler-of.js.map +1 -0
- package/dist/hardware-gamepad.d.ts +1 -1
- package/dist/hardware-gamepad.d.ts.map +1 -1
- package/dist/hardware-gamepad.js +1 -1
- package/dist/hardware-gamepad.js.map +1 -1
- package/dist/hud-math.d.ts +1 -1
- package/dist/hud-math.d.ts.map +1 -1
- package/dist/hud-math.js +1 -1
- package/dist/hud-math.js.map +1 -1
- package/dist/hud.d.ts +3 -3
- package/dist/hud.d.ts.map +1 -1
- package/dist/hud.js +1 -1
- package/dist/hud.js.map +1 -1
- package/dist/icon-data.d.ts.map +1 -1
- package/dist/icon-data.js +11 -0
- package/dist/icon-data.js.map +1 -1
- package/dist/icon-grid.d.ts +2 -2
- package/dist/icon-grid.d.ts.map +1 -1
- package/dist/icon-grid.js +4 -4
- package/dist/icon-grid.js.map +1 -1
- package/dist/index.d.ts +253 -224
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +194 -145
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +58 -3
- package/dist/interaction.d.ts.map +1 -1
- package/dist/interaction.js +26 -10
- package/dist/interaction.js.map +1 -1
- package/dist/interactive-behavior.d.ts +74 -8
- package/dist/interactive-behavior.d.ts.map +1 -1
- package/dist/interactive-behavior.js +129 -9
- package/dist/interactive-behavior.js.map +1 -1
- package/dist/jolt-plugin.d.ts +12 -12
- package/dist/jolt-plugin.d.ts.map +1 -1
- package/dist/jolt-plugin.js +5 -5
- package/dist/jolt-plugin.js.map +1 -1
- package/dist/key-layout.d.ts +1 -1
- package/dist/key-layout.d.ts.map +1 -1
- package/dist/key-layout.js +30 -0
- package/dist/key-layout.js.map +1 -1
- package/dist/keyboard-gamepad.d.ts +1 -1
- package/dist/keyboard-gamepad.d.ts.map +1 -1
- package/dist/keyboard-gamepad.js +19 -1
- package/dist/keyboard-gamepad.js.map +1 -1
- package/dist/keyboard.d.ts +20 -4
- package/dist/keyboard.d.ts.map +1 -1
- package/dist/keyboard.js +172 -55
- package/dist/keyboard.js.map +1 -1
- package/dist/library-mesh.d.ts +47 -0
- package/dist/library-mesh.d.ts.map +1 -0
- package/dist/library-mesh.js +114 -0
- package/dist/library-mesh.js.map +1 -0
- package/dist/light-editor.d.ts +18 -2
- package/dist/light-editor.d.ts.map +1 -1
- package/dist/light-editor.js +39 -13
- package/dist/light-editor.js.map +1 -1
- package/dist/light-modulation.d.ts +57 -3
- package/dist/light-modulation.d.ts.map +1 -1
- package/dist/light-modulation.js +305 -20
- package/dist/light-modulation.js.map +1 -1
- package/dist/light-settings.d.ts +2 -2
- package/dist/light-settings.d.ts.map +1 -1
- package/dist/light-settings.js +2 -2
- package/dist/light-settings.js.map +1 -1
- package/dist/make-mesh.js +2 -2
- package/dist/make-mesh.js.map +1 -1
- package/dist/manipulator-view.d.ts +79 -0
- package/dist/manipulator-view.d.ts.map +1 -0
- package/dist/manipulator-view.js +552 -0
- package/dist/manipulator-view.js.map +1 -0
- package/dist/manipulator.d.ts +214 -0
- package/dist/manipulator.d.ts.map +1 -0
- package/dist/manipulator.js +423 -0
- package/dist/manipulator.js.map +1 -0
- package/dist/min-sim-conformance.d.ts +1 -1
- package/dist/min-sim-conformance.d.ts.map +1 -1
- package/dist/model-transform.d.ts +24 -0
- package/dist/model-transform.d.ts.map +1 -1
- package/dist/model-transform.js +39 -0
- package/dist/model-transform.js.map +1 -1
- package/dist/panel-layer.d.ts +34 -0
- package/dist/panel-layer.d.ts.map +1 -0
- package/dist/panel-layer.js +154 -0
- package/dist/panel-layer.js.map +1 -0
- package/dist/panel-orbit.d.ts +156 -0
- package/dist/panel-orbit.d.ts.map +1 -0
- package/dist/panel-orbit.js +289 -0
- package/dist/panel-orbit.js.map +1 -0
- package/dist/picker.d.ts +40 -0
- package/dist/picker.d.ts.map +1 -0
- package/dist/picker.js +385 -0
- package/dist/picker.js.map +1 -0
- package/dist/popup-surface.d.ts +16 -3
- package/dist/popup-surface.d.ts.map +1 -1
- package/dist/popup-surface.js +9 -6
- package/dist/popup-surface.js.map +1 -1
- package/dist/portal-transform.d.ts +1 -1
- package/dist/portal-transform.d.ts.map +1 -1
- package/dist/portal-transform.js +1 -1
- package/dist/portal-transform.js.map +1 -1
- package/dist/prefab.d.ts +1 -1
- package/dist/prefab.d.ts.map +1 -1
- package/dist/province-climate.d.ts +82 -0
- package/dist/province-climate.d.ts.map +1 -0
- package/dist/province-climate.js +242 -0
- package/dist/province-climate.js.map +1 -0
- package/dist/scene-schemas.d.ts +110 -0
- package/dist/scene-schemas.d.ts.map +1 -0
- package/dist/scene-schemas.js +518 -0
- package/dist/scene-schemas.js.map +1 -0
- package/dist/sdf-lattice.js +4 -4
- package/dist/shadow-decal.js +1 -1
- package/dist/shadow-decal.js.map +1 -1
- package/dist/slope-profile.d.ts +1 -1
- package/dist/slope-profile.d.ts.map +1 -1
- package/dist/slope-profile.js +2 -2
- package/dist/slope-profile.js.map +1 -1
- package/dist/surface.d.ts +4 -2
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +13 -12
- package/dist/surface.js.map +1 -1
- package/dist/svg-icons.d.ts +29 -2
- package/dist/svg-icons.d.ts.map +1 -1
- package/dist/svg-icons.js +125 -9
- package/dist/svg-icons.js.map +1 -1
- package/dist/svg-texture.js +1 -1
- package/dist/svg-texture.js.map +1 -1
- package/dist/table-layout.d.ts +31 -0
- package/dist/table-layout.d.ts.map +1 -1
- package/dist/table-layout.js.map +1 -1
- package/dist/table.d.ts +29 -3
- package/dist/table.d.ts.map +1 -1
- package/dist/table.js +140 -12
- package/dist/table.js.map +1 -1
- package/dist/terrain-editor.d.ts +20 -0
- package/dist/terrain-editor.d.ts.map +1 -0
- package/dist/terrain-editor.js +295 -0
- package/dist/terrain-editor.js.map +1 -0
- package/dist/terrain-grid.d.ts +30 -0
- package/dist/terrain-grid.d.ts.map +1 -1
- package/dist/terrain-grid.js +33 -0
- package/dist/terrain-grid.js.map +1 -1
- package/dist/text-entry.d.ts +9 -0
- package/dist/text-entry.d.ts.map +1 -0
- package/dist/text-entry.js +105 -0
- package/dist/text-entry.js.map +1 -0
- package/dist/theme-editor.d.ts +3 -1
- package/dist/theme-editor.d.ts.map +1 -1
- package/dist/theme-editor.js +25 -6
- package/dist/theme-editor.js.map +1 -1
- package/dist/tosi-b3d.d.ts +92 -13
- package/dist/tosi-b3d.d.ts.map +1 -1
- package/dist/tosi-b3d.js +548 -79
- package/dist/tosi-b3d.js.map +1 -1
- package/dist/touch-gamepad.d.ts +1 -1
- package/dist/touch-gamepad.d.ts.map +1 -1
- package/dist/touch-gamepad.js +1 -1
- package/dist/touch-gamepad.js.map +1 -1
- package/dist/vector-field.d.ts +9 -15
- package/dist/vector-field.d.ts.map +1 -1
- package/dist/vector-field.js +23 -26
- package/dist/vector-field.js.map +1 -1
- package/dist/virtual-gamepad.d.ts +1 -1
- package/dist/virtual-gamepad.d.ts.map +1 -1
- package/dist/virtual-gamepad.js +1 -1
- package/dist/virtual-gamepad.js.map +1 -1
- package/dist/w3d-theme.d.ts.map +1 -1
- package/dist/w3d-theme.js +22 -3
- package/dist/w3d-theme.js.map +1 -1
- package/dist/water-normal.d.ts +1 -1
- package/dist/water-normal.d.ts.map +1 -1
- package/dist/water-normal.js +1 -1
- package/dist/water-normal.js.map +1 -1
- package/dist/widget-box.d.ts +2 -2
- package/dist/widget-box.d.ts.map +1 -1
- package/dist/widget-box.js +2 -2
- package/dist/widget-box.js.map +1 -1
- package/dist/widgets3d-layout.d.ts +19 -2
- package/dist/widgets3d-layout.d.ts.map +1 -1
- package/dist/widgets3d-layout.js +83 -4
- package/dist/widgets3d-layout.js.map +1 -1
- package/dist/widgets3d.d.ts +207 -2
- package/dist/widgets3d.d.ts.map +1 -1
- package/dist/widgets3d.js +862 -110
- package/dist/widgets3d.js.map +1 -1
- package/dist/wind.d.ts +90 -0
- package/dist/wind.d.ts.map +1 -0
- package/dist/wind.js +263 -0
- package/dist/wind.js.map +1 -0
- package/dist/world-store.d.ts +1 -1
- package/dist/world-store.d.ts.map +1 -1
- package/dist/world-store.js +1 -1
- package/dist/world-store.js.map +1 -1
- package/dist/world-topology.d.ts +1 -1
- package/dist/world-topology.d.ts.map +1 -1
- package/dist/world-view.d.ts +2 -2
- package/dist/world-view.d.ts.map +1 -1
- package/dist/wreck-fall.js +1 -1
- package/dist/wreck-fall.js.map +1 -1
- package/dist/xr-gamepad.d.ts +2 -2
- package/dist/xr-gamepad.d.ts.map +1 -1
- package/dist/xr-gamepad.js +1 -1
- package/dist/xr-gamepad.js.map +1 -1
- package/dist/xr-input-provider.d.ts +2 -2
- package/dist/xr-input-provider.d.ts.map +1 -1
- package/dist/xr-input-provider.js +1 -1
- package/dist/xr-input-provider.js.map +1 -1
- package/package.json +13 -4
- package/static/attributes.json +4062 -0
- package/static/attributes.txt +1093 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,604 @@ 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
|
+
|
|
419
|
+
## 0.8.0
|
|
420
|
+
|
|
421
|
+
Lights, editors, and the schema surface `tosijs-3d-ensemble` asked for — plus
|
|
422
|
+
the two renames that were waiting for a minor.
|
|
423
|
+
|
|
424
|
+
### ⚠️ Breaking
|
|
425
|
+
|
|
426
|
+
- **Peer dependency: `tosijs` is now `^1.9.2`** (was `^1.7.8`). Upgrade tosijs
|
|
427
|
+
alongside this. The floor moved because 1.9 fixes five issues we filed
|
|
428
|
+
(tosijs#14/#15/#22/#24/#27) and holding it down only defers the work.
|
|
429
|
+
|
|
430
|
+
Behaviour that changed with it, verified rather than assumed: a wrong-typed
|
|
431
|
+
write to an `initAttributes` prop used to be **silently discarded** and now
|
|
432
|
+
**warns and applies the value**. So `foo: false` on an `'on'|'off'` attribute
|
|
433
|
+
genuinely sets `false` where it used to quietly default — use `isOff()`,
|
|
434
|
+
which accepts `'off'`, `false` and `'false'`.
|
|
435
|
+
|
|
436
|
+
- **Callbacks are `handleX`, not `onX`.** `handleChange`, `handleClick`,
|
|
437
|
+
`handleSelect`. **Both spellings work through 0.8.x** and the old one warns
|
|
438
|
+
once per name; `onX` is removed in 0.9.
|
|
439
|
+
|
|
440
|
+
Not a style preference: these are plain factories today, but the moment one
|
|
441
|
+
becomes a tosijs component the element creator binds an `on*` prop as a DOM
|
|
442
|
+
event **listener** and the class field is silently never called. `handleX`
|
|
443
|
+
cannot be mistaken for an event name. Giving both, the new one wins.
|
|
444
|
+
|
|
445
|
+
**Migrated in this release** — `inputField`, `keyboard`, `table`,
|
|
446
|
+
`box`/`surface`, popups, debug actions and the curve/footprint/vector fields.
|
|
447
|
+
In other words: all of them. `b3d-trigger` gains `whenEnter`/`whenExit`
|
|
448
|
+
instead, because components use `when*` (see Fixed).
|
|
449
|
+
|
|
450
|
+
### Added
|
|
451
|
+
|
|
452
|
+
- **`handlerOf`** (`handler-of.ts`, exported from the barrel) — the shim behind
|
|
453
|
+
the `handleX`/`onX` rule, in its own dependency-free module so the smallest
|
|
454
|
+
widget can adopt it without importing `widgets3d`. Use it for your own
|
|
455
|
+
widgets: `handlerOf(config, 'handleChange', 'onChange')?.(value)`.
|
|
456
|
+
|
|
457
|
+
- **Lamps** — `b3dPointLight`, `b3dSpotLight`, `b3dAreaLight`: a placed light
|
|
458
|
+
with its own fixture geometry, which **tracks the light** (a fluorescent's
|
|
459
|
+
bulb stutters as it strikes and dims to a red ember as it dies). Shadows where
|
|
460
|
+
Babylon allows, **gels** where it allows (spot only), and a generated cone
|
|
461
|
+
`shape` (`circle`/`square` + `shapeAspect`, `shapeSoftness`) plus a true
|
|
462
|
+
`innerAngle` penumbra.
|
|
463
|
+
|
|
464
|
+
- **Light programs** — one curve per channel (brightness, hue, saturation,
|
|
465
|
+
range) split into attack / sustain / decay by two markers. `duration` divides
|
|
466
|
+
by those markers, so dragging one **retimes** the lamp. Presets: `steady`,
|
|
467
|
+
`fluorescent`, `flickery`, `brownout`, `candle`, `fireplace`. `timeSource`
|
|
468
|
+
picks the real clock (default — a flicker should not freeze when the world
|
|
469
|
+
pauses) or the world's.
|
|
470
|
+
|
|
471
|
+
- **Editors** — `curveProgram3d` (several curves sharing one pair of draggable
|
|
472
|
+
split markers), `lightEditor3d` (the whole lamp), and `curveMarkers`.
|
|
473
|
+
Controlled, with `handleCommit(value, describe)` once per gesture carrying
|
|
474
|
+
canonical values and a verb phrase, so a document records one undo step.
|
|
475
|
+
|
|
476
|
+
- **`scene-schemas`** — JSON Schema for all nine scene primitives: skybox, sun,
|
|
477
|
+
water, ground, fog, clouds, ambient, terrain, reflections (and the hemispheric
|
|
478
|
+
light). **No DOM, no Babylon.** So nobody hand-copies our
|
|
479
|
+
attributes: a consumer's hand-written skybox schema carried 6 of 16 and
|
|
480
|
+
disagreed on a default. Drift is caught by a test, not promised.
|
|
481
|
+
|
|
482
|
+
- **`province-climate`** — water, temperature and volcanism as bipolar bias
|
|
483
|
+
curves (`0.5` leaves the base alone) plus water presence and level as scalars,
|
|
484
|
+
because "there is a lake here at 12 m" is not something a curve can say.
|
|
485
|
+
|
|
486
|
+
- **`spinner3d` / `progress3d`** — the widget set could say what a value IS but
|
|
487
|
+
not that work was under way. The spinner animates as GEOMETRY, not CSS,
|
|
488
|
+
because a keyframe animation does not run once the SVG is rasterised to a
|
|
489
|
+
texture — it would look right flat and freeze in a headset.
|
|
490
|
+
|
|
491
|
+
- **Filtered tables** — `filter` / `setFilter(predicate)` and `counts`. A filter
|
|
492
|
+
never drops a selection: hiding is a view state, and losing a selection to it
|
|
493
|
+
would make typing in a search box destructive.
|
|
494
|
+
|
|
495
|
+
- **`table` button columns** — `kind: 'button'` with `menu(row)` opens an action
|
|
496
|
+
menu anchored to the cell. The button takes the press instead of the row, so
|
|
497
|
+
a row's ⋯ does not also select it.
|
|
498
|
+
|
|
499
|
+
- **`registerIcons`** — consumers add icons every widget resolves by name.
|
|
500
|
+
- **Log sliders** — `scale: 'log' | 'log2'`, `snap`, and `zeroStop` for a
|
|
501
|
+
quantity that spans decades and can still be switched off.
|
|
502
|
+
- **Action menus** — `openMenu3d`, `button3d({ menu })`, `iconGrid3d` menu
|
|
503
|
+
cells; `disabled` takes a predicate so a menu can be a constant.
|
|
504
|
+
- **`table`** — `ColumnSpec.kind: 'icon'`.
|
|
505
|
+
|
|
506
|
+
### Fixed
|
|
507
|
+
|
|
508
|
+
- A **move** no longer costs a scene, and a genuine removal now disposes the
|
|
509
|
+
engine — a leaked WebGL context is not just memory (Chrome caps them near 16
|
|
510
|
+
and force-loses the oldest).
|
|
511
|
+
- `shadows`, the gel and `geometry` each accepted a write and did nothing; all
|
|
512
|
+
three now sync per render. Lamps also never marked shadow **receivers**, so a
|
|
513
|
+
shadow map was rendered that nothing read.
|
|
514
|
+
- `canonicalProgram` silently dropped `duration`, so a committed edit turned a
|
|
515
|
+
flickering lamp steady.
|
|
516
|
+
- A nested widget's popup opened at the top of its container rather than beside
|
|
517
|
+
the control.
|
|
518
|
+
- `lightEditor3d` shipped demo copy into every consumer's panel; the hint is now
|
|
519
|
+
opt-in.
|
|
520
|
+
- The aircraft chase camera sat too close after content moved to human scale.
|
|
521
|
+
- **`themeEditor` never called back.** It read `config.onChange` while its
|
|
522
|
+
callers passed `handleChange`, so the theme table updated and the host's
|
|
523
|
+
rebuild never ran — the controls moved and the panels they edit did not.
|
|
524
|
+
`handleChange` is now the option; `onChange` still works, deprecated.
|
|
525
|
+
- A metric typed **out of range** left the slider on the cap and the number
|
|
526
|
+
field above it, with the theme taking the out-of-range value — the exact
|
|
527
|
+
drift a paired slider-and-field exists to prevent. Values are clamped now.
|
|
528
|
+
- Two demos (`w3d-theme`, `keyboard`) passed `handleChange` to `inputField`,
|
|
529
|
+
which reads `onChange` — so typing updated nothing. Demo code lives in doc
|
|
530
|
+
comments and is **not type-checked**, which is why this class of mistake
|
|
531
|
+
reaches a page instead of the compiler.
|
|
532
|
+
- **The `curve-program` demo was truncated on the published site.** Its doc
|
|
533
|
+
comment contained a nested `/* … */`, and block comments do not nest — the
|
|
534
|
+
inner `*/` closed the page early, so roughly half the demo silently vanished.
|
|
535
|
+
- **The in-scene panel was sized by a guess, and the guess was wrong for the
|
|
536
|
+
one panel that mattered.** Height was `46 + rows × 48`, which assumes a row is
|
|
537
|
+
about 48px. `lightEditor3d` is ONE row that lays out over 1200px, so its panel
|
|
538
|
+
was built ~142px tall and you scrolled a postage stamp. It now sizes to its
|
|
539
|
+
content (`height: 'fit'`) with a cap, so the same panel is 620px — Tonio, from
|
|
540
|
+
the headset: _"crammed into a tiny tiny view so you have to scroll it
|
|
541
|
+
constantly… I didn't try messing with curves because they were too far down."_
|
|
542
|
+
- **The in-scene panel's icon bar no longer scrolls away.** It carries Exit VR,
|
|
543
|
+
and a control you need in order to LEAVE is the one thing a headset panel
|
|
544
|
+
cannot afford to lose. `panel3d` gained a `header` option — rows pinned above
|
|
545
|
+
the scrolling body — which also ends a divergence, since the flat
|
|
546
|
+
presentation has always pinned its bar by rendering it as DOM.
|
|
547
|
+
- **The theme editor no longer follows you to other demos.** It edits the global
|
|
548
|
+
table deliberately (that is what makes both panels re-theme live), but the doc
|
|
549
|
+
site is one page, so walking away left everything else wearing your palette.
|
|
550
|
+
The demo now restores it on unmount.
|
|
551
|
+
- **`dist` could not be imported by Node at all** — 394 relative specifiers were
|
|
552
|
+
written without an extension (`from './tosi-b3d'`), which every bundler and
|
|
553
|
+
Bun resolves and Node's ESM resolver does not. Reported by
|
|
554
|
+
`tosijs-3d-ensemble` (#69) after they fixed the identical fault in their own
|
|
555
|
+
package and the failure moved one level down into ours.
|
|
556
|
+
|
|
557
|
+
Source specifiers now carry `.js` — the TypeScript convention, passed through
|
|
558
|
+
by `tsc` and resolved fine by bundlers, so it works everywhere and keeps the
|
|
559
|
+
per-file `dist` we ship deliberately. That covers deep package subpaths too
|
|
560
|
+
(`@babylonjs/core/Misc/observable.js`), which failed the same way. Verified by
|
|
561
|
+
importing the built package under Node 24, not by reasoning about it.
|
|
562
|
+
|
|
563
|
+
A test now asserts it **of the source**, so it fails at authoring time rather
|
|
564
|
+
than after a publish — the only moment anyone was going to notice, since every
|
|
565
|
+
loop here is a bundler or Bun.
|
|
566
|
+
|
|
567
|
+
- **Subpath exports** — `import { validateLight } from 'tosijs-3d/light-settings'`
|
|
568
|
+
now works. The pure modules were split from their editors precisely so a
|
|
569
|
+
consumer could validate documents headlessly, but the only export was the
|
|
570
|
+
barrel, which defines custom elements on import and needs `HTMLElement`. So
|
|
571
|
+
the headless half was still behind a browser. It is not now.
|
|
572
|
+
|
|
573
|
+
⚠️ **This is a wildcard** (`"./*"` → `./dist/*.js`), so **every module in
|
|
574
|
+
`dist/` is now a supported specifier** and covered by semver — renaming one is
|
|
575
|
+
a breaking change from here on. 142 of them were already public through the
|
|
576
|
+
barrel; the genuinely new surface is nine. The three superseded modules
|
|
577
|
+
(`reflections`, `dynamic-shadows`, `rippling-water`) are explicitly blocked so
|
|
578
|
+
the wildcard cannot resurrect them.
|
|
579
|
+
|
|
580
|
+
- **`handleX` now works on every callback option, and `onX` is deprecated.**
|
|
581
|
+
It used to depend on which widget you were holding — `curve3d` took
|
|
582
|
+
`handleChange`, `inputField` took `onChange`, and neither complained about the
|
|
583
|
+
other — which is what made three of the bugs above possible. Migrated:
|
|
584
|
+
`table` (`handleSelect`/`handleActivate`), `box`'s `BoxChild` and `button`
|
|
585
|
+
(`handleActivate`), `surface`'s `MenuItem` (`handleSelect`), `inputField`
|
|
586
|
+
(`handleChange`/`handleEnter`/`handleFocus`, on the object as well as in
|
|
587
|
+
config), `keyboard` (`handleKey`/`handleAction`/`handleCaretMove`), popups
|
|
588
|
+
(`handleClose`), and debug-source actions (`handleClick`). Every `onX` still
|
|
589
|
+
works, warns **once per name**, and is removed in 0.9.
|
|
590
|
+
- `b3d-trigger` gains **`whenEnter`/`whenExit`** (components use `when*`, like
|
|
591
|
+
`whenImpact`). Passing `onEnter` to the element creator never set the field at
|
|
592
|
+
all — it added a listener for the `'enter'` CustomEvent, so the callback got
|
|
593
|
+
an Event while `trigger.onEnter = fn` got the trigger. Same callback, two
|
|
594
|
+
different arguments depending on how you attached it.
|
|
595
|
+
- The `curve-program` and `curve-field` editors did not exist inside a headset:
|
|
596
|
+
both put their controls in flat DOM beside the canvas, which an immersive
|
|
597
|
+
session does not render. Both now also build through `scenePanel`.
|
|
598
|
+
|
|
599
|
+
### Changed
|
|
600
|
+
|
|
601
|
+
- Doc pages are named for what they are (`Light program editor`, `Curve
|
|
602
|
+
editor`, `Lamps`) rather than for their module. URLs are unchanged.
|
|
603
|
+
- ⚠️ `shadows="on"` is not free — one extra render of the caster list per lamp
|
|
604
|
+
per frame, worse with a large `range`. Prefer `off` for dynamically inserted
|
|
605
|
+
content.
|
|
606
|
+
|
|
9
607
|
## 0.7.8
|
|
10
608
|
|
|
11
609
|
Lights you can see, edit and animate — and the editor surface `tosijs-3d-ensemble`
|