@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
@@ -24,6 +24,7 @@ import { MetricsCategory } from "../metrics/MetricsCategory.js";
24
24
  import { CompositingStages } from "./composit/CompositingStages.js";
25
25
 
26
26
  import LayerCompositer from "./composit/LayerCompositer.js";
27
+ import { WebGLContextMonitor } from "./context/WebGLContextMonitor.js";
27
28
  import { Camera } from "./ecs/camera/Camera.js";
28
29
  import { MaterialManager } from "./material/manager/MaterialManager.js";
29
30
  import { ColorAndDepthFrameBuffer } from "./render/buffer/buffers/ColorAndDepthFrameBuffer.js";
@@ -39,10 +40,16 @@ import { three_setSceneAutoUpdate } from "./three/three_setSceneAutoUpdate.js";
39
40
  import { EnvironmentTextureProjection } from "./texture/EnvironmentTextureProjection.js";
40
41
 
41
42
  /**
43
+ * Applies the renderer configuration the engine relies on.
44
+ *
45
+ * Must be re-applied after a context restore: three.js rebuilds its internal modules from scratch in
46
+ * that case, and some of the settings live inside those modules rather than on the renderer itself -
47
+ * most notably the clear colour and alpha, which are owned by `WebGLBackground` and silently revert to
48
+ * transparent black.
42
49
  *
43
50
  * @param {WebGLRenderer} webGLRenderer
44
51
  */
45
- function configureThreeRenderer(webGLRenderer) {
52
+ export function configureThreeRenderer(webGLRenderer) {
46
53
 
47
54
  webGLRenderer.autoClear = false;
48
55
  webGLRenderer.setClearColor(0xBBBBFF, 0.0);
@@ -66,6 +73,40 @@ function configureThreeRenderer(webGLRenderer) {
66
73
  export class GraphicsEngine {
67
74
  #debug = false;
68
75
 
76
+ /**
77
+ * Source texture the environment map was baked from, retained so that the bake can be repeated
78
+ * after a context loss. `null` when no environment has been set.
79
+ * @type {THREE.Texture|null}
80
+ */
81
+ #environment_source = null;
82
+
83
+ /**
84
+ * @type {EnvironmentTextureProjection}
85
+ */
86
+ #environment_projection = EnvironmentTextureProjection.Equirectangular;
87
+
88
+ /**
89
+ * Prefiltered radiance target produced from {@link GraphicsEngine##environment_source}. Kept so it
90
+ * can be disposed when the environment is replaced or re-baked.
91
+ * @type {THREE.WebGLRenderTarget|null}
92
+ */
93
+ #environment_target = null;
94
+
95
+ /**
96
+ * Tracks WebGL context loss. Rendering is suppressed while the context is gone, and GPU-side state
97
+ * that is not re-derived every frame is rebuilt when it comes back.
98
+ * @readonly
99
+ * @type {WebGLContextMonitor}
100
+ */
101
+ context = new WebGLContextMonitor();
102
+
103
+ /**
104
+ * GPU identification string, read once at startup. Queried through an extension, which is unavailable
105
+ * on a lost context, so it has to be captured while the context is alive to be usable in loss reports.
106
+ * @type {string}
107
+ */
108
+ #gpu_name = 'Unknown';
109
+
69
110
  get isGraphicsEngine(){
70
111
  return true;
71
112
  }
@@ -112,7 +153,27 @@ export class GraphicsEngine {
112
153
 
113
154
  buffersRendered: new Signal(),
114
155
  visibilityConstructionStarted: new Signal(),
115
- visibilityConstructionEnded: new Signal()
156
+ visibilityConstructionEnded: new Signal(),
157
+
158
+ /**
159
+ * WebGL context has been lost. No rendering happens until the context comes back; GPU-side
160
+ * resources must be treated as gone.
161
+ * @type {Signal}
162
+ */
163
+ contextLost: new Signal(),
164
+ /**
165
+ * WebGL context has been restored, carries the context generation number. Dispatched after
166
+ * the graphics engine has re-applied its own renderer state, so subscribers can render.
167
+ * Anything held on the GPU that is not rebuilt every frame has to be rebuilt here.
168
+ * @type {Signal<number>}
169
+ */
170
+ contextRestored: new Signal(),
171
+ /**
172
+ * Context recovery was abandoned, carries a {@link WebGLContextFailureReason}. Terminal -
173
+ * there will be no further rendering.
174
+ * @type {Signal<string>}
175
+ */
176
+ contextFailed: new Signal()
116
177
  };
117
178
 
118
179
  /**
@@ -271,28 +332,61 @@ export class GraphicsEngine {
271
332
  }
272
333
 
273
334
  /**
274
- * Set the scene's environment map. The supplied texture is treated as BOTH:
275
- * - the skybox background (shown directly), and
276
- * - the image-based-lighting (IBL) source for physically based materials.
335
+ * Set the scene's image-based-lighting (IBL) source.
277
336
  *
278
- * The texture is run through three.js' PMREMGenerator to produce the
279
- * prefiltered radiance assigned to `scene.environment`, while the original
280
- * texture is assigned to `scene.background`.
337
+ * The texture is run through three.js' PMREMGenerator to produce the prefiltered radiance assigned
338
+ * to `scene.environment`. The scene background is left alone, use
339
+ * {@link GraphicsEngine#set_environment_texture} to show the same texture as a skybox as well.
340
+ *
341
+ * The source texture is retained: the prefiltered radiance lives in a render target, which means its
342
+ * contents are lost along with the WebGL context, so the bake has to be repeatable. The bake is
343
+ * re-run automatically on context restore.
281
344
  *
282
345
  * Must be called after the renderer has started up.
283
346
  *
284
347
  * @param {THREE.Texture} texture environment texture (equirectangular or cube)
285
348
  * @param {EnvironmentTextureProjection} [projection=EnvironmentTextureProjection.Equirectangular] how the texture is projected
286
349
  */
287
- set_environment_texture(texture, projection = EnvironmentTextureProjection.Equirectangular) {
350
+ set_environment_map(texture, projection = EnvironmentTextureProjection.Equirectangular) {
288
351
  assert.defined(texture, 'texture');
289
352
 
353
+ this.#environment_source = texture;
354
+ this.#environment_projection = projection;
355
+
356
+ this.#bake_environment();
357
+ }
358
+
359
+ /**
360
+ * Set the scene's environment map. The supplied texture is treated as BOTH:
361
+ * - the skybox background (shown directly), and
362
+ * - the image-based-lighting (IBL) source for physically based materials.
363
+ *
364
+ * @param {THREE.Texture} texture environment texture (equirectangular or cube)
365
+ * @param {EnvironmentTextureProjection} [projection=EnvironmentTextureProjection.Equirectangular] how the texture is projected
366
+ */
367
+ set_environment_texture(texture, projection = EnvironmentTextureProjection.Equirectangular) {
368
+ this.set_environment_map(texture, projection);
369
+
370
+ // original texture shown as the skybox. Unlike the prefiltered radiance this survives a context
371
+ // loss on its own, three.js re-uploads it from the image it still holds
372
+ this.scene.background = texture;
373
+ }
374
+
375
+ /**
376
+ * Produces prefiltered radiance from the retained environment source and installs it on the scene.
377
+ * Safe to call repeatedly, the previous bake is released first.
378
+ */
379
+ #bake_environment() {
380
+ const texture = this.#environment_source;
381
+
290
382
  const renderer = this.renderer;
291
383
 
292
384
  if (renderer === null || renderer === undefined) {
293
- throw new Error('GraphicsEngine.set_environment_texture: renderer is not initialized, call after startup');
385
+ throw new Error('GraphicsEngine: renderer is not initialized, set the environment after startup');
294
386
  }
295
387
 
388
+ const projection = this.#environment_projection;
389
+
296
390
  const pmrem = new PMREMGenerator(renderer);
297
391
 
298
392
  let target;
@@ -305,17 +399,21 @@ export class GraphicsEngine {
305
399
  target = pmrem.fromCubemap(texture);
306
400
  } else {
307
401
  pmrem.dispose();
308
- throw new Error(`GraphicsEngine.set_environment_texture: unsupported projection '${projection}'`);
402
+ throw new Error(`GraphicsEngine: unsupported environment projection '${projection}'`);
309
403
  }
310
404
 
311
405
  pmrem.dispose();
312
406
 
313
- const scene = this.scene;
407
+ const previous_target = this.#environment_target;
408
+
409
+ this.#environment_target = target;
314
410
 
315
411
  // prefiltered radiance used by PBR materials as the IBL source
316
- scene.environment = target.texture;
317
- // original texture shown as the skybox
318
- scene.background = texture;
412
+ this.scene.environment = target.texture;
413
+
414
+ if (previous_target !== null) {
415
+ previous_target.dispose();
416
+ }
319
417
  }
320
418
 
321
419
  updateSize() {
@@ -408,7 +506,7 @@ export class GraphicsEngine {
408
506
  const webGLRenderer = this.renderer = new WebGLRenderer(rendererParameters);
409
507
 
410
508
  //print GPU info
411
- const GPU_NAME = this.getGPUName();
509
+ const GPU_NAME = this.#gpu_name = this.getGPUName();
412
510
 
413
511
  console.log("GL renderer : ", GPU_NAME);
414
512
 
@@ -418,16 +516,13 @@ export class GraphicsEngine {
418
516
  });
419
517
 
420
518
 
421
- webGLRenderer.domElement.addEventListener("webglcontextrestored", function (event) {
422
- console.warn("webgl cotnext restored", event);
423
- }, false);
519
+ const context_monitor = this.context;
424
520
 
425
- webGLRenderer.domElement.addEventListener("webglcontextlost", function (event) {
426
- // By default when a WebGL program loses the context it never gets it back. To recover, we prevent default behaviour
427
- event.preventDefault();
521
+ context_monitor.on.lost.add(this.#handle_context_lost, this);
522
+ context_monitor.on.restored.add(this.#handle_context_restored, this);
523
+ context_monitor.on.failed.add(this.#handle_context_failed, this);
428
524
 
429
- console.warn("webgl context lost", event);
430
- }, false);
525
+ context_monitor.attach(webGLRenderer.domElement);
431
526
 
432
527
  const domElement = this.domElement = webGLRenderer.domElement;
433
528
  //disable selection
@@ -456,6 +551,75 @@ export class GraphicsEngine {
456
551
  viewport.el = webGLRenderer.domElement;
457
552
  }
458
553
 
554
+ #handle_context_lost() {
555
+ console.warn('WebGL context lost, rendering suspended');
556
+
557
+ globalMetrics.record("webgl-context-lost", {
558
+ category: MetricsCategory.System,
559
+ label: this.#gpu_name
560
+ });
561
+
562
+ this.on.contextLost.send0();
563
+ }
564
+
565
+ /**
566
+ * Rebuilds the renderer state that a context restore does not carry over, then lets everyone else
567
+ * rebuild theirs.
568
+ *
569
+ * Deliberately narrow: three.js re-uploads textures, geometry, render targets and shader programs by
570
+ * itself, because it drops its GPU-object bookkeeping wholesale on restore. Re-running the graphics
571
+ * engine's own initialization here would instead allocate a second set of frame buffers and leak the
572
+ * first one, which would turn a recoverable event into an out-of-memory crash after a few losses.
573
+ *
574
+ * @param {number} generation
575
+ */
576
+ #handle_context_restored(generation) {
577
+ const t0 = performance.now();
578
+
579
+ const renderer = this.renderer;
580
+
581
+ // clear colour/alpha and a few other settings live inside three.js modules that were replaced
582
+ configureThreeRenderer(renderer);
583
+
584
+ renderer.debug.checkShaderErrors = this.#debug;
585
+
586
+ this.enableExtensions();
587
+
588
+ // re-push size, pixel ratio and the derived output resolution
589
+ this.updateSize();
590
+
591
+ if (this.#environment_source !== null) {
592
+ // prefiltered radiance lives in a render target, so it died with the context
593
+ this.#bake_environment();
594
+ }
595
+
596
+ const duration = performance.now() - t0;
597
+
598
+ console.warn(`WebGL context restored (generation ${generation}), engine state re-applied in ${duration.toFixed(1)}ms`);
599
+
600
+ globalMetrics.record("webgl-context-restored", {
601
+ category: MetricsCategory.System,
602
+ label: this.#gpu_name
603
+ });
604
+
605
+ this.on.contextRestored.send1(generation);
606
+ }
607
+
608
+ /**
609
+ *
610
+ * @param {WebGLContextFailureReason} reason
611
+ */
612
+ #handle_context_failed(reason) {
613
+ console.error(`WebGL context recovery abandoned: ${reason}`);
614
+
615
+ globalMetrics.record("webgl-context-failed", {
616
+ category: MetricsCategory.System,
617
+ label: reason
618
+ });
619
+
620
+ this.on.contextFailed.send1(reason);
621
+ }
622
+
459
623
  /**
460
624
  * Produces GPU identification string via WebGL extension if available
461
625
  * @returns {string}
@@ -476,6 +640,8 @@ export class GraphicsEngine {
476
640
  * Shut down renderer engine. After calling this method the engine may no longer be used.
477
641
  */
478
642
  stop() {
643
+ this.context.detach();
644
+
479
645
  const renderer = this.renderer;
480
646
  if (renderer !== undefined) {
481
647
  renderer.forceContextLoss();
@@ -632,6 +798,12 @@ export class GraphicsEngine {
632
798
  *
633
799
  */
634
800
  render() {
801
+ if (!this.context.is_live) {
802
+ // no context to draw with. GL calls would silently do nothing, and readbacks would hand out
803
+ // zeroes that are indistinguishable from a valid black frame
804
+ return;
805
+ }
806
+
635
807
  if (this.needDraw && !this.autoDraw) {
636
808
  this.needDraw = false;
637
809
  }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Why {@link WebGLContextMonitor } gave up on recovery.
3
+ */
4
+ export type WebGLContextFailureReason = string;
5
+ export namespace WebGLContextFailureReason {
6
+ let RestoreTimeout: string;
7
+ let TooManyLosses: string;
8
+ }
9
+ //# sourceMappingURL=WebGLContextFailureReason.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGLContextFailureReason.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics/context/WebGLContextFailureReason.js"],"names":[],"mappings":";;;wCAEU,MAAM"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Why {@link WebGLContextMonitor} gave up on recovery.
3
+ * @enum {string}
4
+ */
5
+ export const WebGLContextFailureReason = {
6
+ /**
7
+ * The browser never delivered `webglcontextrestored` within the allotted time. Happens when the
8
+ * browser refuses to restore, for example because the page itself caused the loss by exceeding the
9
+ * per-page context limit, or because acceleration was disabled for the page.
10
+ */
11
+ RestoreTimeout: 'restore-timeout',
12
+ /**
13
+ * The context was lost more times than {@link WebGLContextMonitor#max_loss_count}. Recovering again
14
+ * would most likely just lead to another loss.
15
+ */
16
+ TooManyLosses: 'too-many-losses'
17
+ };
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Detects WebGL context loss on a canvas and tracks whether the context may be used.
3
+ *
4
+ * The browser is only allowed to restore a lost context if `preventDefault()` was called on the loss
5
+ * event, which is what this class does. Restoration is still the browser's decision - it will refuse
6
+ * when the page caused the loss itself (typically by exceeding the per-page context limit) or when
7
+ * acceleration has been disabled for the page. That is why recovery is bounded: after
8
+ * {@link WebGLContextMonitor#restore_timeout} seconds without a restore, or after more than
9
+ * {@link WebGLContextMonitor#max_loss_count} losses, the monitor gives up and reports
10
+ * {@link WebGLContextMonitor#on}.failed so the application can tell the user instead of presenting a
11
+ * permanently black canvas.
12
+ *
13
+ * The restore deadline only runs while the page is visible. The browser does not restore a context in a
14
+ * hidden tab, so counting hidden time would fail sessions that were merely backgrounded when the loss
15
+ * happened - a common case, since background tabs are where the browser prefers to evict contexts. Each
16
+ * return to visibility restarts the full {@link WebGLContextMonitor#restore_timeout} wait.
17
+ *
18
+ * Detection is entirely event driven. Nothing here runs per frame; consumers read
19
+ * {@link WebGLContextMonitor#is_live} (a single field compare) and subscribe to the signals.
20
+ */
21
+ export class WebGLContextMonitor {
22
+ /**
23
+ * How long to wait for the browser to restore a lost context before declaring failure, in seconds.
24
+ * Only visible time counts - the browser will not restore while the tab is hidden, so the deadline is
25
+ * suspended for as long as the page is, and restarts in full when the page is revealed.
26
+ * @type {number}
27
+ */
28
+ restore_timeout: number;
29
+ /**
30
+ * How many losses within {@link WebGLContextMonitor#loss_window} to recover from before giving up. A
31
+ * context that keeps dying is usually a symptom of something recovery cannot fix, such as a driver
32
+ * that crashes on our workload.
33
+ * @type {number}
34
+ */
35
+ max_loss_count: number;
36
+ /**
37
+ * Window over which {@link WebGLContextMonitor#max_loss_count} is counted, in seconds
38
+ * @type {number}
39
+ */
40
+ loss_window: number;
41
+ on: {
42
+ /**
43
+ * Context has been lost. Rendering must stop until `restored` or `failed`.
44
+ * @type {Signal}
45
+ */
46
+ lost: Signal;
47
+ /**
48
+ * Context has been restored, carries the new generation number. GPU-side state must be
49
+ * considered empty; anything not re-derivable from CPU-side data has to be rebuilt here.
50
+ * @type {Signal<number>}
51
+ */
52
+ restored: any;
53
+ /**
54
+ * Recovery was abandoned, carries a {@link WebGLContextFailureReason}. Terminal.
55
+ * @type {Signal<string>}
56
+ */
57
+ failed: any;
58
+ };
59
+ /**
60
+ * @returns {WebGLContextState}
61
+ */
62
+ get state(): number;
63
+ /**
64
+ * @returns {number}
65
+ */
66
+ get generation(): number;
67
+ /**
68
+ * Total number of losses observed since {@link WebGLContextMonitor#attach}
69
+ * @returns {number}
70
+ */
71
+ get loss_count(): number;
72
+ /**
73
+ * Number of losses within the last {@link WebGLContextMonitor#loss_window} seconds, including the
74
+ * current one if the context is presently lost
75
+ * @returns {number}
76
+ */
77
+ get recent_loss_count(): number;
78
+ /**
79
+ * Duration of the most recent recovery in seconds, `-1` if the context has never been restored
80
+ * @returns {number}
81
+ */
82
+ get restore_duration(): number;
83
+ /**
84
+ * Whether the context may be used for rendering. This is the per-frame gate, keep it cheap.
85
+ * @returns {boolean}
86
+ */
87
+ get is_live(): boolean;
88
+ /**
89
+ * Start watching a canvas, whose context is assumed to be live. Must be called before the context is
90
+ * used, and at most once without an intervening {@link WebGLContextMonitor#detach}.
91
+ *
92
+ * Loss bookkeeping is reset, so attaching to a freshly created canvas after giving up on the previous
93
+ * one starts with a clean slate. The generation counter is not reset - it is monotonic for the
94
+ * lifetime of the monitor, so that stale async results can always be recognised.
95
+ *
96
+ * @param {HTMLCanvasElement} canvas
97
+ */
98
+ attach(canvas: HTMLCanvasElement): void;
99
+ /**
100
+ * Stop watching the canvas and cancel any pending watchdog
101
+ */
102
+ detach(): void;
103
+ #private;
104
+ }
105
+ import Signal from "../../../core/events/signal/Signal.js";
106
+ //# sourceMappingURL=WebGLContextMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGLContextMonitor.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics/context/WebGLContextMonitor.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAsDI;;;;;OAKG;IACH,iBAFU,MAAM,CAEI;IAEpB;;;;;OAKG;IACH,gBAFU,MAAM,CAEG;IAEnB;;;OAGG;IACH,aAFU,MAAM,CAEC;IAEjB;QACI;;;WAGG;cADO,MAAM;QAGhB;;;;WAIG;;QAEH;;;WAGG;;MAEL;IAEF;;OAEG;IACH,oBAEC;IAED;;OAEG;IACH,yBAEC;IAED;;;OAGG;IACH,yBAEC;IAED;;;;OAIG;IACH,gCAcC;IAED;;;OAGG;IACH,+BAEC;IAED;;;OAGG;IACH,uBAEC;IAED;;;;;;;;;OASG;IACH,eAFW,iBAAiB,QAe3B;IAED;;OAEG;IACH,eAeC;;CAsHJ;mBAnVkB,uCAAuC"}