@woosh/meep-engine 2.168.0 → 2.169.0

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 (295) hide show
  1. package/README.md +2 -2
  2. package/build/bundle-worker-image-decoder.js +1 -1
  3. package/package.json +1 -1
  4. package/src/REVIEW_2026_08_06/adv-core.md +511 -0
  5. package/src/REVIEW_2026_08_06/adv-gfx.md +480 -0
  6. package/src/REVIEW_2026_08_06/adv-view.md +446 -0
  7. package/src/REVIEW_2026_08_06/api-core.md +296 -0
  8. package/src/REVIEW_2026_08_06/api-engine.md +195 -0
  9. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +507 -0
  10. package/src/REVIEW_2026_08_06/core-binary.md +348 -0
  11. package/src/REVIEW_2026_08_06/core-collection.md +376 -0
  12. package/src/REVIEW_2026_08_06/core-math.md +221 -0
  13. package/src/REVIEW_2026_08_06/core-process.md +266 -0
  14. package/src/REVIEW_2026_08_06/core-science.md +223 -0
  15. package/src/REVIEW_2026_08_06/engine-ai-nav.md +279 -0
  16. package/src/REVIEW_2026_08_06/engine-animation.md +167 -0
  17. package/src/REVIEW_2026_08_06/engine-asset.md +166 -0
  18. package/src/REVIEW_2026_08_06/engine-ecs.md +920 -0
  19. package/src/REVIEW_2026_08_06/engine-input.md +197 -0
  20. package/src/REVIEW_2026_08_06/engine-misc.md +248 -0
  21. package/src/REVIEW_2026_08_06/engine-terrain.md +52 -0
  22. package/src/REVIEW_2026_08_06/generation.md +176 -0
  23. package/src/REVIEW_2026_08_06/geom-2d.md +434 -0
  24. package/src/REVIEW_2026_08_06/geom-3d.md +117 -0
  25. package/src/REVIEW_2026_08_06/gfx-gi.md +143 -0
  26. package/src/REVIEW_2026_08_06/gfx-render.md +740 -0
  27. package/src/REVIEW_2026_08_06/gfx-texture.md +690 -0
  28. package/src/REVIEW_2026_08_06/prior-criticals.md +49 -0
  29. package/src/REVIEW_2026_08_06/prior-highs.md +138 -0
  30. package/src/REVIEW_2026_08_06/test-gaps.md +364 -0
  31. package/src/REVIEW_2026_08_06/view.md +667 -0
  32. package/src/REVIEW_2026_08_06.md +571 -0
  33. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  34. package/src/core/binary/BinaryBuffer.js +12 -1
  35. package/src/core/binary/BitImage2.d.ts +5 -1
  36. package/src/core/binary/BitImage2.d.ts.map +1 -1
  37. package/src/core/binary/BitImage2.js +5 -1
  38. package/src/core/bvh8/build/NodeProxy.d.ts.map +1 -1
  39. package/src/core/bvh8/build/NodeProxy.js +314 -308
  40. package/src/core/collection/list/List.d.ts +15 -0
  41. package/src/core/collection/list/List.d.ts.map +1 -1
  42. package/src/core/collection/list/List.js +34 -0
  43. package/src/core/collection/list/SortedListProjection.d.ts.map +1 -1
  44. package/src/core/collection/list/SortedListProjection.js +4 -1
  45. package/src/core/collection/map/BiMap.d.ts +25 -2
  46. package/src/core/collection/map/BiMap.d.ts.map +1 -1
  47. package/src/core/collection/map/BiMap.js +57 -3
  48. package/src/core/debug/matchers/IsAnything.d.ts.map +1 -1
  49. package/src/core/debug/matchers/IsAnything.js +5 -1
  50. package/src/core/events/signal/Signal.d.ts.map +1 -1
  51. package/src/core/events/signal/Signal.js +3 -1
  52. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +433 -0
  53. package/src/core/geom/2d/polygon/polygon2_is_counter_clockwise.d.ts +31 -0
  54. package/src/core/geom/2d/polygon/polygon2_is_counter_clockwise.d.ts.map +1 -0
  55. package/src/core/geom/2d/polygon/polygon2_is_counter_clockwise.js +84 -0
  56. package/src/core/geom/2d/polygon/polygon2_signed_area.d.ts +24 -2
  57. package/src/core/geom/2d/polygon/polygon2_signed_area.d.ts.map +1 -1
  58. package/src/core/geom/2d/polygon/polygon2_signed_area.js +52 -34
  59. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts +28 -0
  60. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts.map +1 -0
  61. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +86 -0
  62. package/src/core/geom/2d/polygon/polygon2_triangulate.d.ts +40 -0
  63. package/src/core/geom/2d/polygon/polygon2_triangulate.d.ts.map +1 -0
  64. package/src/core/geom/2d/polygon/polygon2_triangulate.js +1280 -0
  65. package/src/core/geom/2d/polygon/polygon2_triangulation_deviation.d.ts +28 -0
  66. package/src/core/geom/2d/polygon/polygon2_triangulation_deviation.d.ts.map +1 -0
  67. package/src/core/geom/2d/polygon/polygon2_triangulation_deviation.js +77 -0
  68. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts +6 -3
  69. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts.map +1 -1
  70. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.js +26 -13
  71. package/src/core/geom/2d/triangle/tri2_signed_area.d.ts +17 -1
  72. package/src/core/geom/2d/triangle/tri2_signed_area.d.ts.map +1 -1
  73. package/src/core/geom/2d/triangle/tri2_signed_area.js +35 -23
  74. package/src/core/geom/2d/v2_morton_encode.d.ts +20 -0
  75. package/src/core/geom/2d/v2_morton_encode.d.ts.map +1 -0
  76. package/src/core/geom/2d/v2_morton_encode.js +23 -0
  77. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts.map +1 -1
  78. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +4 -1
  79. package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts +27 -0
  80. package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts.map +1 -0
  81. package/src/core/geom/3d/polygon/polygon3_compute_normal.js +60 -0
  82. package/src/core/geom/3d/polygon/polygon3_triangulate.d.ts +34 -0
  83. package/src/core/geom/3d/polygon/polygon3_triangulate.d.ts.map +1 -0
  84. package/src/core/geom/3d/polygon/polygon3_triangulate.js +94 -0
  85. package/src/core/geom/3d/quaternion/quat3_multiply.d.ts +8 -2
  86. package/src/core/geom/3d/quaternion/quat3_multiply.d.ts.map +1 -1
  87. package/src/core/geom/3d/quaternion/quat3_multiply.js +8 -2
  88. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  89. package/src/core/geom/3d/shape/ConvexHullShape3D.js +32 -2
  90. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.d.ts +23 -6
  91. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.d.ts.map +1 -1
  92. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.js +268 -124
  93. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_assert_valid.d.ts +17 -0
  94. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_assert_valid.d.ts.map +1 -0
  95. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_assert_valid.js +44 -0
  96. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_count_edge_faces.d.ts +20 -0
  97. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_count_edge_faces.d.ts.map +1 -0
  98. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_count_edge_faces.js +40 -0
  99. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_is_closed.d.ts +19 -0
  100. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_is_closed.d.ts.map +1 -0
  101. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_is_closed.js +34 -0
  102. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_is_manifold.d.ts +22 -0
  103. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_is_manifold.d.ts.map +1 -0
  104. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_is_manifold.js +37 -0
  105. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_validate.d.ts +87 -0
  106. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_validate.d.ts.map +1 -0
  107. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js +599 -0
  108. package/src/core/geom/3d/triangle/tri3_compute_signed_volume.d.ts +32 -0
  109. package/src/core/geom/3d/triangle/tri3_compute_signed_volume.d.ts.map +1 -1
  110. package/src/core/geom/3d/triangle/tri3_compute_signed_volume.js +66 -7
  111. package/src/core/geom/3d/triangle/tri3_mesh_compute_signed_volume.d.ts +22 -1
  112. package/src/core/geom/3d/triangle/tri3_mesh_compute_signed_volume.d.ts.map +1 -1
  113. package/src/core/geom/3d/triangle/tri3_mesh_compute_signed_volume.js +83 -38
  114. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +554 -0
  115. package/src/core/geom/vec3/v3_cotangent.d.ts +6 -2
  116. package/src/core/geom/vec3/v3_cotangent.d.ts.map +1 -1
  117. package/src/core/geom/vec3/v3_cotangent.js +6 -2
  118. package/src/core/geom/vec3/v3_cross.d.ts +6 -2
  119. package/src/core/geom/vec3/v3_cross.d.ts.map +1 -1
  120. package/src/core/geom/vec3/v3_cross.js +6 -2
  121. package/src/core/geom/vec3/v3_multiply.d.ts +6 -2
  122. package/src/core/geom/vec3/v3_multiply.d.ts.map +1 -1
  123. package/src/core/geom/vec3/v3_multiply.js +6 -2
  124. package/src/core/geom/vec3/v3_subtract.d.ts +6 -2
  125. package/src/core/geom/vec3/v3_subtract.d.ts.map +1 -1
  126. package/src/core/geom/vec3/v3_subtract.js +6 -2
  127. package/src/core/localization/Localization.js +1 -1
  128. package/src/core/math/random/randomSeed.d.ts +13 -0
  129. package/src/core/math/random/randomSeed.d.ts.map +1 -0
  130. package/src/core/math/random/randomSeed.js +16 -0
  131. package/src/core/math/spline/spline3_hermite_apply_transform.d.ts +50 -0
  132. package/src/core/math/spline/spline3_hermite_apply_transform.d.ts.map +1 -0
  133. package/src/core/math/spline/spline3_hermite_apply_transform.js +107 -0
  134. package/src/core/math/spline/spline3_hermite_reverse.d.ts +34 -0
  135. package/src/core/math/spline/spline3_hermite_reverse.d.ts.map +1 -0
  136. package/src/core/math/spline/spline3_hermite_reverse.js +49 -0
  137. package/src/core/math/statistics/hammersley_sequence.d.ts +17 -4
  138. package/src/core/math/statistics/hammersley_sequence.d.ts.map +1 -1
  139. package/src/core/math/statistics/hammersley_sequence.js +25 -16
  140. package/src/core/process/Future.d.ts.map +1 -1
  141. package/src/core/process/Future.js +12 -0
  142. package/src/core/process/PromiseWatcher.d.ts.map +1 -1
  143. package/src/core/process/PromiseWatcher.js +9 -2
  144. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  145. package/src/core/process/executor/ConcurrentExecutor.js +12 -2
  146. package/src/core/process/worker/WorkerProxy.d.ts.map +1 -1
  147. package/src/core/process/worker/WorkerProxy.js +5 -2
  148. package/src/core/process/worker/extractTransferables.d.ts.map +1 -1
  149. package/src/core/process/worker/extractTransferables.js +4 -1
  150. package/src/engine/Engine.d.ts +12 -12
  151. package/src/engine/Engine.d.ts.map +1 -1
  152. package/src/engine/Engine.js +149 -10
  153. package/src/engine/EngineHarness.d.ts.map +1 -1
  154. package/src/engine/EngineHarness.js +4 -1
  155. package/src/engine/asset/loaders/ArrayBufferLoader.d.ts.map +1 -1
  156. package/src/engine/asset/loaders/ArrayBufferLoader.js +7 -0
  157. package/src/engine/ecs/speaker/lines/sets/LineSetDescription.d.ts.map +1 -1
  158. package/src/engine/ecs/speaker/lines/sets/LineSetDescription.js +3 -1
  159. package/src/engine/ecs/terrain/ecs/TerrainSystem.d.ts.map +1 -1
  160. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +4 -1
  161. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts +29 -0
  162. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
  163. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +84 -23
  164. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +446 -0
  165. package/src/engine/graphics/GraphicsEngine.d.ts +56 -7
  166. package/src/engine/graphics/GraphicsEngine.d.ts.map +1 -1
  167. package/src/engine/graphics/GraphicsEngine.js +196 -24
  168. package/src/engine/graphics/context/WebGLContextFailureReason.d.ts +9 -0
  169. package/src/engine/graphics/context/WebGLContextFailureReason.d.ts.map +1 -0
  170. package/src/engine/graphics/context/WebGLContextFailureReason.js +17 -0
  171. package/src/engine/graphics/context/WebGLContextMonitor.d.ts +106 -0
  172. package/src/engine/graphics/context/WebGLContextMonitor.d.ts.map +1 -0
  173. package/src/engine/graphics/context/WebGLContextMonitor.js +341 -0
  174. package/src/engine/graphics/context/WebGLContextState.d.ts +14 -0
  175. package/src/engine/graphics/context/WebGLContextState.d.ts.map +1 -0
  176. package/src/engine/graphics/context/WebGLContextState.js +24 -0
  177. package/src/engine/graphics/context/testWebGLContextLoss.d.ts +2 -0
  178. package/src/engine/graphics/context/testWebGLContextLoss.d.ts.map +1 -0
  179. package/src/engine/graphics/context/testWebGLContextLoss.js +696 -0
  180. package/src/engine/graphics/ecs/camera/serialization/CameraSerializationAdapter.d.ts.map +1 -1
  181. package/src/engine/graphics/ecs/camera/serialization/CameraSerializationAdapter.js +68 -32
  182. package/src/engine/graphics/ecs/camera/serialization/CameraSerializationUpgrader_0_1.d.ts +14 -0
  183. package/src/engine/graphics/ecs/camera/serialization/CameraSerializationUpgrader_0_1.d.ts.map +1 -0
  184. package/src/engine/graphics/ecs/camera/serialization/CameraSerializationUpgrader_0_1.js +41 -0
  185. package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +1 -1
  186. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts.map +1 -1
  187. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +5 -0
  188. package/src/engine/graphics/ecs/trail2d/Trail2D.d.ts +5 -1
  189. package/src/engine/graphics/ecs/trail2d/Trail2D.d.ts.map +1 -1
  190. package/src/engine/graphics/ecs/trail2d/Trail2D.js +15 -0
  191. package/src/engine/graphics/ecs/trail2d/Trail2DSystem.d.ts +1 -1
  192. package/src/engine/graphics/ecs/trail2d/Trail2DSystem.d.ts.map +1 -1
  193. package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +2 -1
  194. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +4 -1
  195. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
  196. package/src/engine/graphics/ecs/trail3d/Trail3D.js +488 -476
  197. package/src/engine/graphics/ecs/trail3d/Trail3DSystem.d.ts +1 -1
  198. package/src/engine/graphics/ecs/trail3d/Trail3DSystem.d.ts.map +1 -1
  199. package/src/engine/graphics/ecs/trail3d/Trail3DSystem.js +280 -253
  200. package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.d.ts.map +1 -1
  201. package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.js +3 -2
  202. package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.d.ts.map +1 -1
  203. package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.js +3 -1
  204. package/src/engine/graphics/geometry/computeMeshSurfaceArea.js +1 -1
  205. package/src/engine/graphics/load_and_set_cubemap_v0.d.ts +5 -0
  206. package/src/engine/graphics/load_and_set_cubemap_v0.d.ts.map +1 -1
  207. package/src/engine/graphics/load_and_set_cubemap_v0.js +26 -21
  208. package/src/engine/graphics/particles/particular/group/ParticleGroup.d.ts.map +1 -1
  209. package/src/engine/graphics/particles/particular/group/ParticleGroup.js +19 -8
  210. package/src/engine/graphics/particles/particular/group/optimizeCommandQueue.js +1 -1
  211. package/src/engine/graphics/texture/atlas/AtlasLookupTexture.d.ts.map +1 -1
  212. package/src/engine/graphics/texture/atlas/AtlasLookupTexture.js +10 -3
  213. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
  214. package/src/engine/graphics/texture/atlas/TextureAtlas.js +4 -1
  215. package/src/engine/graphics/texture/atlas/gpu/WebGLTextureAtlas.d.ts.map +1 -1
  216. package/src/engine/graphics/texture/atlas/gpu/WebGLTextureAtlas.js +11 -0
  217. package/src/engine/graphics/texture/cubemap/load_environment_map.d.ts.map +1 -1
  218. package/src/engine/graphics/texture/cubemap/load_environment_map.js +5 -2
  219. package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_Chamfer.d.ts.map +1 -1
  220. package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_Chamfer.js +26 -18
  221. package/src/engine/graphics/texture/sampler/filter/sampler2d_blur_gaussian.d.ts +15 -2
  222. package/src/engine/graphics/texture/sampler/filter/sampler2d_blur_gaussian.d.ts.map +1 -1
  223. package/src/engine/graphics/texture/sampler/filter/sampler2d_blur_gaussian.js +29 -3
  224. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.d.ts +11 -1
  225. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.d.ts.map +1 -1
  226. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.js +158 -171
  227. package/src/engine/graphics/texture/sampler/sampler2d_paint.js +1 -1
  228. package/src/engine/graphics/texture/sampler/util/bitSet2Sampler2D.js +2 -2
  229. package/src/engine/input/ecs/util/TopDownCameraControllerHelper.d.ts.map +1 -1
  230. package/src/engine/input/ecs/util/TopDownCameraControllerHelper.js +10 -3
  231. package/src/engine/navigation/ecs/components/PathSerializationUpgrader_2_3.d.ts +14 -0
  232. package/src/engine/navigation/ecs/components/PathSerializationUpgrader_2_3.d.ts.map +1 -0
  233. package/src/engine/navigation/ecs/components/PathSerializationUpgrader_2_3.js +38 -0
  234. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  235. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +433 -425
  236. package/src/engine/physics/constraint/solve_constraints.d.ts +4 -1
  237. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  238. package/src/engine/physics/constraint/solve_constraints.js +38 -13
  239. package/src/engine/physics/contact/ManifoldStore.d.ts +15 -3
  240. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
  241. package/src/engine/physics/contact/ManifoldStore.js +15 -3
  242. package/src/engine/physics/ecs/Joint.d.ts +7 -4
  243. package/src/engine/physics/ecs/Joint.d.ts.map +1 -1
  244. package/src/engine/physics/ecs/Joint.js +7 -4
  245. package/src/engine/physics/ecs/PhysicsSystem.d.ts +14 -0
  246. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  247. package/src/engine/physics/ecs/PhysicsSystem.js +16 -0
  248. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  249. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +3 -3
  250. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts +15 -7
  251. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts.map +1 -1
  252. package/src/engine/physics/narrowphase/convex_convex_manifold.js +33 -10
  253. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts +6 -2
  254. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
  255. package/src/engine/physics/narrowphase/refine_ray_concave.js +6 -2
  256. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +6 -2
  257. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  258. package/src/engine/physics/narrowphase/refine_ray_hit.js +6 -2
  259. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  260. package/src/engine/physics/queries/raycast.js +11 -4
  261. package/src/engine/save/storage/IndexedDBStorage.d.ts.map +1 -1
  262. package/src/engine/save/storage/IndexedDBStorage.js +21 -3
  263. package/src/engine/simulation/Ticker.d.ts +12 -0
  264. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  265. package/src/engine/simulation/Ticker.js +18 -0
  266. package/src/engine/sound/simulation/AcousticSimulator.d.ts.map +1 -1
  267. package/src/engine/sound/simulation/AcousticSimulator.js +9 -1
  268. package/src/engine/sound/simulation/core/VolumeField.d.ts +6 -2
  269. package/src/engine/sound/simulation/core/VolumeField.d.ts.map +1 -1
  270. package/src/engine/sound/simulation/core/VolumeField.js +6 -2
  271. package/src/engine/sound/simulation/probe/AcousticProbeField.d.ts +6 -2
  272. package/src/engine/sound/simulation/probe/AcousticProbeField.d.ts.map +1 -1
  273. package/src/engine/sound/simulation/probe/AcousticProbeField.js +6 -2
  274. package/src/engine/sound/simulation/probe/acoustic_probe_transfer.d.ts +6 -2
  275. package/src/engine/sound/simulation/probe/acoustic_probe_transfer.d.ts.map +1 -1
  276. package/src/engine/sound/simulation/probe/acoustic_probe_transfer.js +6 -2
  277. package/src/engine/sound/simulation/probe/bakeProbeReflectors.d.ts +3 -1
  278. package/src/engine/sound/simulation/probe/bakeProbeReflectors.d.ts.map +1 -1
  279. package/src/engine/sound/simulation/probe/bakeProbeReflectors.js +3 -1
  280. package/src/engine/ui/GUIEngine.d.ts.map +1 -1
  281. package/src/engine/ui/GUIEngine.js +8 -1
  282. package/src/generation/theme/TerrainTheme.d.ts.map +1 -1
  283. package/src/generation/theme/TerrainTheme.js +2 -1
  284. package/src/generation/theme/ThemeEngine.d.ts.map +1 -1
  285. package/src/generation/theme/ThemeEngine.js +6 -5
  286. package/src/view/ViewGroup.d.ts.map +1 -1
  287. package/src/view/ViewGroup.js +9 -7
  288. package/src/view/graphics/WebGLContextFailureView.d.ts +19 -0
  289. package/src/view/graphics/WebGLContextFailureView.d.ts.map +1 -0
  290. package/src/view/graphics/WebGLContextFailureView.js +76 -0
  291. package/src/view/minimap/Minimap.d.ts +8 -0
  292. package/src/view/minimap/Minimap.d.ts.map +1 -1
  293. package/src/view/minimap/Minimap.js +16 -3
  294. package/src/view/minimap/dom/MinimapMarkerView.d.ts.map +1 -1
  295. package/src/view/minimap/dom/MinimapMarkerView.js +3 -1
@@ -0,0 +1,341 @@
1
+ import { assert } from "../../../core/assert.js";
2
+ import Signal from "../../../core/events/signal/Signal.js";
3
+ import { WebGLContextFailureReason } from "./WebGLContextFailureReason.js";
4
+ import { WebGLContextState } from "./WebGLContextState.js";
5
+
6
+ /**
7
+ * Detects WebGL context loss on a canvas and tracks whether the context may be used.
8
+ *
9
+ * The browser is only allowed to restore a lost context if `preventDefault()` was called on the loss
10
+ * event, which is what this class does. Restoration is still the browser's decision - it will refuse
11
+ * when the page caused the loss itself (typically by exceeding the per-page context limit) or when
12
+ * acceleration has been disabled for the page. That is why recovery is bounded: after
13
+ * {@link WebGLContextMonitor#restore_timeout} seconds without a restore, or after more than
14
+ * {@link WebGLContextMonitor#max_loss_count} losses, the monitor gives up and reports
15
+ * {@link WebGLContextMonitor#on}.failed so the application can tell the user instead of presenting a
16
+ * permanently black canvas.
17
+ *
18
+ * The restore deadline only runs while the page is visible. The browser does not restore a context in a
19
+ * hidden tab, so counting hidden time would fail sessions that were merely backgrounded when the loss
20
+ * happened - a common case, since background tabs are where the browser prefers to evict contexts. Each
21
+ * return to visibility restarts the full {@link WebGLContextMonitor#restore_timeout} wait.
22
+ *
23
+ * Detection is entirely event driven. Nothing here runs per frame; consumers read
24
+ * {@link WebGLContextMonitor#is_live} (a single field compare) and subscribe to the signals.
25
+ */
26
+ export class WebGLContextMonitor {
27
+ /**
28
+ *
29
+ * @type {HTMLCanvasElement|null}
30
+ */
31
+ #canvas = null;
32
+
33
+ /**
34
+ *
35
+ * @type {WebGLContextState}
36
+ */
37
+ #state = WebGLContextState.Live;
38
+
39
+ /**
40
+ * Incremented every time the context is restored. Async work that spans a loss can compare the
41
+ * generation it started in against the current one to find out whether its GPU-side results are
42
+ * still meaningful.
43
+ * @type {number}
44
+ */
45
+ #generation = 0;
46
+
47
+ /**
48
+ * How many times the context has been lost since {@link WebGLContextMonitor#attach}
49
+ * @type {number}
50
+ */
51
+ #loss_count = 0;
52
+
53
+ /**
54
+ * Timestamps of recent losses, in milliseconds, oldest first. Entries older than
55
+ * {@link WebGLContextMonitor#loss_window} are dropped, so this measures a burst rather than a
56
+ * lifetime total - a session that hits an unrelated loss every couple of hours should keep
57
+ * recovering, one that dies four times in a minute should not.
58
+ * @type {number[]}
59
+ */
60
+ #recent_losses = [];
61
+
62
+ /**
63
+ * Handle of the pending restore watchdog, `-1` when none is scheduled
64
+ * @type {number}
65
+ */
66
+ #restore_watchdog = -1;
67
+
68
+ /**
69
+ * Timestamp of the most recent loss, in milliseconds
70
+ * @type {number}
71
+ */
72
+ #time_of_loss = 0;
73
+
74
+ /**
75
+ * How long the most recent recovery took, in seconds. `-1` until the first recovery.
76
+ * @type {number}
77
+ */
78
+ #restore_duration = -1;
79
+
80
+ /**
81
+ * How long to wait for the browser to restore a lost context before declaring failure, in seconds.
82
+ * Only visible time counts - the browser will not restore while the tab is hidden, so the deadline is
83
+ * suspended for as long as the page is, and restarts in full when the page is revealed.
84
+ * @type {number}
85
+ */
86
+ restore_timeout = 5;
87
+
88
+ /**
89
+ * How many losses within {@link WebGLContextMonitor#loss_window} to recover from before giving up. A
90
+ * context that keeps dying is usually a symptom of something recovery cannot fix, such as a driver
91
+ * that crashes on our workload.
92
+ * @type {number}
93
+ */
94
+ max_loss_count = 3;
95
+
96
+ /**
97
+ * Window over which {@link WebGLContextMonitor#max_loss_count} is counted, in seconds
98
+ * @type {number}
99
+ */
100
+ loss_window = 60;
101
+
102
+ on = {
103
+ /**
104
+ * Context has been lost. Rendering must stop until `restored` or `failed`.
105
+ * @type {Signal}
106
+ */
107
+ lost: new Signal(),
108
+ /**
109
+ * Context has been restored, carries the new generation number. GPU-side state must be
110
+ * considered empty; anything not re-derivable from CPU-side data has to be rebuilt here.
111
+ * @type {Signal<number>}
112
+ */
113
+ restored: new Signal(),
114
+ /**
115
+ * Recovery was abandoned, carries a {@link WebGLContextFailureReason}. Terminal.
116
+ * @type {Signal<string>}
117
+ */
118
+ failed: new Signal()
119
+ };
120
+
121
+ /**
122
+ * @returns {WebGLContextState}
123
+ */
124
+ get state() {
125
+ return this.#state;
126
+ }
127
+
128
+ /**
129
+ * @returns {number}
130
+ */
131
+ get generation() {
132
+ return this.#generation;
133
+ }
134
+
135
+ /**
136
+ * Total number of losses observed since {@link WebGLContextMonitor#attach}
137
+ * @returns {number}
138
+ */
139
+ get loss_count() {
140
+ return this.#loss_count;
141
+ }
142
+
143
+ /**
144
+ * Number of losses within the last {@link WebGLContextMonitor#loss_window} seconds, including the
145
+ * current one if the context is presently lost
146
+ * @returns {number}
147
+ */
148
+ get recent_loss_count() {
149
+ const window_start = performance.now() - this.loss_window * 1000;
150
+
151
+ const recent = this.#recent_losses;
152
+
153
+ let result = 0;
154
+
155
+ for (let i = 0; i < recent.length; i++) {
156
+ if (recent[i] >= window_start) {
157
+ result++;
158
+ }
159
+ }
160
+
161
+ return result;
162
+ }
163
+
164
+ /**
165
+ * Duration of the most recent recovery in seconds, `-1` if the context has never been restored
166
+ * @returns {number}
167
+ */
168
+ get restore_duration() {
169
+ return this.#restore_duration;
170
+ }
171
+
172
+ /**
173
+ * Whether the context may be used for rendering. This is the per-frame gate, keep it cheap.
174
+ * @returns {boolean}
175
+ */
176
+ get is_live() {
177
+ return this.#state === WebGLContextState.Live;
178
+ }
179
+
180
+ /**
181
+ * Start watching a canvas, whose context is assumed to be live. Must be called before the context is
182
+ * used, and at most once without an intervening {@link WebGLContextMonitor#detach}.
183
+ *
184
+ * Loss bookkeeping is reset, so attaching to a freshly created canvas after giving up on the previous
185
+ * one starts with a clean slate. The generation counter is not reset - it is monotonic for the
186
+ * lifetime of the monitor, so that stale async results can always be recognised.
187
+ *
188
+ * @param {HTMLCanvasElement} canvas
189
+ */
190
+ attach(canvas) {
191
+ assert.defined(canvas, 'canvas');
192
+ assert.equal(this.#canvas, null, 'monitor is already attached');
193
+
194
+ this.#canvas = canvas;
195
+ this.#state = WebGLContextState.Live;
196
+ this.#loss_count = 0;
197
+ this.#recent_losses.length = 0;
198
+
199
+ canvas.addEventListener('webglcontextlost', this.#handle_lost, false);
200
+ canvas.addEventListener('webglcontextrestored', this.#handle_restored, false);
201
+
202
+ canvas.ownerDocument.addEventListener('visibilitychange', this.#handle_visibility_change, false);
203
+ }
204
+
205
+ /**
206
+ * Stop watching the canvas and cancel any pending watchdog
207
+ */
208
+ detach() {
209
+ const canvas = this.#canvas;
210
+
211
+ if (canvas === null) {
212
+ return;
213
+ }
214
+
215
+ canvas.removeEventListener('webglcontextlost', this.#handle_lost, false);
216
+ canvas.removeEventListener('webglcontextrestored', this.#handle_restored, false);
217
+
218
+ canvas.ownerDocument.removeEventListener('visibilitychange', this.#handle_visibility_change, false);
219
+
220
+ this.#cancel_watchdog();
221
+
222
+ this.#canvas = null;
223
+ }
224
+
225
+ #cancel_watchdog() {
226
+ if (this.#restore_watchdog !== -1) {
227
+ clearTimeout(this.#restore_watchdog);
228
+ this.#restore_watchdog = -1;
229
+ }
230
+ }
231
+
232
+ #arm_watchdog() {
233
+ this.#restore_watchdog = setTimeout(
234
+ () => {
235
+ this.#restore_watchdog = -1;
236
+ this.#fail(WebGLContextFailureReason.RestoreTimeout);
237
+ },
238
+ this.restore_timeout * 1000
239
+ );
240
+ }
241
+
242
+ /**
243
+ * Whether the page holding the canvas is currently hidden
244
+ * @returns {boolean}
245
+ */
246
+ #is_page_hidden() {
247
+ return this.#canvas.ownerDocument.visibilityState === 'hidden';
248
+ }
249
+
250
+ /**
251
+ *
252
+ * @param {WebGLContextFailureReason} reason
253
+ */
254
+ #fail(reason) {
255
+ this.#cancel_watchdog();
256
+
257
+ this.#state = WebGLContextState.Failed;
258
+
259
+ this.on.failed.send1(reason);
260
+ }
261
+
262
+ /**
263
+ *
264
+ * @param {WebGLContextEvent} event
265
+ */
266
+ #handle_lost = (event) => {
267
+ // by default a lost context is never handed back; preventing the default behaviour is what makes
268
+ // the browser consider restoring it
269
+ event.preventDefault();
270
+
271
+ if (this.#state === WebGLContextState.Failed) {
272
+ // already given up, nothing more to do
273
+ return;
274
+ }
275
+
276
+ this.#cancel_watchdog();
277
+
278
+ const now = performance.now();
279
+
280
+ this.#loss_count++;
281
+ this.#time_of_loss = now;
282
+ this.#state = WebGLContextState.Lost;
283
+
284
+ const recent = this.#recent_losses;
285
+
286
+ // drop losses that have aged out of the window
287
+ const window_start = now - this.loss_window * 1000;
288
+
289
+ let surviving = 0;
290
+ for (let i = 0; i < recent.length; i++) {
291
+ if (recent[i] >= window_start) {
292
+ recent[surviving++] = recent[i];
293
+ }
294
+ }
295
+ recent.length = surviving;
296
+
297
+ recent.push(now);
298
+
299
+ this.on.lost.send0();
300
+
301
+ if (recent.length > this.max_loss_count) {
302
+ this.#fail(WebGLContextFailureReason.TooManyLosses);
303
+ return;
304
+ }
305
+
306
+ if (!this.#is_page_hidden()) {
307
+ // a hidden tab's context cannot be restored, so the deadline would be unmeetable; it is
308
+ // armed by #handle_visibility_change once the page is revealed
309
+ this.#arm_watchdog();
310
+ }
311
+ };
312
+
313
+ #handle_visibility_change = () => {
314
+ if (this.#state !== WebGLContextState.Lost) {
315
+ return;
316
+ }
317
+
318
+ if (this.#is_page_hidden()) {
319
+ this.#cancel_watchdog();
320
+ } else if (this.#restore_watchdog === -1) {
321
+ this.#arm_watchdog();
322
+ }
323
+ };
324
+
325
+ #handle_restored = () => {
326
+ if (this.#state === WebGLContextState.Failed) {
327
+ // we already told the application that the device is gone and it may have torn down its
328
+ // presentation state; coming back to life here would leave it in an inconsistent state
329
+ return;
330
+ }
331
+
332
+ this.#cancel_watchdog();
333
+
334
+ this.#restore_duration = (performance.now() - this.#time_of_loss) / 1000;
335
+
336
+ this.#generation++;
337
+ this.#state = WebGLContextState.Live;
338
+
339
+ this.on.restored.send1(this.#generation);
340
+ };
341
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Lifecycle state of the WebGL context tracked by {@link WebGLContextMonitor }.
3
+ *
4
+ * There is deliberately no separate "restoring" state: the monitor always calls `preventDefault()` on
5
+ * the loss event, so `Lost` already means "gone, waiting for the browser to hand it back". Recovery
6
+ * fix-ups run synchronously inside the restore handler, so no state is observable in between.
7
+ */
8
+ export type WebGLContextState = number;
9
+ export namespace WebGLContextState {
10
+ let Live: number;
11
+ let Lost: number;
12
+ let Failed: number;
13
+ }
14
+ //# sourceMappingURL=WebGLContextState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGLContextState.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics/context/WebGLContextState.js"],"names":[],"mappings":";;;;;;;gCAOU,MAAM"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Lifecycle state of the WebGL context tracked by {@link WebGLContextMonitor}.
3
+ *
4
+ * There is deliberately no separate "restoring" state: the monitor always calls `preventDefault()` on
5
+ * the loss event, so `Lost` already means "gone, waiting for the browser to hand it back". Recovery
6
+ * fix-ups run synchronously inside the restore handler, so no state is observable in between.
7
+ *
8
+ * @enum {number}
9
+ */
10
+ export const WebGLContextState = {
11
+ /**
12
+ * Context is usable, rendering is allowed
13
+ */
14
+ Live: 0,
15
+ /**
16
+ * Context is gone and we are waiting for the browser to restore it. Rendering is suppressed.
17
+ */
18
+ Lost: 1,
19
+ /**
20
+ * Recovery was given up on. Terminal - the context will not come back without recreating the
21
+ * renderer or reloading the page.
22
+ */
23
+ Failed: 2
24
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=testWebGLContextLoss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testWebGLContextLoss.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics/context/testWebGLContextLoss.js"],"names":[],"mappings":""}