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

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 (297) 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 +706 -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/lighting.d.ts.map +1 -1
  203. package/dist/lighting.js +5 -1
  204. package/dist/lighting.js.map +1 -1
  205. package/dist/material-owner.d.ts +128 -0
  206. package/dist/material-owner.d.ts.map +1 -0
  207. package/dist/material-owner.js +434 -0
  208. package/dist/material-owner.js.map +1 -0
  209. package/dist/material-profile.d.ts +62 -0
  210. package/dist/material-profile.d.ts.map +1 -0
  211. package/dist/material-profile.js +132 -0
  212. package/dist/material-profile.js.map +1 -0
  213. package/dist/rendering/index.d.ts +14 -0
  214. package/dist/rendering/index.d.ts.map +1 -0
  215. package/dist/rendering/index.js +12 -0
  216. package/dist/rendering/index.js.map +1 -0
  217. package/dist/rendering/rendering-profile-types.d.ts +322 -0
  218. package/dist/rendering/rendering-profile-types.d.ts.map +1 -0
  219. package/dist/rendering/rendering-profile-types.js +2 -0
  220. package/dist/rendering/rendering-profile-types.js.map +1 -0
  221. package/dist/rendering/rendering-profile-validation.d.ts +2 -0
  222. package/dist/rendering/rendering-profile-validation.d.ts.map +1 -0
  223. package/dist/rendering/rendering-profile-validation.js +364 -0
  224. package/dist/rendering/rendering-profile-validation.js.map +1 -0
  225. package/dist/rendering/rendering-profile-values.d.ts +19 -0
  226. package/dist/rendering/rendering-profile-values.d.ts.map +1 -0
  227. package/dist/rendering/rendering-profile-values.js +79 -0
  228. package/dist/rendering/rendering-profile-values.js.map +1 -0
  229. package/dist/rendering/rendering-profile.d.ts +15 -0
  230. package/dist/rendering/rendering-profile.d.ts.map +1 -0
  231. package/dist/rendering/rendering-profile.js +442 -0
  232. package/dist/rendering/rendering-profile.js.map +1 -0
  233. package/dist/rendering/shadow-map-experiment-depth.d.ts +63 -0
  234. package/dist/rendering/shadow-map-experiment-depth.d.ts.map +1 -0
  235. package/dist/rendering/shadow-map-experiment-depth.js +186 -0
  236. package/dist/rendering/shadow-map-experiment-depth.js.map +1 -0
  237. package/dist/rendering/shadow-map-experiment-lifecycle.d.ts +94 -0
  238. package/dist/rendering/shadow-map-experiment-lifecycle.d.ts.map +1 -0
  239. package/dist/rendering/shadow-map-experiment-lifecycle.js +407 -0
  240. package/dist/rendering/shadow-map-experiment-lifecycle.js.map +1 -0
  241. package/dist/rendering/shadow-map-experiment.d.ts +189 -0
  242. package/dist/rendering/shadow-map-experiment.d.ts.map +1 -0
  243. package/dist/rendering/shadow-map-experiment.js +549 -0
  244. package/dist/rendering/shadow-map-experiment.js.map +1 -0
  245. package/dist/rendering/shadow-quality.d.ts +5 -0
  246. package/dist/rendering/shadow-quality.d.ts.map +1 -0
  247. package/dist/rendering/shadow-quality.js +83 -0
  248. package/dist/rendering/shadow-quality.js.map +1 -0
  249. package/dist/rendering/shadow-runtime.d.ts +59 -0
  250. package/dist/rendering/shadow-runtime.d.ts.map +1 -0
  251. package/dist/rendering/shadow-runtime.js +378 -0
  252. package/dist/rendering/shadow-runtime.js.map +1 -0
  253. package/dist/rendering/shadow-settings.d.ts +15 -0
  254. package/dist/rendering/shadow-settings.d.ts.map +1 -0
  255. package/dist/rendering/shadow-settings.js +129 -0
  256. package/dist/rendering/shadow-settings.js.map +1 -0
  257. package/dist/rendering/shadow-types.d.ts +99 -0
  258. package/dist/rendering/shadow-types.d.ts.map +1 -0
  259. package/dist/rendering/shadow-types.js +5 -0
  260. package/dist/rendering/shadow-types.js.map +1 -0
  261. package/dist/rendering/shadow-validation.d.ts +3 -0
  262. package/dist/rendering/shadow-validation.d.ts.map +1 -0
  263. package/dist/rendering/shadow-validation.js +166 -0
  264. package/dist/rendering/shadow-validation.js.map +1 -0
  265. package/dist/rendering/value.d.ts +2 -0
  266. package/dist/rendering/value.d.ts.map +1 -0
  267. package/dist/rendering/value.js +6 -0
  268. package/dist/rendering/value.js.map +1 -0
  269. package/dist/runtime-data-token.d.ts +4 -0
  270. package/dist/runtime-data-token.d.ts.map +1 -0
  271. package/dist/runtime-data-token.js +4 -0
  272. package/dist/runtime-data-token.js.map +1 -0
  273. package/dist/runtime-data-types.d.ts +83 -0
  274. package/dist/runtime-data-types.d.ts.map +1 -0
  275. package/dist/runtime-data-types.js +2 -0
  276. package/dist/runtime-data-types.js.map +1 -0
  277. package/dist/runtime-data.d.ts +18 -0
  278. package/dist/runtime-data.d.ts.map +1 -0
  279. package/dist/runtime-data.js +301 -0
  280. package/dist/runtime-data.js.map +1 -0
  281. package/dist/runtime-scene-resolvers.d.ts +37 -0
  282. package/dist/runtime-scene-resolvers.d.ts.map +1 -0
  283. package/dist/runtime-scene-resolvers.js +40 -0
  284. package/dist/runtime-scene-resolvers.js.map +1 -0
  285. package/dist/scene-artifact-types.d.ts +383 -0
  286. package/dist/scene-artifact-types.d.ts.map +1 -0
  287. package/dist/scene-artifact-types.js +2 -0
  288. package/dist/scene-artifact-types.js.map +1 -0
  289. package/dist/scene-artifact-validation.d.ts +19 -0
  290. package/dist/scene-artifact-validation.d.ts.map +1 -0
  291. package/dist/scene-artifact-validation.js +1352 -0
  292. package/dist/scene-artifact-validation.js.map +1 -0
  293. package/dist/static-shadow-artifact.d.ts +131 -0
  294. package/dist/static-shadow-artifact.d.ts.map +1 -0
  295. package/dist/static-shadow-artifact.js +327 -0
  296. package/dist/static-shadow-artifact.js.map +1 -0
  297. 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