@call-me-sensei/toonlab 0.4.21 → 0.4.23

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 (129) hide show
  1. package/NPM-LIBRARY.md +87 -27
  2. package/README.md +11 -10
  3. package/agents/PROMPTS.md +17 -3
  4. package/agents/README.md +13 -3
  5. package/agents/claude/CLAUDE.md +3 -0
  6. package/agents/codex/AGENTS.md +112 -159
  7. package/agents/cursor/toonlab.mdc +7 -3
  8. package/agents/examples/game-foundation.mjs +104 -0
  9. package/agents/references/game-lifecycle.md +57 -0
  10. package/agents/references/runtime-entry-points.md +26 -0
  11. package/agents/references/style-bundles.md +4 -1
  12. package/agents/skills/claude/asset-sourcing/SKILL.md +7 -4
  13. package/agents/skills/claude/environment/SKILL.md +4 -0
  14. package/agents/skills/claude/game-dev/SKILL.md +63 -87
  15. package/agents/skills/claude/lighting/SKILL.md +36 -0
  16. package/agents/skills/claude/post-processing/SKILL.md +8 -3
  17. package/agents/skills/claude/rock-ground-shaders/SKILL.md +10 -15
  18. package/agents/skills/claude/rockgen/SKILL.md +52 -21
  19. package/agents/skills/claude/scene-style-application/SKILL.md +4 -0
  20. package/agents/skills/claude/style-presets/SKILL.md +11 -8
  21. package/agents/skills/claude/toon-shading/SKILL.md +4 -0
  22. package/agents/skills/claude/vegetation-sky/SKILL.md +13 -7
  23. package/agents/skills/claude/visual-verification/SKILL.md +45 -119
  24. package/agents/skills/claude/water/SKILL.md +6 -2
  25. package/agents/skills/codex/asset-sourcing/SKILL.md +7 -4
  26. package/agents/skills/codex/environment/SKILL.md +4 -0
  27. package/agents/skills/codex/game-dev/SKILL.md +63 -87
  28. package/agents/skills/codex/lighting/SKILL.md +36 -0
  29. package/agents/skills/codex/post-processing/SKILL.md +8 -3
  30. package/agents/skills/codex/rock-ground-shaders/SKILL.md +10 -15
  31. package/agents/skills/codex/rockgen/SKILL.md +52 -21
  32. package/agents/skills/codex/scene-style-application/SKILL.md +4 -0
  33. package/agents/skills/codex/style-presets/SKILL.md +11 -8
  34. package/agents/skills/codex/toon-shading/SKILL.md +4 -0
  35. package/agents/skills/codex/vegetation-sky/SKILL.md +13 -7
  36. package/agents/skills/codex/visual-verification/SKILL.md +45 -119
  37. package/agents/skills/codex/water/SKILL.md +6 -2
  38. package/database/apply-one-catalog-seed.mjs +63 -0
  39. package/database/providers.mjs +1 -0
  40. package/database/seeds/catalog/0005_2026-08-c8-first12.sql +1101 -0
  41. package/database/seeds/catalog/0006_2026-09-c8-first100.sql +14245 -0
  42. package/database/seeds/catalog/0007_2026-09-c8-first100-primary-model.sql +14845 -0
  43. package/mcp/lab-management.mjs +11 -8
  44. package/mcp/public-catalog.mjs +0 -16
  45. package/mcp/tree-lab-contract.mjs +2381 -0
  46. package/mcp/vite-plugin.mjs +5 -1
  47. package/package.json +29 -18
  48. package/src/catalog/officialCatalog.js +1 -0
  49. package/src/catalog/officialCatalogAssetRuntime.js +98 -1
  50. package/src/catalog/officialCatalogLod.js +160 -16
  51. package/src/catalog/officialCatalogPlacement.js +52 -12
  52. package/src/catalog/officialCatalogProvider.js +79 -8
  53. package/src/catalog/officialCatalogRockPackage.js +172 -0
  54. package/src/cloud/cloudReprojection.js +40 -7
  55. package/src/cloud/cloudVolume.js +44 -7
  56. package/src/cloud/noise/baseShapeVolume.js +8 -6
  57. package/src/cloud/noise/cirrusMap.js +2 -1
  58. package/src/cloud/noise/curlNoise.js +2 -1
  59. package/src/cloud/noise/erosionVolume.js +2 -1
  60. package/src/cloud/noise/textureCache.js +77 -0
  61. package/src/cloud/noise/weatherMap.js +2 -1
  62. package/src/core/sha256.js +83 -0
  63. package/src/ground-shader/groundShaderMaterial.js +12 -3
  64. package/src/rock-shader/rockMaterial.js +205 -28
  65. package/src/rock-shader/rockShaderRuntime.js +17 -1
  66. package/src/rock-shader/rockShaderSettings.js +16 -0
  67. package/src/rockgen/index.js +9 -0
  68. package/src/rockgen/lod/index.js +1 -0
  69. package/src/rockgen/lod/rockDenseFieldPolicy.js +143 -0
  70. package/src/rockgen/rockDocument.js +899 -35
  71. package/src/rockgen/surface/c7GeologySurface.js +39 -9
  72. package/src/rockgen/surface/naturalRockSurface.js +1948 -0
  73. package/src/shaders-tsl/chunks/projected-water-caustics.js +14 -2
  74. package/src/shaders-tsl/chunks/water-foam.js +6 -6
  75. package/src/shaders-tsl/chunks/water-lighting.js +28 -5
  76. package/src/shaders-tsl/chunks/water-shore-state.js +5 -2
  77. package/src/shaders-tsl/chunks/water-waves.js +10 -5
  78. package/src/shaders-tsl/flower.js +7 -4
  79. package/src/shaders-tsl/grass.js +4 -3
  80. package/src/shaders-tsl/water-shore-state-simulation.js +3 -2
  81. package/src/shaders-tsl/water.js +209 -41
  82. package/src/sky/skySystem.js +30 -7
  83. package/src/toon/settings/perspectiveRemovalSettings.js +1 -1
  84. package/src/toon/toonSettings.js +74 -0
  85. package/src/vegetation/stylizedFlower.js +6 -0
  86. package/src/version.js +1 -1
  87. package/src/water/waterDetailSpectrum.js +91 -0
  88. package/src/water/waterDynamics.js +422 -0
  89. package/src/water/waterFoamParticles.js +196 -0
  90. package/src/water/waterFoamTexture.js +57 -0
  91. package/src/water/waterHydrodynamics.js +209 -0
  92. package/src/water/waterMaterial.js +1 -0
  93. package/src/water/waterRenderExtension.js +107 -0
  94. package/src/water/waterScenePasses.js +14 -6
  95. package/src/water/waterSettings.js +53 -26
  96. package/src/water/waterShoreMaterial.js +38 -14
  97. package/src/water/waterSpectralOcean.js +137 -0
  98. package/src/water/waterStageSettings.js +19 -1
  99. package/src/water/waterSurface.js +62 -18
  100. package/src/water/waterUnderwaterAtmosphere.js +30 -3
  101. package/types/catalog/officialCatalog.d.ts +1 -0
  102. package/types/catalog/officialCatalogPlacement.d.ts +4 -0
  103. package/types/catalog/officialCatalogRockPackage.d.ts +68 -0
  104. package/types/cloud/noise/baseShapeVolume.d.ts +1 -1
  105. package/types/cloud/noise/textureCache.d.ts +12 -0
  106. package/types/core/sha256.d.ts +2 -0
  107. package/types/index.d.ts +30 -0
  108. package/types/rock-shader/rockMaterial.d.ts +3 -0
  109. package/types/rock-shader/rockShaderSettings.d.ts +2 -0
  110. package/types/rockgen/index.d.ts +1 -0
  111. package/types/rockgen/lod/index.d.ts +1 -0
  112. package/types/rockgen/lod/rockDenseFieldPolicy.d.ts +181 -0
  113. package/types/rockgen/rockDocument.d.ts +654 -71
  114. package/types/rockgen/surface/naturalRockSurface.d.ts +100 -0
  115. package/types/shaders-tsl/chunks/projected-water-caustics.d.ts +7 -1
  116. package/types/shaders-tsl/chunks/water-lighting.d.ts +4 -3
  117. package/types/shaders-tsl/water.d.ts +2 -1
  118. package/types/version.d.ts +1 -1
  119. package/types/water/waterDetailSpectrum.d.ts +13 -0
  120. package/types/water/waterDynamics.d.ts +89 -0
  121. package/types/water/waterFoamParticles.d.ts +32 -0
  122. package/types/water/waterFoamTexture.d.ts +1 -0
  123. package/types/water/waterHydrodynamics.d.ts +49 -0
  124. package/types/water/waterRenderExtension.d.ts +16 -0
  125. package/types/water/waterScenePasses.d.ts +1 -1
  126. package/types/water/waterSettings.d.ts +1 -0
  127. package/types/water/waterSpectralOcean.d.ts +17 -0
  128. package/types/water/waterStageSettings.d.ts +1 -1
  129. package/types/water/waterUnderwaterAtmosphere.d.ts +19 -4
@@ -13,6 +13,7 @@ import {
13
13
  setWaterDebugMode,
14
14
  updateWaterMaterialCamera,
15
15
  } from './waterMaterial.js';
16
+ import { WaterDynamics } from './waterDynamics.js';
16
17
  import { WaterCurrentField } from './waterCurrentField.js';
17
18
  import {
18
19
  buildNearshorePhaseField,
@@ -127,6 +128,7 @@ export class WaterSurface extends THREE.Mesh {
127
128
  passes = {},
128
129
  interaction = {},
129
130
  currentField = null,
131
+ dynamics = null,
130
132
  nearshorePhase = false,
131
133
  shoreState = false,
132
134
  underwaterAtmosphere = true,
@@ -138,8 +140,8 @@ export class WaterSurface extends THREE.Mesh {
138
140
  ...settingsOptions
139
141
  } = {}) {
140
142
  const settings = createWaterSettings(settingsOptions);
141
- const segmentsX = Math.min(maxSegments, Math.max(16, Math.round(width * segmentsPerMeter)));
142
- const segmentsZ = Math.min(maxSegments, Math.max(16, Math.round(depth * segmentsPerMeter)));
143
+ const segmentsX = dynamics ? (dynamics.columns ?? 96) - 1 : Math.min(maxSegments, Math.max(16, Math.round(width * segmentsPerMeter)));
144
+ const segmentsZ = dynamics ? (dynamics.rows ?? 96) - 1 : Math.min(maxSegments, Math.max(16, Math.round(depth * segmentsPerMeter)));
143
145
  const geometry = new THREE.PlaneGeometry(width, depth, segmentsX, segmentsZ);
144
146
  geometry.rotateX(-Math.PI / 2);
145
147
 
@@ -147,7 +149,7 @@ export class WaterSurface extends THREE.Mesh {
147
149
  // (graph shape must be known at creation); createWaterSettings drops the
148
150
  // key, so the classic ShaderMaterial path is untouched by it.
149
151
  super(geometry, createWaterMaterial(
150
- typeof bedHeight === 'function' ? { ...settings, shoaling: true } : settings,
152
+ { ...settings, shoaling: typeof bedHeight === 'function', dynamics: Boolean(dynamics) },
151
153
  ));
152
154
  this.name = 'WaterSurface';
153
155
  markFactoryStyleMaterial(this.material, 'WaterSurface');
@@ -236,7 +238,7 @@ export class WaterSurface extends THREE.Mesh {
236
238
  this.material.defines = { ...this.material.defines, WATER_SHOALING: 1 };
237
239
  }
238
240
 
239
- this.simulationEnabled = simulation !== false;
241
+ this.simulationEnabled = simulation !== false && !dynamics;
240
242
  this.ripples = this.simulationEnabled
241
243
  ? new WaterRippleSimulation({
242
244
  resolution: simulation.resolution ?? 256,
@@ -305,7 +307,7 @@ export class WaterSurface extends THREE.Mesh {
305
307
  // so foam transport and wet-sand memory do not enlarge the already-dense
306
308
  // main water material (important for WebGPU's private-memory limit).
307
309
  const shoreStateOptions = shoreState === true ? {} : shoreState;
308
- this.shoreState = this.bedHeightSampler && shoreStateOptions
310
+ this.shoreState = !dynamics && this.bedHeightSampler && shoreStateOptions
309
311
  ? new WaterShoreStateField({
310
312
  region: {
311
313
  centerX: 0,
@@ -320,6 +322,7 @@ export class WaterSurface extends THREE.Mesh {
320
322
  : null;
321
323
  this.shoreStateMaterials = new Set();
322
324
 
325
+ this.dynamics = dynamics ? new WaterDynamics(this, dynamics) : null;
323
326
  this.syncSimulationParameters();
324
327
  this.bindShoreState();
325
328
  }
@@ -506,7 +509,7 @@ export class WaterSurface extends THREE.Mesh {
506
509
  attachShoreStateMaterial(material) {
507
510
  if (!material) return this;
508
511
  this.shoreStateMaterials.add(material);
509
- updateWaterShoreMaterial(material, { stateField: this.shoreState });
512
+ updateWaterShoreMaterial(material, { stateField: this.dynamics ?? this.shoreState });
510
513
  return this;
511
514
  }
512
515
 
@@ -517,7 +520,11 @@ export class WaterSurface extends THREE.Mesh {
517
520
 
518
521
  bindShoreState() {
519
522
  const uniforms = this.material.uniforms;
520
- if (this.shoreState) {
523
+ if (this.dynamics) {
524
+ uniforms.uShoreStateMap.value = this.dynamics.texture;
525
+ uniforms.uUseShoreState.value = 1;
526
+ this.dynamics.getRegion(uniforms.uShoreStateRegion.value);
527
+ } else if (this.shoreState) {
521
528
  uniforms.uShoreStateMap.value = this.shoreState.texture;
522
529
  uniforms.uUseShoreState.value = 1;
523
530
  this.shoreState.getRegion(uniforms.uShoreStateRegion.value);
@@ -525,7 +532,7 @@ export class WaterSurface extends THREE.Mesh {
525
532
  uniforms.uUseShoreState.value = 0;
526
533
  }
527
534
  for (const material of this.shoreStateMaterials ?? []) {
528
- updateWaterShoreMaterial(material, { stateField: this.shoreState });
535
+ updateWaterShoreMaterial(material, { stateField: this.dynamics ?? this.shoreState });
529
536
  }
530
537
  return this;
531
538
  }
@@ -828,11 +835,12 @@ export class WaterSurface extends THREE.Mesh {
828
835
  return surfaceY + this.relativeSurfaceHeightAt(x, z, surfaceY);
829
836
  }
830
837
 
831
- // Surface height relative to the rest level the exact CPU mirror of the
832
- // vertex shader's shoaling/breaking/swash displacement, so buoyancy, swim
833
- // floats, and splash anchors sit on the rendered surface everywhere,
834
- // including the surf zone and the run-up film on the beach.
838
+ // Approximate CPU height relative to rest level. Mirrors vertical shoreline
839
+ // shaping but does not invert Gerstner horizontal displacement or read GPU
840
+ // ripples. Do not use this as an exact Eulerian contact/volume solver; see
841
+ // docs/audits/water-shader-lab-2026-09-05.md.
835
842
  relativeSurfaceHeightAt(x, z, surfaceY) {
843
+ if (this.dynamics?.gridSignature) return this.dynamics.sample(x, z).height - surfaceY;
836
844
  if (!this.bedHeightSampler) {
837
845
  return sampleGerstnerHeight(this.gerstnerWaves, x, z, this.time);
838
846
  }
@@ -888,7 +896,7 @@ export class WaterSurface extends THREE.Mesh {
888
896
  swashFrame.primaryDirectionX ?? waves[0]?.dirX ?? settings.flowDirection?.[0] ?? 0,
889
897
  swashFrame.cycle,
890
898
  swashFrame.edgeShape,
891
- );
899
+ ) * swashFrame.activity * (maximumDistance > 0 ? 1 : 0);
892
900
  const edgeHead = edgeDistance * safeSlope + edgeOffset * safeSlope;
893
901
  const filmHead = restDepth + edgeHead;
894
902
  const film = THREE.MathUtils.clamp(filmHead * 0.45 + 0.008, 0.003, 0.045);
@@ -916,6 +924,10 @@ export class WaterSurface extends THREE.Mesh {
916
924
  // their traveling face flow; explicit swash adds uphill uprush and downhill
917
925
  // backwash so gameplay objects move with the rendered shoreline.
918
926
  getFlowAt(x, z, out = new THREE.Vector2()) {
927
+ if (this.dynamics?.gridSignature) {
928
+ const sample = this.dynamics.sample(x, z);
929
+ return out.set(sample.velocityX, sample.velocityZ);
930
+ }
919
931
  out.set(0, 0);
920
932
  if (this.currentField) {
921
933
  this.currentField.sampleAt(x, z, currentSampleScratch);
@@ -946,7 +958,7 @@ export class WaterSurface extends THREE.Mesh {
946
958
  swashFrame.primaryDirectionX ?? this.gerstnerWaves[0]?.dirX ?? 0,
947
959
  swashFrame.cycle,
948
960
  swashFrame.edgeShape,
949
- );
961
+ ) * swashFrame.activity;
950
962
  const maximumDistance = this.settings.runupDistance;
951
963
  const edgeDistance = swashFrame.edgeDistance;
952
964
  const head = edgeDistance * slope + offset * slope;
@@ -964,7 +976,7 @@ export class WaterSurface extends THREE.Mesh {
964
976
  frame.primaryDirectionX ?? this.gerstnerWaves[0]?.dirX ?? 0,
965
977
  frame.cycle,
966
978
  frame.edgeShape,
967
- );
979
+ ) * frame.activity;
968
980
  };
969
981
  const before = totalEdgeAt(this.time - dt);
970
982
  const after = totalEdgeAt(this.time + dt);
@@ -1128,6 +1140,7 @@ export class WaterSurface extends THREE.Mesh {
1128
1140
  // breakerAmount setting and rebuilds the break line whenever the surface
1129
1141
  // moves or the swell energy shifts enough to relocate the collapse depth.
1130
1142
  updateBreakers() {
1143
+ if (this.dynamics) return;
1131
1144
  const enabled = shouldUseDedicatedBreakerShell(this.settings, Boolean(this.bedHeightSampler));
1132
1145
  if (!enabled) {
1133
1146
  if (this.breakers) {
@@ -1190,6 +1203,7 @@ export class WaterSurface extends THREE.Mesh {
1190
1203
  // Composite splash at a world position: particles + a downward impulse and
1191
1204
  // an outward ring wave in the ripple simulation.
1192
1205
  splash(worldPoint, { strength = 1, radius = 0.5 } = {}) {
1206
+ this.dynamics?.impulse(worldPoint.x, worldPoint.z, strength, radius);
1193
1207
  const local = this.worldToLocalPoint(worldPoint);
1194
1208
  local.y = this.relativeSurfaceHeightAt(
1195
1209
  worldPoint.x ?? 0, worldPoint.z ?? 0, worldPositionScratch.y);
@@ -1210,6 +1224,7 @@ export class WaterSurface extends THREE.Mesh {
1210
1224
 
1211
1225
  // Plain ripple impulse (no particles) — wakes, rain, gentle touches.
1212
1226
  addRipple(worldPoint, { radius = 0.4, strength = 0.4 } = {}) {
1227
+ this.dynamics?.impulse(worldPoint.x, worldPoint.z, strength * this.settings.rippleStrength, radius);
1213
1228
  this.ripples?.addImpulse(worldPoint.x, worldPoint.z, {
1214
1229
  radius,
1215
1230
  strength: strength * this.settings.rippleStrength,
@@ -1235,6 +1250,18 @@ export class WaterSurface extends THREE.Mesh {
1235
1250
  this.interactions.remove(id);
1236
1251
  }
1237
1252
 
1253
+ // Hosts with buoyant actors may prepare the field before moving actors;
1254
+ // update() then captures that same field without advancing it a second time.
1255
+ prepareDynamics(delta) {
1256
+ if (this.dynamics) {
1257
+ this.dynamics.update(Math.max(0, Math.min(delta, 0.1)));
1258
+ this.time = this.dynamics.time;
1259
+ this.dynamicsPrepared = true;
1260
+ this.bindShoreState();
1261
+ }
1262
+ return this;
1263
+ }
1264
+
1238
1265
  // Call once per frame before rendering the scene.
1239
1266
  update(renderer, scene, camera, delta) {
1240
1267
  // A preceding frame's underwater atmosphere must never leak into the
@@ -1259,7 +1286,12 @@ export class WaterSurface extends THREE.Mesh {
1259
1286
  this.bakeShoalingDepths();
1260
1287
  }
1261
1288
  }
1262
- this.updateBreakers();
1289
+ if (this.dynamics) {
1290
+ if (!this.dynamicsPrepared) this.dynamics.update(clampedDelta);
1291
+ this.dynamicsPrepared = false;
1292
+ this.time = this.dynamics.time;
1293
+ this.bindShoreState();
1294
+ } else this.updateBreakers();
1263
1295
 
1264
1296
  if (this.ripples) {
1265
1297
  this.getWorldPosition(worldPositionScratch);
@@ -1344,11 +1376,18 @@ export class WaterSurface extends THREE.Mesh {
1344
1376
  updateWaterMaterialCamera(this.material, renderer, camera);
1345
1377
  this.getWorldPosition(worldPositionScratch);
1346
1378
  const cameraPosition = camera.getWorldPosition(followScratch);
1347
- const cameraBelow = cameraPosition.y < worldPositionScratch.y;
1379
+ // Use the animated local column, including finite XZ and the authored
1380
+ // bed. A flat rest-plane test misclassified cameras inside crests, above
1381
+ // troughs, or below dry terrain. Capture passes consume this same flag.
1382
+ const cameraSurfaceY = this.getHeightAt(cameraPosition.x, cameraPosition.z);
1383
+ const cameraBedY = this.bedHeightSampler?.(cameraPosition.x, cameraPosition.z) ?? -Infinity;
1384
+ const cameraBelow = this.containsPoint(cameraPosition.x, cameraPosition.z)
1385
+ && cameraPosition.y < cameraSurfaceY && cameraPosition.y > cameraBedY
1386
+ && (!this.dynamics || this.dynamics.sample(cameraPosition.x, cameraPosition.z).wet);
1348
1387
  uniforms.uCameraBelow.value = cameraBelow ? 1 : 0;
1349
1388
  const renderedSettings = this.renderedSettings ?? this.settings;
1350
1389
  updateProjectedWaterCaustics({
1351
- enabled: cameraBelow && renderedSettings.causticsStrength > 0.001,
1390
+ enabled: (cameraBelow || Boolean(this.dynamics)) && renderedSettings.causticsStrength > 0.001,
1352
1391
  time: this.time,
1353
1392
  waterLevel: worldPositionScratch.y,
1354
1393
  centerX: worldPositionScratch.x,
@@ -1361,6 +1400,8 @@ export class WaterSurface extends THREE.Mesh {
1361
1400
  speed: renderedSettings.causticsSpeed,
1362
1401
  flowDirection: renderedSettings.flowDirection,
1363
1402
  waveDistortion: 0.035 + renderedSettings.detailNormalStrength * 0.08,
1403
+ surfaceMap: this.dynamics?.causticTexture ?? null,
1404
+ surfaceRegion: this.dynamics?.causticRegion ?? null,
1364
1405
  depthAttenuation: 1 / Math.max(
1365
1406
  renderedSettings.depthFadeDistance + renderedSettings.deepFadeDistance,
1366
1407
  0.25,
@@ -1389,12 +1430,15 @@ export class WaterSurface extends THREE.Mesh {
1389
1430
  waterZ: worldPositionScratch.z,
1390
1431
  width: this.width,
1391
1432
  depth: this.depth,
1433
+ surfaceY: cameraSurfaceY,
1434
+ bedY: cameraBedY,
1392
1435
  settings: renderedSettings,
1393
1436
  });
1394
1437
  return this;
1395
1438
  }
1396
1439
 
1397
1440
  dispose() {
1441
+ this.dynamics?.dispose();
1398
1442
  this.volumeSkirt?.geometry.dispose();
1399
1443
  this.volumeSkirt?.material.dispose();
1400
1444
  this.geometry.dispose();
@@ -1,4 +1,5 @@
1
1
  import * as THREE from 'three';
2
+ import { cameraPosition, clamp, exp, Fn, length, max, mix, output, positionWorld, uniform, vec3, vec4 } from 'three/tsl';
2
3
 
3
4
  export const DEFAULT_WATER_UNDERWATER_ATMOSPHERE = Object.freeze({
4
5
  enabled: true,
@@ -55,6 +56,7 @@ export function createWaterUnderwaterAtmosphereOptions(options = true) {
55
56
  clipToSurfaceBounds: source.clipToSurfaceBounds ?? true,
56
57
  boundsMargin: Math.max(0, finiteOr(source.boundsMargin, 0)),
57
58
  clearFogNode: source.clearFogNode ?? true,
59
+ waterPathFog: source.waterPathFog ?? false,
58
60
  };
59
61
  }
60
62
 
@@ -65,6 +67,8 @@ export function resolveWaterUnderwaterAtmosphereState({
65
67
  waterX = 0,
66
68
  waterY = 0,
67
69
  waterZ = 0,
70
+ surfaceY = waterY,
71
+ bedY = -Infinity,
68
72
  width = Infinity,
69
73
  depth = Infinity,
70
74
  settings = {},
@@ -76,10 +80,12 @@ export function resolveWaterUnderwaterAtmosphereState({
76
80
  Math.abs(cameraX - waterX) <= Math.max(0, width * 0.5) + boundsMargin
77
81
  && Math.abs(cameraZ - waterZ) <= Math.max(0, depth * 0.5) + boundsMargin
78
82
  );
79
- const submergedDepth = Math.max(waterY - cameraY, 0);
83
+ const submergedDepth = Math.max(surfaceY - cameraY, 0);
80
84
  const active = Boolean(
81
85
  resolvedOptions.enabled
82
- && cameraY < waterY
86
+ && cameraY < surfaceY
87
+ && cameraY > bedY
88
+ && surfaceY > bedY
83
89
  && insideBounds
84
90
  );
85
91
  const midColor = colorArray(
@@ -98,7 +104,10 @@ export function resolveWaterUnderwaterAtmosphereState({
98
104
  fogFar: resolvedOptions.fogFar,
99
105
  overlayOpacity: resolvedOptions.overlayOpacity,
100
106
  clearFogNode: resolvedOptions.clearFogNode,
107
+ waterPathFog: resolvedOptions.waterPathFog ?? false,
101
108
  waterY,
109
+ surfaceY,
110
+ bedY,
102
111
  };
103
112
  }
104
113
 
@@ -220,7 +229,25 @@ function applySelectedAtmosphere(scene, state) {
220
229
  state.ownedFog.far = selected.fogFar;
221
230
  scene.background = state.ownedBackground;
222
231
  scene.fog = state.ownedFog;
223
- if (selected.clearFogNode) scene.fogNode = null;
232
+ if (selected.waterPathFog) {
233
+ if (!state.opticalFog) {
234
+ const color = uniform(new THREE.Color()), level = uniform(0), density = uniform(1);
235
+ const node = Fn(() => {
236
+ const ray = positionWorld.sub(cameraPosition);
237
+ // Main camera is submerged. Above-water geometry only accumulates
238
+ // attenuation up to the interface, never over its segment in air.
239
+ const fraction = clamp(level.sub(cameraPosition.y).div(max(ray.y, 1e-5)), 0.0, 1.0);
240
+ const waterDistance = length(ray).mul(fraction);
241
+ const transmission = exp(vec3(0.18,0.065,0.04).mul(waterDistance).mul(density).negate());
242
+ return vec4(output.rgb.mul(transmission).add(color.mul(transmission.oneMinus())), output.a);
243
+ })();
244
+ state.opticalFog = { color, level, density, node };
245
+ }
246
+ state.opticalFog.color.value.setRGB(...selected.color, THREE.SRGBColorSpace);
247
+ state.opticalFog.level.value = selected.surfaceY ?? selected.waterY;
248
+ state.opticalFog.density.value = 32 / Math.max(selected.fogFar, 1);
249
+ scene.fogNode = state.opticalFog.node;
250
+ } else if (selected.clearFogNode) scene.fogNode = null;
224
251
  placeAtmosphereOverlay(
225
252
  ensureAtmosphereOverlay(scene, state),
226
253
  selected.camera,
@@ -2,3 +2,4 @@ export * from "./officialCatalogProvider.js";
2
2
  export * from "./officialCatalogAssetRuntime.js";
3
3
  export * from "./officialCatalogLod.js";
4
4
  export * from "./officialCatalogPlacement.js";
5
+ export * from "./officialCatalogRockPackage.js";
@@ -18,6 +18,9 @@ export interface OfficialCatalogPlacementOptions {
18
18
  rotation?: CatalogVector3;
19
19
  scale?: CatalogVector3;
20
20
  targetId?: string | null;
21
+ textures?: Readonly<Record<string, unknown>>;
22
+ usePublishedRockSurface?: boolean;
23
+ variation?: number;
21
24
  }
22
25
  export interface OfficialCatalogPlacement {
23
26
  readonly asset: unknown;
@@ -32,6 +35,7 @@ export interface OfficialCatalogPlacement {
32
35
  };
33
36
  readonly normalization: Readonly<Record<string, unknown>>;
34
37
  readonly object: Object3D;
38
+ readonly publishedRockSurface: unknown;
35
39
  readonly quality: unknown;
36
40
  readonly released: boolean;
37
41
  readonly style: StyleApplicationResult;
@@ -0,0 +1,68 @@
1
+ import type { Texture, TextureLoader } from 'three';
2
+
3
+ export const OFFICIAL_ROCK_GALLERY_RECIPE_SCHEMA: 'toonlab/rock-gallery-recipe';
4
+ export const OFFICIAL_ROCK_MATERIAL_SCHEMA: 'toonlab.pro-rock-material';
5
+
6
+ export interface OfficialCatalogArtifact {
7
+ readonly byteSize: number;
8
+ readonly contentType: string;
9
+ readonly name: string;
10
+ readonly sha256: string;
11
+ readonly url: string | null;
12
+ }
13
+
14
+ export interface OfficialCatalogRockPackageFiles {
15
+ readonly collisionModelUrl: string | null;
16
+ readonly controlModelUrl: string | null;
17
+ readonly lodModelUrls: readonly (string | null)[];
18
+ readonly manifestUrl: string | null;
19
+ readonly materialConfigUrl: string | null;
20
+ readonly natureProvenanceUrl: string | null;
21
+ readonly natureReferenceUrl: string | null;
22
+ readonly realisticModelUrl: string;
23
+ readonly realisticPreviewUrl: string | null;
24
+ readonly recipeUrl: string | null;
25
+ readonly retainedHighModelUrl: string | null;
26
+ readonly stylizedModelUrl: string | null;
27
+ readonly stylizedPreviewUrl: string | null;
28
+ }
29
+
30
+ export interface OfficialCatalogRockPackage {
31
+ readonly asset: Readonly<Record<string, unknown>>;
32
+ readonly files: OfficialCatalogRockPackageFiles;
33
+ readonly manifest: Readonly<Record<string, unknown>> | null;
34
+ readonly materialConfig: Readonly<Record<string, unknown>> | null;
35
+ readonly natureProvenance: Readonly<Record<string, unknown>> | null;
36
+ readonly recipe: Readonly<Record<string, unknown>> | null;
37
+ }
38
+
39
+ export interface OfficialCatalogRockShaderInput {
40
+ readonly materialConfig: Readonly<Record<string, unknown>>;
41
+ readonly settings: Readonly<Record<string, unknown>>;
42
+ readonly textures: Readonly<Record<string, Texture>>;
43
+ }
44
+
45
+ export function findOfficialCatalogArtifact(
46
+ asset: { readonly artifacts?: readonly OfficialCatalogArtifact[] },
47
+ ...names: string[]
48
+ ): OfficialCatalogArtifact | null;
49
+ export function getOfficialCatalogArtifactUrl(
50
+ asset: { readonly artifacts?: readonly OfficialCatalogArtifact[] },
51
+ ...names: string[]
52
+ ): string | null;
53
+ export function loadOfficialCatalogRockPackage(
54
+ asset: Readonly<Record<string, unknown>>,
55
+ options?: {
56
+ readonly fetchImpl?: typeof globalThis.fetch;
57
+ readonly includeManifest?: boolean;
58
+ readonly includeNatureProvenance?: boolean;
59
+ },
60
+ ): Promise<OfficialCatalogRockPackage>;
61
+ export function loadOfficialCatalogRockShaderInput(
62
+ rockPackage: OfficialCatalogRockPackage,
63
+ options?: { readonly textureLoader?: TextureLoader },
64
+ ): Promise<OfficialCatalogRockShaderInput | null>;
65
+ export function createOfficialCatalogRockEditorDescriptor(
66
+ asset: Readonly<Record<string, unknown>>,
67
+ rockPackage?: OfficialCatalogRockPackage | null,
68
+ ): Readonly<Record<string, unknown>> | null;
@@ -44,7 +44,7 @@ export function createCloudBaseShapeVolume({ dims, seed, }?: {
44
44
  seed?: number;
45
45
  }): import("three").Data3DTexture;
46
46
  /**
47
- * Cached base-shape volume, keyed by resolution and seed. A tier switch that
47
+ * Cached canonical base-shape volume, keyed by resolution. A tier switch that
48
48
  * returns to a resolution already baked pays nothing, and the shadow/env-map
49
49
  * bakes share the runtime's volumes.
50
50
  */
@@ -0,0 +1,12 @@
1
+ export function getCloudTextureCacheStats(): {
2
+ retainedBytes: number;
3
+ retainedEntries: number;
4
+ maxBytes: number;
5
+ maxEntries: number;
6
+ };
7
+ export function createCloudTextureCache(namespace: any): {
8
+ get(key: any): any;
9
+ set(key: any, texture: any): void;
10
+ values(): Generator<any, void, unknown>;
11
+ clear(): void;
12
+ };
@@ -0,0 +1,2 @@
1
+ /** Synchronous browser-safe SHA-256 used for portable document identities. */
2
+ export function sha256Hex(value: any): string;
package/types/index.d.ts CHANGED
@@ -243,6 +243,11 @@ export const DEFAULT_WATER_INTERACTION_CONFIG: any;
243
243
  export const DEFAULT_WATER_SCENARIO: any;
244
244
  export const DEFAULT_WATER_SETTINGS: any;
245
245
  export const DEFAULT_WATER_UNDERWATER_ATMOSPHERE: any;
246
+ export const DENSE_FIELD_ROCK_CULL_BELOW_PIXELS: any;
247
+ export const DENSE_FIELD_ROCK_LOD_LEVELS: any;
248
+ export const DENSE_FIELD_ROCK_PIXEL_THRESHOLDS: any;
249
+ export const DENSE_FIELD_ROCK_PRODUCTION_RULE: any;
250
+ export const DENSE_FIELD_ROCK_TRIANGLE_CEILINGS: any;
246
251
  export const ENVIRONMENT_DEBUG_MODES: any;
247
252
  export const ENVIRONMENT_MATERIAL_ROLES: any;
248
253
  export const ENVIRONMENT_PRESET_ALIASES: any;
@@ -347,6 +352,8 @@ export const MOON_DISC_NORMALISATION: any;
347
352
  export const MULTI_SCATTERING_LUT_SIZE: any;
348
353
  export class ManufacturedStyleLabelingError { constructor(...args: any[]); [key: string]: any; }
349
354
  export const NATIVE_LOCOMOTION_CLIP_NAMES: any;
355
+ export const NATURAL_ROCK_MAP_ROLES: any;
356
+ export const NATURAL_ROCK_SURFACE_PROFILES: any;
350
357
  export const NEEDLE_LEAF_SHAPES: any;
351
358
  export const NEUTRAL_ENVIRONMENT_PRESET: any;
352
359
  export const NEUTRAL_ENVIRONMENT_RESOLVED_SETTINGS: any;
@@ -371,6 +378,8 @@ export const NIGHT_SKY_PARAM_KEYS: any;
371
378
  export const NIGHT_SKY_PARAM_SCHEMA: any;
372
379
  export const OFFICIAL_CATALOG_ASSET_VERSION: any;
373
380
  export const OFFICIAL_CATALOG_PROVIDER_TRANSPORTS: any;
381
+ export const OFFICIAL_ROCK_GALLERY_RECIPE_SCHEMA: any;
382
+ export const OFFICIAL_ROCK_MATERIAL_SCHEMA: any;
374
383
  export class OfficialCatalogProviderError { constructor(...args: any[]); [key: string]: any; }
375
384
  export const POST_GENERATOR_DOMAIN: any;
376
385
  export const POST_PROCESSING_PRESETS: any;
@@ -397,6 +406,7 @@ export const RESOLVED_SCENE_LOOK_DOCUMENT_TYPE: any;
397
406
  export const RESOLVED_SCENE_LOOK_DOCUMENT_VERSION: any;
398
407
  export const REVIEWED_CATALOG_LICENSES: any;
399
408
  export const RIM_LIGHT_MODES: any;
409
+ export const ROCKGEN_MAX_MESH_CUT_OPERATIONS: any;
400
410
  export const ROCKGEN_MAX_MESH_EDIT_DELTAS: any;
401
411
  export const ROCKGEN_MAX_MESH_EDIT_OPERATIONS: any;
402
412
  export const ROCKGEN_MESH_EDIT_ENCODING: any;
@@ -777,6 +787,9 @@ export function createBranchTubeGeometry(...args: any[]): any;
777
787
  export function createBranchingTreeSkeleton(...args: any[]): any;
778
788
  export function createC7GeologyMapData(...args: any[]): any;
779
789
  export function createC7SurfaceSpecification(...args: any[]): any;
790
+ export function createC8ReferenceAuthoritySourceId(...args: any[]): any;
791
+ export function createC8ReferenceGeometrySourceId(...args: any[]): any;
792
+ export function createC8ReferenceSurfaceSourceId(...args: any[]): any;
780
793
  export function createCallMeSenseiGrassField(...args: any[]): any;
781
794
  export function createCallMeSenseiGrassMaterial(...args: any[]): any;
782
795
  export function createCallMeSenseiSkyLightProbe(...args: any[]): any;
@@ -809,6 +822,7 @@ export function createCurlNoiseVolume(...args: any[]): any;
809
822
  export function createCurveFrame(...args: any[]): any;
810
823
  export function createDebugEnvironmentMaterial(...args: any[]): any;
811
824
  export function createDefaultRockShaderTextureSet(...args: any[]): any;
825
+ export function createDenseFieldRockLodRuntime(...args: any[]): any;
812
826
  export function createDensityWeightMask(...args: any[]): any;
813
827
  export function createDirectionalLightDescriptor(...args: any[]): any;
814
828
  export function createDiscAreaLightDescriptor(...args: any[]): any;
@@ -896,10 +910,13 @@ export function createManufacturedMaterialLook(...args: any[]): any;
896
910
  export function createMaterialMapSettings(...args: any[]): any;
897
911
  export function createMoonAlbedoData(...args: any[]): any;
898
912
  export function createMoonAlbedoTexture(...args: any[]): any;
913
+ export function createNaturalRockMapData(...args: any[]): any;
914
+ export function createNaturalRockSurfaceSpecification(...args: any[]): any;
899
915
  export function createNightSky(...args: any[]): any;
900
916
  export function createNoisePatchMask(...args: any[]): any;
901
917
  export function createOfficialCatalogAssetRuntime(...args: any[]): any;
902
918
  export function createOfficialCatalogProvider(...args: any[]): any;
919
+ export function createOfficialCatalogRockEditorDescriptor(...args: any[]): any;
903
920
  export function createOrganLeafSpriteTexture(...args: any[]): any;
904
921
  export function createOssStyleBundleProvider(...args: any[]): any;
905
922
  export function createOutlineSettings(...args: any[]): any;
@@ -1031,6 +1048,7 @@ export function deriveCanopyPalette(...args: any[]): any;
1031
1048
  export function describeCatalogLicense(...args: any[]): any;
1032
1049
  export function describeNeutralStyleCoverage(...args: any[]): any;
1033
1050
  export function describeTexture(...args: any[]): any;
1051
+ export function describeToonLabDirectionalBeddingProjection(...args: any[]): any;
1034
1052
  export function deserializeLightingLook(...args: any[]): any;
1035
1053
  export function deserializeLightingLookPreset(...args: any[]): any;
1036
1054
  export function deserializeLightingRecipe(...args: any[]): any;
@@ -1059,6 +1077,7 @@ export const environmentStateUniforms: any;
1059
1077
  export function environmentUsesAlphaCutout(...args: any[]): any;
1060
1078
  export function erodeHeightfield(...args: any[]): any;
1061
1079
  export function erodeHeightfieldStylized(...args: any[]): any;
1080
+ export function estimateCatalogProjectedPixels(...args: any[]): any;
1062
1081
  export function estimateSurfaceNetsResolution(...args: any[]): any;
1063
1082
  export function evaluateAssetCandidate(...args: any[]): any;
1064
1083
  export function evaluateField(...args: any[]): any;
@@ -1073,6 +1092,7 @@ export const fallbackEnvironmentNormalTexture: any;
1073
1092
  export const fallbackEnvironmentWhiteTexture: any;
1074
1093
  export function fetchStyleBundle(...args: any[]): any;
1075
1094
  export function findCloudLayerCrossing(...args: any[]): any;
1095
+ export function findOfficialCatalogArtifact(...args: any[]): any;
1076
1096
  export function findPrimarySkinnedMesh(...args: any[]): any;
1077
1097
  export function finiteDepthWaveNumberRatio(...args: any[]): any;
1078
1098
  export function fitModelForController(...args: any[]): any;
@@ -1101,6 +1121,7 @@ export function getLightingStyleGeneratorFamilyOptions(...args: any[]): any;
1101
1121
  export function getLightingStylePresetOptions(...args: any[]): any;
1102
1122
  export function getLightingTypeCapability(...args: any[]): any;
1103
1123
  export function getMoonAlbedoTexture(...args: any[]): any;
1124
+ export function getOfficialCatalogArtifactUrl(...args: any[]): any;
1104
1125
  export function getPostGeneratorFamilyOptions(...args: any[]): any;
1105
1126
  export function getPostProcessingPresetOptions(...args: any[]): any;
1106
1127
  export function getRenderLayer(...args: any[]): any;
@@ -1133,6 +1154,7 @@ export function hashGeometry(...args: any[]): any;
1133
1154
  export function henyeyGreensteinPhaseNode(...args: any[]): any;
1134
1155
  export function heroCloudSkyOverrides(...args: any[]): any;
1135
1156
  export function hourFromDayCycleTime(...args: any[]): any;
1157
+ export function inferDenseFieldRockClass(...args: any[]): any;
1136
1158
  export function inferManufacturedObjectClass(...args: any[]): any;
1137
1159
  export function inspectRockGeometryTangents(...args: any[]): any;
1138
1160
  export function inspectRockRegionBinding(...args: any[]): any;
@@ -1147,6 +1169,7 @@ export function isEnvironmentShadowMesh(...args: any[]): any;
1147
1169
  export function isFoliageMaterial(...args: any[]): any;
1148
1170
  export function isPostProcessingEnabled(...args: any[]): any;
1149
1171
  export function isRockHelperPiece(...args: any[]): any;
1172
+ export function isRockSourceMeshReference(...args: any[]): any;
1150
1173
  export function isScanAssetMaterial(...args: any[]): any;
1151
1174
  export function isUtilityTextureLabel(...args: any[]): any;
1152
1175
  export function isVegetationSharedShaderGroup(...args: any[]): any;
@@ -1162,6 +1185,8 @@ export function loadEnvironmentTexture(...args: any[]): any;
1162
1185
  export function loadIdleClipForTarget(...args: any[]): any;
1163
1186
  export function loadJumpClipForTarget(...args: any[]): any;
1164
1187
  export function loadOfficialCatalogAsset(...args: any[]): any;
1188
+ export function loadOfficialCatalogRockPackage(...args: any[]): any;
1189
+ export function loadOfficialCatalogRockShaderInput(...args: any[]): any;
1165
1190
  export function loadPackagedLocomotionClipsForTarget(...args: any[]): any;
1166
1191
  export function loadRetargetedMixamoClipForTarget(...args: any[]): any;
1167
1192
  export function loadRunningClipForTarget(...args: any[]): any;
@@ -1340,6 +1365,7 @@ export function resolveLuminairePreset(...args: any[]): any;
1340
1365
  export function resolveManufacturedMaterialLook(...args: any[]): any;
1341
1366
  export function resolveMarchBudget(...args: any[]): any;
1342
1367
  export function resolveNativeLocomotionClips(...args: any[]): any;
1368
+ export function resolveNaturalRockProjection(...args: any[]): any;
1343
1369
  export function resolveOfficialCatalogUrl(...args: any[]): any;
1344
1370
  export function resolveOutlineForMaterial(...args: any[]): any;
1345
1371
  export function resolvePadPruning(...args: any[]): any;
@@ -1432,6 +1458,7 @@ export function sceneCollisionRuntimeFor(...args: any[]): any;
1432
1458
  export function sculptEditBounds(...args: any[]): any;
1433
1459
  export function searchSurfaceNetsResolution(...args: any[]): any;
1434
1460
  export function selectCatalogLodLevel(...args: any[]): any;
1461
+ export function selectCatalogLodLevelByProjectedPixels(...args: any[]): any;
1435
1462
  export function serializableTreeOptions(...args: any[]): any;
1436
1463
  export function serializeGrassPreset(...args: any[]): any;
1437
1464
  export function serializeGroundShaderPreset(...args: any[]): any;
@@ -1520,6 +1547,8 @@ export function toMaterialArray(...args: any[]): any;
1520
1547
  export function toSerializableCloudStyleParams(...args: any[]): any;
1521
1548
  export function toSerializableSkyColorParams(...args: any[]): any;
1522
1549
  export function toSerializableSkyParams(...args: any[]): any;
1550
+ export function toonLabDirectionalBeddingColor(...args: any[]): any;
1551
+ export function toonLabDirectionalBeddingNormal(...args: any[]): any;
1523
1552
  export function toonLabMountainProfileFromResolvedMaterial(...args: any[]): any;
1524
1553
  export function toonLabRockProfileFromResolvedMaterial(...args: any[]): any;
1525
1554
  export function toonLabScalar(...args: any[]): any;
@@ -1542,6 +1571,7 @@ export function usesAlphaBlend(...args: any[]): any;
1542
1571
  export function validateAssetSourcingPolicy(...args: any[]): any;
1543
1572
  export function validateCollisionMetadata(...args: any[]): any;
1544
1573
  export function validateCompiledTreeManifest(...args: any[]): any;
1574
+ export function validateDenseFieldRockLodTargets(...args: any[]): any;
1545
1575
  export function validateEnvironmentPresetDocument(...args: any[]): any;
1546
1576
  export function validateGrassPresetDocument(...args: any[]): any;
1547
1577
  export function validateGroundShaderPresetDocument(...args: any[]): any;
@@ -9,12 +9,15 @@ export const TOONLAB_ROCK_PROFILE_DEFAULTS: any;
9
9
  export const TOONLAB_ROCK_SHADER_GUID: any;
10
10
  export function createToonLabMountainMaterial(...args: any[]): any;
11
11
  export function createToonRockMaterial(...args: any[]): any;
12
+ export function describeToonLabDirectionalBeddingProjection(...args: any[]): any;
12
13
  export function loadToonLabMountainMaterial(...args: any[]): any;
13
14
  export function loadToonRockMaterial(...args: any[]): any;
14
15
  export function loadToonRockMaterialInputs(...args: any[]): any;
15
16
  export function normalizeToonLabMountainProfile(...args: any[]): any;
16
17
  export function normalizeToonLabRockProfile(...args: any[]): any;
17
18
  export function tangentNormalToView(...args: any[]): any;
19
+ export function toonLabDirectionalBeddingColor(...args: any[]): any;
20
+ export function toonLabDirectionalBeddingNormal(...args: any[]): any;
18
21
  export function toonLabMountainProfileFromResolvedMaterial(...args: any[]): any;
19
22
  export function toonLabRockProfileFromResolvedMaterial(...args: any[]): any;
20
23
  export function toonLabTriplanarColor(...args: any[]): any;
@@ -70,6 +70,8 @@ export const DEFAULT_ROCK_SHADER_SETTINGS: Readonly<{
70
70
  }>;
71
71
  export const CALL_ME_SENSEI_ROCK_SHADER_SETTINGS: Readonly<{
72
72
  projection: Readonly<{
73
+ mode: "triplanar";
74
+ upAxis: "y";
73
75
  scale: 48;
74
76
  saturation: 1;
75
77
  contrast: 1;
@@ -10,3 +10,4 @@ export * from "./mesh/meshDocument.js";
10
10
  export * from "./lod/index.js";
11
11
  export * from "./export/glbExport.js";
12
12
  export * from "./surface/c7GeologySurface.js";
13
+ export { C8_FIRST12_LITHOLOGY_PROFILES as NATURAL_ROCK_SURFACE_PROFILES, C8_FIRST12_MAP_ROLES as NATURAL_ROCK_MAP_ROLES, createC8First12GeologyMapData as createNaturalRockMapData, createC8First12SurfaceSpecification as createNaturalRockSurfaceSpecification, resolveC8First12Projection as resolveNaturalRockProjection } from "./surface/naturalRockSurface.js";
@@ -1,4 +1,5 @@
1
1
  export * from "./rockLodMetrics.js";
2
+ export * from "./rockDenseFieldPolicy.js";
2
3
  export * from "./rockLodPlanner.js";
3
4
  export * from "./rockLodPolicy.js";
4
5
  export * from "./rockLodRuntime.js";