@3driseai/3drise-viewer 0.1.41 → 0.1.43

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 (414) hide show
  1. package/dist/animationsV2/ClipsRuntime.d.ts +16 -1
  2. package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
  3. package/dist/animationsV2/ClipsRuntime.js +144 -25
  4. package/dist/animationsV2/appliers.d.ts +9 -0
  5. package/dist/animationsV2/appliers.d.ts.map +1 -1
  6. package/dist/animationsV2/appliers.js +62 -2
  7. package/dist/animationsV2/clipUtils.d.ts +30 -0
  8. package/dist/animationsV2/clipUtils.d.ts.map +1 -1
  9. package/dist/animationsV2/clipUtils.js +163 -17
  10. package/dist/animationsV2/elementSettings.d.ts +5 -0
  11. package/dist/animationsV2/elementSettings.d.ts.map +1 -1
  12. package/dist/animationsV2/elementSettings.js +6 -3
  13. package/dist/animationsV2/sequenceUtils.js +4 -4
  14. package/dist/animationsV2/types.d.ts +23 -0
  15. package/dist/animationsV2/types.d.ts.map +1 -1
  16. package/dist/api/sceneHandle.js +2 -2
  17. package/dist/components/CreatedObject.d.ts +3 -0
  18. package/dist/components/CreatedObject.d.ts.map +1 -1
  19. package/dist/components/CreatedObject.js +6 -2
  20. package/dist/components/CustomPrimitive.d.ts.map +1 -1
  21. package/dist/components/CustomPrimitive.js +1 -10
  22. package/dist/components/EnvironmentManager.d.ts.map +1 -1
  23. package/dist/components/EnvironmentManager.js +11 -5
  24. package/dist/components/GeometryShape.d.ts +5 -2
  25. package/dist/components/GeometryShape.d.ts.map +1 -1
  26. package/dist/components/GeometryShape.js +71 -10
  27. package/dist/components/LandObject.d.ts.map +1 -1
  28. package/dist/components/LandObject.js +1 -1
  29. package/dist/components/LayoutInstances.d.ts +2 -1
  30. package/dist/components/LayoutInstances.d.ts.map +1 -1
  31. package/dist/components/LayoutInstances.js +39 -6
  32. package/dist/components/LightObject.d.ts.map +1 -1
  33. package/dist/components/LightObject.js +3 -0
  34. package/dist/components/ObjectNode.d.ts.map +1 -1
  35. package/dist/components/ObjectNode.js +62 -13
  36. package/dist/components/OceanBuilder.d.ts +2 -0
  37. package/dist/components/OceanBuilder.d.ts.map +1 -1
  38. package/dist/components/OceanBuilder.js +2 -1
  39. package/dist/components/RenderEffects.d.ts +8 -0
  40. package/dist/components/RenderEffects.d.ts.map +1 -0
  41. package/dist/components/RenderEffects.js +120 -0
  42. package/dist/components/SceneBuilder.d.ts.map +1 -1
  43. package/dist/components/SceneBuilder.js +18 -9
  44. package/dist/components/SportsObject.d.ts +9 -0
  45. package/dist/components/SportsObject.d.ts.map +1 -0
  46. package/dist/components/SportsObject.js +20 -0
  47. package/dist/components/UrbanObject.d.ts +9 -0
  48. package/dist/components/UrbanObject.d.ts.map +1 -0
  49. package/dist/components/UrbanObject.js +28 -0
  50. package/dist/components/VegetationObject.d.ts +9 -0
  51. package/dist/components/VegetationObject.d.ts.map +1 -0
  52. package/dist/components/VegetationObject.js +26 -0
  53. package/dist/components/WaterObject.d.ts +15 -0
  54. package/dist/components/WaterObject.d.ts.map +1 -0
  55. package/dist/components/WaterObject.js +29 -0
  56. package/dist/components/index.d.ts +7 -2
  57. package/dist/components/index.d.ts.map +1 -1
  58. package/dist/components/index.js +6 -1
  59. package/dist/components/land/LandPatch.d.ts +3 -1
  60. package/dist/components/land/LandPatch.d.ts.map +1 -1
  61. package/dist/components/land/LandPatch.js +80 -7
  62. package/dist/components/layout/InstancedLayout.d.ts +19 -0
  63. package/dist/components/layout/InstancedLayout.d.ts.map +1 -0
  64. package/dist/components/layout/InstancedLayout.js +154 -0
  65. package/dist/components/layout/LayoutGrounds.d.ts +19 -0
  66. package/dist/components/layout/LayoutGrounds.d.ts.map +1 -0
  67. package/dist/components/layout/LayoutGrounds.js +104 -0
  68. package/dist/components/layout/LinkProxies.d.ts +5 -0
  69. package/dist/components/layout/LinkProxies.d.ts.map +1 -0
  70. package/dist/components/layout/LinkProxies.js +51 -0
  71. package/dist/components/layout/LinkedSource.d.ts +14 -0
  72. package/dist/components/layout/LinkedSource.d.ts.map +1 -0
  73. package/dist/components/layout/LinkedSource.js +129 -0
  74. package/dist/components/projector/Projector.d.ts +14 -0
  75. package/dist/components/projector/Projector.d.ts.map +1 -0
  76. package/dist/components/projector/Projector.js +44 -0
  77. package/dist/components/projector/index.d.ts +4 -0
  78. package/dist/components/projector/index.d.ts.map +1 -0
  79. package/dist/components/projector/index.js +2 -0
  80. package/dist/components/projector/projectorCore.d.ts +19 -0
  81. package/dist/components/projector/projectorCore.d.ts.map +1 -0
  82. package/dist/components/projector/projectorCore.js +545 -0
  83. package/dist/components/sports/SportsBall.d.ts +9 -0
  84. package/dist/components/sports/SportsBall.d.ts.map +1 -0
  85. package/dist/components/sports/SportsBall.js +23 -0
  86. package/dist/components/sports/SportsCourt.d.ts +9 -0
  87. package/dist/components/sports/SportsCourt.d.ts.map +1 -0
  88. package/dist/components/sports/SportsCourt.js +23 -0
  89. package/dist/components/sports/SportsEquipment.d.ts +9 -0
  90. package/dist/components/sports/SportsEquipment.d.ts.map +1 -0
  91. package/dist/components/sports/SportsEquipment.js +23 -0
  92. package/dist/components/sports/SportsGoal.d.ts +9 -0
  93. package/dist/components/sports/SportsGoal.d.ts.map +1 -0
  94. package/dist/components/sports/SportsGoal.js +23 -0
  95. package/dist/components/sports/core/ball.d.ts +166 -0
  96. package/dist/components/sports/core/ball.d.ts.map +1 -0
  97. package/dist/components/sports/core/ball.js +402 -0
  98. package/dist/components/sports/core/court.d.ts +442 -0
  99. package/dist/components/sports/core/court.d.ts.map +1 -0
  100. package/dist/components/sports/core/court.js +658 -0
  101. package/dist/components/sports/core/equipment.d.ts +103 -0
  102. package/dist/components/sports/core/equipment.d.ts.map +1 -0
  103. package/dist/components/sports/core/equipment.js +403 -0
  104. package/dist/components/sports/core/goal.d.ts +98 -0
  105. package/dist/components/sports/core/goal.d.ts.map +1 -0
  106. package/dist/components/sports/core/goal.js +44 -0
  107. package/dist/components/sports/index.d.ts +11 -0
  108. package/dist/components/sports/index.d.ts.map +1 -0
  109. package/dist/components/sports/index.js +8 -0
  110. package/dist/components/sports/sportsCore.d.ts +195 -0
  111. package/dist/components/sports/sportsCore.d.ts.map +1 -0
  112. package/dist/components/sports/sportsCore.js +758 -0
  113. package/dist/components/sports/useSportsInstance.d.ts +35 -0
  114. package/dist/components/sports/useSportsInstance.d.ts.map +1 -0
  115. package/dist/components/sports/useSportsInstance.js +47 -0
  116. package/dist/components/terrain/TerrainSurface.d.ts.map +1 -1
  117. package/dist/components/terrain/TerrainSurface.js +14 -0
  118. package/dist/components/urban/UrbanBlock.d.ts +9 -0
  119. package/dist/components/urban/UrbanBlock.d.ts.map +1 -0
  120. package/dist/components/urban/UrbanBlock.js +23 -0
  121. package/dist/components/urban/UrbanBuilding.d.ts +9 -0
  122. package/dist/components/urban/UrbanBuilding.d.ts.map +1 -0
  123. package/dist/components/urban/UrbanBuilding.js +23 -0
  124. package/dist/components/urban/UrbanJunction.d.ts +9 -0
  125. package/dist/components/urban/UrbanJunction.d.ts.map +1 -0
  126. package/dist/components/urban/UrbanJunction.js +23 -0
  127. package/dist/components/urban/UrbanPark.d.ts +9 -0
  128. package/dist/components/urban/UrbanPark.d.ts.map +1 -0
  129. package/dist/components/urban/UrbanPark.js +23 -0
  130. package/dist/components/urban/UrbanParkingLot.d.ts +9 -0
  131. package/dist/components/urban/UrbanParkingLot.d.ts.map +1 -0
  132. package/dist/components/urban/UrbanParkingLot.js +23 -0
  133. package/dist/components/urban/UrbanPlaza.d.ts +9 -0
  134. package/dist/components/urban/UrbanPlaza.d.ts.map +1 -0
  135. package/dist/components/urban/UrbanPlaza.js +23 -0
  136. package/dist/components/urban/UrbanRoad.d.ts +9 -0
  137. package/dist/components/urban/UrbanRoad.d.ts.map +1 -0
  138. package/dist/components/urban/UrbanRoad.js +23 -0
  139. package/dist/components/urban/UrbanSignage.d.ts +9 -0
  140. package/dist/components/urban/UrbanSignage.d.ts.map +1 -0
  141. package/dist/components/urban/UrbanSignage.js +23 -0
  142. package/dist/components/urban/UrbanSkyline.d.ts +9 -0
  143. package/dist/components/urban/UrbanSkyline.d.ts.map +1 -0
  144. package/dist/components/urban/UrbanSkyline.js +23 -0
  145. package/dist/components/urban/UrbanStreetFurniture.d.ts +9 -0
  146. package/dist/components/urban/UrbanStreetFurniture.d.ts.map +1 -0
  147. package/dist/components/urban/UrbanStreetFurniture.js +23 -0
  148. package/dist/components/urban/UrbanStreetGrid.d.ts +9 -0
  149. package/dist/components/urban/UrbanStreetGrid.d.ts.map +1 -0
  150. package/dist/components/urban/UrbanStreetGrid.js +34 -0
  151. package/dist/components/urban/UrbanTraffic.d.ts +9 -0
  152. package/dist/components/urban/UrbanTraffic.d.ts.map +1 -0
  153. package/dist/components/urban/UrbanTraffic.js +23 -0
  154. package/dist/components/urban/core/block.d.ts +119 -0
  155. package/dist/components/urban/core/block.d.ts.map +1 -0
  156. package/dist/components/urban/core/block.js +266 -0
  157. package/dist/components/urban/core/building.d.ts +128 -0
  158. package/dist/components/urban/core/building.d.ts.map +1 -0
  159. package/dist/components/urban/core/building.js +741 -0
  160. package/dist/components/urban/core/junction.d.ts +152 -0
  161. package/dist/components/urban/core/junction.d.ts.map +1 -0
  162. package/dist/components/urban/core/junction.js +617 -0
  163. package/dist/components/urban/core/park.d.ts +67 -0
  164. package/dist/components/urban/core/park.d.ts.map +1 -0
  165. package/dist/components/urban/core/park.js +176 -0
  166. package/dist/components/urban/core/parkingLot.d.ts +82 -0
  167. package/dist/components/urban/core/parkingLot.d.ts.map +1 -0
  168. package/dist/components/urban/core/parkingLot.js +284 -0
  169. package/dist/components/urban/core/plaza.d.ts +24 -0
  170. package/dist/components/urban/core/plaza.d.ts.map +1 -0
  171. package/dist/components/urban/core/plaza.js +243 -0
  172. package/dist/components/urban/core/road.d.ts +113 -0
  173. package/dist/components/urban/core/road.d.ts.map +1 -0
  174. package/dist/components/urban/core/road.js +347 -0
  175. package/dist/components/urban/core/signage.d.ts +83 -0
  176. package/dist/components/urban/core/signage.d.ts.map +1 -0
  177. package/dist/components/urban/core/signage.js +209 -0
  178. package/dist/components/urban/core/skyline.d.ts +100 -0
  179. package/dist/components/urban/core/skyline.d.ts.map +1 -0
  180. package/dist/components/urban/core/skyline.js +89 -0
  181. package/dist/components/urban/core/streetFurniture.d.ts +75 -0
  182. package/dist/components/urban/core/streetFurniture.d.ts.map +1 -0
  183. package/dist/components/urban/core/streetFurniture.js +193 -0
  184. package/dist/components/urban/core/streetGrid.d.ts +134 -0
  185. package/dist/components/urban/core/streetGrid.d.ts.map +1 -0
  186. package/dist/components/urban/core/streetGrid.js +422 -0
  187. package/dist/components/urban/core/traffic.d.ts +125 -0
  188. package/dist/components/urban/core/traffic.d.ts.map +1 -0
  189. package/dist/components/urban/core/traffic.js +305 -0
  190. package/dist/components/urban/index.d.ts +29 -0
  191. package/dist/components/urban/index.d.ts.map +1 -0
  192. package/dist/components/urban/index.js +16 -0
  193. package/dist/components/urban/textureSetResolver.d.ts +8 -0
  194. package/dist/components/urban/textureSetResolver.d.ts.map +1 -0
  195. package/dist/components/urban/textureSetResolver.js +16 -0
  196. package/dist/components/urban/urbanCore.d.ts +262 -0
  197. package/dist/components/urban/urbanCore.d.ts.map +1 -0
  198. package/dist/components/urban/urbanCore.js +928 -0
  199. package/dist/components/urban/useUrbanInstance.d.ts +53 -0
  200. package/dist/components/urban/useUrbanInstance.d.ts.map +1 -0
  201. package/dist/components/urban/useUrbanInstance.js +100 -0
  202. package/dist/components/vegetation/VegetationBush.d.ts +9 -0
  203. package/dist/components/vegetation/VegetationBush.d.ts.map +1 -0
  204. package/dist/components/vegetation/VegetationBush.js +23 -0
  205. package/dist/components/vegetation/VegetationCrops.d.ts +9 -0
  206. package/dist/components/vegetation/VegetationCrops.d.ts.map +1 -0
  207. package/dist/components/vegetation/VegetationCrops.js +23 -0
  208. package/dist/components/vegetation/VegetationFlowers.d.ts +9 -0
  209. package/dist/components/vegetation/VegetationFlowers.d.ts.map +1 -0
  210. package/dist/components/vegetation/VegetationFlowers.js +23 -0
  211. package/dist/components/vegetation/VegetationForest.d.ts +9 -0
  212. package/dist/components/vegetation/VegetationForest.d.ts.map +1 -0
  213. package/dist/components/vegetation/VegetationForest.js +23 -0
  214. package/dist/components/vegetation/VegetationFruit.d.ts +9 -0
  215. package/dist/components/vegetation/VegetationFruit.d.ts.map +1 -0
  216. package/dist/components/vegetation/VegetationFruit.js +23 -0
  217. package/dist/components/vegetation/VegetationGrass.d.ts +9 -0
  218. package/dist/components/vegetation/VegetationGrass.d.ts.map +1 -0
  219. package/dist/components/vegetation/VegetationGrass.js +23 -0
  220. package/dist/components/vegetation/VegetationHedge.d.ts +9 -0
  221. package/dist/components/vegetation/VegetationHedge.d.ts.map +1 -0
  222. package/dist/components/vegetation/VegetationHedge.js +23 -0
  223. package/dist/components/vegetation/VegetationIvy.d.ts +9 -0
  224. package/dist/components/vegetation/VegetationIvy.d.ts.map +1 -0
  225. package/dist/components/vegetation/VegetationIvy.js +23 -0
  226. package/dist/components/vegetation/VegetationTree.d.ts +9 -0
  227. package/dist/components/vegetation/VegetationTree.d.ts.map +1 -0
  228. package/dist/components/vegetation/VegetationTree.js +23 -0
  229. package/dist/components/vegetation/VegetationVegetable.d.ts +9 -0
  230. package/dist/components/vegetation/VegetationVegetable.d.ts.map +1 -0
  231. package/dist/components/vegetation/VegetationVegetable.js +23 -0
  232. package/dist/components/vegetation/core/bush.d.ts +1256 -0
  233. package/dist/components/vegetation/core/bush.d.ts.map +1 -0
  234. package/dist/components/vegetation/core/bush.js +376 -0
  235. package/dist/components/vegetation/core/crops.d.ts +1033 -0
  236. package/dist/components/vegetation/core/crops.d.ts.map +1 -0
  237. package/dist/components/vegetation/core/crops.js +378 -0
  238. package/dist/components/vegetation/core/flowers.d.ts +648 -0
  239. package/dist/components/vegetation/core/flowers.d.ts.map +1 -0
  240. package/dist/components/vegetation/core/flowers.js +225 -0
  241. package/dist/components/vegetation/core/forest.d.ts +138 -0
  242. package/dist/components/vegetation/core/forest.d.ts.map +1 -0
  243. package/dist/components/vegetation/core/forest.js +310 -0
  244. package/dist/components/vegetation/core/fruit.d.ts +99 -0
  245. package/dist/components/vegetation/core/fruit.d.ts.map +1 -0
  246. package/dist/components/vegetation/core/fruit.js +77 -0
  247. package/dist/components/vegetation/core/grass.d.ts +103 -0
  248. package/dist/components/vegetation/core/grass.d.ts.map +1 -0
  249. package/dist/components/vegetation/core/grass.js +102 -0
  250. package/dist/components/vegetation/core/hedge.d.ts +193 -0
  251. package/dist/components/vegetation/core/hedge.d.ts.map +1 -0
  252. package/dist/components/vegetation/core/hedge.js +243 -0
  253. package/dist/components/vegetation/core/ivy.d.ts +213 -0
  254. package/dist/components/vegetation/core/ivy.d.ts.map +1 -0
  255. package/dist/components/vegetation/core/ivy.js +173 -0
  256. package/dist/components/vegetation/core/tree.d.ts +1117 -0
  257. package/dist/components/vegetation/core/tree.d.ts.map +1 -0
  258. package/dist/components/vegetation/core/tree.js +408 -0
  259. package/dist/components/vegetation/core/vegetable.d.ts +99 -0
  260. package/dist/components/vegetation/core/vegetable.d.ts.map +1 -0
  261. package/dist/components/vegetation/core/vegetable.js +76 -0
  262. package/dist/components/vegetation/index.d.ts +23 -0
  263. package/dist/components/vegetation/index.d.ts.map +1 -0
  264. package/dist/components/vegetation/index.js +14 -0
  265. package/dist/components/vegetation/produceCore.d.ts +929 -0
  266. package/dist/components/vegetation/produceCore.d.ts.map +1 -0
  267. package/dist/components/vegetation/produceCore.js +723 -0
  268. package/dist/components/vegetation/useVegetationInstance.d.ts +39 -0
  269. package/dist/components/vegetation/useVegetationInstance.d.ts.map +1 -0
  270. package/dist/components/vegetation/useVegetationInstance.js +45 -0
  271. package/dist/components/vegetation/vegetationCore.d.ts +412 -0
  272. package/dist/components/vegetation/vegetationCore.d.ts.map +1 -0
  273. package/dist/components/vegetation/vegetationCore.js +1728 -0
  274. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +5 -0
  275. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
  276. package/dist/components/volumetricClouds/VolumetricCloudsPass.js +39 -13
  277. package/dist/components/water/OceanSurface.d.ts.map +1 -1
  278. package/dist/components/water/OceanSurface.js +3 -2
  279. package/dist/components/water/WaterBody.d.ts.map +1 -1
  280. package/dist/components/water/WaterBody.js +31 -10
  281. package/dist/components/water/WaterFountain.d.ts +9 -0
  282. package/dist/components/water/WaterFountain.d.ts.map +1 -0
  283. package/dist/components/water/WaterFountain.js +24 -0
  284. package/dist/components/water/WaterStream.d.ts +9 -0
  285. package/dist/components/water/WaterStream.d.ts.map +1 -0
  286. package/dist/components/water/WaterStream.js +24 -0
  287. package/dist/components/water/WaterWaterfall.d.ts +9 -0
  288. package/dist/components/water/WaterWaterfall.d.ts.map +1 -0
  289. package/dist/components/water/WaterWaterfall.js +24 -0
  290. package/dist/components/water/core/fountain.d.ts +70 -0
  291. package/dist/components/water/core/fountain.d.ts.map +1 -0
  292. package/dist/components/water/core/fountain.js +619 -0
  293. package/dist/components/water/core/stream.d.ts +72 -0
  294. package/dist/components/water/core/stream.d.ts.map +1 -0
  295. package/dist/components/water/core/stream.js +167 -0
  296. package/dist/components/water/core/waterfall.d.ts +78 -0
  297. package/dist/components/water/core/waterfall.d.ts.map +1 -0
  298. package/dist/components/water/core/waterfall.js +325 -0
  299. package/dist/components/water/index.d.ts +8 -0
  300. package/dist/components/water/index.d.ts.map +1 -1
  301. package/dist/components/water/index.js +7 -0
  302. package/dist/components/water/types.d.ts +3 -0
  303. package/dist/components/water/types.d.ts.map +1 -1
  304. package/dist/components/water/useWaterInstance.d.ts +43 -0
  305. package/dist/components/water/useWaterInstance.d.ts.map +1 -0
  306. package/dist/components/water/useWaterInstance.js +89 -0
  307. package/dist/components/water/waterCore.d.ts +179 -0
  308. package/dist/components/water/waterCore.d.ts.map +1 -0
  309. package/dist/components/water/waterCore.js +516 -0
  310. package/dist/constants.d.ts.map +1 -1
  311. package/dist/constants.js +9 -1
  312. package/dist/hooks/index.d.ts +7 -2
  313. package/dist/hooks/index.d.ts.map +1 -1
  314. package/dist/hooks/index.js +5 -2
  315. package/dist/hooks/useActionPatch.d.ts +23 -0
  316. package/dist/hooks/useActionPatch.d.ts.map +1 -0
  317. package/dist/hooks/useActionPatch.js +38 -0
  318. package/dist/hooks/useCloudSun.d.ts.map +1 -1
  319. package/dist/hooks/useCloudSun.js +3 -2
  320. package/dist/hooks/useCommittedInstance.d.ts +6 -0
  321. package/dist/hooks/useCommittedInstance.d.ts.map +1 -0
  322. package/dist/hooks/useCommittedInstance.js +42 -0
  323. package/dist/hooks/useConfigLive.d.ts +1 -1
  324. package/dist/hooks/useConfigLive.d.ts.map +1 -1
  325. package/dist/hooks/useContinuousEffects.d.ts.map +1 -1
  326. package/dist/hooks/useContinuousEffects.js +36 -20
  327. package/dist/hooks/useGridLayout.d.ts +7 -0
  328. package/dist/hooks/useGridLayout.d.ts.map +1 -0
  329. package/dist/hooks/useGridLayout.js +10 -0
  330. package/dist/hooks/useInteractionEffects.d.ts.map +1 -1
  331. package/dist/hooks/useInteractionEffects.js +48 -9
  332. package/dist/hooks/useLightLive.d.ts.map +1 -1
  333. package/dist/hooks/useLightLive.js +2 -0
  334. package/dist/hooks/useLinkStatus.d.ts +7 -0
  335. package/dist/hooks/useLinkStatus.d.ts.map +1 -0
  336. package/dist/hooks/useLinkStatus.js +20 -0
  337. package/dist/hooks/useMaterialApplication.d.ts +6 -1
  338. package/dist/hooks/useMaterialApplication.d.ts.map +1 -1
  339. package/dist/hooks/useMaterialApplication.js +7 -2
  340. package/dist/hooks/useOceanMaterial.d.ts +11 -1
  341. package/dist/hooks/useOceanMaterial.d.ts.map +1 -1
  342. package/dist/hooks/useOceanMaterial.js +185 -27
  343. package/dist/hooks/usePathAnimation.d.ts +8 -0
  344. package/dist/hooks/usePathAnimation.d.ts.map +1 -1
  345. package/dist/hooks/usePathAnimation.js +140 -59
  346. package/dist/hooks/useResolvedLayout.d.ts +10 -0
  347. package/dist/hooks/useResolvedLayout.d.ts.map +1 -0
  348. package/dist/hooks/useResolvedLayout.js +17 -0
  349. package/dist/hooks/useTimeLighting.d.ts +36 -0
  350. package/dist/hooks/useTimeLighting.d.ts.map +1 -0
  351. package/dist/hooks/useTimeLighting.js +67 -0
  352. package/dist/index.d.ts +4 -0
  353. package/dist/index.d.ts.map +1 -1
  354. package/dist/index.js +4 -0
  355. package/dist/operations/catalogue/shaderLayers.d.ts.map +1 -1
  356. package/dist/operations/catalogue/shaderLayers.js +26 -3
  357. package/dist/render/renderLive.d.ts +11 -0
  358. package/dist/render/renderLive.d.ts.map +1 -0
  359. package/dist/render/renderLive.js +57 -0
  360. package/dist/shaders/glsl/oceanCore.glsl.d.ts +2 -2
  361. package/dist/shaders/glsl/oceanCore.glsl.d.ts.map +1 -1
  362. package/dist/shaders/glsl/oceanCore.glsl.js +35 -5
  363. package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +12 -0
  364. package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -1
  365. package/dist/shaders/ocean/OceanSurfaceMaterial.js +55 -7
  366. package/dist/shaders/terrain/TerrainMaterial.d.ts.map +1 -1
  367. package/dist/shaders/terrain/TerrainMaterial.js +28 -0
  368. package/dist/triggers/kinds/change.js +1 -1
  369. package/dist/ui/UiLayers.d.ts +17 -1
  370. package/dist/ui/UiLayers.d.ts.map +1 -1
  371. package/dist/ui/UiLayers.js +76 -3
  372. package/dist/ui/index.d.ts +2 -2
  373. package/dist/ui/index.d.ts.map +1 -1
  374. package/dist/ui/index.js +1 -1
  375. package/dist/utils/composerHostedPass.d.ts +74 -0
  376. package/dist/utils/composerHostedPass.d.ts.map +1 -0
  377. package/dist/utils/composerHostedPass.js +63 -0
  378. package/dist/utils/geometryScript.d.ts +17 -0
  379. package/dist/utils/geometryScript.d.ts.map +1 -0
  380. package/dist/utils/geometryScript.js +92 -0
  381. package/dist/utils/geometryScript.worker.d.ts +2 -0
  382. package/dist/utils/geometryScript.worker.d.ts.map +1 -0
  383. package/dist/utils/geometryScript.worker.js +42 -0
  384. package/dist/utils/groundRegistry.d.ts +11 -0
  385. package/dist/utils/groundRegistry.d.ts.map +1 -0
  386. package/dist/utils/groundRegistry.js +39 -0
  387. package/dist/utils/instancingSupport.d.ts +9 -0
  388. package/dist/utils/instancingSupport.d.ts.map +1 -0
  389. package/dist/utils/instancingSupport.js +13 -0
  390. package/dist/utils/landPatch.d.ts +26 -5
  391. package/dist/utils/landPatch.d.ts.map +1 -1
  392. package/dist/utils/landPatch.js +124 -9
  393. package/dist/utils/layoutPlacement.d.ts +30 -0
  394. package/dist/utils/layoutPlacement.d.ts.map +1 -0
  395. package/dist/utils/layoutPlacement.js +113 -0
  396. package/dist/utils/linkRegistry.d.ts +15 -0
  397. package/dist/utils/linkRegistry.d.ts.map +1 -0
  398. package/dist/utils/linkRegistry.js +11 -0
  399. package/dist/utils/shapes.d.ts +28 -2
  400. package/dist/utils/shapes.d.ts.map +1 -1
  401. package/dist/utils/shapes.js +32 -3
  402. package/dist/utils/sharedParts.d.ts +61 -0
  403. package/dist/utils/sharedParts.d.ts.map +1 -0
  404. package/dist/utils/sharedParts.js +268 -0
  405. package/dist/utils/svgAsset.d.ts +6 -0
  406. package/dist/utils/svgAsset.d.ts.map +1 -0
  407. package/dist/utils/svgAsset.js +46 -0
  408. package/dist/utils/waterLight.d.ts +29 -0
  409. package/dist/utils/waterLight.d.ts.map +1 -0
  410. package/dist/utils/waterLight.js +67 -0
  411. package/dist/utils/waterReflection.d.ts +185 -0
  412. package/dist/utils/waterReflection.d.ts.map +1 -0
  413. package/dist/utils/waterReflection.js +616 -0
  414. package/package.json +4 -3
@@ -0,0 +1,616 @@
1
+ import * as THREE from 'three';
2
+ /** 0 off, 1 the sky, 2 the planar target, 3 the baked probe. What the shaders switch on. */
3
+ export const WATER_REFLECTION_UNIFORM = { off: 0, env: 1, planar: 2, baked: 3 };
4
+ /**
5
+ * When a planar mirror is worth rendering for a placed body: it must be on
6
+ * screen and not hidden (the occlusion query), and big enough on screen that a
7
+ * mirrored scene reads differently from the sky. Below ~0.5 % of the view a
8
+ * pond far away or seen edge-on shows the sky either way, so it gets the sky
9
+ * (free). Measured as the solid angle the water subtends — area x |height| /
10
+ * distance³ for a horizontal patch — with hysteresis so it does not flicker on
11
+ * the threshold.
12
+ */
13
+ const COVERAGE_ON = 0.008; // steradians (~0.5 % of a 50 deg 16:9 view)
14
+ const COVERAGE_OFF = 0.005;
15
+ const eligible = new WeakMap();
16
+ /**
17
+ * Where the camera that actually draws the frame is. The studio renders with
18
+ * its own view camera, which is not R3F's `state.camera` (that one can sit
19
+ * anywhere — the authored pose), so the election must not measure from it.
20
+ * Noted by every water surface as it is drawn (onBeforeRender, outside a mirror
21
+ * pass); the election, which runs before the next render, reads it.
22
+ */
23
+ const _viewer = new THREE.Vector3();
24
+ let viewerKnown = false;
25
+ export function noteWaterViewer(camera) {
26
+ if (mirrorPass)
27
+ return;
28
+ _viewer.setFromMatrixPosition(camera.matrixWorld);
29
+ viewerKnown = true;
30
+ }
31
+ /** The view camera's position as last noted, or null before the first draw. */
32
+ export function waterViewerPosition() {
33
+ return viewerKnown ? _viewer : null;
34
+ }
35
+ const surfaces = new Map();
36
+ let electedId = null;
37
+ let electedAt = -1;
38
+ const _pos = new THREE.Vector3();
39
+ const _scl = new THREE.Vector3();
40
+ /** Register a surface for the per-frame election. Returns the unregister. */
41
+ export function registerWaterSurface(surface) {
42
+ surfaces.set(surface.id, surface);
43
+ return () => {
44
+ surfaces.delete(surface.id);
45
+ if (electedId === surface.id)
46
+ electedId = null;
47
+ };
48
+ }
49
+ /**
50
+ * Which surface owns the reflection this frame. Computed once per frame (keyed
51
+ * on the frame clock, which R3F advances once before any useFrame runs), so every
52
+ * surface asking in the same frame gets the same answer.
53
+ */
54
+ export function electedWaterSurface(state) {
55
+ const t = state.clock.elapsedTime;
56
+ if (t === electedAt)
57
+ return electedId;
58
+ electedAt = t;
59
+ electedId = null;
60
+ let best = -1;
61
+ const cam = viewerKnown ? _viewer : state.camera.position;
62
+ for (const s of surfaces.values()) {
63
+ if (s.mode() !== 'planar')
64
+ continue;
65
+ if (s.world) {
66
+ electedId = s.id;
67
+ return electedId;
68
+ }
69
+ // Hidden behind something (or off screen) last frame: no mirror.
70
+ if (s.visible && !s.visible()) {
71
+ eligible.set(s, false);
72
+ continue;
73
+ }
74
+ s.object.getWorldPosition(_pos);
75
+ s.object.getWorldScale(_scl);
76
+ const [w, d] = s.size();
77
+ const area = Math.abs(w * _scl.x) * Math.abs(d * _scl.z);
78
+ const dist = Math.max(_pos.distanceTo(cam), 1e-3);
79
+ const halfDiag = 0.5 * Math.sqrt(area * 2);
80
+ const solid = dist <= halfDiag ? Infinity : (area * Math.abs(cam.y - _pos.y)) / (dist * dist * dist);
81
+ const was = eligible.get(s) ?? false;
82
+ const on = solid >= (was ? COVERAGE_OFF : COVERAGE_ON);
83
+ eligible.set(s, on);
84
+ if (!on)
85
+ continue;
86
+ const score = area / (dist * dist);
87
+ if (score > best) {
88
+ best = score;
89
+ electedId = s.id;
90
+ }
91
+ }
92
+ return electedId;
93
+ }
94
+ // -----------------------------------------------------------------------------
95
+ // Visibility: did any of the water's pixels survive the depth test?
96
+ // -----------------------------------------------------------------------------
97
+ /** True while a mirror pass is rendering: queries and nested passes stand down. */
98
+ let mirrorPass = false;
99
+ export function isWaterMirrorPass() { return mirrorPass; }
100
+ /**
101
+ * A WebGL2 occlusion query around a water body's draw (begin at the end of its
102
+ * onBeforeRender, end in onAfterRender). The answer arrives a frame or two later
103
+ * and drives the election: a pond hidden behind the city is drawn (it is in the
104
+ * view frustum) but none of its pixels pass, so it gets no mirror. A body whose
105
+ * mesh was not drawn at all last frame (frustum-culled) is not visible either.
106
+ * WebGL1, or before the first answer: visible.
107
+ */
108
+ export class WaterVisibility {
109
+ gl = null;
110
+ active = null;
111
+ pending = [];
112
+ free = [];
113
+ passed = true;
114
+ frame = 0;
115
+ drawnAt = -10;
116
+ /** Once per frame, before the render (useFrame). */
117
+ tick() { this.frame++; }
118
+ /** Visible as of the latest answer, and drawn in the last frame or two. */
119
+ isVisible() { return this.passed && this.frame - this.drawnAt <= 2; }
120
+ begin(renderer) {
121
+ if (mirrorPass || this.active)
122
+ return;
123
+ this.drawnAt = this.frame;
124
+ const gl = renderer.getContext();
125
+ if (typeof WebGL2RenderingContext === 'undefined' || !(gl instanceof WebGL2RenderingContext))
126
+ return;
127
+ this.gl = gl;
128
+ this.poll();
129
+ if (this.pending.length >= 4)
130
+ return; // the GPU is behind; ask again later
131
+ const q = this.free.pop() ?? gl.createQuery();
132
+ if (!q)
133
+ return;
134
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, q);
135
+ this.active = q;
136
+ }
137
+ end() {
138
+ if (!this.active || !this.gl)
139
+ return;
140
+ this.gl.endQuery(this.gl.ANY_SAMPLES_PASSED_CONSERVATIVE);
141
+ this.pending.push(this.active);
142
+ this.active = null;
143
+ }
144
+ poll() {
145
+ const gl = this.gl;
146
+ if (!gl)
147
+ return;
148
+ while (this.pending.length) {
149
+ const q = this.pending[0];
150
+ if (!gl.getQueryParameter(q, gl.QUERY_RESULT_AVAILABLE))
151
+ break;
152
+ this.passed = !!gl.getQueryParameter(q, gl.QUERY_RESULT);
153
+ this.free.push(this.pending.shift());
154
+ }
155
+ }
156
+ dispose() {
157
+ const gl = this.gl;
158
+ if (!gl)
159
+ return;
160
+ if (this.active) {
161
+ gl.endQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE);
162
+ this.active = null;
163
+ }
164
+ for (const q of [...this.pending, ...this.free])
165
+ gl.deleteQuery(q);
166
+ this.pending.length = 0;
167
+ this.free.length = 0;
168
+ }
169
+ }
170
+ // -----------------------------------------------------------------------------
171
+ // The planar pass
172
+ // -----------------------------------------------------------------------------
173
+ const _normal = new THREE.Vector3();
174
+ const _point = new THREE.Vector3();
175
+ const _camPos = new THREE.Vector3();
176
+ const _view = new THREE.Vector3();
177
+ const _target = new THREE.Vector3();
178
+ const _lookAt = new THREE.Vector3();
179
+ const _rot = new THREE.Matrix4();
180
+ const _plane = new THREE.Plane();
181
+ const _clip = new THREE.Vector4();
182
+ const _q = new THREE.Vector4();
183
+ const _size = new THREE.Vector2();
184
+ const _origin = new THREE.Vector3(0, 0, 0);
185
+ const _up = new THREE.Vector3(0, 1, 0);
186
+ const _forward = new THREE.Vector3(0, 0, -1);
187
+ const _corner = new THREE.Vector3();
188
+ /** Margin around the water's screen rectangle, in NDC: room for the ripple
189
+ * distortion of the lookup and for the waves standing above the flat plane. */
190
+ const RECT_MARGIN = 0.08;
191
+ /**
192
+ * Mirrors the camera about a horizontal plane and renders the scene into a
193
+ * target (the three.js Reflector construction: mirrored camera, oblique near
194
+ * plane so nothing under the water leaks into the mirror, bias matrix so the
195
+ * fragment shader can project a world position straight into the texture).
196
+ */
197
+ export class PlanarReflector {
198
+ target;
199
+ textureMatrix = new THREE.Matrix4();
200
+ camera = new THREE.PerspectiveCamera();
201
+ rendering = false;
202
+ /** Scratch for the outline clip (4 corners in, at most 8 points out). */
203
+ viewPts = Array.from({ length: 4 }, () => new THREE.Vector3());
204
+ clipped = Array.from({ length: 8 }, () => new THREE.Vector3());
205
+ /** True after a pass this frame actually drew; false when the camera was
206
+ * under the plane and the target holds nothing to sample. */
207
+ valid = false;
208
+ constructor() {
209
+ this.target = new THREE.WebGLRenderTarget(256, 256, {
210
+ minFilter: THREE.LinearFilter,
211
+ magFilter: THREE.LinearFilter,
212
+ depthBuffer: true,
213
+ stencilBuffer: false,
214
+ });
215
+ }
216
+ dispose() { this.target.dispose(); }
217
+ /**
218
+ * @param hide the water mesh (or its root) — invisible while the mirror renders
219
+ * @param point a world point on the water plane (the body's root position)
220
+ * @param scale target size as a fraction of the drawing buffer (quality.reflectionScale)
221
+ * @param corners the water's outline on the plane, world space (a placed body's
222
+ * four corners). The mirror is then rendered only for the rectangle they
223
+ * cover in the mirror view — a sub-frustum (setViewOffset) and a target
224
+ * that size — so everything not reflected in THIS water is frustum-culled
225
+ * by the renderer and the target holds no unused pixels. null (the world
226
+ * ocean, which covers everything below the horizon) renders the full view.
227
+ */
228
+ render(renderer, scene, camera, hide, point, scale, corners = null) {
229
+ if (this.rendering || scale <= 0) {
230
+ this.valid = false;
231
+ return false;
232
+ }
233
+ renderer.getDrawingBufferSize(_size);
234
+ _normal.set(0, 1, 0);
235
+ _point.copy(point);
236
+ _camPos.setFromMatrixPosition(camera.matrixWorld);
237
+ _view.subVectors(_point, _camPos);
238
+ // Camera under the water: the mirror would show the sky from below.
239
+ if (_view.dot(_normal) > 0) {
240
+ this.valid = false;
241
+ return false;
242
+ }
243
+ _view.reflect(_normal).negate().add(_point);
244
+ _rot.extractRotation(camera.matrixWorld);
245
+ _lookAt.copy(_forward).applyMatrix4(_rot).add(_camPos);
246
+ _target.subVectors(_point, _lookAt).reflect(_normal).negate().add(_point);
247
+ const vc = this.camera;
248
+ vc.position.copy(_view);
249
+ vc.up.copy(_up).applyMatrix4(_rot).reflect(_normal);
250
+ vc.lookAt(_target);
251
+ const pc = camera;
252
+ vc.near = pc.near ?? 0.1;
253
+ vc.far = pc.far ?? 2000;
254
+ vc.updateMatrixWorld();
255
+ vc.layers.mask = camera.layers.mask;
256
+ // The mirror's projection: the main camera's, narrowed to the water's
257
+ // rectangle when its outline is known (the "reflect only what is seen" cut).
258
+ let rx = 0, ry = 0, rw = 1, rh = 1;
259
+ if (pc.isPerspectiveCamera) {
260
+ vc.fov = pc.fov;
261
+ vc.aspect = pc.aspect;
262
+ vc.zoom = pc.zoom;
263
+ vc.clearViewOffset();
264
+ vc.updateProjectionMatrix();
265
+ if (corners) {
266
+ const rect = this.screenRect(corners);
267
+ if (rect === 'offscreen') {
268
+ this.valid = false;
269
+ return false;
270
+ }
271
+ if (rect) {
272
+ [rx, ry, rw, rh] = rect;
273
+ vc.setViewOffset(_size.x, _size.y, rx * _size.x, ry * _size.y, rw * _size.x, rh * _size.y);
274
+ vc.updateProjectionMatrix();
275
+ }
276
+ }
277
+ }
278
+ else {
279
+ vc.projectionMatrix.copy(camera.projectionMatrix);
280
+ }
281
+ // Target: ONE allocation at the frame's size x scale (reallocated only when
282
+ // the window or the resolution changes — resizing it every frame as the
283
+ // water's rectangle moves made the reflection hitch). The rectangle is
284
+ // drawn into its lower-left w x h through viewport + scissor, and the
285
+ // texture matrix maps into that corner.
286
+ const W = Math.max(16, Math.round(_size.x * scale));
287
+ const H = Math.max(16, Math.round(_size.y * scale));
288
+ if (this.target.width !== W || this.target.height !== H)
289
+ this.target.setSize(W, H);
290
+ const w = Math.max(1, Math.min(W, Math.round(W * rw)));
291
+ const h = Math.max(1, Math.min(H, Math.round(H * rh)));
292
+ this.target.viewport.set(0, 0, w, h);
293
+ this.target.scissor.set(0, 0, w, h);
294
+ this.target.scissorTest = w < W || h < H;
295
+ const sx = w / W, sy = h / H;
296
+ // bias * proj * view: world -> texture space ([0, sx] x [0, sy], the drawn corner).
297
+ this.textureMatrix.set(0.5 * sx, 0.0, 0.0, 0.5 * sx, 0.0, 0.5 * sy, 0.0, 0.5 * sy, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
298
+ this.textureMatrix.multiply(vc.projectionMatrix).multiply(vc.matrixWorldInverse);
299
+ // Oblique near plane: clip everything below the water in the mirror view
300
+ // (Lengyel), so the floor of a pool does not reflect in its own surface.
301
+ _plane.setFromNormalAndCoplanarPoint(_normal, _point);
302
+ _plane.applyMatrix4(vc.matrixWorldInverse);
303
+ _clip.set(_plane.normal.x, _plane.normal.y, _plane.normal.z, _plane.constant);
304
+ const p = vc.projectionMatrix;
305
+ _q.x = (Math.sign(_clip.x) + p.elements[8]) / p.elements[0];
306
+ _q.y = (Math.sign(_clip.y) + p.elements[9]) / p.elements[5];
307
+ _q.z = -1.0;
308
+ _q.w = (1.0 + p.elements[10]) / p.elements[14];
309
+ _clip.multiplyScalar(2.0 / _clip.dot(_q));
310
+ p.elements[2] = _clip.x;
311
+ p.elements[6] = _clip.y;
312
+ p.elements[10] = _clip.z + 1.0;
313
+ p.elements[14] = _clip.w;
314
+ // Render, with everything the main pass set put back afterwards.
315
+ this.rendering = true;
316
+ mirrorPass = true;
317
+ const wasVisible = hide.visible;
318
+ hide.visible = false;
319
+ const prevTarget = renderer.getRenderTarget();
320
+ const prevXr = renderer.xr.enabled;
321
+ const prevShadow = renderer.shadowMap.autoUpdate;
322
+ const prevAutoClear = renderer.autoClear;
323
+ renderer.xr.enabled = false;
324
+ renderer.shadowMap.autoUpdate = false;
325
+ renderer.autoClear = true;
326
+ try {
327
+ renderer.setRenderTarget(this.target);
328
+ renderer.state.buffers.depth.setMask(true);
329
+ renderer.render(scene, vc);
330
+ this.valid = true;
331
+ }
332
+ catch {
333
+ // A disposed material mid-swap throws inside three's caches; the
334
+ // frame is skipped and the next one resolves it.
335
+ this.valid = false;
336
+ }
337
+ finally {
338
+ renderer.setRenderTarget(prevTarget);
339
+ renderer.xr.enabled = prevXr;
340
+ renderer.shadowMap.autoUpdate = prevShadow;
341
+ renderer.autoClear = prevAutoClear;
342
+ hide.visible = wasVisible;
343
+ this.rendering = false;
344
+ mirrorPass = false;
345
+ }
346
+ return this.valid;
347
+ }
348
+ /**
349
+ * The rectangle the water's outline covers in the mirror view, as fractions
350
+ * of the frame [x, y (from the top), w, h], grown by RECT_MARGIN; null when it
351
+ * is most of the frame or a corner is behind the mirror camera (use the full
352
+ * view), 'offscreen' when none of it is in view.
353
+ */
354
+ screenRect(corners) {
355
+ const vc = this.camera;
356
+ // The outline in view space, clipped at the near plane (Sutherland-Hodgman
357
+ // against z = -near): standing on the bank of a long pond, its near corners
358
+ // are behind the camera, and only the part in front can be in the mirror.
359
+ const zNear = -vc.near * 1.001;
360
+ const view = this.viewPts;
361
+ for (let i = 0; i < corners.length; i++)
362
+ view[i].copy(corners[i]).applyMatrix4(vc.matrixWorldInverse);
363
+ let clippedN = 0;
364
+ for (let i = 0; i < corners.length; i++) {
365
+ const a = view[i], b = view[(i + 1) % corners.length];
366
+ const aIn = a.z <= zNear, bIn = b.z <= zNear;
367
+ if (aIn)
368
+ this.clipped[clippedN++].copy(a);
369
+ if (aIn !== bIn) {
370
+ const t = (zNear - a.z) / (b.z - a.z);
371
+ this.clipped[clippedN++].copy(a).lerp(b, t);
372
+ }
373
+ }
374
+ if (clippedN === 0)
375
+ return 'offscreen';
376
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
377
+ for (let i = 0; i < clippedN; i++) {
378
+ _corner.copy(this.clipped[i]).applyMatrix4(vc.projectionMatrix);
379
+ minX = Math.min(minX, _corner.x);
380
+ maxX = Math.max(maxX, _corner.x);
381
+ minY = Math.min(minY, _corner.y);
382
+ maxY = Math.max(maxY, _corner.y);
383
+ }
384
+ minX = Math.max(minX - RECT_MARGIN, -1);
385
+ maxX = Math.min(maxX + RECT_MARGIN, 1);
386
+ minY = Math.max(minY - RECT_MARGIN, -1);
387
+ maxY = Math.min(maxY + RECT_MARGIN, 1);
388
+ if (minX >= maxX || minY >= maxY)
389
+ return 'offscreen';
390
+ const w = (maxX - minX) / 2, h = (maxY - minY) / 2;
391
+ if (w * h > 0.85)
392
+ return null;
393
+ return [(minX + 1) / 2, (1 - maxY) / 2, w, h];
394
+ }
395
+ }
396
+ // -----------------------------------------------------------------------------
397
+ // The baked probe ('baked' mode)
398
+ // -----------------------------------------------------------------------------
399
+ /**
400
+ * A reflection probe: the scene captured ONCE into a cubemap from just above
401
+ * the water, and sampled by the water every frame with a texture lookup.
402
+ *
403
+ * Why it is cheap: a planar mirror depends on where the camera is, so it must be
404
+ * re-rendered every frame the camera moves. The probe belongs to the WATER, not
405
+ * the view — the reflected ray from each fragment is looked up in it — so it
406
+ * stays valid while the camera moves and costs nothing per frame. It is
407
+ * re-captured only when it goes stale (the sun turned, the body moved, a slow
408
+ * refresh for scene edits), one cube face per frame so no frame pays for six.
409
+ *
410
+ * Why it is not exact: a cubemap is a picture from one point. The lookup is
411
+ * parallax-corrected against a sphere around the probe (`radius`), so the bank
412
+ * and the skyline sit roughly where they should across a large pond, but things
413
+ * close to the water and far from its centre are slightly off, and anything that
414
+ * moves is frozen until the next capture. Under ripples this reads the same as
415
+ * the mirror at a fraction of the cost; calm hero water seen close is what
416
+ * 'planar' is for. Every baked body has its own probe — no election.
417
+ */
418
+ export class WaterProbe {
419
+ size;
420
+ target;
421
+ cube;
422
+ /** Where the last COMPLETE capture was taken: the centre of the lookup. */
423
+ position = new THREE.Vector3();
424
+ /** Parallax sphere radius, metres; 0 = everything infinitely far (the world ocean). */
425
+ radius = 0;
426
+ /** True once all six faces have been drawn; until then the water shows the sky. */
427
+ valid = false;
428
+ /** Next face to draw; 6 = up to date. */
429
+ face = 6;
430
+ again = false;
431
+ pending = new THREE.Vector3();
432
+ lastPos = new THREE.Vector3(Infinity, Infinity, Infinity);
433
+ lastSun = new THREE.Vector3();
434
+ sunScratch = new THREE.Vector3();
435
+ lastAt = -Infinity;
436
+ constructor(size) {
437
+ this.size = size;
438
+ this.target = new THREE.WebGLCubeRenderTarget(size, {
439
+ type: THREE.HalfFloatType,
440
+ generateMipmaps: true,
441
+ minFilter: THREE.LinearMipmapLinearFilter,
442
+ magFilter: THREE.LinearFilter,
443
+ });
444
+ this.cube = new THREE.CubeCamera(0.5, 10000, this.target);
445
+ }
446
+ dispose() { this.target.dispose(); }
447
+ /**
448
+ * Once per frame: where the probe should be and what the sun is doing. Marks
449
+ * the capture stale when the probe moved more than `moveTolerance` metres,
450
+ * the sun turned more than ~0.5 degrees, or `refreshSec` passed since the last
451
+ * capture (scene edits). A request while a capture is in flight finishes that
452
+ * capture first, then starts again.
453
+ */
454
+ request(pos, sun, moveTolerance, nowSec, refreshSec = 10) {
455
+ const moved = this.lastPos.distanceToSquared(pos) > moveTolerance * moveTolerance;
456
+ // Normalized here: the rendered sky's sun direction is not always unit
457
+ // length, and a short vector reads as "turned" every frame (a capture
458
+ // that never stops).
459
+ const s = sun && sun.lengthSq() > 1e-8 ? this.sunScratch.copy(sun).normalize() : null;
460
+ const turned = !!s && this.lastSun.dot(s) < SUN_STALE_COS;
461
+ const old = nowSec - this.lastAt > refreshSec;
462
+ if (!moved && !turned && !old)
463
+ return;
464
+ // At most one capture every MIN_INTERVAL_SEC: with the clock playing fast
465
+ // the sun turns half a degree every frame, and re-capturing on every one
466
+ // of them is a face per frame forever (a quarter of the scene, always).
467
+ if (this.lastAt > -Infinity && nowSec - this.lastAt < MIN_INTERVAL_SEC)
468
+ return;
469
+ this.lastPos.copy(pos);
470
+ if (s)
471
+ this.lastSun.copy(s);
472
+ this.lastAt = nowSec;
473
+ if (this.face < 6) {
474
+ this.again = true;
475
+ this.pending.copy(pos);
476
+ return;
477
+ }
478
+ this.pending.copy(pos);
479
+ this.face = 0;
480
+ }
481
+ /** True while faces are still to be drawn. */
482
+ get stale() { return this.face < 6; }
483
+ /**
484
+ * Draw the next stale face (at most one per call; the host calls once per
485
+ * frame from onBeforeRender). `hide` is the water itself.
486
+ */
487
+ step(renderer, scene, hide, layers) {
488
+ if (this.face >= 6 || mirrorPass)
489
+ return;
490
+ const cc = this.cube;
491
+ if (this.face === 0) {
492
+ cc.position.copy(this.pending);
493
+ cc.updateMatrixWorld(true);
494
+ }
495
+ if (cc.coordinateSystem !== renderer.coordinateSystem) {
496
+ cc.coordinateSystem = renderer.coordinateSystem;
497
+ cc.updateCoordinateSystem();
498
+ cc.updateMatrixWorld(true);
499
+ }
500
+ const cam = cc.children[this.face];
501
+ cam.layers.mask = layers;
502
+ mirrorPass = true;
503
+ const wasVisible = hide.visible;
504
+ hide.visible = false;
505
+ const prevTarget = renderer.getRenderTarget();
506
+ const prevFace = renderer.getActiveCubeFace();
507
+ const prevMip = renderer.getActiveMipmapLevel();
508
+ const prevXr = renderer.xr.enabled;
509
+ const prevShadow = renderer.shadowMap.autoUpdate;
510
+ const prevAutoClear = renderer.autoClear;
511
+ renderer.xr.enabled = false;
512
+ renderer.shadowMap.autoUpdate = false;
513
+ renderer.autoClear = true;
514
+ // Mipmaps once, on the last face (the CubeCamera.update trick).
515
+ this.target.texture.generateMipmaps = this.face === 5;
516
+ try {
517
+ renderer.setRenderTarget(this.target, this.face);
518
+ renderer.state.buffers.depth.setMask(true);
519
+ renderer.render(scene, cam);
520
+ this.face++;
521
+ }
522
+ catch {
523
+ // A disposed material mid-swap: try this face again next frame.
524
+ }
525
+ finally {
526
+ this.target.texture.generateMipmaps = true;
527
+ renderer.setRenderTarget(prevTarget, prevFace, prevMip);
528
+ renderer.xr.enabled = prevXr;
529
+ renderer.shadowMap.autoUpdate = prevShadow;
530
+ renderer.autoClear = prevAutoClear;
531
+ hide.visible = wasVisible;
532
+ mirrorPass = false;
533
+ }
534
+ if (this.face === 6) {
535
+ this.valid = true;
536
+ this.position.copy(cc.position);
537
+ if (this.again) {
538
+ this.again = false;
539
+ this.face = 0;
540
+ }
541
+ }
542
+ }
543
+ }
544
+ /** Shortest time between two captures of one probe, seconds. */
545
+ const MIN_INTERVAL_SEC = 1.5;
546
+ /** Sun movement that makes a capture stale (~0.5 degrees). */
547
+ const SUN_STALE_COS = Math.cos((0.5 * Math.PI) / 180);
548
+ /** Cube face size for a reflection resolution (quality.reflectionScale): 0.5 -> 256. */
549
+ export function waterProbeSize(scale) {
550
+ const px = Math.max(64, Math.min(1024, 512 * Math.max(scale, 0.1)));
551
+ return 2 ** Math.round(Math.log2(px));
552
+ }
553
+ /**
554
+ * Push the reflection state into a water material. `mode` is what the surface
555
+ * asked for; the pass is only handed over when this surface won the election
556
+ * and its pass drew, otherwise planar falls back to the sky for this frame.
557
+ */
558
+ export function applyWaterReflection(uniforms, mode, reflector, probe = null) {
559
+ if (mode === 'baked') {
560
+ const ok = !!probe && probe.valid;
561
+ if (uniforms.u_reflectionMode)
562
+ uniforms.u_reflectionMode.value = ok ? 3 : 1;
563
+ if (uniforms.u_reflectionCube)
564
+ uniforms.u_reflectionCube.value = ok ? probe.target.texture : null;
565
+ if (ok && uniforms.u_probePos)
566
+ uniforms.u_probePos.value.copy(probe.position);
567
+ if (ok && uniforms.u_probeRadius)
568
+ uniforms.u_probeRadius.value = probe.radius;
569
+ return;
570
+ }
571
+ const planar = mode === 'planar' && !!reflector && reflector.valid;
572
+ if (uniforms.u_reflectionMode)
573
+ uniforms.u_reflectionMode.value = planar ? 2 : WATER_REFLECTION_UNIFORM[mode === 'planar' ? 'env' : mode];
574
+ if (uniforms.u_reflectionMap)
575
+ uniforms.u_reflectionMap.value = planar ? reflector.target.texture : null;
576
+ if (uniforms.u_reflectionMatrix && planar)
577
+ uniforms.u_reflectionMatrix.value.copy(reflector.textureMatrix);
578
+ }
579
+ /** GLSL shared by both water shaders: the three uniforms and the projected sample. */
580
+ export const waterReflectionGlsl = /* glsl */ `
581
+ uniform int u_reflectionMode; // 0 off, 1 sky, 2 planar target, 3 baked probe
582
+ uniform sampler2D u_reflectionMap;
583
+ uniform mat4 u_reflectionMatrix;
584
+ uniform samplerCube u_reflectionCube;
585
+ uniform vec3 u_probePos;
586
+ uniform float u_probeRadius; // parallax sphere; 0 = infinitely far
587
+
588
+ /** The baked probe along the reflected ray. The normal is flattened by
589
+ * 'distortion' (0 flat, 1 the full ripple) so the probe wobbles like the mirror
590
+ * rather than like a physically rough sea. The lookup direction is corrected
591
+ * against a sphere around the probe, so a fragment far from the probe still
592
+ * sees the bank where it is. Only valid when u_reflectionMode == 3. */
593
+ vec3 waterProbeReflection(vec3 worldPos, vec3 viewDir, vec3 n, float distortion){
594
+ vec3 nb = normalize(vec3(n.x * distortion, max(n.y, 1e-3), n.z * distortion));
595
+ vec3 r = reflect(viewDir, nb);
596
+ r.y = max(r.y, 0.005);
597
+ r = normalize(r);
598
+ vec3 dir = r;
599
+ if (u_probeRadius > 0.0) {
600
+ vec3 o = worldPos - u_probePos;
601
+ float b = dot(o, r);
602
+ float c = dot(o, o) - u_probeRadius * u_probeRadius;
603
+ dir = o + r * (-b + sqrt(max(b * b - c, 0.0)));
604
+ }
605
+ return textureCube(u_reflectionCube, dir).rgb;
606
+ }
607
+
608
+ /** The mirrored scene at a world point, with the surface normal bending the
609
+ * lookup (the ripple distortion). Only valid when u_reflectionMode == 2. */
610
+ vec3 waterPlanarReflection(vec3 worldPos, vec3 n, float distortion){
611
+ vec4 rc = u_reflectionMatrix * vec4(worldPos, 1.0);
612
+ vec2 uv = rc.xy / max(rc.w, 1e-4) + n.xz * distortion;
613
+ uv = clamp(uv, vec2(0.002), vec2(0.998));
614
+ return texture2D(u_reflectionMap, uv).rgb;
615
+ }
616
+ `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3driseai/3drise-viewer",
3
- "version": "0.1.41",
3
+ "version": "0.1.43",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,6 +25,7 @@
25
25
  "@gsap/react": "^2.1.2",
26
26
  "@react-three/drei": "^10",
27
27
  "@react-three/fiber": "^9",
28
+ "@react-three/postprocessing": "^3",
28
29
  "@react-three/rapier": "^2",
29
30
  "react": "^18 || ^19",
30
31
  "three": "^0.170"
@@ -32,14 +33,14 @@
32
33
  "devDependencies": {
33
34
  "@react-three/drei": "^10.0.0",
34
35
  "@react-three/fiber": "^9.0.0",
36
+ "@react-three/postprocessing": "^3.0.0",
35
37
  "@types/react": "^19.0.0",
36
38
  "react": "^19.0.0",
37
39
  "three": "^0.170.0",
38
40
  "typescript": "^5.7.2"
39
41
  },
40
42
  "dependencies": {
41
- "@3driseai/3drise-common": "^1.0.1",
42
- "@3driseai/3drise-core": "^1.0.30",
43
+ "@3driseai/3drise-core": "^1.0.31",
43
44
  "three-mesh-bvh": "^0.8.3"
44
45
  }
45
46
  }