@woosh/meep-engine 3.60.0 → 3.60.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/src/shade/playground/sh_exponential/main.js +2 -2
  3. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +4 -0
  4. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts +6 -1
  5. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  6. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +12 -4
  7. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  8. package/src/shade/renderer/light/GPULightCollection.js +3 -5
  9. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +13 -5
  10. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  11. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +133 -7
  12. package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts +9 -0
  13. package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
  14. package/src/shade/renderer/light/environment/graph_filter_environment_map.js +33 -4
  15. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts +13 -0
  16. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts.map +1 -0
  17. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.js +169 -0
  18. package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts +3 -0
  19. package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -0
  20. package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +105 -0
  21. package/src/shade/renderer/light/environment/sphere_probe_lod_to_roughness.d.ts +10 -0
  22. package/src/shade/renderer/light/environment/sphere_probe_lod_to_roughness.d.ts.map +1 -0
  23. package/src/shade/renderer/light/environment/sphere_probe_lod_to_roughness.js +23 -0
  24. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts +8 -4
  25. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts.map +1 -1
  26. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.js +9 -5
  27. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  28. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +26 -1
  29. package/src/view/elements/progress/segmented/GhostTrail.d.ts +78 -12
  30. package/src/view/elements/progress/segmented/GhostTrail.d.ts.map +1 -1
  31. package/src/view/elements/progress/segmented/GhostTrail.js +294 -98
  32. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +68 -24
  33. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
  34. package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +196 -128
  35. package/src/view/elements/progress/segmented/playground/main.js +18 -11
  36. package/src/view/elements/progress/segmented/segment_cell_extent.d.ts +14 -0
  37. package/src/view/elements/progress/segmented/segment_cell_extent.d.ts.map +1 -0
  38. package/src/view/elements/progress/segmented/segment_cell_extent.js +44 -0
  39. package/src/view/elements/progress/segmented/segment_mask_url.d.ts +24 -0
  40. package/src/view/elements/progress/segmented/segment_mask_url.d.ts.map +1 -0
  41. package/src/view/elements/progress/segmented/segment_mask_url.js +74 -0
  42. package/src/view/elements/progress/segmented/segment_mask_width.d.ts +18 -0
  43. package/src/view/elements/progress/segmented/segment_mask_width.d.ts.map +1 -0
  44. package/src/view/elements/progress/segmented/segment_mask_width.js +46 -0
  45. package/src/view/elements/progress/segmented/segmented-resource-bar.css +6 -10
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @type {HTMLCanvasElement|null}
3
+ */
4
+ let canvas = null;
5
+
6
+ /**
7
+ * Whether masks can be drawn here. Keyed on `OffscreenCanvas`, which every browser that draws a canvas has and
8
+ * jsdom does not: jsdom's own canvas reports "not implemented" on the console for every call, so it is never asked.
9
+ * @returns {boolean}
10
+ */
11
+ export function segment_mask_supported() {
12
+ return typeof OffscreenCanvas === 'function' && typeof document !== 'undefined';
13
+ }
14
+
15
+ /**
16
+ * A mask image of opaque columns, one device pixel tall, for a layer `width_device` device pixels wide: stretched
17
+ * over the layer with `mask-size: 100% 100%`, each column covers exactly the device pixels it was drawn on. CSS keeps
18
+ * painting the layer (its colour, gradient, height); the mask only decides which columns of it show.
19
+ *
20
+ * @param {number} width_device
21
+ * @param {number[]} columns [x, width, x, width, ...] in whole device pixels from the layer's left edge
22
+ * @param {number} column_count how many pairs of `columns` to draw
23
+ * @returns {string|null} a `url(...)` for `mask-image`, or null where masks cannot be drawn
24
+ */
25
+ export function segment_mask_url(width_device, columns, column_count) {
26
+ if (!segment_mask_supported() || !(width_device > 0)) {
27
+ return null;
28
+ }
29
+
30
+ if (canvas === null) {
31
+ canvas = document.createElement('canvas');
32
+ }
33
+
34
+ canvas.width = width_device;
35
+ canvas.height = 1;
36
+
37
+ const ctx = canvas.getContext('2d');
38
+
39
+ if (ctx === null) {
40
+ return null;
41
+ }
42
+
43
+ ctx.clearRect(0, 0, width_device, 1);
44
+ ctx.fillStyle = '#000';
45
+
46
+ for (let i = 0; i < column_count; i++) {
47
+ ctx.fillRect(columns[i * 2], 0, columns[i * 2 + 1], 1);
48
+ }
49
+
50
+ return `url(${canvas.toDataURL()})`;
51
+ }
52
+
53
+ /**
54
+ * Put a mask from {@link segment_mask_url} on an element, sampled nearest so its columns stay whole, or take it off
55
+ * @param {HTMLElement} el
56
+ * @param {string|null} url
57
+ */
58
+ export function segment_mask_apply(el, url) {
59
+ const style = el.style;
60
+ const value = url === null ? '' : url;
61
+
62
+ style.setProperty('mask-image', value);
63
+ style.setProperty('-webkit-mask-image', value);
64
+
65
+ if (url === null) {
66
+ return;
67
+ }
68
+
69
+ style.setProperty('mask-size', '100% 100%');
70
+ style.setProperty('-webkit-mask-size', '100% 100%');
71
+ style.setProperty('mask-repeat', 'no-repeat');
72
+ style.setProperty('-webkit-mask-repeat', 'no-repeat');
73
+ style.setProperty('image-rendering', 'pixelated');
74
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The width to give a layer whose content is drawn in whole device pixels and stretched over it by a mask: the
3
+ * widest whole number of CSS pixels, no wider than `width_px`, that is also a whole number of device pixels.
4
+ *
5
+ * Measured in Chrome (90% to 300%): a masked layer whose width is not whole in both units is resampled when it is
6
+ * painted, and somewhere along it one device column is doubled or dropped, so one gap of a row of equal gaps paints
7
+ * a pixel wider or narrower than the rest. Whole in both, every column lands where it was drawn. The cost is up to a
8
+ * few CSS pixels at the layer's right end (at 125%, a multiple of 4).
9
+ *
10
+ * Where no such width lies within {@link SEARCH_CSS_PX} (a ratio like 2/3), it falls back to the whole device
11
+ * pixels that fit.
12
+ *
13
+ * @param {number} width_px the room there is, CSS pixels
14
+ * @param {number} ratio device pixels per CSS pixel
15
+ * @returns {number} the layer's width in device pixels; divided by `ratio`, its width in CSS pixels
16
+ */
17
+ export function segment_mask_width(width_px: number, ratio: number): number;
18
+ //# sourceMappingURL=segment_mask_width.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment_mask_width.d.ts","sourceRoot":"","sources":["../../../../../../src/view/elements/progress/segmented/segment_mask_width.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;GAeG;AACH,6CAJW,MAAM,SACN,MAAM,GACJ,MAAM,CAmBlB"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * How far a scan gives up looking for a whole width that is also whole in device pixels, in CSS pixels
3
+ * @type {number}
4
+ */
5
+ const SEARCH_CSS_PX = 12;
6
+
7
+ /**
8
+ * Tolerance for "a whole number of device pixels"
9
+ * @type {number}
10
+ */
11
+ const WHOLE_TOLERANCE = 1e-6;
12
+
13
+ /**
14
+ * The width to give a layer whose content is drawn in whole device pixels and stretched over it by a mask: the
15
+ * widest whole number of CSS pixels, no wider than `width_px`, that is also a whole number of device pixels.
16
+ *
17
+ * Measured in Chrome (90% to 300%): a masked layer whose width is not whole in both units is resampled when it is
18
+ * painted, and somewhere along it one device column is doubled or dropped, so one gap of a row of equal gaps paints
19
+ * a pixel wider or narrower than the rest. Whole in both, every column lands where it was drawn. The cost is up to a
20
+ * few CSS pixels at the layer's right end (at 125%, a multiple of 4).
21
+ *
22
+ * Where no such width lies within {@link SEARCH_CSS_PX} (a ratio like 2/3), it falls back to the whole device
23
+ * pixels that fit.
24
+ *
25
+ * @param {number} width_px the room there is, CSS pixels
26
+ * @param {number} ratio device pixels per CSS pixel
27
+ * @returns {number} the layer's width in device pixels; divided by `ratio`, its width in CSS pixels
28
+ */
29
+ export function segment_mask_width(width_px, ratio) {
30
+ if (!(width_px > 0) || !(ratio > 0)) {
31
+ return 0;
32
+ }
33
+
34
+ const widest = Math.floor(width_px);
35
+
36
+ for (let w = widest; w > 0 && w > widest - SEARCH_CSS_PX; w--) {
37
+ const device = w * ratio;
38
+ const whole = Math.round(device);
39
+
40
+ if (Math.abs(device - whole) <= WHOLE_TOLERANCE) {
41
+ return whole;
42
+ }
43
+ }
44
+
45
+ return Math.floor(width_px * ratio);
46
+ }
@@ -3,7 +3,7 @@
3
3
 
4
4
  Theming: every colour, notch height and the ghost go through a --segmented-bar-* custom property with a
5
5
  fallback, so a game re-skins the bar by defining the properties on the bar or any ancestor, without overriding a
6
- selector. Each notch carries its tier's class_name; the three classes below are the ones SEGMENT_TIERS_DEFAULT
6
+ selector. Each tier's layer carries its class_name; the three classes below are the ones SEGMENT_TIERS_DEFAULT
7
7
  uses, and a game's own tiers may reuse them or style their own.
8
8
 
9
9
  Import this from a style entry point, never from a logic module. Give the bar its width and height there; keep
@@ -61,14 +61,14 @@
61
61
  background: var(--segmented-bar-fill-2-color, #7a5fd0);
62
62
  }
63
63
 
64
- /* notches */
64
+ /* notches: one layer per tier, the width of the bar, cut to its notches by a mask the view draws. Style the
65
+ layer as you would one notch: its colour, its height, from the top. */
65
66
 
66
67
  .ui-segmented-resource-bar-view .notch {
67
68
  position: absolute;
68
69
  top: 0;
69
70
  height: var(--segmented-bar-tick-height, 100%);
70
71
  background: var(--segmented-bar-tick-color, rgba(0, 0, 0, 0.6));
71
- box-shadow: var(--segmented-bar-tick-highlight, none);
72
72
  }
73
73
 
74
74
  .ui-segmented-resource-bar-view .notch.segment-tier-minor {
@@ -86,7 +86,8 @@
86
86
  background: var(--segmented-bar-tick-super-color, rgba(0, 0, 0, 0.85));
87
87
  }
88
88
 
89
- /* cells */
89
+ /* cells: one strip, the empty cells colour, cut into cells by a mask the view draws; the ghost and the fill run
90
+ along it and end on a cell edge (or part way across the one filling up) */
90
91
 
91
92
  .ui-segmented-resource-bar-view.mode-cells {
92
93
  /* the gaps between cells show the bar through them */
@@ -94,7 +95,7 @@
94
95
  box-shadow: none;
95
96
  }
96
97
 
97
- .ui-segmented-resource-bar-view .cell {
98
+ .ui-segmented-resource-bar-view .cell-strip {
98
99
  position: absolute;
99
100
  top: 0;
100
101
  bottom: 0;
@@ -119,11 +120,6 @@
119
120
  background: var(--segmented-bar-cell-filled-color, #e8c25a);
120
121
  }
121
122
 
122
- /* a cell filling up one at a time, e.g. a round being loaded */
123
- .ui-segmented-resource-bar-view .cell.partial > .cell-fill {
124
- background: var(--segmented-bar-cell-partial-color, rgba(232, 194, 90, 0.6));
125
- }
126
-
127
123
  /* highlights (the view's `highlights` list) */
128
124
 
129
125
  .ui-segmented-resource-bar-view > .highlights {