@fps-games/engine 0.0.1-beta.5 → 0.0.1-beta.8

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 (294) hide show
  1. package/dist/asset-resource.d.ts +39 -0
  2. package/dist/asset-resource.d.ts.map +1 -0
  3. package/dist/asset-resource.js +121 -0
  4. package/dist/asset-resource.js.map +1 -0
  5. package/dist/babylon/game-world-plugin-lifecycle.d.ts +26 -0
  6. package/dist/babylon/game-world-plugin-lifecycle.d.ts.map +1 -0
  7. package/dist/babylon/game-world-plugin-lifecycle.js +257 -0
  8. package/dist/babylon/game-world-plugin-lifecycle.js.map +1 -0
  9. package/dist/babylon/plugin-contract.d.ts +15 -0
  10. package/dist/babylon/plugin-contract.d.ts.map +1 -0
  11. package/dist/babylon/plugin-contract.js +9 -0
  12. package/dist/babylon/plugin-contract.js.map +1 -0
  13. package/dist/babylon/renderer/brdf-texture-settlement.d.ts +7 -0
  14. package/dist/babylon/renderer/brdf-texture-settlement.d.ts.map +1 -0
  15. package/dist/babylon/renderer/brdf-texture-settlement.js +29 -0
  16. package/dist/babylon/renderer/brdf-texture-settlement.js.map +1 -0
  17. package/dist/babylon/renderer/environment/environment-texture-controller.d.ts +7 -0
  18. package/dist/babylon/renderer/environment/environment-texture-controller.d.ts.map +1 -0
  19. package/dist/babylon/renderer/environment/environment-texture-controller.js +357 -0
  20. package/dist/babylon/renderer/environment/environment-texture-controller.js.map +1 -0
  21. package/dist/babylon/renderer/environment/index.d.ts +4 -0
  22. package/dist/babylon/renderer/environment/index.d.ts.map +1 -0
  23. package/dist/babylon/renderer/environment/index.js +4 -0
  24. package/dist/babylon/renderer/environment/index.js.map +1 -0
  25. package/dist/babylon/renderer/environment/profile.d.ts +3 -0
  26. package/dist/babylon/renderer/environment/profile.d.ts.map +1 -0
  27. package/dist/babylon/renderer/environment/profile.js +27 -0
  28. package/dist/babylon/renderer/environment/profile.js.map +1 -0
  29. package/dist/babylon/renderer/environment/types.d.ts +24 -0
  30. package/dist/babylon/renderer/environment/types.d.ts.map +1 -0
  31. package/dist/babylon/renderer/environment/types.js +6 -0
  32. package/dist/babylon/renderer/environment/types.js.map +1 -0
  33. package/dist/babylon/renderer/index.d.ts +24 -0
  34. package/dist/babylon/renderer/index.d.ts.map +1 -0
  35. package/dist/babylon/renderer/index.js +24 -0
  36. package/dist/babylon/renderer/index.js.map +1 -0
  37. package/dist/babylon/renderer/lighting/directional-light-angles.d.ts +17 -0
  38. package/dist/babylon/renderer/lighting/directional-light-angles.d.ts.map +1 -0
  39. package/dist/babylon/renderer/lighting/directional-light-angles.js +67 -0
  40. package/dist/babylon/renderer/lighting/directional-light-angles.js.map +1 -0
  41. package/dist/babylon/renderer/material-owner-candidates.d.ts +19 -0
  42. package/dist/babylon/renderer/material-owner-candidates.d.ts.map +1 -0
  43. package/dist/babylon/renderer/material-owner-candidates.js +212 -0
  44. package/dist/babylon/renderer/material-owner-candidates.js.map +1 -0
  45. package/dist/babylon/renderer/materials/index.d.ts +3 -0
  46. package/dist/babylon/renderer/materials/index.d.ts.map +1 -0
  47. package/dist/babylon/renderer/materials/index.js +3 -0
  48. package/dist/babylon/renderer/materials/index.js.map +1 -0
  49. package/dist/babylon/renderer/materials/material-runtime.d.ts +29 -0
  50. package/dist/babylon/renderer/materials/material-runtime.d.ts.map +1 -0
  51. package/dist/babylon/renderer/materials/material-runtime.js +660 -0
  52. package/dist/babylon/renderer/materials/material-runtime.js.map +1 -0
  53. package/dist/babylon/renderer/materials/material-slot-owner.d.ts +42 -0
  54. package/dist/babylon/renderer/materials/material-slot-owner.d.ts.map +1 -0
  55. package/dist/babylon/renderer/materials/material-slot-owner.js +318 -0
  56. package/dist/babylon/renderer/materials/material-slot-owner.js.map +1 -0
  57. package/dist/babylon/renderer/outlines/babylon-default/apply.d.ts +4 -0
  58. package/dist/babylon/renderer/outlines/babylon-default/apply.d.ts.map +1 -0
  59. package/dist/babylon/renderer/outlines/babylon-default/apply.js +45 -0
  60. package/dist/babylon/renderer/outlines/babylon-default/apply.js.map +1 -0
  61. package/dist/babylon/renderer/outlines/babylon-default/index.d.ts +3 -0
  62. package/dist/babylon/renderer/outlines/babylon-default/index.d.ts.map +1 -0
  63. package/dist/babylon/renderer/outlines/babylon-default/index.js +2 -0
  64. package/dist/babylon/renderer/outlines/babylon-default/index.js.map +1 -0
  65. package/dist/babylon/renderer/outlines/babylon-default/types.d.ts +7 -0
  66. package/dist/babylon/renderer/outlines/babylon-default/types.d.ts.map +1 -0
  67. package/dist/babylon/renderer/outlines/babylon-default/types.js +2 -0
  68. package/dist/babylon/renderer/outlines/babylon-default/types.js.map +1 -0
  69. package/dist/babylon/renderer/outlines/index.d.ts +4 -0
  70. package/dist/babylon/renderer/outlines/index.d.ts.map +1 -0
  71. package/dist/babylon/renderer/outlines/index.js +3 -0
  72. package/dist/babylon/renderer/outlines/index.js.map +1 -0
  73. package/dist/babylon/renderer/outlines/runtime-override.d.ts +36 -0
  74. package/dist/babylon/renderer/outlines/runtime-override.d.ts.map +1 -0
  75. package/dist/babylon/renderer/outlines/runtime-override.js +131 -0
  76. package/dist/babylon/renderer/outlines/runtime-override.js.map +1 -0
  77. package/dist/babylon/renderer/outlines/types.d.ts +7 -0
  78. package/dist/babylon/renderer/outlines/types.d.ts.map +1 -0
  79. package/dist/babylon/renderer/outlines/types.js +2 -0
  80. package/dist/babylon/renderer/outlines/types.js.map +1 -0
  81. package/dist/babylon/renderer/placement/index.d.ts +2 -0
  82. package/dist/babylon/renderer/placement/index.d.ts.map +1 -0
  83. package/dist/babylon/renderer/placement/index.js +2 -0
  84. package/dist/babylon/renderer/placement/index.js.map +1 -0
  85. package/dist/babylon/renderer/placement/runtime-drop-position.d.ts +24 -0
  86. package/dist/babylon/renderer/placement/runtime-drop-position.d.ts.map +1 -0
  87. package/dist/babylon/renderer/placement/runtime-drop-position.js +63 -0
  88. package/dist/babylon/renderer/placement/runtime-drop-position.js.map +1 -0
  89. package/dist/babylon/renderer/post-process/babylon-default-pipeline.d.ts +7 -0
  90. package/dist/babylon/renderer/post-process/babylon-default-pipeline.d.ts.map +1 -0
  91. package/dist/babylon/renderer/post-process/babylon-default-pipeline.js +301 -0
  92. package/dist/babylon/renderer/post-process/babylon-default-pipeline.js.map +1 -0
  93. package/dist/babylon/renderer/post-process/index.d.ts +5 -0
  94. package/dist/babylon/renderer/post-process/index.d.ts.map +1 -0
  95. package/dist/babylon/renderer/post-process/index.js +5 -0
  96. package/dist/babylon/renderer/post-process/index.js.map +1 -0
  97. package/dist/babylon/renderer/post-process/profile.d.ts +5 -0
  98. package/dist/babylon/renderer/post-process/profile.d.ts.map +1 -0
  99. package/dist/babylon/renderer/post-process/profile.js +155 -0
  100. package/dist/babylon/renderer/post-process/profile.js.map +1 -0
  101. package/dist/babylon/renderer/post-process/types.d.ts +81 -0
  102. package/dist/babylon/renderer/post-process/types.d.ts.map +1 -0
  103. package/dist/babylon/renderer/post-process/types.js +24 -0
  104. package/dist/babylon/renderer/post-process/types.js.map +1 -0
  105. package/dist/babylon/renderer/post-process/volume-stack.d.ts +4 -0
  106. package/dist/babylon/renderer/post-process/volume-stack.d.ts.map +1 -0
  107. package/dist/babylon/renderer/post-process/volume-stack.js +105 -0
  108. package/dist/babylon/renderer/post-process/volume-stack.js.map +1 -0
  109. package/dist/babylon/renderer/rendering/image-node.d.ts +35 -0
  110. package/dist/babylon/renderer/rendering/image-node.d.ts.map +1 -0
  111. package/dist/babylon/renderer/rendering/image-node.js +39 -0
  112. package/dist/babylon/renderer/rendering/image-node.js.map +1 -0
  113. package/dist/babylon/renderer/rendering/index.d.ts +3 -0
  114. package/dist/babylon/renderer/rendering/index.d.ts.map +1 -0
  115. package/dist/babylon/renderer/rendering/index.js +3 -0
  116. package/dist/babylon/renderer/rendering/index.js.map +1 -0
  117. package/dist/babylon/renderer/rendering/node-rendering.d.ts +19 -0
  118. package/dist/babylon/renderer/rendering/node-rendering.d.ts.map +1 -0
  119. package/dist/babylon/renderer/rendering/node-rendering.js +66 -0
  120. package/dist/babylon/renderer/rendering/node-rendering.js.map +1 -0
  121. package/dist/babylon/renderer/shadows/blob-shadow-shaders.d.ts +5 -0
  122. package/dist/babylon/renderer/shadows/blob-shadow-shaders.d.ts.map +1 -0
  123. package/dist/babylon/renderer/shadows/blob-shadow-shaders.js +46 -0
  124. package/dist/babylon/renderer/shadows/blob-shadow-shaders.js.map +1 -0
  125. package/dist/babylon/renderer/shadows/blob-shadow-system.d.ts +5 -0
  126. package/dist/babylon/renderer/shadows/blob-shadow-system.d.ts.map +1 -0
  127. package/dist/babylon/renderer/shadows/blob-shadow-system.js +402 -0
  128. package/dist/babylon/renderer/shadows/blob-shadow-system.js.map +1 -0
  129. package/dist/babylon/renderer/shadows/dynamic-shadow-system.d.ts +84 -0
  130. package/dist/babylon/renderer/shadows/dynamic-shadow-system.d.ts.map +1 -0
  131. package/dist/babylon/renderer/shadows/dynamic-shadow-system.js +566 -0
  132. package/dist/babylon/renderer/shadows/dynamic-shadow-system.js.map +1 -0
  133. package/dist/babylon/renderer/shadows/planar-shadow-shaders.d.ts +7 -0
  134. package/dist/babylon/renderer/shadows/planar-shadow-shaders.d.ts.map +1 -0
  135. package/dist/babylon/renderer/shadows/planar-shadow-shaders.js +316 -0
  136. package/dist/babylon/renderer/shadows/planar-shadow-shaders.js.map +1 -0
  137. package/dist/babylon/renderer/shadows/planar-shadow-system.d.ts +5 -0
  138. package/dist/babylon/renderer/shadows/planar-shadow-system.d.ts.map +1 -0
  139. package/dist/babylon/renderer/shadows/planar-shadow-system.js +1562 -0
  140. package/dist/babylon/renderer/shadows/planar-shadow-system.js.map +1 -0
  141. package/dist/babylon/renderer/shadows/shadow-generator-shaders.d.ts +14 -0
  142. package/dist/babylon/renderer/shadows/shadow-generator-shaders.d.ts.map +1 -0
  143. package/dist/babylon/renderer/shadows/shadow-generator-shaders.js +14 -0
  144. package/dist/babylon/renderer/shadows/shadow-generator-shaders.js.map +1 -0
  145. package/dist/babylon/renderer/shadows/shadow-map-experiment-depth-backend.d.ts +68 -0
  146. package/dist/babylon/renderer/shadows/shadow-map-experiment-depth-backend.d.ts.map +1 -0
  147. package/dist/babylon/renderer/shadows/shadow-map-experiment-depth-backend.js +829 -0
  148. package/dist/babylon/renderer/shadows/shadow-map-experiment-depth-backend.js.map +1 -0
  149. package/dist/babylon/renderer/shadows/shadow-map-experiment-system.d.ts +148 -0
  150. package/dist/babylon/renderer/shadows/shadow-map-experiment-system.d.ts.map +1 -0
  151. package/dist/babylon/renderer/shadows/shadow-map-experiment-system.js +4529 -0
  152. package/dist/babylon/renderer/shadows/shadow-map-experiment-system.js.map +1 -0
  153. package/dist/babylon/renderer/shadows/static-projected-shadow-artifact-system.d.ts +4 -0
  154. package/dist/babylon/renderer/shadows/static-projected-shadow-artifact-system.d.ts.map +1 -0
  155. package/dist/babylon/renderer/shadows/static-projected-shadow-artifact-system.js +645 -0
  156. package/dist/babylon/renderer/shadows/static-projected-shadow-artifact-system.js.map +1 -0
  157. package/dist/babylon/renderer/shadows/static-projected-shadow-atlas.d.ts +61 -0
  158. package/dist/babylon/renderer/shadows/static-projected-shadow-atlas.d.ts.map +1 -0
  159. package/dist/babylon/renderer/shadows/static-projected-shadow-atlas.js +382 -0
  160. package/dist/babylon/renderer/shadows/static-projected-shadow-atlas.js.map +1 -0
  161. package/dist/babylon/renderer/shadows/static-projected-shadow-bake.d.ts +47 -0
  162. package/dist/babylon/renderer/shadows/static-projected-shadow-bake.d.ts.map +1 -0
  163. package/dist/babylon/renderer/shadows/static-projected-shadow-bake.js +285 -0
  164. package/dist/babylon/renderer/shadows/static-projected-shadow-bake.js.map +1 -0
  165. package/dist/babylon/renderer/shadows/static-projected-shadow-baker.d.ts +88 -0
  166. package/dist/babylon/renderer/shadows/static-projected-shadow-baker.d.ts.map +1 -0
  167. package/dist/babylon/renderer/shadows/static-projected-shadow-baker.js +830 -0
  168. package/dist/babylon/renderer/shadows/static-projected-shadow-baker.js.map +1 -0
  169. package/dist/babylon/renderer/shadows/static-projected-shadow-options.d.ts +3 -0
  170. package/dist/babylon/renderer/shadows/static-projected-shadow-options.d.ts.map +1 -0
  171. package/dist/babylon/renderer/shadows/static-projected-shadow-options.js +60 -0
  172. package/dist/babylon/renderer/shadows/static-projected-shadow-options.js.map +1 -0
  173. package/dist/babylon/renderer/shadows/static-projected-shadow-rendering.d.ts +27 -0
  174. package/dist/babylon/renderer/shadows/static-projected-shadow-rendering.d.ts.map +1 -0
  175. package/dist/babylon/renderer/shadows/static-projected-shadow-rendering.js +220 -0
  176. package/dist/babylon/renderer/shadows/static-projected-shadow-rendering.js.map +1 -0
  177. package/dist/babylon/renderer/shadows/types.d.ts +421 -0
  178. package/dist/babylon/renderer/shadows/types.d.ts.map +1 -0
  179. package/dist/babylon/renderer/shadows/types.js +127 -0
  180. package/dist/babylon/renderer/shadows/types.js.map +1 -0
  181. package/dist/babylon/renderer-controller.d.ts +93 -0
  182. package/dist/babylon/renderer-controller.d.ts.map +1 -0
  183. package/dist/babylon/renderer-controller.js +699 -0
  184. package/dist/babylon/renderer-controller.js.map +1 -0
  185. package/dist/babylon.d.ts +4 -0
  186. package/dist/babylon.d.ts.map +1 -1
  187. package/dist/babylon.js +4 -0
  188. package/dist/babylon.js.map +1 -1
  189. package/dist/build-info.json +4 -4
  190. package/dist/compiled-scene-data.d.ts +23 -0
  191. package/dist/compiled-scene-data.d.ts.map +1 -0
  192. package/dist/compiled-scene-data.js +100 -0
  193. package/dist/compiled-scene-data.js.map +1 -0
  194. package/dist/ground-decal.d.ts +22 -0
  195. package/dist/ground-decal.d.ts.map +1 -0
  196. package/dist/ground-decal.js +48 -0
  197. package/dist/ground-decal.js.map +1 -0
  198. package/dist/index.d.ts +13 -0
  199. package/dist/index.d.ts.map +1 -1
  200. package/dist/index.js +13 -0
  201. package/dist/index.js.map +1 -1
  202. package/dist/material-owner.d.ts +128 -0
  203. package/dist/material-owner.d.ts.map +1 -0
  204. package/dist/material-owner.js +434 -0
  205. package/dist/material-owner.js.map +1 -0
  206. package/dist/material-profile.d.ts +62 -0
  207. package/dist/material-profile.d.ts.map +1 -0
  208. package/dist/material-profile.js +132 -0
  209. package/dist/material-profile.js.map +1 -0
  210. package/dist/rendering/index.d.ts +14 -0
  211. package/dist/rendering/index.d.ts.map +1 -0
  212. package/dist/rendering/index.js +12 -0
  213. package/dist/rendering/index.js.map +1 -0
  214. package/dist/rendering/rendering-profile-types.d.ts +322 -0
  215. package/dist/rendering/rendering-profile-types.d.ts.map +1 -0
  216. package/dist/rendering/rendering-profile-types.js +2 -0
  217. package/dist/rendering/rendering-profile-types.js.map +1 -0
  218. package/dist/rendering/rendering-profile-validation.d.ts +2 -0
  219. package/dist/rendering/rendering-profile-validation.d.ts.map +1 -0
  220. package/dist/rendering/rendering-profile-validation.js +364 -0
  221. package/dist/rendering/rendering-profile-validation.js.map +1 -0
  222. package/dist/rendering/rendering-profile-values.d.ts +19 -0
  223. package/dist/rendering/rendering-profile-values.d.ts.map +1 -0
  224. package/dist/rendering/rendering-profile-values.js +79 -0
  225. package/dist/rendering/rendering-profile-values.js.map +1 -0
  226. package/dist/rendering/rendering-profile.d.ts +15 -0
  227. package/dist/rendering/rendering-profile.d.ts.map +1 -0
  228. package/dist/rendering/rendering-profile.js +442 -0
  229. package/dist/rendering/rendering-profile.js.map +1 -0
  230. package/dist/rendering/shadow-map-experiment-depth.d.ts +63 -0
  231. package/dist/rendering/shadow-map-experiment-depth.d.ts.map +1 -0
  232. package/dist/rendering/shadow-map-experiment-depth.js +186 -0
  233. package/dist/rendering/shadow-map-experiment-depth.js.map +1 -0
  234. package/dist/rendering/shadow-map-experiment-lifecycle.d.ts +94 -0
  235. package/dist/rendering/shadow-map-experiment-lifecycle.d.ts.map +1 -0
  236. package/dist/rendering/shadow-map-experiment-lifecycle.js +407 -0
  237. package/dist/rendering/shadow-map-experiment-lifecycle.js.map +1 -0
  238. package/dist/rendering/shadow-map-experiment.d.ts +189 -0
  239. package/dist/rendering/shadow-map-experiment.d.ts.map +1 -0
  240. package/dist/rendering/shadow-map-experiment.js +549 -0
  241. package/dist/rendering/shadow-map-experiment.js.map +1 -0
  242. package/dist/rendering/shadow-quality.d.ts +5 -0
  243. package/dist/rendering/shadow-quality.d.ts.map +1 -0
  244. package/dist/rendering/shadow-quality.js +83 -0
  245. package/dist/rendering/shadow-quality.js.map +1 -0
  246. package/dist/rendering/shadow-runtime.d.ts +59 -0
  247. package/dist/rendering/shadow-runtime.d.ts.map +1 -0
  248. package/dist/rendering/shadow-runtime.js +378 -0
  249. package/dist/rendering/shadow-runtime.js.map +1 -0
  250. package/dist/rendering/shadow-settings.d.ts +15 -0
  251. package/dist/rendering/shadow-settings.d.ts.map +1 -0
  252. package/dist/rendering/shadow-settings.js +129 -0
  253. package/dist/rendering/shadow-settings.js.map +1 -0
  254. package/dist/rendering/shadow-types.d.ts +99 -0
  255. package/dist/rendering/shadow-types.d.ts.map +1 -0
  256. package/dist/rendering/shadow-types.js +5 -0
  257. package/dist/rendering/shadow-types.js.map +1 -0
  258. package/dist/rendering/shadow-validation.d.ts +3 -0
  259. package/dist/rendering/shadow-validation.d.ts.map +1 -0
  260. package/dist/rendering/shadow-validation.js +166 -0
  261. package/dist/rendering/shadow-validation.js.map +1 -0
  262. package/dist/rendering/value.d.ts +2 -0
  263. package/dist/rendering/value.d.ts.map +1 -0
  264. package/dist/rendering/value.js +6 -0
  265. package/dist/rendering/value.js.map +1 -0
  266. package/dist/runtime-data-token.d.ts +4 -0
  267. package/dist/runtime-data-token.d.ts.map +1 -0
  268. package/dist/runtime-data-token.js +4 -0
  269. package/dist/runtime-data-token.js.map +1 -0
  270. package/dist/runtime-data-types.d.ts +83 -0
  271. package/dist/runtime-data-types.d.ts.map +1 -0
  272. package/dist/runtime-data-types.js +2 -0
  273. package/dist/runtime-data-types.js.map +1 -0
  274. package/dist/runtime-data.d.ts +18 -0
  275. package/dist/runtime-data.d.ts.map +1 -0
  276. package/dist/runtime-data.js +301 -0
  277. package/dist/runtime-data.js.map +1 -0
  278. package/dist/runtime-scene-resolvers.d.ts +37 -0
  279. package/dist/runtime-scene-resolvers.d.ts.map +1 -0
  280. package/dist/runtime-scene-resolvers.js +40 -0
  281. package/dist/runtime-scene-resolvers.js.map +1 -0
  282. package/dist/scene-artifact-types.d.ts +383 -0
  283. package/dist/scene-artifact-types.d.ts.map +1 -0
  284. package/dist/scene-artifact-types.js +2 -0
  285. package/dist/scene-artifact-types.js.map +1 -0
  286. package/dist/scene-artifact-validation.d.ts +19 -0
  287. package/dist/scene-artifact-validation.d.ts.map +1 -0
  288. package/dist/scene-artifact-validation.js +1352 -0
  289. package/dist/scene-artifact-validation.js.map +1 -0
  290. package/dist/static-shadow-artifact.d.ts +131 -0
  291. package/dist/static-shadow-artifact.d.ts.map +1 -0
  292. package/dist/static-shadow-artifact.js +327 -0
  293. package/dist/static-shadow-artifact.js.map +1 -0
  294. package/package.json +9 -1
@@ -0,0 +1,645 @@
1
+ import { Vector3 } from '@babylonjs/core/Maths/math.vector.js';
2
+ import { Texture } from '@babylonjs/core/Materials/Textures/texture.js';
3
+ import { Mesh } from '@babylonjs/core/Meshes/mesh.js';
4
+ import { VertexData } from '@babylonjs/core/Meshes/mesh.vertexData.js';
5
+ import { createStaticProjectedShadowSdfMaterial, markStaticProjectedShadowInternal, STATIC_PROJECTED_SHADOW_ALPHA_INDEX, } from './static-projected-shadow-rendering.js';
6
+ import { DEFAULT_STATIC_PROJECTED_SHADOW_OPTIONS, } from './types.js';
7
+ export function createStaticProjectedShadowArtifactSystem(scene, artifact, options = {}) {
8
+ return new BabylonStaticProjectedShadowArtifactSystem(scene, artifact, options);
9
+ }
10
+ class BabylonStaticProjectedShadowArtifactSystem {
11
+ scene;
12
+ artifact;
13
+ options;
14
+ pages = new Map();
15
+ loadedTextureIds = new Set();
16
+ bindingSyncObserver = null;
17
+ textureLoadEpoch = 0;
18
+ initialized = false;
19
+ diagnostics = {
20
+ status: 'missing',
21
+ reason: 'Static shadow artifact is missing.',
22
+ chunkCount: 0,
23
+ textureCount: 0,
24
+ };
25
+ constructor(scene, artifact, options) {
26
+ this.scene = scene;
27
+ this.artifact = artifact ?? null;
28
+ this.options = resolveStaticProjectedShadowArtifactOptions(options);
29
+ }
30
+ initialize() {
31
+ if (this.initialized)
32
+ return;
33
+ this.initialized = true;
34
+ this.rebuild();
35
+ }
36
+ setArtifact(artifact) {
37
+ this.artifact = artifact ?? null;
38
+ this.rebuild();
39
+ }
40
+ setOptions(options) {
41
+ this.options = resolveStaticProjectedShadowArtifactOptions(options, this.options);
42
+ this.rebuild();
43
+ }
44
+ getArtifact() {
45
+ return this.artifact;
46
+ }
47
+ getDiagnostics() {
48
+ return { ...this.diagnostics };
49
+ }
50
+ getChunkCount() {
51
+ return [...this.pages.values()].reduce((sum, page) => sum + page.chunkIds.length, 0);
52
+ }
53
+ dispose() {
54
+ this.textureLoadEpoch += 1;
55
+ this.loadedTextureIds.clear();
56
+ if (this.bindingSyncObserver) {
57
+ this.scene.onBeforeRenderObservable.remove(this.bindingSyncObserver);
58
+ this.bindingSyncObserver = null;
59
+ }
60
+ this.disposeChunks();
61
+ this.initialized = false;
62
+ this.diagnostics = {
63
+ status: 'missing',
64
+ reason: 'Static shadow artifact is missing.',
65
+ chunkCount: 0,
66
+ textureCount: 0,
67
+ };
68
+ }
69
+ rebuild() {
70
+ if (!this.initialized)
71
+ return;
72
+ this.textureLoadEpoch += 1;
73
+ this.loadedTextureIds.clear();
74
+ this.disposeChunks();
75
+ if (!this.options.enabled) {
76
+ this.setBindingSyncEnabled(false);
77
+ this.diagnostics = {
78
+ status: 'disabled',
79
+ reason: 'Static projected shadows are disabled.',
80
+ chunkCount: 0,
81
+ textureCount: 0,
82
+ };
83
+ return;
84
+ }
85
+ if (!this.artifact) {
86
+ this.setBindingSyncEnabled(false);
87
+ this.diagnostics = {
88
+ status: 'missing',
89
+ reason: 'Static shadow artifact is missing.',
90
+ chunkCount: 0,
91
+ textureCount: 0,
92
+ };
93
+ return;
94
+ }
95
+ const artifactDiagnostic = diagnoseStaticProjectedShadowArtifact(this.artifact, this.options.expectedHashes);
96
+ if (artifactDiagnostic.status !== 'loaded') {
97
+ this.setBindingSyncEnabled(false);
98
+ this.diagnostics = artifactDiagnostic;
99
+ return;
100
+ }
101
+ const sdfRadiusPx = readFiniteNumberWithFallback(this.artifact.stats?.sdfRadiusPx, DEFAULT_STATIC_PROJECTED_SHADOW_OPTIONS.bake.sdfRadiusPx);
102
+ for (const page of this.artifact.pages) {
103
+ const rendered = this.createAtlasPage(page, this.artifact.chunks.filter(chunk => chunk.pageId === page.id), sdfRadiusPx);
104
+ if (rendered)
105
+ this.pages.set(rendered.id, rendered);
106
+ }
107
+ const renderedChunkCount = [...this.pages.values()].reduce((sum, page) => sum + page.chunkIds.length, 0);
108
+ this.diagnostics = {
109
+ status: 'loaded',
110
+ reason: null,
111
+ chunkCount: renderedChunkCount,
112
+ textureCount: this.pages.size,
113
+ ...createArtifactDiagnosticStats(this.artifact, 'loaded'),
114
+ sourceHash: this.artifact.sourceHash,
115
+ lightHash: this.artifact.lightHash,
116
+ profileHash: this.artifact.profileHash,
117
+ expectedSourceHash: this.options.expectedHashes?.sourceHash ?? null,
118
+ expectedLightHash: this.options.expectedHashes?.lightHash ?? null,
119
+ expectedProfileHash: this.options.expectedHashes?.profileHash ?? null,
120
+ };
121
+ this.refreshBindings();
122
+ this.setBindingSyncEnabled(this.hasBindings());
123
+ }
124
+ refreshBindings() {
125
+ for (const page of this.pages.values()) {
126
+ const visible = page.bindings.length === 0
127
+ ? true
128
+ : page.bindings.some(binding => resolveBindingVisibility(this.scene, binding));
129
+ page.mesh.setEnabled(visible);
130
+ }
131
+ }
132
+ createAtlasPage(page, chunks, sdfRadiusPx) {
133
+ const textureDataUrl = readPngDataUrl(page.sdfTextureDataUrl);
134
+ if (!textureDataUrl || chunks.length === 0)
135
+ return null;
136
+ const name = `staticProjectedArtifact_${sanitizeName(page.id)}`;
137
+ const texture = new Texture(textureDataUrl, this.scene, true, false, Texture.BILINEAR_SAMPLINGMODE);
138
+ texture.name = `${name}_staticProjectedShadowSdfAtlas`;
139
+ texture.hasAlpha = true;
140
+ texture.wrapU = Texture.CLAMP_ADDRESSMODE;
141
+ texture.wrapV = Texture.CLAMP_ADDRESSMODE;
142
+ texture.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);
143
+ this.observeTextureReady(page.id, texture, this.textureLoadEpoch);
144
+ const material = createStaticProjectedShadowSdfMaterial(name, this.scene, texture, {
145
+ color: this.options.appearance.color,
146
+ blur: this.options.bake.blur,
147
+ sdfRadiusPx,
148
+ });
149
+ const mesh = this.createAtlasMesh(`${name}_staticProjectedShadowAtlas`, chunks);
150
+ if (!mesh) {
151
+ texture.dispose();
152
+ material.dispose();
153
+ return null;
154
+ }
155
+ mesh.material = material;
156
+ const bindings = chunks.map(readStaticProjectedShadowArtifactBinding).filter((binding) => !!binding);
157
+ if (bindings.length > 0) {
158
+ mesh.metadata = {
159
+ ...(isRecord(mesh.metadata) ? mesh.metadata : {}),
160
+ staticProjectedShadowBindings: bindings.map(cloneStaticProjectedShadowArtifactBinding),
161
+ };
162
+ }
163
+ return {
164
+ id: page.id,
165
+ mesh,
166
+ material,
167
+ texture,
168
+ chunkIds: chunks.map(chunk => chunk.id),
169
+ bindings,
170
+ };
171
+ }
172
+ createAtlasMesh(name, chunks) {
173
+ const positions = [];
174
+ const normals = [];
175
+ const uvs = [];
176
+ const indices = [];
177
+ for (const chunk of chunks) {
178
+ const bounds = readChunkBounds(chunk);
179
+ if (!bounds)
180
+ continue;
181
+ const base = positions.length / 3;
182
+ positions.push(bounds.minX, bounds.center.y, bounds.minZ, bounds.maxX, bounds.center.y, bounds.minZ, bounds.maxX, bounds.center.y, bounds.maxZ, bounds.minX, bounds.center.y, bounds.maxZ);
183
+ normals.push(0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0);
184
+ uvs.push(chunk.atlasUv.u0, chunk.atlasUv.v0, chunk.atlasUv.u1, chunk.atlasUv.v0, chunk.atlasUv.u1, chunk.atlasUv.v1, chunk.atlasUv.u0, chunk.atlasUv.v1);
185
+ indices.push(base, base + 1, base + 2, base, base + 2, base + 3);
186
+ }
187
+ if (positions.length === 0)
188
+ return null;
189
+ const mesh = new Mesh(name, this.scene);
190
+ const vertexData = new VertexData();
191
+ vertexData.positions = positions;
192
+ vertexData.normals = normals;
193
+ vertexData.uvs = uvs;
194
+ vertexData.indices = indices;
195
+ vertexData.applyToMesh(mesh);
196
+ mesh.isPickable = false;
197
+ mesh.alphaIndex = STATIC_PROJECTED_SHADOW_ALPHA_INDEX;
198
+ markStaticProjectedShadowInternal(mesh);
199
+ return mesh;
200
+ }
201
+ observeTextureReady(textureId, texture, epoch) {
202
+ const notify = () => {
203
+ if (epoch !== this.textureLoadEpoch)
204
+ return;
205
+ if (this.loadedTextureIds.has(textureId))
206
+ return;
207
+ this.loadedTextureIds.add(textureId);
208
+ this.options.onTextureReady?.(createTextureReadyEvent({
209
+ textureId,
210
+ texture,
211
+ loadedTextureCount: this.loadedTextureIds.size,
212
+ totalTextureCount: this.getTextureCount(),
213
+ }));
214
+ };
215
+ const scheduleNotify = () => {
216
+ void Promise.resolve().then(notify);
217
+ };
218
+ if (typeof texture.isReady === 'function' && texture.isReady()) {
219
+ scheduleNotify();
220
+ return;
221
+ }
222
+ const observable = texture.onLoadObservable;
223
+ if (observable?.addOnce) {
224
+ observable.addOnce(scheduleNotify);
225
+ return;
226
+ }
227
+ scheduleNotify();
228
+ }
229
+ disposeChunks() {
230
+ for (const page of this.pages.values()) {
231
+ if (!page.mesh.isDisposed())
232
+ page.mesh.dispose();
233
+ page.texture.dispose();
234
+ page.material.dispose();
235
+ }
236
+ this.pages.clear();
237
+ }
238
+ hasBindings() {
239
+ for (const page of this.pages.values()) {
240
+ if (page.bindings.length > 0)
241
+ return true;
242
+ }
243
+ return false;
244
+ }
245
+ setBindingSyncEnabled(enabled) {
246
+ if (enabled) {
247
+ if (!this.bindingSyncObserver) {
248
+ this.bindingSyncObserver = this.scene.onBeforeRenderObservable.add(() => this.refreshBindings());
249
+ }
250
+ return;
251
+ }
252
+ if (this.bindingSyncObserver) {
253
+ this.scene.onBeforeRenderObservable.remove(this.bindingSyncObserver);
254
+ this.bindingSyncObserver = null;
255
+ }
256
+ }
257
+ getTextureCount() {
258
+ return this.pages.size;
259
+ }
260
+ }
261
+ function createTextureReadyEvent(input) {
262
+ return {
263
+ chunkId: input.textureId,
264
+ textureName: input.texture.name,
265
+ loadedTextureCount: input.loadedTextureCount,
266
+ totalTextureCount: input.totalTextureCount,
267
+ };
268
+ }
269
+ function resolveStaticProjectedShadowArtifactOptions(options = {}, fallback = {
270
+ enabled: DEFAULT_STATIC_PROJECTED_SHADOW_OPTIONS.enabled,
271
+ appearance: DEFAULT_STATIC_PROJECTED_SHADOW_OPTIONS.appearance,
272
+ bake: { blur: DEFAULT_STATIC_PROJECTED_SHADOW_OPTIONS.bake.blur },
273
+ expectedHashes: null,
274
+ onTextureReady: undefined,
275
+ debug: DEFAULT_STATIC_PROJECTED_SHADOW_OPTIONS.debug,
276
+ }) {
277
+ return {
278
+ enabled: readBoolean(options.enabled, fallback.enabled),
279
+ appearance: {
280
+ color: {
281
+ r: readClampedNumber(options.appearance?.color.r, fallback.appearance.color.r, 0, 1),
282
+ g: readClampedNumber(options.appearance?.color.g, fallback.appearance.color.g, 0, 1),
283
+ b: readClampedNumber(options.appearance?.color.b, fallback.appearance.color.b, 0, 1),
284
+ a: readClampedNumber(options.appearance?.color.a, fallback.appearance.color.a, 0, 1),
285
+ },
286
+ },
287
+ bake: {
288
+ blur: readNonNegativeNumber(options.bake?.blur, fallback.bake.blur),
289
+ },
290
+ expectedHashes: readArtifactHashInput(options.expectedHashes, fallback.expectedHashes),
291
+ onTextureReady: options.onTextureReady ?? fallback.onTextureReady,
292
+ debug: readBoolean(options.debug, fallback.debug),
293
+ };
294
+ }
295
+ function diagnoseStaticProjectedShadowArtifact(artifact, expectedHashes) {
296
+ if (!Array.isArray(artifact.chunks) || artifact.version == null) {
297
+ return createArtifactDiagnostic('invalid', 'Static shadow artifact is invalid.', artifact, expectedHashes);
298
+ }
299
+ const shapeError = validateStaticProjectedShadowArtifactShape(artifact);
300
+ if (shapeError) {
301
+ return createArtifactDiagnostic('invalid', shapeError, artifact, expectedHashes);
302
+ }
303
+ if (!readNonEmptyString(artifact.sourceHash) || !readNonEmptyString(artifact.lightHash) || !readNonEmptyString(artifact.profileHash)) {
304
+ return createArtifactDiagnostic('invalid', 'Static shadow artifact is missing required hashes.', artifact, expectedHashes);
305
+ }
306
+ const chunkMismatch = findStaticProjectedShadowArtifactChunkHashMismatch(artifact);
307
+ if (chunkMismatch) {
308
+ return createArtifactDiagnostic('invalid', `Static shadow artifact chunk hash mismatch: ${chunkMismatch}.`, artifact, expectedHashes);
309
+ }
310
+ const mismatches = [
311
+ expectedHashes?.sourceHash && expectedHashes.sourceHash !== artifact.sourceHash ? 'source' : null,
312
+ expectedHashes?.lightHash && expectedHashes.lightHash !== artifact.lightHash ? 'light' : null,
313
+ expectedHashes?.profileHash && expectedHashes.profileHash !== artifact.profileHash ? 'profile' : null,
314
+ ].filter((entry) => !!entry);
315
+ if (mismatches.length > 0) {
316
+ return createArtifactDiagnostic('out-of-date', `Static shadow artifact hash mismatch: ${mismatches.join(', ')}.`, artifact, expectedHashes);
317
+ }
318
+ return createArtifactDiagnostic('loaded', null, artifact, expectedHashes);
319
+ }
320
+ function validateStaticProjectedShadowArtifactShape(artifact) {
321
+ if (artifact.version !== 2 || artifact.format !== 'sdf-atlas' || !Array.isArray(artifact.pages)) {
322
+ return 'Static shadow artifact is invalid.';
323
+ }
324
+ const pages = new Map();
325
+ for (const pageValue of artifact.pages) {
326
+ if (!isRecord(pageValue))
327
+ return 'Static shadow artifact atlas page is invalid.';
328
+ const page = pageValue;
329
+ const pageId = readNonEmptyString(page.id);
330
+ if (!pageId || pages.has(pageId) || !readPngDataUrl(page.sdfTextureDataUrl)) {
331
+ return 'Static shadow artifact atlas page is invalid.';
332
+ }
333
+ if (!Number.isInteger(page.width) || page.width <= 0 || !Number.isInteger(page.height) || page.height <= 0) {
334
+ return 'Static shadow artifact atlas page is invalid.';
335
+ }
336
+ pages.set(pageId, page);
337
+ }
338
+ const chunkIds = new Set();
339
+ for (const chunkValue of artifact.chunks) {
340
+ if (!isRecord(chunkValue))
341
+ return 'Static shadow artifact chunk is invalid.';
342
+ const chunk = chunkValue;
343
+ const chunkId = readNonEmptyString(chunk.id);
344
+ if (!chunkId || chunkIds.has(chunkId))
345
+ return 'Static shadow artifact chunk is invalid.';
346
+ chunkIds.add(chunkId);
347
+ const page = pages.get(readNonEmptyString(chunk.pageId) ?? '');
348
+ if (!page)
349
+ return 'Static shadow artifact chunk references a missing atlas page.';
350
+ if (!readChunkBounds(chunk))
351
+ return 'Static shadow artifact chunk bounds are invalid.';
352
+ if (!isValidAtlasRect(chunk, page))
353
+ return 'Static shadow artifact chunk atlas rect is invalid.';
354
+ if (!isValidAtlasUv(chunk))
355
+ return 'Static shadow artifact chunk atlas UV is invalid.';
356
+ if (!isValidSourceNodeIds(chunk.sourceNodeIds))
357
+ return 'Static shadow artifact chunk source ids are invalid.';
358
+ }
359
+ return null;
360
+ }
361
+ function isValidAtlasRect(chunk, page) {
362
+ const rect = chunk.atlasRect;
363
+ if (!rect)
364
+ return false;
365
+ if (!Number.isInteger(rect.x) || rect.x < 0 || !Number.isInteger(rect.y) || rect.y < 0)
366
+ return false;
367
+ if (!Number.isInteger(rect.width) || rect.width <= 0 || !Number.isInteger(rect.height) || rect.height <= 0)
368
+ return false;
369
+ return rect.x + rect.width <= page.width && rect.y + rect.height <= page.height;
370
+ }
371
+ function isValidAtlasUv(chunk) {
372
+ const uv = chunk.atlasUv;
373
+ if (!uv)
374
+ return false;
375
+ const values = [uv.u0, uv.v0, uv.u1, uv.v1];
376
+ if (!values.every(value => Number.isFinite(value) && value >= 0 && value <= 1))
377
+ return false;
378
+ return uv.u1 > uv.u0 && uv.v1 > uv.v0;
379
+ }
380
+ function isValidSourceNodeIds(value) {
381
+ return Array.isArray(value) && value.length > 0 && value.every(entry => !!readNonEmptyString(entry));
382
+ }
383
+ function findStaticProjectedShadowArtifactChunkHashMismatch(artifact) {
384
+ for (const chunk of artifact.chunks) {
385
+ const chunkId = readNonEmptyString(chunk.id) ?? '(unknown)';
386
+ if (createSourceNodeIdsHash(chunk.sourceNodeIds) !== chunk.sourceHash)
387
+ return `${chunkId}: source`;
388
+ if (chunk.lightHash !== artifact.lightHash)
389
+ return `${chunkId}: light`;
390
+ if (chunk.profileHash !== artifact.profileHash)
391
+ return `${chunkId}: profile`;
392
+ }
393
+ return null;
394
+ }
395
+ function createArtifactDiagnostic(status, reason, artifact, expectedHashes) {
396
+ return {
397
+ status,
398
+ reason,
399
+ chunkCount: status === 'loaded' ? artifact.chunks.length : 0,
400
+ textureCount: 0,
401
+ ...createArtifactDiagnosticStats(artifact, status),
402
+ sourceHash: readNonEmptyString(artifact.sourceHash),
403
+ lightHash: readNonEmptyString(artifact.lightHash),
404
+ profileHash: readNonEmptyString(artifact.profileHash),
405
+ expectedSourceHash: expectedHashes?.sourceHash ?? null,
406
+ expectedLightHash: expectedHashes?.lightHash ?? null,
407
+ expectedProfileHash: expectedHashes?.profileHash ?? null,
408
+ };
409
+ }
410
+ function createArtifactDiagnosticStats(artifact, status) {
411
+ if (status === 'invalid') {
412
+ return {
413
+ sourceRootCount: 0,
414
+ sourceMeshCount: null,
415
+ attemptedChunkCount: null,
416
+ skippedChunkCount: null,
417
+ pageCount: null,
418
+ resolution: null,
419
+ chunkSize: null,
420
+ atlasSize: null,
421
+ atlasUsedPixels: null,
422
+ atlasAllocatedPixels: null,
423
+ atlasOccupancy: null,
424
+ texelsPerMeter: null,
425
+ effectiveTexelsPerMeter: null,
426
+ maxAtlasPages: null,
427
+ sdfRadiusPx: null,
428
+ spatialChunkSize: null,
429
+ effectiveSpatialChunkSize: null,
430
+ targetChunkCount: null,
431
+ bakedChunkCount: null,
432
+ reusedChunkCount: null,
433
+ durationMs: null,
434
+ stats: null,
435
+ };
436
+ }
437
+ const stats = artifact.stats ?? null;
438
+ const pageCount = stats?.pageCount ?? artifact.pages.length;
439
+ return {
440
+ sourceRootCount: stats?.sourceRootCount ?? uniqueArtifactSourceNodeIds(artifact).length,
441
+ sourceMeshCount: stats?.sourceMeshCount ?? null,
442
+ attemptedChunkCount: stats?.attemptedChunkCount ?? artifact.chunks.length,
443
+ skippedChunkCount: stats?.skippedChunkCount ?? null,
444
+ pageCount,
445
+ resolution: stats?.resolution ?? null,
446
+ chunkSize: stats?.chunkSize ?? null,
447
+ atlasSize: stats?.atlasSize ?? null,
448
+ atlasUsedPixels: stats?.atlasUsedPixels ?? null,
449
+ atlasAllocatedPixels: stats?.atlasAllocatedPixels ?? null,
450
+ atlasOccupancy: stats?.atlasOccupancy ?? null,
451
+ texelsPerMeter: stats?.texelsPerMeter ?? null,
452
+ effectiveTexelsPerMeter: stats?.effectiveTexelsPerMeter ?? null,
453
+ maxAtlasPages: stats?.maxAtlasPages ?? null,
454
+ sdfRadiusPx: stats?.sdfRadiusPx ?? null,
455
+ spatialChunkSize: stats?.spatialChunkSize ?? null,
456
+ effectiveSpatialChunkSize: stats?.effectiveSpatialChunkSize ?? null,
457
+ targetChunkCount: stats?.targetChunkCount ?? null,
458
+ bakedChunkCount: stats?.bakedChunkCount ?? null,
459
+ reusedChunkCount: stats?.reusedChunkCount ?? null,
460
+ durationMs: stats?.durationMs ?? null,
461
+ stats,
462
+ };
463
+ }
464
+ function uniqueArtifactSourceNodeIds(artifact) {
465
+ return [...new Set(artifact.chunks.flatMap(chunk => Array.isArray(chunk.sourceNodeIds) ? chunk.sourceNodeIds : []))];
466
+ }
467
+ function readChunkBounds(chunk) {
468
+ const minX = readFiniteNumber(chunk.bounds?.minX);
469
+ const maxX = readFiniteNumber(chunk.bounds?.maxX);
470
+ const minZ = readFiniteNumber(chunk.bounds?.minZ);
471
+ const maxZ = readFiniteNumber(chunk.bounds?.maxZ);
472
+ const y = readFiniteNumber(chunk.bounds?.y);
473
+ if (minX == null || maxX == null || minZ == null || maxZ == null || y == null)
474
+ return null;
475
+ if (maxX <= minX || maxZ <= minZ)
476
+ return null;
477
+ return {
478
+ center: new Vector3((minX + maxX) * 0.5, y, (minZ + maxZ) * 0.5),
479
+ minX,
480
+ maxX,
481
+ minZ,
482
+ maxZ,
483
+ };
484
+ }
485
+ function readPngDataUrl(value) {
486
+ return typeof value === 'string' && /^data:image\/png[;,]/i.test(value.trim())
487
+ ? value.trim()
488
+ : null;
489
+ }
490
+ function readArtifactHashInput(value, fallback) {
491
+ if (value === null)
492
+ return null;
493
+ if (!value || typeof value !== 'object' || Array.isArray(value))
494
+ return fallback;
495
+ const hashes = value;
496
+ const sourceHash = readNonEmptyString(hashes.sourceHash);
497
+ const lightHash = readNonEmptyString(hashes.lightHash);
498
+ const profileHash = readNonEmptyString(hashes.profileHash);
499
+ if (!sourceHash && !lightHash && !profileHash)
500
+ return null;
501
+ return {
502
+ ...(sourceHash ? { sourceHash } : {}),
503
+ ...(lightHash ? { lightHash } : {}),
504
+ ...(profileHash ? { profileHash } : {}),
505
+ };
506
+ }
507
+ function readStaticProjectedShadowArtifactBinding(chunk) {
508
+ const binding = chunk.binding;
509
+ if (!isRecord(binding))
510
+ return null;
511
+ const id = readNonEmptyString(binding.id);
512
+ const ownerCasterId = readNonEmptyString(binding.ownerCasterId);
513
+ const receiverId = readNonEmptyString(binding.receiverId);
514
+ const generatedAt = readNonEmptyString(binding.generatedAt);
515
+ const sourceHash = readNonEmptyString(binding.sourceHash);
516
+ if (!id
517
+ || !ownerCasterId
518
+ || !receiverId
519
+ || !generatedAt
520
+ || !sourceHash
521
+ || binding.visibleWhenOwnerVisible !== true
522
+ || binding.staleWhenOwnerTransformChanges !== true
523
+ || binding.staleWhenLightChanges !== true) {
524
+ return null;
525
+ }
526
+ const lightId = readNonEmptyString(binding.lightId);
527
+ const textureAssetId = readNonEmptyString(binding.textureAssetId);
528
+ const projectionNodeId = readNonEmptyString(binding.projectionNodeId);
529
+ return {
530
+ id,
531
+ ownerCasterId,
532
+ receiverId,
533
+ ...(lightId ? { lightId } : {}),
534
+ ...(textureAssetId ? { textureAssetId } : {}),
535
+ ...(projectionNodeId ? { projectionNodeId } : {}),
536
+ visibleWhenOwnerVisible: true,
537
+ staleWhenOwnerTransformChanges: true,
538
+ staleWhenLightChanges: true,
539
+ generatedAt,
540
+ sourceHash,
541
+ };
542
+ }
543
+ function cloneStaticProjectedShadowArtifactBinding(binding) {
544
+ return {
545
+ id: binding.id,
546
+ ownerCasterId: binding.ownerCasterId,
547
+ receiverId: binding.receiverId,
548
+ ...(binding.lightId ? { lightId: binding.lightId } : {}),
549
+ ...(binding.textureAssetId ? { textureAssetId: binding.textureAssetId } : {}),
550
+ ...(binding.projectionNodeId ? { projectionNodeId: binding.projectionNodeId } : {}),
551
+ visibleWhenOwnerVisible: true,
552
+ staleWhenOwnerTransformChanges: true,
553
+ staleWhenLightChanges: true,
554
+ generatedAt: binding.generatedAt,
555
+ sourceHash: binding.sourceHash,
556
+ };
557
+ }
558
+ function resolveBindingVisibility(scene, binding) {
559
+ if (!binding)
560
+ return true;
561
+ const owner = findSceneNode(scene, binding.ownerCasterId) ?? (binding.projectionNodeId ? findSceneNode(scene, binding.projectionNodeId) : null);
562
+ return !!owner && isSceneNodeEnabledAndVisible(owner);
563
+ }
564
+ function findSceneNode(scene, idOrName) {
565
+ const sceneWithLookup = scene;
566
+ const byId = sceneWithLookup.getNodeById?.(idOrName);
567
+ if (byId)
568
+ return byId;
569
+ const byName = sceneWithLookup.getNodeByName?.(idOrName);
570
+ if (byName)
571
+ return byName;
572
+ const collections = [
573
+ scene.meshes,
574
+ scene.transformNodes,
575
+ scene.lights,
576
+ ];
577
+ for (const collection of collections) {
578
+ const match = collection.find(node => {
579
+ const candidate = node;
580
+ return candidate.id === idOrName || candidate.name === idOrName;
581
+ });
582
+ if (match)
583
+ return match;
584
+ }
585
+ return null;
586
+ }
587
+ function isSceneNodeEnabledAndVisible(node) {
588
+ let current = node;
589
+ while (current && typeof current === 'object') {
590
+ const candidate = current;
591
+ if (typeof candidate.isEnabled === 'function' && !candidate.isEnabled())
592
+ return false;
593
+ if (candidate.isVisible === false)
594
+ return false;
595
+ current = candidate.parent;
596
+ }
597
+ return true;
598
+ }
599
+ function readNonEmptyString(value) {
600
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
601
+ }
602
+ function isRecord(value) {
603
+ return !!value && typeof value === 'object' && !Array.isArray(value);
604
+ }
605
+ function createSourceNodeIdsHash(sourceNodeIds) {
606
+ return createFnv1aHash([...new Set(sourceNodeIds)]);
607
+ }
608
+ function createFnv1aHash(value) {
609
+ const text = stableStringify(value);
610
+ let hash = 0x811c9dc5;
611
+ for (let index = 0; index < text.length; index += 1) {
612
+ hash ^= text.charCodeAt(index);
613
+ hash = Math.imul(hash, 0x01000193);
614
+ }
615
+ return `fnv1a:${(hash >>> 0).toString(16).padStart(8, '0')}`;
616
+ }
617
+ function stableStringify(value) {
618
+ if (value == null || typeof value !== 'object')
619
+ return JSON.stringify(value);
620
+ if (Array.isArray(value))
621
+ return `[${value.map(stableStringify).join(',')}]`;
622
+ const entries = Object.entries(value)
623
+ .sort(([left], [right]) => left.localeCompare(right));
624
+ return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${stableStringify(entry)}`).join(',')}}`;
625
+ }
626
+ function sanitizeName(value) {
627
+ return value.trim().replace(/[^a-z0-9_-]+/gi, '_') || 'chunk';
628
+ }
629
+ function readBoolean(value, fallback) {
630
+ return typeof value === 'boolean' ? value : fallback;
631
+ }
632
+ function readFiniteNumber(value) {
633
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
634
+ }
635
+ function readFiniteNumberWithFallback(value, fallback) {
636
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
637
+ }
638
+ function readNonNegativeNumber(value, fallback) {
639
+ const next = readFiniteNumberWithFallback(value, fallback);
640
+ return next >= 0 ? next : fallback;
641
+ }
642
+ function readClampedNumber(value, fallback, min, max) {
643
+ return Math.min(max, Math.max(min, readFiniteNumberWithFallback(value, fallback)));
644
+ }
645
+ //# sourceMappingURL=static-projected-shadow-artifact-system.js.map