@woosh/meep-engine 3.14.1 → 3.14.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 (220) hide show
  1. package/README.md +31 -24
  2. package/package.json +1 -1
  3. package/src/avif/native/DECISIONS.md +544 -536
  4. package/src/avif/native/heif/parse_avif_file.d.ts.map +1 -1
  5. package/src/avif/native/heif/parse_avif_file.js +384 -383
  6. package/src/avif/native/heif/parse_image_grid.d.ts.map +1 -1
  7. package/src/avif/native/heif/parse_image_grid.js +49 -48
  8. package/src/basis/BasisBitReader.d.ts +77 -0
  9. package/src/basis/BasisBitReader.d.ts.map +1 -0
  10. package/src/basis/BasisBitReader.js +231 -0
  11. package/src/basis/BasisHuffmanTable.d.ts +53 -0
  12. package/src/basis/BasisHuffmanTable.d.ts.map +1 -0
  13. package/src/basis/BasisHuffmanTable.js +263 -0
  14. package/src/basis/basis_read_huffman_table.d.ts +20 -0
  15. package/src/basis/basis_read_huffman_table.d.ts.map +1 -0
  16. package/src/basis/basis_read_huffman_table.js +187 -0
  17. package/src/basis/etc1s/Etc1sSelectorHistory.d.ts +50 -0
  18. package/src/basis/etc1s/Etc1sSelectorHistory.d.ts.map +1 -0
  19. package/src/basis/etc1s/Etc1sSelectorHistory.js +89 -0
  20. package/src/basis/etc1s/etc1s_block_colors.d.ts +14 -0
  21. package/src/basis/etc1s/etc1s_block_colors.d.ts.map +1 -0
  22. package/src/basis/etc1s/etc1s_block_colors.js +75 -0
  23. package/src/basis/etc1s/etc1s_decode_slice.d.ts +57 -0
  24. package/src/basis/etc1s/etc1s_decode_slice.d.ts.map +1 -0
  25. package/src/basis/etc1s/etc1s_decode_slice.js +258 -0
  26. package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts +48 -0
  27. package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts.map +1 -0
  28. package/src/basis/etc1s/etc1s_read_endpoint_codebook.js +111 -0
  29. package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts +42 -0
  30. package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts.map +1 -0
  31. package/src/basis/etc1s/etc1s_read_selector_codebook.js +127 -0
  32. package/src/basis/etc1s/etc1s_read_slice_tables.d.ts +54 -0
  33. package/src/basis/etc1s/etc1s_read_slice_tables.d.ts.map +1 -0
  34. package/src/basis/etc1s/etc1s_read_slice_tables.js +47 -0
  35. package/src/basis/transcode/build_range_plan.js +54 -0
  36. package/src/basis/transcode/etc1s_to_bc1.d.ts +24 -0
  37. package/src/basis/transcode/etc1s_to_bc1.d.ts.map +1 -0
  38. package/src/basis/transcode/etc1s_to_bc1.js +205 -0
  39. package/src/basis/transcode/etc1s_to_bc7.d.ts +30 -0
  40. package/src/basis/transcode/etc1s_to_bc7.d.ts.map +1 -0
  41. package/src/basis/transcode/etc1s_to_bc7.js +496 -0
  42. package/src/basis/transcode/fit_endpoints.d.ts +59 -0
  43. package/src/basis/transcode/fit_endpoints.d.ts.map +1 -0
  44. package/src/basis/transcode/fit_endpoints.js +226 -0
  45. package/src/{avif/native/isobmff → core/binary}/ByteCursor.d.ts +19 -6
  46. package/src/core/binary/ByteCursor.d.ts.map +1 -0
  47. package/src/{avif/native/isobmff → core/binary}/ByteCursor.js +41 -14
  48. package/src/engine/EngineHarness.js +1 -1
  49. package/src/engine/asset/codec/Codec.d.ts.map +1 -0
  50. package/src/engine/asset/codec/CodecWithFallback.d.ts.map +1 -0
  51. package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.js +2 -2
  52. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +4 -4
  53. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
  54. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
  55. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
  56. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts +1 -1
  57. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts.map +1 -1
  58. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.js +1 -1
  59. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts +1 -1
  60. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts.map +1 -1
  61. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
  62. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
  63. package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -0
  64. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  65. package/src/engine/physics/broadphase/generate_pairs.js +7 -1
  66. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  67. package/src/ktx2/KTX2_IDENTIFIER.d.ts +14 -0
  68. package/src/ktx2/KTX2_IDENTIFIER.d.ts.map +1 -0
  69. package/src/ktx2/KTX2_IDENTIFIER.js +15 -0
  70. package/src/ktx2/KhrDfModel.d.ts +35 -0
  71. package/src/ktx2/KhrDfModel.d.ts.map +1 -0
  72. package/src/ktx2/KhrDfModel.js +49 -0
  73. package/src/ktx2/SupercompressionScheme.d.ts +16 -0
  74. package/src/ktx2/SupercompressionScheme.d.ts.map +1 -0
  75. package/src/ktx2/SupercompressionScheme.js +23 -0
  76. package/src/ktx2/ktx2_read.d.ts +71 -0
  77. package/src/ktx2/ktx2_read.d.ts.map +1 -0
  78. package/src/ktx2/ktx2_read.js +581 -0
  79. package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts +27 -0
  80. package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts.map +1 -0
  81. package/src/ktx2/ktx2_read_basis_lz_global_data.js +189 -0
  82. package/src/ktx2/vk_format_to_texture_format.d.ts +55 -0
  83. package/src/ktx2/vk_format_to_texture_format.d.ts.map +1 -0
  84. package/src/ktx2/vk_format_to_texture_format.js +290 -0
  85. package/src/shade/descriptor/GPUTextureUsage.d.ts +23 -0
  86. package/src/shade/descriptor/GPUTextureUsage.d.ts.map +1 -0
  87. package/src/shade/descriptor/GPUTextureUsage.js +24 -0
  88. package/src/shade/descriptor/WebGPUExtensionType.d.ts +3 -0
  89. package/src/shade/descriptor/WebGPUExtensionType.js +26 -0
  90. package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -6
  91. package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
  92. package/src/shade/descriptor/texture/TextureDescriptor.js +24 -40
  93. package/src/shade/descriptor/texture/format/TextureFormat.d.ts +125 -0
  94. package/src/shade/descriptor/texture/format/TextureFormat.d.ts.map +1 -0
  95. package/src/shade/descriptor/texture/format/TextureFormat.js +146 -0
  96. package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts +60 -0
  97. package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts.map +1 -1
  98. package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +102 -0
  99. package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
  100. package/src/shade/device/graph/TextureResourceDescriptor.js +160 -155
  101. package/src/shade/device/mock/SoftwareGPUQueue.d.ts +11 -4
  102. package/src/shade/device/mock/SoftwareGPUQueue.d.ts.map +1 -1
  103. package/src/shade/device/mock/SoftwareGPUQueue.js +31 -37
  104. package/src/shade/device/mock/SoftwareGPUTexture.d.ts.map +1 -1
  105. package/src/shade/device/mock/SoftwareGPUTexture.js +8 -4
  106. package/src/shade/device/timing/profile/frame_graph_extract_topology.d.ts.map +1 -1
  107. package/src/shade/device/timing/profile/frame_graph_extract_topology.js +164 -174
  108. package/src/shade/playground/ground_seam/README.md +235 -0
  109. package/src/shade/playground/ground_seam/capture_scene_color.d.ts +45 -0
  110. package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -0
  111. package/src/shade/playground/ground_seam/capture_scene_color.js +242 -0
  112. package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts +11 -0
  113. package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts.map +1 -0
  114. package/src/shade/playground/ground_seam/depth_step_across_seam.js +185 -0
  115. package/src/shade/playground/ground_seam/index.html +195 -0
  116. package/src/shade/playground/ground_seam/main.d.ts +2 -0
  117. package/src/shade/playground/ground_seam/main.d.ts.map +1 -0
  118. package/src/shade/playground/ground_seam/main.js +879 -0
  119. package/src/shade/playground/ground_seam/make_grid_texture.d.ts +29 -0
  120. package/src/shade/playground/ground_seam/make_grid_texture.d.ts.map +1 -0
  121. package/src/shade/playground/ground_seam/make_grid_texture.js +105 -0
  122. package/src/shade/playground/ground_seam/make_ground.d.ts +70 -0
  123. package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -0
  124. package/src/shade/playground/ground_seam/make_ground.js +161 -0
  125. package/src/shade/playground/ground_seam/measure_flicker.d.ts +71 -0
  126. package/src/shade/playground/ground_seam/measure_flicker.d.ts.map +1 -0
  127. package/src/shade/playground/ground_seam/measure_flicker.js +531 -0
  128. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  129. package/src/shade/renderer/Renderer.js +2519 -2511
  130. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  131. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +275 -274
  132. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  133. package/src/shade/renderer/light/GPULightCollection.js +323 -314
  134. package/src/shade/renderer/lightmap/GPULightMap.js +336 -336
  135. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  136. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +12 -2
  137. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  138. package/src/shade/renderer/material/standard/fragment_gbuffer.js +3 -1
  139. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  140. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  141. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -1
  142. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  143. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  144. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.js +3 -1
  145. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  146. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.js +3 -1
  147. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts +28 -0
  148. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts.map +1 -0
  149. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.js +39 -0
  150. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts +45 -0
  151. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts.map +1 -1
  152. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.js +94 -61
  153. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts +24 -0
  154. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts.map +1 -0
  155. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.js +43 -0
  156. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +1462 -0
  157. package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
  158. package/src/shade/renderer/texture/TextureManager.js +20 -8
  159. package/src/shade/renderer/texture/TextureRole.d.ts +19 -0
  160. package/src/shade/renderer/texture/TextureRole.d.ts.map +1 -0
  161. package/src/shade/renderer/texture/TextureRole.js +26 -0
  162. package/src/shade/renderer/texture/TextureVariantSet.d.ts +71 -0
  163. package/src/shade/renderer/texture/TextureVariantSet.d.ts.map +1 -0
  164. package/src/shade/renderer/texture/TextureVariantSet.js +105 -0
  165. package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
  166. package/src/shade/renderer/texture/download_texture_data.js +22 -0
  167. package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts +15 -0
  168. package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts.map +1 -0
  169. package/src/shade/renderer/texture/format/gpu_texture_compression_support.js +50 -0
  170. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts +27 -0
  171. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts.map +1 -0
  172. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.js +65 -0
  173. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts +11 -0
  174. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -0
  175. package/src/shade/renderer/texture/format/infer_format_from_parameters.js +88 -0
  176. package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts +24 -0
  177. package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts.map +1 -0
  178. package/src/shade/renderer/texture/format/texture_format_from_shade_image.js +71 -0
  179. package/src/shade/renderer/texture/format/texture_format_preference.d.ts +22 -0
  180. package/src/shade/renderer/texture/format/texture_format_preference.d.ts.map +1 -0
  181. package/src/shade/renderer/texture/format/texture_format_preference.js +89 -0
  182. package/src/shade/renderer/texture/format/texture_variant_select.d.ts +24 -0
  183. package/src/shade/renderer/texture/format/texture_variant_select.d.ts.map +1 -0
  184. package/src/shade/renderer/texture/format/texture_variant_select.js +38 -0
  185. package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts +9 -1
  186. package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts.map +1 -1
  187. package/src/shade/renderer/texture/shade_texture_might_have_alpha.js +73 -8
  188. package/src/shade/renderer/texture/source/AlphaMode.d.ts +27 -0
  189. package/src/shade/renderer/texture/source/AlphaMode.d.ts.map +1 -0
  190. package/src/shade/renderer/texture/source/AlphaMode.js +52 -0
  191. package/src/shade/renderer/texture/source/ShadeImage.d.ts +33 -0
  192. package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
  193. package/src/shade/renderer/texture/source/ShadeImage.js +74 -0
  194. package/src/shade/renderer/texture/source/ShadeTexelData.d.ts +78 -0
  195. package/src/shade/renderer/texture/source/ShadeTexelData.d.ts.map +1 -0
  196. package/src/shade/renderer/texture/source/ShadeTexelData.js +158 -0
  197. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts +0 -10
  198. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts.map +1 -1
  199. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.js +73 -175
  200. package/src/shade/renderer/texture/texture_write_level.d.ts +32 -0
  201. package/src/shade/renderer/texture/texture_write_level.d.ts.map +1 -0
  202. package/src/shade/renderer/texture/texture_write_level.js +77 -0
  203. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts +8 -1
  204. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
  205. package/src/shade/renderer/texture/texture_write_to_gpu.js +62 -37
  206. package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts +8 -0
  207. package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts.map +1 -1
  208. package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +8 -0
  209. package/src/shade/util/texture_mip_extent.d.ts +49 -0
  210. package/src/shade/util/texture_mip_extent.d.ts.map +1 -0
  211. package/src/shade/util/texture_mip_extent.js +87 -0
  212. package/src/avif/native/isobmff/ByteCursor.d.ts.map +0 -1
  213. package/src/engine/asset/loaders/image/codec/Codec.d.ts.map +0 -1
  214. package/src/engine/asset/loaders/image/codec/CodecWithFallback.d.ts.map +0 -1
  215. package/src/shade/util/compute_max_mip_count.d.ts +0 -8
  216. package/src/shade/util/compute_max_mip_count.d.ts.map +0 -1
  217. package/src/shade/util/compute_max_mip_count.js +0 -27
  218. /package/src/engine/asset/{loaders/image/codec → codec}/Codec.d.ts +0 -0
  219. /package/src/engine/asset/{loaders/image/codec → codec}/Codec.js +0 -0
  220. /package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.d.ts +0 -0
@@ -0,0 +1,226 @@
1
+ /**
2
+ * How many refine-and-reassign rounds to run. The fit converges in two or three for almost every
3
+ * codebook entry, and the loop leaves early when nothing moves, so this is a ceiling rather than a
4
+ * cost.
5
+ *
6
+ * @readonly
7
+ * @type {number}
8
+ */
9
+ const MAX_ITERATIONS = 8;
10
+
11
+ /**
12
+ * Every `[min, max]` span of selector values a block can use, as pairs.
13
+ *
14
+ * Ten of them, because a span is an ordered pair drawn from four values. A block that only uses the
15
+ * darkest two colours is fitted against those two alone, which is the whole reason this exists — see
16
+ * {@link fit_endpoints}.
17
+ *
18
+ * @readonly
19
+ * @type {number[][]}
20
+ */
21
+ export const SELECTOR_RANGES = [
22
+ [0, 0], [0, 1], [0, 2], [0, 3],
23
+ [1, 1], [1, 2], [1, 3],
24
+ [2, 2], [2, 3],
25
+ [3, 3],
26
+ ];
27
+
28
+ /**
29
+ * Which entry of {@link SELECTOR_RANGES} a `[min, max]` span is.
30
+ *
31
+ * @param {number} min
32
+ * @param {number} max
33
+ * @returns {number}
34
+ */
35
+ export function selector_range_index(min, max) {
36
+ for (let i = 0; i < SELECTOR_RANGES.length; i++) {
37
+ if (SELECTOR_RANGES[i][0] === min && SELECTOR_RANGES[i][1] === max) {
38
+ return i;
39
+ }
40
+ }
41
+
42
+ throw new Error(`Basis: ${min}..${max} is not a selector range`);
43
+ }
44
+
45
+ /**
46
+ * Fit a pair of endpoints to the colours a block actually uses, by least squares.
47
+ *
48
+ * **Why the obvious choice is not good enough.** An ETC1S block's four colours are its base colour
49
+ * plus a modifier applied equally to every channel, so before clamping they lie on a line and the
50
+ * darkest and brightest of them span it exactly. Clamping breaks that. A base colour near white with
51
+ * a large modifier gives, say, red `{67, 203, 255, 255}` beside green `{0, 0, 57, 193}` — still
52
+ * ordered, but no longer collinear, because red saturated and green did not. Taking the outer two as
53
+ * endpoints then leaves the middle two nowhere near the line between them, and no interpolation
54
+ * weight can recover them.
55
+ *
56
+ * So the endpoints are fitted rather than read off: each colour is assigned the weight that suits it
57
+ * best, the endpoints are re-solved to minimise squared error against all of them at once, and the
58
+ * two steps alternate.
59
+ *
60
+ * **And the fit is over `[min_selector, max_selector]` only.** Which colours a block uses is a
61
+ * property of its *selector* codebook entry, and most entries do not use all four — a block spanning
62
+ * only the darkest two is a line those two define exactly, and fitting it against colours it never
63
+ * samples throws that away for nothing. Conditioning on the span is what closes most of the distance
64
+ * to the reference transcoder on saturated content.
65
+ *
66
+ * @param {Uint8Array} low three channels, seeded with a guess and overwritten with the fit
67
+ * @param {Uint8Array} high three channels, likewise
68
+ * @param {Uint8Array} colors twelve bytes, the block's four `[r, g, b]` colours
69
+ * @param {Int32Array} weights the destination format's interpolation weights, out of 64
70
+ * @param {number} min_selector lowest selector value any block using this pairing has
71
+ * @param {number} max_selector highest
72
+ *
73
+ * @author Alex Goldring
74
+ * @copyright Company Named Limited (c) 2026
75
+ */
76
+ export function fit_endpoints(low, high, colors, weights, min_selector, max_selector) {
77
+ if (min_selector === max_selector) {
78
+ /*
79
+ One colour, and both endpoints are it — every weight then interpolates to the same value, so
80
+ there is nothing to solve and the normal equations below would be singular anyway.
81
+ */
82
+ for (let c = 0; c < 3; c++) {
83
+ low[c] = colors[min_selector * 3 + c];
84
+ high[c] = colors[min_selector * 3 + c];
85
+ }
86
+
87
+ return;
88
+ }
89
+
90
+ const assigned = new Int32Array(4);
91
+
92
+ for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
93
+ for (let selector = min_selector; selector <= max_selector; selector++) {
94
+ assigned[selector] = nearest_weight(low, high, weights, colors, selector * 3);
95
+ }
96
+
97
+ let sum_aa = 0;
98
+ let sum_ab = 0;
99
+ let sum_bb = 0;
100
+
101
+ for (let selector = min_selector; selector <= max_selector; selector++) {
102
+ const b = weights[assigned[selector]] / 64;
103
+ const a = 1 - b;
104
+
105
+ sum_aa += a * a;
106
+ sum_ab += a * b;
107
+ sum_bb += b * b;
108
+ }
109
+
110
+ const determinant = sum_aa * sum_bb - sum_ab * sum_ab;
111
+
112
+ // singular when every colour in the span was assigned the same weight; the fit is done
113
+ if (Math.abs(determinant) < 1e-6) {
114
+ return;
115
+ }
116
+
117
+ let moved = false;
118
+
119
+ for (let c = 0; c < 3; c++) {
120
+ let sum_ap = 0;
121
+ let sum_bp = 0;
122
+
123
+ for (let selector = min_selector; selector <= max_selector; selector++) {
124
+ const b = weights[assigned[selector]] / 64;
125
+ const a = 1 - b;
126
+ const p = colors[selector * 3 + c];
127
+
128
+ sum_ap += a * p;
129
+ sum_bp += b * p;
130
+ }
131
+
132
+ const solved_low = (sum_bb * sum_ap - sum_ab * sum_bp) / determinant;
133
+ const solved_high = (sum_aa * sum_bp - sum_ab * sum_ap) / determinant;
134
+
135
+ const next_low = clamp_round(solved_low);
136
+ const next_high = clamp_round(solved_high);
137
+
138
+ if (next_low !== low[c] || next_high !== high[c]) {
139
+ moved = true;
140
+ }
141
+
142
+ low[c] = next_low;
143
+ high[c] = next_high;
144
+ }
145
+
146
+ if (!moved) {
147
+ return;
148
+ }
149
+ }
150
+ }
151
+
152
+ /**
153
+ * @param {number} value
154
+ * @returns {number} rounded into `[0, 255]`
155
+ */
156
+ function clamp_round(value) {
157
+ const rounded = Math.round(value);
158
+
159
+ return rounded < 0 ? 0 : rounded > 255 ? 255 : rounded;
160
+ }
161
+
162
+ /**
163
+ * Which weight puts the interpolated colour closest to a target.
164
+ *
165
+ * @param {Uint8Array} low three channels
166
+ * @param {Uint8Array} high three channels
167
+ * @param {Int32Array} weights
168
+ * @param {Uint8Array} target
169
+ * @param {number} target_offset
170
+ * @returns {number} an index into `weights`
171
+ */
172
+ function nearest_weight(low, high, weights, target, target_offset) {
173
+ let best = 0;
174
+ let best_error = Infinity;
175
+
176
+ for (let i = 0; i < weights.length; i++) {
177
+ const weight = weights[i];
178
+
179
+ let error = 0;
180
+
181
+ for (let c = 0; c < 3; c++) {
182
+ const interpolated = (low[c] * (64 - weight) + high[c] * weight + 32) >> 6;
183
+ const delta = interpolated - target[target_offset + c];
184
+
185
+ error += delta * delta;
186
+ }
187
+
188
+ if (error < best_error) {
189
+ best_error = error;
190
+ best = i;
191
+ }
192
+ }
193
+
194
+ return best;
195
+ }
196
+
197
+ /**
198
+ * The `[min, max]` selector span of every entry of a selector codebook.
199
+ *
200
+ * @param {Etc1sSelectorCodebook} selectors
201
+ * @returns {Uint8Array} one index into {@link SELECTOR_RANGES} per entry
202
+ */
203
+ export function selector_codebook_ranges(selectors) {
204
+ const out = new Uint8Array(selectors.count);
205
+
206
+ for (let entry = 0; entry < selectors.count; entry++) {
207
+ let min = 3;
208
+ let max = 0;
209
+
210
+ for (let i = 0; i < 16; i++) {
211
+ const selector = selectors.selectors[entry * 16 + i];
212
+
213
+ if (selector < min) {
214
+ min = selector;
215
+ }
216
+
217
+ if (selector > max) {
218
+ max = selector;
219
+ }
220
+ }
221
+
222
+ out[entry] = selector_range_index(min, max);
223
+ }
224
+
225
+ return out;
226
+ }
@@ -1,15 +1,20 @@
1
1
  /**
2
- * Big-endian byte cursor over an `ArrayBuffer`, bounds-checked on every read.
2
+ * Byte cursor over an `ArrayBuffer`, bounds-checked on every read.
3
3
  *
4
- * ISOBMFF parsing wants cheap random access into a buffer that already exists — box sizes point
5
- * forwards, item offsets point anywhere — and it never wants a copy. `core/binary/BinaryBuffer.js`
6
- * is a growable stream built for the opposite job; using it here would mean carrying its growth
4
+ * Container parsing wants cheap random access into a buffer that already exists — box sizes point
5
+ * forwards, level offsets point backwards — and it never wants a copy. {@link BinaryBuffer} is a
6
+ * growable stream built for the opposite job; using it here would mean carrying its growth
7
7
  * machinery through a parser that never grows anything. This is the read half; writing goes through
8
- * {@link BoxWriter}, which does use `BinaryBuffer`.
8
+ * `BinaryBuffer`, which is the right shape for it.
9
9
  *
10
10
  * Every accessor validates against {@link end} before touching memory. A truncated or hostile file
11
11
  * must throw a named error, not read whatever happens to follow in the buffer.
12
12
  *
13
+ * **Endianness is stated by the caller, once**, because it is a property of the *container* rather
14
+ * than of any one field: ISOBMFF is big-endian throughout, KTX2 is little-endian throughout, and a
15
+ * parser that had to name the order at every call site would eventually name one of them wrong.
16
+ * {@link u8}, {@link fourcc} and {@link view_bytes} are order-free and read the same either way.
17
+ *
13
18
  * @author Alex Goldring
14
19
  * @copyright Company Named Limited (c) 2026
15
20
  */
@@ -32,13 +37,20 @@ export class ByteCursor {
32
37
  * @type {number}
33
38
  */
34
39
  end: number;
40
+ /**
41
+ * Byte order of every multi-byte read. Stated at {@link init}, never guessed.
42
+ * @type {EndianType|boolean}
43
+ */
44
+ endianness: EndianType | boolean;
35
45
  /**
36
46
  * @param {ArrayBuffer|Uint8Array} source
47
+ * @param {EndianType|boolean} endianness byte order of the container being read. Required — a
48
+ * cursor that guessed would read a plausible wrong number rather than fail
37
49
  * @param {number} [byte_offset]
38
50
  * @param {number} [byte_length]
39
51
  * @returns {ByteCursor} this
40
52
  */
41
- init(source: ArrayBuffer | Uint8Array, byte_offset?: number, byte_length?: number): ByteCursor;
53
+ init(source: ArrayBuffer | Uint8Array, endianness: EndianType | boolean, byte_offset?: number, byte_length?: number): ByteCursor;
42
54
  /**
43
55
  * Create an independent cursor over a sub-range of this one, sharing the same memory.
44
56
  * @param {number} byte_offset absolute offset
@@ -122,4 +134,5 @@ export class ByteCursor {
122
134
  */
123
135
  seek(position: number): void;
124
136
  }
137
+ import { EndianType } from "./EndianType.js";
125
138
  //# sourceMappingURL=ByteCursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ByteCursor.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/ByteCursor.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IACI;;OAEG;IACH,MAFU,QAAQ,CAEN;IAEZ;;OAEG;IACH,OAFU,UAAU,CAEP;IAEb;;;OAGG;IACH,UAFU,MAAM,CAEH;IAEb;;;OAGG;IACH,KAFU,MAAM,CAER;IAER;;;OAGG;IACH,YAFU,UAAU,GAAC,OAAO,CAEM;IAElC;;;;;;;OAOG;IACH,aAPW,WAAW,GAAC,UAAU,cACtB,UAAU,GAAC,OAAO,gBAElB,MAAM,gBACN,MAAM,GACJ,UAAU,CAsBtB;IAED;;;;;OAKG;IACH,wBAJW,MAAM,eACN,MAAM,GACJ,UAAU,CAgBtB;IAED;;OAEG;IACH,wBAEC;IAED;;;OAGG;IACH,eAHW,MAAM,QACN,MAAM,QAMhB;IAED;;OAEG;IACH,MAFa,MAAM,CAMlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;OAEG;IACH,OAFa,MAAM,CAiBlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;;;;;;OAOG;IACH,OAFa,MAAM,CAiBlB;IAED;;;;;;OAMG;IACH,mBAHW,MAAM,GACJ,MAAM,CAoBlB;IAED;;;OAGG;IACH,UAFa,MAAM,CAUlB;IAED;;;;OAIG;IACH,eAFa,MAAM,CAgBlB;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,UAAU,CAUtB;IAED;;OAEG;IACH,YAFW,MAAM,QAMhB;IAED;;OAEG;IACH,eAFW,MAAM,QAQhB;CACJ;2BAnU0B,iBAAiB"}
@@ -1,17 +1,24 @@
1
- import { utf8_decode } from "../../../core/binary/utf8/utf8_decode.js";
1
+ import { assert } from "../assert.js";
2
+ import { EndianType } from "./EndianType.js";
3
+ import { utf8_decode } from "./utf8/utf8_decode.js";
2
4
 
3
5
  /**
4
- * Big-endian byte cursor over an `ArrayBuffer`, bounds-checked on every read.
6
+ * Byte cursor over an `ArrayBuffer`, bounds-checked on every read.
5
7
  *
6
- * ISOBMFF parsing wants cheap random access into a buffer that already exists — box sizes point
7
- * forwards, item offsets point anywhere — and it never wants a copy. `core/binary/BinaryBuffer.js`
8
- * is a growable stream built for the opposite job; using it here would mean carrying its growth
8
+ * Container parsing wants cheap random access into a buffer that already exists — box sizes point
9
+ * forwards, level offsets point backwards — and it never wants a copy. {@link BinaryBuffer} is a
10
+ * growable stream built for the opposite job; using it here would mean carrying its growth
9
11
  * machinery through a parser that never grows anything. This is the read half; writing goes through
10
- * {@link BoxWriter}, which does use `BinaryBuffer`.
12
+ * `BinaryBuffer`, which is the right shape for it.
11
13
  *
12
14
  * Every accessor validates against {@link end} before touching memory. A truncated or hostile file
13
15
  * must throw a named error, not read whatever happens to follow in the buffer.
14
16
  *
17
+ * **Endianness is stated by the caller, once**, because it is a property of the *container* rather
18
+ * than of any one field: ISOBMFF is big-endian throughout, KTX2 is little-endian throughout, and a
19
+ * parser that had to name the order at every call site would eventually name one of them wrong.
20
+ * {@link u8}, {@link fourcc} and {@link view_bytes} are order-free and read the same either way.
21
+ *
15
22
  * @author Alex Goldring
16
23
  * @copyright Company Named Limited (c) 2026
17
24
  */
@@ -38,13 +45,23 @@ export class ByteCursor {
38
45
  */
39
46
  end = 0;
40
47
 
48
+ /**
49
+ * Byte order of every multi-byte read. Stated at {@link init}, never guessed.
50
+ * @type {EndianType|boolean}
51
+ */
52
+ endianness = EndianType.BigEndian;
53
+
41
54
  /**
42
55
  * @param {ArrayBuffer|Uint8Array} source
56
+ * @param {EndianType|boolean} endianness byte order of the container being read. Required — a
57
+ * cursor that guessed would read a plausible wrong number rather than fail
43
58
  * @param {number} [byte_offset]
44
59
  * @param {number} [byte_length]
45
60
  * @returns {ByteCursor} this
46
61
  */
47
- init(source, byte_offset = 0, byte_length = -1) {
62
+ init(source, endianness, byte_offset = 0, byte_length = -1) {
63
+ assert.isBoolean(endianness, 'endianness');
64
+
48
65
  const buffer = source instanceof Uint8Array ? source.buffer : source;
49
66
  const base = source instanceof Uint8Array ? source.byteOffset : 0;
50
67
  const available = source instanceof Uint8Array ? source.byteLength : source.byteLength;
@@ -59,6 +76,7 @@ export class ByteCursor {
59
76
  this.bytes = new Uint8Array(buffer, base, available);
60
77
  this.position = byte_offset;
61
78
  this.end = byte_offset + length;
79
+ this.endianness = endianness;
62
80
 
63
81
  return this;
64
82
  }
@@ -80,6 +98,7 @@ export class ByteCursor {
80
98
  cursor.bytes = this.bytes;
81
99
  cursor.position = byte_offset;
82
100
  cursor.end = byte_offset + byte_length;
101
+ cursor.endianness = this.endianness;
83
102
 
84
103
  return cursor;
85
104
  }
@@ -116,7 +135,7 @@ export class ByteCursor {
116
135
  u16() {
117
136
  this.require(2, "uint16");
118
137
 
119
- const value = this.view.getUint16(this.position, false);
138
+ const value = this.view.getUint16(this.position, this.endianness);
120
139
 
121
140
  this.position += 2;
122
141
 
@@ -130,7 +149,13 @@ export class ByteCursor {
130
149
  this.require(3, "uint24");
131
150
 
132
151
  const p = this.position;
133
- const value = (this.bytes[p] << 16) | (this.bytes[p + 1] << 8) | this.bytes[p + 2];
152
+ const b0 = this.bytes[p];
153
+ const b1 = this.bytes[p + 1];
154
+ const b2 = this.bytes[p + 2];
155
+
156
+ const value = this.endianness === EndianType.LittleEndian
157
+ ? (b2 << 16) | (b1 << 8) | b0
158
+ : (b0 << 16) | (b1 << 8) | b2;
134
159
 
135
160
  this.position += 3;
136
161
 
@@ -143,7 +168,7 @@ export class ByteCursor {
143
168
  u32() {
144
169
  this.require(4, "uint32");
145
170
 
146
- const value = this.view.getUint32(this.position, false);
171
+ const value = this.view.getUint32(this.position, this.endianness);
147
172
 
148
173
  this.position += 4;
149
174
 
@@ -156,7 +181,7 @@ export class ByteCursor {
156
181
  i16() {
157
182
  this.require(2, "int16");
158
183
 
159
- const value = this.view.getInt16(this.position, false);
184
+ const value = this.view.getInt16(this.position, this.endianness);
160
185
 
161
186
  this.position += 2;
162
187
 
@@ -169,7 +194,7 @@ export class ByteCursor {
169
194
  i32() {
170
195
  this.require(4, "int32");
171
196
 
172
- const value = this.view.getInt32(this.position, false);
197
+ const value = this.view.getInt32(this.position, this.endianness);
173
198
 
174
199
  this.position += 4;
175
200
 
@@ -187,8 +212,10 @@ export class ByteCursor {
187
212
  u64() {
188
213
  this.require(8, "uint64");
189
214
 
190
- const high = this.view.getUint32(this.position, false);
191
- const low = this.view.getUint32(this.position + 4, false);
215
+ const little = this.endianness === EndianType.LittleEndian;
216
+
217
+ const high = this.view.getUint32(this.position + (little ? 4 : 0), little);
218
+ const low = this.view.getUint32(this.position + (little ? 0 : 4), little);
192
219
 
193
220
  this.position += 8;
194
221
 
@@ -234,7 +234,7 @@ export class EngineHarness {
234
234
  yaw = 0,
235
235
  autoClip = true,
236
236
  distanceMin = 0.01,
237
- distanceMax = 1000,
237
+ distanceMax = 300,
238
238
  fieldOfView = 45
239
239
  }
240
240
  ) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Codec.d.ts","sourceRoot":"","sources":["../../../../../src/engine/asset/codec/Codec.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;IACI;;;;OAIG;IACH,aAHW,UAAU,GACR,QAAQ,CAAC,CAAC,CAKtB;IAED;;;;OAIG;IACH,WAHW,UAAU,GACT,QAAQ,OAAO,CAAC,CAI3B;CACJ"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodecWithFallback.d.ts","sourceRoot":"","sources":["../../../../../src/engine/asset/codec/CodecWithFallback.js"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH;IAOI;;;OAGG;IACH,uBAFW,MAAM,CAAC,CAAC,EAclB;IAtBD;;;OAGG;IACH,UAFU,MAAM,CAAC,CAAC,EAAE,CAEP;IAgCb,kCAeC;IAED,8BAuCC;;CACJ;sBAtGqB,YAAY"}
@@ -1,5 +1,5 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { array_push_if_unique } from "../../../../../core/collection/array/array_push_if_unique.js";
1
+ import { assert } from "../../../core/assert.js";
2
+ import { array_push_if_unique } from "../../../core/collection/array/array_push_if_unique.js";
3
3
  import { Codec } from "./Codec.js";
4
4
 
5
5
  /**
@@ -28,7 +28,7 @@ drifts.
28
28
  reimplement, badly and privately, things AVIF already has generalised — channel expansion to RGBA,
29
29
  YCbCr conversion, chroma upsampling, chunk walking, bounds checking. The single most valuable move
30
30
  in this document is not a merge: it is **registering AVIF and JPEG behind the `Codec` interface that
31
- already exists** ([Codec.js](codec/Codec.js)) so that all three formats reach the engine through one
31
+ already exists** ([Codec.js](../../codec/Codec.js)) so that all three formats reach the engine through one
32
32
  door with one result shape. Today PNG goes through a worker, JPEG goes nowhere at all, and AVIF
33
33
  bypasses the asset-loader system entirely via `avif_to_sampler2d`.
34
34
 
@@ -106,7 +106,7 @@ browser canvas path — which is why the native JPEG decoder has never needed to
106
106
  [JpegImage.js:139](jpeg/JpegImage.js#L139), and `ftyp`/`meta` presence at
107
107
  [parse_avif_file.js:51](../../../../avif/native/heif/parse_avif_file.js#L51). Give each format a
108
108
  `*_HEADER_BYTES` (or a `test` predicate) beside its decoder and have the codec use it.
109
- 3. `CodecWithFallback` ([CodecWithFallback.js:11](codec/CodecWithFallback.js#L11)) already does
109
+ 3. `CodecWithFallback` ([CodecWithFallback.js:11](../../codec/CodecWithFallback.js#L11)) already does
110
110
  ordered try-with-sniff correctly. Compose `[Threaded(PNG), Jpeg, Avif, Native]` and the format
111
111
  switch disappears from `ImageRGBADataLoader` and from `ImageDecoderWorker`.
112
112
  4. `avif_to_sampler2d` stays — it is the HDR-aware adapter and the exact inverse of
@@ -273,7 +273,7 @@ struct, visitor returns `false`, walker guarantees forward progress — so that
273
273
 
274
274
  ### C6 — Bounds checking exists on one side of the fence only
275
275
 
276
- `ByteCursor.require(count, what)` ([ByteCursor.js:96](../../../../avif/native/isobmff/ByteCursor.js#L96))
276
+ `ByteCursor.require(count, what)` ([ByteCursor.js:96](../../../../core/binary/ByteCursor.js#L96))
277
277
  validates every read and names the field in the error. `BitReader` does the same for every
278
278
  descriptor. There is a `robustness.spec.js` that feeds the decoder truncated and hostile files.
279
279
 
@@ -327,7 +327,7 @@ records choices like this in `DECISIONS.md`. Give the PNG folder the same treatm
327
327
 
328
328
  ### C8 — NUL-terminated UTF-8, encoded and decoded privately in two places
329
329
 
330
- [ByteCursor.js:307](../../../../avif/native/isobmff/ByteCursor.js#L307) has a private `utf8_decode`
330
+ [ByteCursor.js:307](../../../../core/binary/ByteCursor.js#L307) has a private `utf8_decode`
331
331
  with the stated reason that `TextDecoder` is not universally available.
332
332
  [BoxWriter.js:205](../../../../avif/native/isobmff/BoxWriter.js#L205) has the matching encoder inline
333
333
  in `utf8_string`. `BinaryBuffer` has `readUTF8String` / `writeUTF8String` but they are
@@ -35,5 +35,5 @@ export class ImageRGBADataLoader extends AssetLoader<any, any> {
35
35
  load(scope: any, path: any, success: any, failure: any, progress: any): Promise<void>;
36
36
  }
37
37
  import { AssetLoader } from "../AssetLoader.js";
38
- import { CodecWithFallback } from "./codec/CodecWithFallback.js";
38
+ import { CodecWithFallback } from "../../codec/CodecWithFallback.js";
39
39
  //# sourceMappingURL=ImageRGBADataLoader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageRGBADataLoader.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/asset/loaders/image/ImageRGBADataLoader.js"],"names":[],"mappings":"AASA;IACI;;;OAGG;IACH,8BAFW,MAAM,EAehB;IARG;;;OAGG;IACH,SAFU,kBAAkB;QAAC,IAAI,CAAC;QAAC,KAAK,EAAC,MAAM,CAAC;QAAC,MAAM,EAAC,MAAM,CAAC;QAAC,QAAQ,EAAC,MAAM,CAAC;QAAC,QAAQ,EAAC,MAAM,CAAA;KAAC,CAAC,CAKjG;IAGL,oDAOC;IAED;;;;;;OAMG;IACH,4BASC;IAED;;;;;;OAMG;IACH,mBAyBC;IAED,sFAEC;CACJ;4BA5F2B,mBAAmB;kCACb,8BAA8B"}
1
+ {"version":3,"file":"ImageRGBADataLoader.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/asset/loaders/image/ImageRGBADataLoader.js"],"names":[],"mappings":"AASA;IACI;;;OAGG;IACH,8BAFW,MAAM,EAehB;IARG;;;OAGG;IACH,SAFU,kBAAkB;QAAC,IAAI,CAAC;QAAC,KAAK,EAAC,MAAM,CAAC;QAAC,MAAM,EAAC,MAAM,CAAC;QAAC,QAAQ,EAAC,MAAM,CAAC;QAAC,QAAQ,EAAC,MAAM,CAAA;KAAC,CAAC,CAKjG;IAGL,oDAOC;IAED;;;;;;OAMG;IACH,4BASC;IAED;;;;;;OAMG;IACH,mBAyBC;IAED,sFAEC;CACJ;4BA5F2B,mBAAmB;kCACb,kCAAkC"}
@@ -1,6 +1,6 @@
1
1
  import { ArrayBufferLoader } from "../ArrayBufferLoader.js";
2
2
  import { AssetLoader } from "../AssetLoader.js";
3
- import { CodecWithFallback } from "./codec/CodecWithFallback.js";
3
+ import { CodecWithFallback } from "../../codec/CodecWithFallback.js";
4
4
  import { NativeImageDecoder } from "./codec/NativeImageDecoder.js";
5
5
  import { ThreadedImageDecoder } from "./codec/ThreadedImageDecoder.js";
6
6
  import { ImageRGBADataAsset } from "./ImageRGBADataAsset.js";
@@ -30,5 +30,5 @@ export class NativeImageDecoder extends Codec<{
30
30
  bitDepth: number;
31
31
  }>;
32
32
  }
33
- import { Codec } from "./Codec.js";
33
+ import { Codec } from "../../../codec/Codec.js";
34
34
  //# sourceMappingURL=NativeImageDecoder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeImageDecoder.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/asset/loaders/image/codec/NativeImageDecoder.js"],"names":[],"mappings":"AA4DA;;;GAGG;AACH;WAF0B,MAAM;YAAS,MAAM;UAAQ,UAAU;cAAY,MAAM;cAAW,MAAM;;;IAGhG;;;;OAIG;IACH,iBAHW,UAAU,GACT;QAAC,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAgBhG;IAED;;;;;;OAiBC;CACJ;sBAxGqB,YAAY"}
1
+ {"version":3,"file":"NativeImageDecoder.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/asset/loaders/image/codec/NativeImageDecoder.js"],"names":[],"mappings":"AA4DA;;;GAGG;AACH;WAF0B,MAAM;YAAS,MAAM;UAAQ,UAAU;cAAY,MAAM;cAAW,MAAM;;;IAGhG;;;;OAIG;IACH,iBAHW,UAAU,GACT;QAAC,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAgBhG;IAED;;;;;;OAiBC;CACJ;sBAxGqB,yBAAyB"}
@@ -1,4 +1,4 @@
1
- import { Codec } from "./Codec.js";
1
+ import { Codec } from "../../../codec/Codec.js";
2
2
 
3
3
  /**
4
4
  *
@@ -12,6 +12,6 @@ export class ThreadedImageDecoder extends Codec<any> {
12
12
  test(data: any): Promise<boolean>;
13
13
  decode(data: any): Promise<any>;
14
14
  }
15
- import { Codec } from "./Codec.js";
15
+ import { Codec } from "../../../codec/Codec.js";
16
16
  import { OnDemandWorkerManager } from "../../../../../core/process/worker/OnDemandWorkerManager.js";
17
17
  //# sourceMappingURL=ThreadedImageDecoder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadedImageDecoder.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js"],"names":[],"mappings":"AAMA;IACI;;;OAGG;IACH,8BAFW,MAAM,EAwBhB;IARG;;;OAGG;IACH,QAFU,qBAAqB,CAE+B;IAMlE,kCAaC;IAED,gCAEC;CACJ;sBAjDqB,YAAY;sCAHI,6DAA6D"}
1
+ {"version":3,"file":"ThreadedImageDecoder.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js"],"names":[],"mappings":"AAMA;IACI;;;OAGG;IACH,8BAFW,MAAM,EAwBhB;IARG;;;OAGG;IACH,QAFU,qBAAqB,CAE+B;IAMlE,kCAaC;IAED,gCAEC;CACJ;sBAjDqB,yBAAyB;sCAHT,6DAA6D"}
@@ -2,7 +2,7 @@ import { assert } from "../../../../../core/assert.js";
2
2
  import { OnDemandWorkerManager } from "../../../../../core/process/worker/OnDemandWorkerManager.js";
3
3
  import WorkerBuilder from "../../../../../core/process/worker/WorkerBuilder.js";
4
4
  import { PNG_HEADER_BYTES } from "../png/PNG_HEADER_BYTES.js";
5
- import { Codec } from "./Codec.js";
5
+ import { Codec } from "../../../codec/Codec.js";
6
6
 
7
7
  export class ThreadedImageDecoder extends Codec {
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TextureAtlas.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/texture/atlas/TextureAtlas.js"],"names":[],"mappings":"AAkBA;IAcI;;;;;;OAMG;IACH,mBALW,MAAM,cACN,cAAc,kBACd,MAAM,EA6ChB;IA9DD;;;OAGG;IACH,gBAAa;IAEb;;;;OAIG;IACH,sBAAsB;IAgBlB;;;;OAIG;IACH,eAA0B;IAE1B;;;OAGG;IACH,eAFU,OAAO,CAEkB;IAInC;;;;OAIG;IACH,2BAAgH;IAEhH;;;OAGG;IACH,eAAiD;IAEjD;;QAEI;;WAEG;;MAEN;IAGL;;;OAGG;IACH,yBAEC;IAED;;;;OAIG;IACH,kBAHW,SAAS,GACP,UAAU,GAAC,SAAS,CAYhC;IAED;;;OAGG;IACH,eAFa,OAAO,CAInB;IAED;;;;OAIG;IACH,gBAHW,UAAU,GACR,OAAO,CAQnB;IAED;;OAEG;IACH,cAkBC;IAED;;;;;OAKG;IACH,UAJW,MAAM,KACN,MAAM,GACJ,OAAO,CA0CnB;IAED;;;;OAIG;IACH,mBAqBC;IAED;;;;OAIG;IACH,mBAaC;IAED;;;;;;OAMG;IACH,kBAIC;IAED;;;;;OAKG;IACH,aAJW,SAAS,YACT,MAAM,GACL,UAAU,CAgCrB;IAED;;;;;OAKG;IACH,YAJW,MAAM,KACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;OAIG;IACH,cAHW,UAAU,GACT,OAAO,CAiClB;IAED;;;OAGG;IACH,UAFa,OAAO,CAyBnB;IAED;;;;OAIG;IACH,aAqGC;IAED;;OAEG;IACH,cA6BC;IAsDD;;OAEG;IACH,cAQC;CACJ;qCAxjBoC,2BAA2B;oBAN5C,kCAAkC;mBAFnC,0CAA0C;0BAMnC,yBAAyB;2BAGxB,iBAAiB;+BAbb,gDAAgD"}
1
+ {"version":3,"file":"TextureAtlas.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/texture/atlas/TextureAtlas.js"],"names":[],"mappings":"AAkBA;IAcI;;;;;;OAMG;IACH,mBALW,MAAM,cACN,cAAc,kBACd,MAAM,EA6ChB;IA9DD;;;OAGG;IACH,gBAAa;IAEb;;;;OAIG;IACH,sBAAsB;IAgBlB;;;;OAIG;IACH,eAA0B;IAE1B;;;OAGG;IACH,eAFU,OAAO,CAEkB;IAInC;;;;OAIG;IACH,2BAAgH;IAEhH;;;OAGG;IACH,eAAiD;IAEjD;;QAEI;;WAEG;;MAEN;IAGL;;;OAGG;IACH,yBAEC;IAED;;;;OAIG;IACH,kBAHW,SAAS,GACP,UAAU,GAAC,SAAS,CAYhC;IAED;;;OAGG;IACH,eAFa,OAAO,CAInB;IAED;;;;OAIG;IACH,gBAHW,UAAU,GACR,OAAO,CAQnB;IAED;;OAEG;IACH,cAqBC;IAED;;;;;OAKG;IACH,UAJW,MAAM,KACN,MAAM,GACJ,OAAO,CA0CnB;IAED;;;;OAIG;IACH,mBAqBC;IAED;;;;OAIG;IACH,mBAaC;IAED;;;;;;OAMG;IACH,kBAIC;IAED;;;;;OAKG;IACH,aAJW,SAAS,YACT,MAAM,GACL,UAAU,CAgCrB;IAED;;;;;OAKG;IACH,YAJW,MAAM,KACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;OAIG;IACH,cAHW,UAAU,GACT,OAAO,CAiClB;IAED;;;OAGG;IACH,UAFa,OAAO,CAyBnB;IAED;;;;OAIG;IACH,aAqGC;IAED;;OAEG;IACH,cAsCC;IAsDD;;OAEG;IACH,cASC;CACJ;qCArkBoC,2BAA2B;oBAN5C,kCAAkC;mBAFnC,0CAA0C;0BAMnC,yBAAyB;2BAGxB,iBAAiB;+BAbb,gDAAgD"}
@@ -147,6 +147,9 @@ export class TextureAtlas extends AbstractTextureAtlas {
147
147
  //erase data
148
148
  this.__sampler.data.fill(0);
149
149
 
150
+ // written through `data` rather than through the sampler, so the version is moved by hand
151
+ this.__sampler.version++;
152
+
150
153
  this.__needsUpdate = true;
151
154
  }
152
155
 
@@ -511,6 +514,15 @@ export class TextureAtlas extends AbstractTextureAtlas {
511
514
  // console.timeEnd('TextureAtlas.paint');
512
515
 
513
516
  if (paintCount > 0) {
517
+ /*
518
+ The atlas's own pixels have changed, and everything that mirrors them -- a GPU texture,
519
+ a debug canvas -- decides whether to re-read by comparing this version. The bump belongs
520
+ here rather than in `paintPatch`, because that is the method subclasses override: one
521
+ that paints into `data` itself, as `DecalAtlas` does for its borders, never reaches the
522
+ copy helper that would otherwise have moved the version for it.
523
+ */
524
+ this.__sampler.version++;
525
+
514
526
  //notify that atlas was painted
515
527
  this.on.painted.send0();
516
528
  }
@@ -573,6 +585,7 @@ export class TextureAtlas extends AbstractTextureAtlas {
573
585
  */
574
586
  reset() {
575
587
  this.__sampler.data.fill(0);
588
+ this.__sampler.version++;
576
589
 
577
590
  this.patches = [];
578
591
 
@@ -1 +1 @@
1
- {"version":3,"file":"generate_pairs.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/broadphase/generate_pairs.js"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,uIATW,MAAM,MAAM;IAAC,QAAQ,WAAW;IAAC,SAAS,YAAY;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,+CAElF,MAAM,OAAO,MAAM,KAAK,OAAO,oCAyFhD"}
1
+ {"version":3,"file":"generate_pairs.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/broadphase/generate_pairs.js"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,uIATW,MAAM,MAAM;IAAC,QAAQ,WAAW;IAAC,SAAS,YAAY;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,+CAElF,MAAM,OAAO,MAAM,KAAK,OAAO,oCA+FhD"}
@@ -86,9 +86,14 @@ export function generate_pairs(
86
86
  dynamic_bvh,
87
87
  scratch_aabb
88
88
  );
89
- if (n <= candidates.length) break;
89
+
90
+ if (n <= candidates.length){
91
+ break;
92
+ }
93
+
90
94
  candidates = new Uint32Array(Math.max(n, candidates.length * 2));
91
95
  }
96
+
92
97
  for (let c = 0; c < n; c++) {
93
98
  const other = candidates[c];
94
99
  if (other === my_packed) continue;
@@ -115,6 +120,7 @@ export function generate_pairs(
115
120
  if (n <= candidates.length) break;
116
121
  candidates = new Uint32Array(Math.max(n, candidates.length * 2));
117
122
  }
123
+
118
124
  for (let c = 0; c < n; c++) {
119
125
  const other = candidates[c];
120
126
 
@@ -64,11 +64,11 @@ export class FluidObstacleSystem extends System<any> {
64
64
  /**
65
65
  * @param {FluidComponent} fluid
66
66
  */
67
- static "__#364@#refresh_masks"(fluid: FluidComponent): void;
67
+ static "__#368@#refresh_masks"(fluid: FluidComponent): void;
68
68
  /**
69
69
  * @param {FluidComponent} fluid
70
70
  */
71
- static "__#364@#clear_field"(fluid: FluidComponent): void;
71
+ static "__#368@#clear_field"(fluid: FluidComponent): void;
72
72
  /**
73
73
  * Mark every cell of `fluid` whose centre lies within `inflation` of the
74
74
  * posed shape as solid. Iteration is clipped to the shape's world AABB
@@ -80,7 +80,7 @@ export class FluidObstacleSystem extends System<any> {
80
80
  * @param {number} inflation world-units SDF threshold
81
81
  * @param {Float64Array} point length-3 scratch
82
82
  */
83
- static "__#364@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
83
+ static "__#368@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
84
84
  /**
85
85
  * Write the obstacle's translation velocity onto every face of every cell
86
86
  * it voxelized — the moving-wall boundary condition. Runs AFTER the mask
@@ -100,7 +100,7 @@ export class FluidObstacleSystem extends System<any> {
100
100
  * @param {number} wvy
101
101
  * @param {number} wvz
102
102
  */
103
- static "__#364@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
103
+ static "__#368@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
104
104
  constructor();
105
105
  dependencies: (typeof FluidObstacle)[];
106
106
  components_used: (ResourceAccessSpecification<typeof Transform> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof FluidComponent> | ResourceAccessSpecification<typeof FluidObstacle>)[];