procedural-terrains 2.0.0 → 2.0.1
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.
- package/dist/{FiniteTerrain-B34WMz5S.js → FiniteTerrain-B5_3y6xX.js} +3 -3
- package/dist/{FiniteTerrain-B34WMz5S.js.map → FiniteTerrain-B5_3y6xX.js.map} +1 -1
- package/dist/{InfiniteTerrain-SgoJz3qJ.js → InfiniteTerrain-jeCy6RED.js} +5 -5
- package/dist/{InfiniteTerrain-SgoJz3qJ.js.map → InfiniteTerrain-jeCy6RED.js.map} +1 -1
- package/dist/{MiniTerrain-Blt0H1S0.js → MiniTerrain-Bb5VYkZU.js} +8 -8
- package/dist/MiniTerrain-Bb5VYkZU.js.map +1 -0
- package/dist/{PlanetMaterial-B1_ZPlx5.js → PlanetMaterial-Cs-_x6vr.js} +4 -4
- package/dist/{PlanetMaterial-B1_ZPlx5.js.map → PlanetMaterial-Cs-_x6vr.js.map} +1 -1
- package/dist/{PlanetTerrain-DCvxS1Q8.js → PlanetTerrain-Bsfx7YA6.js} +5 -5
- package/dist/{PlanetTerrain-DCvxS1Q8.js.map → PlanetTerrain-Bsfx7YA6.js.map} +1 -1
- package/dist/{RevisionScope-J__6V9I_.js → RevisionScope-Dl4yjj-0.js} +2 -2
- package/dist/{RevisionScope-J__6V9I_.js.map → RevisionScope-Dl4yjj-0.js.map} +1 -1
- package/dist/{TerrainClouds-BuKvwnWw.js → TerrainClouds-DV6ny7P1.js} +31 -19
- package/dist/TerrainClouds-DV6ny7P1.js.map +1 -0
- package/dist/{TerrainHeightCache-Dsde6EDL.js → TerrainHeightCache-DIZxi9jz.js} +2 -2
- package/dist/{TerrainHeightCache-Dsde6EDL.js.map → TerrainHeightCache-DIZxi9jz.js.map} +1 -1
- package/dist/{TerrainParameters-A3fcNJTR.js → TerrainParameters-DMCjnnxz.js} +10 -8
- package/dist/TerrainParameters-DMCjnnxz.js.map +1 -0
- package/dist/{TerrainWater-Cil7waG3.js → TerrainWater-CX4XdwA0.js} +17 -11
- package/dist/TerrainWater-CX4XdwA0.js.map +1 -0
- package/dist/{WaterMaterial-BUsAp0SS.js → WaterMaterial-C9h1xm9E.js} +7 -5
- package/dist/WaterMaterial-C9h1xm9E.js.map +1 -0
- package/dist/{biomeGLSL-CIkhxIlH.js → biomeGLSL-DWGDDBqT.js} +6 -3
- package/dist/{biomeGLSL-CIkhxIlH.js.map → biomeGLSL-DWGDDBqT.js.map} +1 -1
- package/dist/clouds.js +1 -1
- package/dist/documents.js +6 -6
- package/dist/export.js +2 -2
- package/dist/index.js +1 -1
- package/dist/infinite.js +1 -1
- package/dist/mini.js +1 -1
- package/dist/planet.js +1 -1
- package/dist/{planetGLSL-2xas0f3o.js → planetGLSL-D9Zy2IAw.js} +2 -2
- package/dist/{planetGLSL-2xas0f3o.js.map → planetGLSL-D9Zy2IAw.js.map} +1 -1
- package/dist/real-world.js +1 -1
- package/dist/render.js +1 -1
- package/dist/viewer.js +1 -1
- package/dist/water.js +1 -1
- package/package.json +1 -1
- package/dist/MiniTerrain-Blt0H1S0.js.map +0 -1
- package/dist/TerrainClouds-BuKvwnWw.js.map +0 -1
- package/dist/TerrainParameters-A3fcNJTR.js.map +0 -1
- package/dist/TerrainWater-Cil7waG3.js.map +0 -1
- package/dist/WaterMaterial-BUsAp0SS.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FiniteTerrain-B34WMz5S.js","sources":["../../../src/engine/terrain/TerrainHeightSampler.js","../../../src/engine/terrain/ChunkGeometry.js","../../../src/engine/terrain/InfiniteTerrainCulling.js","../../../src/engine/terrain/LodMorph.js","../../../src/engine/terrain/TerrainBoard.js","../../../src/runtime/FiniteTerrainRuntime.js","../../../src/runtime/FiniteTerrain.js"],"sourcesContent":["// ============================================================================\n// CPU-side terrain height sampler — exact JS port of the GLSL height field\n// (terrainGLSL.js + biomeGLSL.js). Reads the LIVE shared uniform objects so\n// it always matches what the GPU renders, in both studio and infinite mode,\n// across chunk borders, for any seed / preset / octave count.\n//\n// IMPORTANT: every arithmetic step goes through Math.fround to emulate the\n// GPU's float32 precision. The Dave Hoskins hash relies on fract() of large\n// products, so its output is a function of the exact 32-bit rounding — a\n// double-precision evaluation produces different per-cell noise values and\n// heights drift tens of units away from the rendered mesh. With f32\n// emulation the CPU result tracks the GPU to within rounding noise.\n//\n// Used by the player physics controller for ground detection. A handful of\n// samples per frame — no raycasting against chunk meshes is ever needed.\n// ============================================================================\n\nconst f = Math.fround;\n\nfunction fract32(v) { return f(v - Math.floor(v)); }\nfunction clamp(v, a, b) { return v < a ? a : v > b ? b : v; }\n// Terrain Detail twins of octaveKeep / creaseAbs (TERRAIN_DETAIL_GLSL), f32.\nfunction octaveKeep32(i, n, cut) {\n return clamp(f(f(n - i) - f(cut * f(n - 1))), 0, 1);\n}\nfunction creaseAbs32(x, cut) {\n const s = f(f(cut * cut) * 0.04);\n return s > 0 ? f(f(Math.sqrt(f(f(x * x) + s))) - f(Math.sqrt(s))) : Math.abs(x);\n}\nfunction mix32(a, b, t) { return f(a + f(f(b - a) * t)); }\nfunction smoothstep32(e0, e1, x) {\n const t = clamp(f(f(x - e0) / f(e1 - e0)), 0, 1);\n return f(f(t * t) * f(3 - f(2 * t)));\n}\n\nfunction stackSoftClamp(h) {\n if (h <= 0) return 0;\n if (h <= 1) return f(h);\n return f(Math.min(1.35, f(1 + f(0.35 * f(1 - Math.exp(f(-(h - 1) / 0.35)))))));\n}\n\nfunction finalizeStackHeight(h, u) {\n if ((u.uStackNormalize?.value ?? 0) < 0.5) return clamp(h, 0, 1.35);\n const outMin = f(u.uStackOutMin?.value ?? 0);\n const outMax = Math.max(f(u.uStackOutMax?.value ?? 1.35), f(outMin + 0.0001));\n return stackSoftClamp(f(f(h - outMin) / f(outMax - outMin)));\n}\n\n// GLSL: mat2(0.80,-0.60,0.60,0.80) * p => (0.80x + 0.60y, -0.60x + 0.80y)\nfunction rot2x(x, y) { return f(f(0.80 * x) + f(0.60 * y)); }\nfunction rot2y(x, y) { return f(f(-0.60 * x) + f(0.80 * y)); }\n\n// --- hash without sine precision issues (Dave Hoskins) — port of hash12 ----\nfunction hash12(px, py) {\n let p3x = fract32(f(px * 0.1031));\n let p3y = fract32(f(py * 0.1031));\n let p3z = p3x; // vec3(p.xyx)\n // dot(p3, p3.yzx + 33.33)\n const d = f(\n f(f(p3x * f(p3y + 33.33)) + f(p3y * f(p3z + 33.33))) + f(p3z * f(p3x + 33.33))\n );\n p3x = f(p3x + d); p3y = f(p3y + d); p3z = f(p3z + d);\n return fract32(f(f(p3x + p3y) * p3z));\n}\n\n// --- quintic value noise ----------------------------------------------------\nfunction vnoise(px, py) {\n const ix = Math.floor(px), iy = Math.floor(py);\n const fx = f(px - ix), fy = f(py - iy);\n // u = f*f*f*(f*(f*6-15)+10)\n const ux = f(f(f(fx * fx) * fx) * f(f(fx * f(f(fx * 6) - 15)) + 10));\n const uy = f(f(f(fy * fy) * fy) * f(f(fy * f(f(fy * 6) - 15)) + 10));\n const a = hash12(ix, iy);\n const b = hash12(f(ix + 1), iy);\n const c = hash12(ix, f(iy + 1));\n const d = hash12(f(ix + 1), f(iy + 1));\n return mix32(mix32(a, b, ux), mix32(c, d, ux), uy);\n}\n\nimport { evalStack2D } from './noise/noiseStackCodegen.js';\nimport { setNoiseDetailCut } from './noise/cpuNoise.js';\nimport { isLegacyStack } from './noise/NoiseStack.js';\nimport { miniComposeCPU } from '../mini/miniCompositionGLSL.js';\n\nexport class TerrainHeightSampler {\n /**\n * @param {object} uniforms shared terrain uniform objects (live references)\n * @param {function} getEnv () => ({ octaves:number, infinite:boolean })\n * @param {object} [stack] live NoiseStack (custom stacks use the f64 evaluator)\n */\n constructor(uniforms, getEnv, stack = null) {\n this.u = uniforms;\n this.getEnv = getEnv;\n this.stack = stack;\n this.heightProgram = null;\n // Optional erosion height-offset field (CPU mirror of the GLSL\n // erosionOffsetAt). When set and enabled, heightAt adds its signed\n // world-unit delta so CPU physics/props track the eroded mesh. null = none.\n this.erosion = null;\n this.destruction = null;\n }\n\n setStack(stack) { this.stack = stack; }\n setHeightProgram(program) { this.heightProgram = program?.kind === 'graph' ? program : null; }\n\n _rimFalloff(t) {\n t = clamp(t, 0, 1);\n return f(f(t * t) * f(3 - f(2 * t)));\n }\n\n _applyEdgeProfile(h, x, z, rim, octaves) {\n if ((this.u.uEdgeFalloffMode?.value ?? 0) < 0.5) return f(h * rim);\n const edgeMask = f(1 - rim);\n const freq = f(this.u.uFrequency.value);\n const px = f(f(f(x * freq) + f(this.u.uSeedOffset.value.x)) + 173.7);\n const pz = f(f(f(z * freq) + f(this.u.uSeedOffset.value.y)) + 419.2);\n const mountains = f(Math.pow(this._ridgedFBM(f(px * 2.35), f(pz * 2.35), octaves), 1.25));\n const breakup = vnoise(f(f(px * 5.1) + 61.4), f(f(pz * 5.1) + 27.8));\n const added = f(f(f(mountains * 0.55) + f(breakup * 0.12)) * edgeMask);\n const fall = clamp(f(this.u.uFalloff.value), 0, 1);\n return f(h + f(f(added * f(this.u.uAmplitude.value)) * fall));\n }\n\n _tileOccAt(cx, cz) {\n const tex = this.u.uTileOccupancy?.value;\n const dim = this.u.uTileGridDim?.value;\n const w = Math.max(1, Math.round(dim?.x ?? 1));\n const h = Math.max(1, Math.round(dim?.y ?? 1));\n if (cx < 0 || cz < 0 || cx >= w || cz >= h) return 0;\n return (tex?.image?.data?.[cz * w + cx] ?? 0) >= 128 ? 1 : 0;\n }\n\n _tileFalloff(x, z) {\n if (f(this.u.uFalloff.value) <= 0) return 1; // no edge attenuation\n const cs = f(this.u.uTileCellSize?.value ?? f(this.u.uBoardHalf.value * 2));\n const ox = f(this.u.uTileGridOrigin?.value?.x ?? -f(cs * 0.5));\n const oz = f(this.u.uTileGridOrigin?.value?.y ?? -f(cs * 0.5));\n const rx = f(f(x - ox) / cs), rz = f(f(z - oz) / cs);\n const cx = Math.floor(rx), cz = Math.floor(rz);\n const lx = f(f(rx - cx) * 2 - 1), lz = f(f(rz - cz) * 2 - 1);\n const band = f(this.u.uFalloff.value);\n const fXp = mix32(smoothstep32(0, band, f(1 - lx)), 1, this._tileOccAt(cx + 1, cz));\n const fXn = mix32(smoothstep32(0, band, f(1 + lx)), 1, this._tileOccAt(cx - 1, cz));\n const fZp = mix32(smoothstep32(0, band, f(1 - lz)), 1, this._tileOccAt(cx, cz + 1));\n const fZn = mix32(smoothstep32(0, band, f(1 + lz)), 1, this._tileOccAt(cx, cz - 1));\n return f(f(fXp * fXn) * f(fZp * fZn));\n }\n\n _assemblyFalloff(x, z) {\n if ((this.u.uTileShape?.value ?? 0) >= 0.5) {\n // inward disk island profile: fades to 0 exactly at the perimeter (no\n // half-height boundary), and uFalloff == 0 disables it entirely.\n const fall = f(this.u.uFalloff.value);\n if (fall <= 0) return 1;\n const radius = f(this.u.uTileDiskRadius?.value ?? this.u.uBoardHalf.value);\n const cs = f(this.u.uTileCellSize?.value ?? f(this.u.uBoardHalf.value * 2));\n const band = f(fall * cs);\n const t = clamp(f(f(radius - f(Math.hypot(x, z))) / band), 0, 1);\n return this._rimFalloff(t);\n }\n return this._tileFalloff(x, z);\n }\n\n\n // detail = false: the 4-octave warp/mask FBM, never thinned (fbm4 in GLSL)\n _fbm(px, py, octaves, detail = true) {\n const pers = f(this.u.uPersistence.value);\n const lac = f(this.u.uLacunarity.value);\n const cut = detail ? f(this.u.uTerrainDetailCut?.value ?? 0) : 0;\n let amp = 0.5, sum = 0, norm = 0;\n for (let i = 0; i < octaves; i++) {\n const w = f(amp * octaveKeep32(i, octaves, cut));\n sum = f(sum + f(w * vnoise(px, py)));\n norm = f(norm + w);\n amp = f(amp * pers);\n const nx = f(rot2x(px, py) * lac), ny = f(rot2y(px, py) * lac);\n px = nx; py = ny;\n }\n return f(sum / Math.max(norm, 1e-4));\n }\n\n _fbm4(px, py) { return this._fbm(px, py, 4, false); }\n\n // 3-octave climate FBM with hardcoded gain/lacunarity (matches fbm3 in GLSL)\n _fbm3(px, py) {\n let v = f(vnoise(px, py) * 0.55);\n const nx = f(rot2x(px, py) * 2.13), ny = f(rot2y(px, py) * 2.13);\n v = f(v + f(vnoise(nx, ny) * 0.30));\n const mx = f(rot2x(nx, ny) * 2.13), my = f(rot2y(nx, ny) * 2.13);\n v = f(v + f(vnoise(mx, my) * 0.15));\n return v;\n }\n\n _ridgedFBM(px, py, octaves) {\n const pers = f(this.u.uPersistence.value);\n const lac = f(this.u.uLacunarity.value);\n const cut = f(this.u.uTerrainDetailCut?.value ?? 0);\n let amp = 0.5, sum = 0, norm = 0, carry = 1;\n for (let i = 0; i < octaves; i++) {\n const w = f(amp * octaveKeep32(i, octaves, cut));\n let v = f(1 - creaseAbs32(f(f(vnoise(px, py) * 2) - 1), cut));\n v = f(v * v);\n sum = f(sum + f(f(w * v) * carry));\n carry = clamp(f(v * 1.4), 0, 1);\n norm = f(norm + w);\n amp = f(amp * pers);\n const nx = f(rot2x(px, py) * lac), ny = f(rot2y(px, py) * lac);\n px = nx; py = ny;\n }\n return f(sum / Math.max(norm, 1e-4));\n }\n\n _climateAt(px, py) {\n const u = this.u;\n const bs = f(u.uBiomeScale.value);\n const bx = f(px * bs), by = f(py * bs);\n const cont = this._fbm3(f(f(bx * 0.085) + 211.3), f(f(by * 0.085) + 57.9));\n const temp = clamp(f(f(f(this._fbm3(f(f(bx * 0.150) + 71.7), f(f(by * 0.150) + 313.1)) * 1.5) - 0.25) + f(u.uTempBias.value)), 0, 1);\n const ms = f(0.130 * f(u.uMoistScale.value));\n const moist = clamp(f(f(f(this._fbm3(f(f(bx * ms) + 91.7), f(f(by * ms) + 53.9)) * 1.5) - 0.25) + f(u.uMoistBias.value)), 0, 1);\n const erosion = this._fbm3(f(f(bx * 0.190) + 157.1), f(f(by * 0.190) + 423.7));\n const region = this._fbm3(f(f(px * 0.700) + 631.4), f(f(py * 0.700) + 199.2));\n return { temp, moist, cont, erosion, region };\n }\n\n _biomeWeights(c) {\n const j = f(f(c.region - 0.5) * 0.16);\n const hot = smoothstep32(0.52, 0.74, f(c.temp + j));\n const dry = smoothstep32(0.55, 0.30, f(c.moist - j));\n const wet = smoothstep32(0.55, 0.78, f(c.moist + j));\n const lowC = smoothstep32(0.55, 0.32, c.cont);\n const eroded = smoothstep32(0.40, 0.70, f(c.erosion + f(j * 0.5)));\n return {\n desert: f(f(hot * dry) * f(1 - f(eroded * 0.55))),\n canyon: f(f(dry * eroded) * smoothstep32(0.30, 0.55, c.cont)),\n wetland: f(f(wet * lowC) * f(1 - f(hot * 0.4))),\n mountains: f(smoothstep32(0.38, 0.62, c.cont) * f(1 - f(eroded * 0.7))),\n };\n }\n\n _dominantBiome(weights, overrides = null) {\n const painted = overrides ? {\n desert: clamp((weights.desert ?? 0) + (overrides.desert ?? 0), 0, 1),\n canyon: clamp((weights.canyon ?? 0) + (overrides.canyon ?? 0), 0, 1),\n wetland: clamp((weights.wetland ?? 0) + (overrides.wetland ?? 0), 0, 1),\n mountains: clamp((weights.mountains ?? 0) + (overrides.mountains ?? 0), 0, 1),\n } : weights;\n let label = 'Forest';\n let score = 0.18;\n for (const [key, value] of Object.entries(painted)) {\n if (value > score) {\n score = value;\n label = key[0].toUpperCase() + key.slice(1);\n }\n }\n return { label, weights: painted };\n }\n\n _terrace(h, steps) {\n const t = f(h * steps);\n const s = smoothstep32(0.20, 0.80, fract32(t));\n return f(f(Math.floor(t) + s) / steps);\n }\n\n // ctx for the generic f64 stack evaluator. legacy2d delegates back to the\n // exact f32 legacy recipe so a legacy layer inside a custom stack matches.\n _ctx() {\n if (!this._ctxObj) {\n this._ctxObj = { uniforms: this.u, legacy2d: (x, z) => this._legacyShape2D(x, z) };\n }\n return this._ctxObj;\n }\n\n /** World-space terrain height at world position (x, z). */\n heightAt(x, z) {\n const u = this.u;\n const env = this.getEnv();\n\n let h = this._smoothedStackHeightAt(x, z);\n\n // island falloff (studio board only) + clamp + world height scale\n if (!env.infinite) {\n let rim = 1;\n if ((u.uUseTiles?.value ?? 0) > 0.5) {\n rim = this._assemblyFalloff(x, z);\n } else if (f(u.uFalloff.value) > 0) {\n const half = f(u.uBoardHalf.value);\n const ex = f(Math.abs(f(x)) / half), ey = f(Math.abs(f(z)) / half);\n const edge = mix32(Math.max(ex, ey), f(Math.hypot(ex, ey) * 0.7071), 0.5);\n const t = clamp(f(f(1 - edge) / f(u.uFalloff.value)), 0, 1);\n rim = this._rimFalloff(t);\n }\n h = this._applyEdgeProfile(h, x, z, rim, env.octaves);\n }\n // World-unit height, then the erosion delta on top (matches GLSL heightAt:\n // the offset is added after the clamp/scale, in world units).\n let h01 = finalizeStackHeight(h, u);\n if (!env.infinite) h01 = miniComposeCPU(u, x, z, h01);\n return f(f(f(h01 * f(u.uHeightScale.value)) + this._erosionOffset(x, z)) + this._destructionOffset(x, z));\n }\n\n _erosionOffset(x, z) {\n const e = this.erosion;\n return (e && e.enabled) ? f(e.offsetAt(x, z)) : 0;\n }\n\n _destructionOffset(x, z) {\n const field = this.destruction;\n return (field && field.enabled) ? f(field.offsetAt(x, z)) : 0;\n }\n\n shapeAt(x, z) {\n return this._smoothedStackHeightAt(x, z);\n }\n\n _rawStackHeightAt(x, z) {\n const u = this.u;\n if (this.heightProgram?.evaluate2D) return this.heightProgram.evaluate2D(x, z, this._ctx());\n setNoiseDetailCut(u.uTerrainDetailCut?.value ?? 0);\n return (this.stack && !isLegacyStack(this.stack))\n ? evalStack2D(this.stack, x, z, this._ctx())\n : f(this._legacyShape2D(x, z) * f(u.uAmplitude.value));\n }\n\n _smoothedStackHeightAt(x, z) {\n const h = this._rawStackHeightAt(x, z);\n const amt = clamp(f(this.u.uTerrainSmoothing?.value ?? 0), 0, 1);\n if (amt <= 0.0001) return h;\n const t = clamp(f(h / 1.35), 0, 1);\n const peakStart = 0.42;\n const peak = Math.max(f(t - peakStart), 0);\n const peakMask = smoothstep32(peakStart, 0.72, t);\n const compressed = f(peakStart + f(peak / f(1 + f(f(f(amt * 3.2) * peak) / f(1 - peakStart)))));\n return mix32(h, f(compressed * 1.35), f(peakMask * amt));\n }\n\n biomeAt(x, z, overrides = null) {\n const u = this.u;\n const freq = f(u.uFrequency.value);\n const px = f(f(f(x) * freq) + f(u.uSeedOffset.value.x));\n const py = f(f(f(z) * freq) + f(u.uSeedOffset.value.y));\n const climate = this._climateAt(px, py);\n const weights = this._biomeWeights(climate);\n return this._dominantBiome(weights, overrides);\n }\n\n /** Public climate at world (x,z): { temp, moist, cont, erosion, region }. */\n climateAt(x, z) {\n const u = this.u;\n const freq = f(u.uFrequency.value);\n const px = f(f(f(x) * freq) + f(u.uSeedOffset.value.x));\n const py = f(f(f(z) * freq) + f(u.uSeedOffset.value.y));\n return this._climateAt(px, py);\n }\n\n /** Legacy biome-coupled recipe (layers 1-6), h in ~0..1.35 (pre falloff/scale). */\n _legacyShape2D(x, z) {\n const u = this.u;\n const env = this.getEnv();\n const octaves = env.octaves;\n\n const freq = f(u.uFrequency.value);\n const px = f(f(f(x) * freq) + f(u.uSeedOffset.value.x));\n const py = f(f(f(z) * freq) + f(u.uSeedOffset.value.y));\n\n const c = this._climateAt(px, py);\n const bw = this._biomeWeights(c);\n\n // layer 1: domain warp\n const wx = this._fbm4(f(px + 13.7), f(py + 41.3));\n const wy = this._fbm4(f(px + 87.2), f(py + 9.1));\n const warp = f(f(u.uWarp.value) * f(1 - f(bw.canyon * 0.5)));\n const qx = f(px + f(f(wx - 0.5) * warp));\n const qy = f(py + f(f(wy - 0.5) * warp));\n\n // layer 2: rolling base\n const base = this._fbm(qx, qy, octaves);\n const baseAmp = f(f(0.30 * f(1 - f(bw.desert * 0.45))) * f(1 - f(bw.wetland * 0.75)));\n let h = f(f(base * baseAmp) + 0.06);\n\n // layer 3: desert dunes\n const dnx = f(f(f(qx * 2.2) + f(qy * 0.4)) + 311.7);\n const dny = f(f(qy * 0.8) + 89.1);\n const dune = f(1 - Math.abs(f(f(vnoise(dnx, dny) * 2) - 1)));\n h = f(h + f(f(f(dune * dune) * 0.05) * bw.desert));\n\n // layer 4: ridged mountain chains\n const ridge = this._ridgedFBM(f(f(qx * 1.7) + 31.4), f(f(qy * 1.7) + 27.2), octaves);\n const smoothAmt = clamp(f(u.uTerrainSmoothing?.value ?? 0), 0, 1);\n const ridgeNeedle = f(Math.pow(ridge, 1.35));\n const ridgeRounded = f(f(Math.pow(ridge, 0.62)) * 0.58);\n const ridgeShape = mix32(ridgeNeedle, ridgeRounded, smoothAmt);\n const chain = smoothstep32(0.34, 0.66, this._fbm4(f(f(qx * 0.35) + 5.1), f(f(qy * 0.35) + 17.7)));\n const mountains = f(f(f(chain * mix32(0.35, 1.0, bw.mountains))\n * f(1 - f(bw.desert * 0.85)))\n * f(1 - bw.wetland));\n h = f(h + f(f(f(ridgeShape * mountains) * f(u.uRidge.value)) * mix32(1.15, 0.82, smoothAmt)));\n\n // layer 5: wetlands use the frozen formation baseline. Fall back to the\n // live sea uniform only for older standalone sampler callers.\n const formationSeaLevel = u.uTerrainFormationSeaLevel?.value\n ?? u.uSeaLevel.value;\n const sea01 = f(f(formationSeaLevel) / Math.max(f(u.uHeightScale.value), 1));\n h = mix32(h, f(f(sea01 + 0.012) + f(base * 0.03)), f(bw.wetland * 0.85));\n\n // layer 6: canyon strata terracing\n h = mix32(h, this._terrace(h, 14.0), f(bw.canyon * 0.75));\n\n return h;\n }\n\n /**\n * Approximate surface normal at (x, z) via central differences.\n * @returns {{x:number, y:number, z:number}} normalized\n */\n normalAt(x, z, eps = 1.0) {\n const hL = this.heightAt(x - eps, z);\n const hR = this.heightAt(x + eps, z);\n const hD = this.heightAt(x, z - eps);\n const hU = this.heightAt(x, z + eps);\n let nx = hL - hR, ny = 2 * eps, nz = hD - hU;\n const len = Math.hypot(nx, ny, nz) || 1;\n return { x: nx / len, y: ny / len, z: nz / len };\n }\n\n sampleSurfaceInfo(x, z, {\n waterLevel = 0,\n paintHeightOffset = 0,\n paintBiomeWeights = null,\n eps = 2.0,\n } = {}) {\n const baseHeight = this.heightAt(x, z);\n const height = baseHeight + paintHeightOffset;\n const normal = this.normalAt(x, z, eps);\n const slope = clamp(1 - normal.y, 0, 1);\n const biome = this.biomeAt(x, z, paintBiomeWeights);\n return {\n baseHeight,\n height,\n normal,\n slope,\n water: height <= waterLevel + 0.01,\n biome: biome.label,\n biomeWeights: biome.weights,\n noise: this.shapeAt(x, z),\n };\n }\n}\n","import * as THREE from 'three';\n\n// ============================================================================\n// One chunk geometry = a unit grid in local space ([0,1] on X/Z, Y handled\n// entirely in the vertex shader) plus a duplicated border ring (\"skirt\").\n// The shader drops skirt vertices down by uSkirtDepth, which hides any\n// T-junction cracks between neighbouring chunks at different LOD levels.\n// Geometries are shared: every chunk currently at LOD n uses the same one.\n// ============================================================================\n\n// `morph` marks the shared per-LOD grids that take part in geomorphing\n// (aMorph = 1): their odd vertices slide onto the next-coarser grid as they\n// approach the LOD switch distance. Merged/boundary/export meshes leave it 0\n// (or omit the attribute, which WebGL reads as 0).\nexport function buildChunkGeometry(res, lodIndex, { morph = false } = {}) {\n const vps = res + 1; // vertices per side\n const gridCount = vps * vps;\n\n // border ring vertex indices, walked clockwise around the perimeter\n const ring = [];\n for (let x = 0; x < res; x++) ring.push(x); // top row →\n for (let z = 0; z < res; z++) ring.push(z * vps + res); // right col ↓\n for (let x = res; x > 0; x--) ring.push(res * vps + x); // bottom row ←\n for (let z = res; z > 0; z--) ring.push(z * vps); // left col ↑\n const ringCount = ring.length; // 4 * res\n\n const total = gridCount + ringCount;\n const positions = new Float32Array(total * 3);\n const uvs = new Float32Array(total * 2);\n const skirt = new Float32Array(total); // 0 = surface, 1 = skirt\n const lod = new Float32Array(total).fill(lodIndex);\n\n let i = 0;\n for (let z = 0; z < vps; z++) {\n for (let x = 0; x < vps; x++) {\n positions[i * 3 + 0] = x / res;\n positions[i * 3 + 1] = 0;\n positions[i * 3 + 2] = z / res;\n uvs[i * 2 + 0] = x / res;\n uvs[i * 2 + 1] = z / res;\n i++;\n }\n }\n // skirt vertices: same XZ as the border vertex they duplicate\n for (let k = 0; k < ringCount; k++) {\n const src = ring[k];\n const dst = gridCount + k;\n positions[dst * 3 + 0] = positions[src * 3 + 0];\n positions[dst * 3 + 1] = 0;\n positions[dst * 3 + 2] = positions[src * 3 + 2];\n uvs[dst * 2 + 0] = uvs[src * 2 + 0];\n uvs[dst * 2 + 1] = uvs[src * 2 + 1];\n skirt[dst] = 1;\n }\n\n const indices = [];\n for (let z = 0; z < res; z++) {\n for (let x = 0; x < res; x++) {\n const a = z * vps + x;\n const b = a + 1;\n const c = a + vps;\n const d = c + 1;\n indices.push(a, c, b, b, c, d);\n }\n }\n // skirt wall quads between each border vertex and its dropped duplicate\n for (let k = 0; k < ringCount; k++) {\n const a = ring[k];\n const b = ring[(k + 1) % ringCount];\n const a2 = gridCount + k;\n const b2 = gridCount + ((k + 1) % ringCount);\n indices.push(a, a2, b, b, a2, b2);\n }\n\n const geo = new THREE.BufferGeometry();\n geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));\n geo.setAttribute('aSkirt', new THREE.BufferAttribute(skirt, 1));\n geo.setAttribute('aLod', new THREE.BufferAttribute(lod, 1));\n // aWall stays 0 for terrain chunks; only the dedicated circular radial wall\n // mesh sets it to 1 so the shared terrain shader can tell them apart.\n geo.setAttribute('aWall', new THREE.BufferAttribute(new Float32Array(total), 1));\n if (morph) geo.setAttribute('aMorph', new THREE.BufferAttribute(new Float32Array(total).fill(1), 1));\n geo.setIndex(new THREE.BufferAttribute(new Uint32Array(indices), 1));\n return geo;\n}\n\n// Bounding sphere covering the displaced chunk so three.js frustum culling\n// stays correct. Local space: XZ in [0,1], Y in [-skirt, maxHeight] before\n// the uniform chunk-size scale is applied by the mesh's world matrix.\nexport function setChunkBounds(geometry, chunkSize, maxHeight, skirtDepth) {\n const yMaxL = maxHeight / chunkSize;\n const yMinL = -skirtDepth / chunkSize;\n const cy = (yMaxL + yMinL) / 2;\n const radius = Math.hypot(0.5, 0.5, (yMaxL - yMinL) / 2) * 1.05;\n geometry.boundingSphere = new THREE.Sphere(new THREE.Vector3(0.5, cy, 0.5), radius);\n}\n","import * as THREE from 'three';\n\n// ============================================================================\n// Shared visibility context for flat terrain chunks and merged nodes. Hosts\n// build it once per frame, then reuse the same projection matrix and frustum\n// for every terrain collection.\n// ============================================================================\n\n/**\n * Update (or create) a reusable culling context from the camera's latest\n * transform. Call camera.updateMatrixWorld(true) before this function.\n */\nexport function createCullingContext(\n camera,\n chunkSize,\n behindCameraCulling,\n aggressiveness = 1,\n target = {},\n minHeight = 0\n) {\n const context = target;\n context.frustum ||= new THREE.Frustum();\n context.projScreenMatrix ||= new THREE.Matrix4();\n context.sphere ||= new THREE.Sphere();\n context.camFwd ||= new THREE.Vector3();\n\n context.projScreenMatrix.multiplyMatrices(\n camera.projectionMatrix,\n camera.matrixWorldInverse\n );\n context.frustum.setFromProjectionMatrix(context.projScreenMatrix);\n context.camFwd.set(0, 0, -1).applyQuaternion(camera.quaternion);\n context.cameraX = camera.position.x;\n context.cameraY = camera.position.y;\n context.cameraZ = camera.position.z;\n context.behindCameraCulling = !!behindCameraCulling;\n context.minHeight = minHeight;\n\n // The player neighborhood is measured only in the ground plane. Including\n // altitude here used to remove the chunk directly below a walking/flying\n // camera when its center happened to be behind the view direction.\n const protectionMargin = chunkSize * Math.max(1, 2 - aggressiveness * 0.5);\n context.protectionMargin2 = protectionMargin * protectionMargin;\n\n // Extra margin behind the camera plane. The item loop projects the complete\n // 3D bounds on that plane, so camera pitch and tall terrain remain safe.\n context.backMargin = chunkSize * Math.max(0.1, 0.7 - aggressiveness * 0.25);\n return context;\n}\n\nfunction setItemVisible(item, visible) {\n const changed = item.visible !== visible;\n item.visible = visible;\n if (item.mesh) item.mesh.visible = visible;\n return changed;\n}\n\n/**\n * Cull terrain records or quadtree nodes. spanWorld is honored when present,\n * so a folded 2×2 node and a folded 16×16 node no longer share a world-sized\n * conservative sphere.\n *\n * The optional context keeps the legacy call sites compatible while allowing\n * callers with two collections to build the frustum only once.\n */\nexport function cullChunks(\n chunks,\n camera,\n chunkSize,\n maxHeight,\n behindCameraCulling,\n aggressiveness = 1,\n sharedContext = null,\n minHeight = 0\n) {\n if (!sharedContext) camera.updateMatrixWorld(true);\n const context = sharedContext || createCullingContext(\n camera,\n chunkSize,\n behindCameraCulling,\n aggressiveness,\n {},\n minHeight\n );\n\n let visibleCount = 0;\n let culledCount = 0;\n let changedCount = 0;\n const values = chunks.values ? chunks.values() : chunks;\n\n for (const item of values) {\n const centerX = item.centerX ?? item.center?.x ?? 0;\n const centerZ = item.centerZ ?? item.center?.z ?? 0;\n const spanX = item.spanX ?? item.spanWorld ?? chunkSize;\n const spanZ = item.spanZ ?? item.spanWorld ?? chunkSize;\n const halfX = spanX * 0.5;\n const halfZ = spanZ * 0.5;\n const dx = centerX - context.cameraX;\n const dz = centerZ - context.cameraZ;\n\n // Keep the chunk containing the player and a small ring around it alive,\n // independently of frustum/back tests. Distance is measured to the nearest\n // point of the chunk footprint rather than to its center.\n const outsideX = Math.max(0, Math.abs(dx) - halfX);\n const outsideZ = Math.max(0, Math.abs(dz) - halfZ);\n const protectedByProximity = (\n outsideX * outsideX + outsideZ * outsideZ\n ) <= context.protectionMargin2;\n if (protectedByProximity) {\n if (setItemVisible(item, true)) changedCount++;\n visibleCount++;\n continue;\n }\n\n const verticalMin = item.minHeight ?? context.minHeight ?? minHeight;\n const verticalMax = item.maxHeight ?? maxHeight;\n const verticalCenter = (verticalMin + verticalMax) * 0.5;\n const verticalHalf = Math.max(0, verticalMax - verticalMin) * 0.5;\n const radius = item.boundingRadius\n ?? Math.hypot(halfX, verticalHalf, halfZ) * 1.05;\n\n context.sphere.center.set(centerX, verticalCenter, centerZ);\n context.sphere.radius = radius;\n\n if (!context.frustum.intersectsSphere(context.sphere)) {\n if (setItemVisible(item, false)) changedCount++;\n culledCount++;\n continue;\n }\n\n if (context.behindCameraCulling) {\n const dy = verticalCenter - context.cameraY;\n const forwardDistance = (\n dx * context.camFwd.x\n + dy * context.camFwd.y\n + dz * context.camFwd.z\n );\n // Project the complete 3D AABB onto the camera-forward axis. Cull only\n // when every point in the terrain bound is safely behind the camera.\n const projectedHalfExtent = (\n Math.abs(context.camFwd.x) * halfX\n + Math.abs(context.camFwd.y) * verticalHalf\n + Math.abs(context.camFwd.z) * halfZ\n );\n if (forwardDistance + projectedHalfExtent < -context.backMargin) {\n if (setItemVisible(item, false)) changedCount++;\n culledCount++;\n continue;\n }\n }\n\n if (setItemVisible(item, true)) changedCount++;\n visibleCount++;\n }\n\n return { visibleCount, culledCount, changedCount };\n}\n","// ============================================================================\n// Geomorph (CDLOD-style) band planning shared by the Tile board, Infinite\n// World and Planet chunk systems.\n//\n// Chunks pick LOD L while their centre distance d_c lies in [T_{L-1}, T_L).\n// Every vertex of such a chunk is within `halfExtent` of the centre, so its own\n// distance lies in [d_c - halfExtent, d_c + halfExtent]. The vertex shader\n// morphs an LOD L vertex onto the LOD L+1 grid over [start_L, end_L]:\n//\n// end_L = T_L - halfExtent → at the L→L+1 swap every vertex is fully\n// on the coarser grid (identical shape)\n// start_L ≥ T_{L-1} + halfExtent → right after the L-1→L swap no vertex has\n// started morphing (identical shape)\n//\n// so geometry swaps in either direction are invisible. Levels whose spacing is\n// too tight for a band get no morph (start = end = DISABLED).\n// ============================================================================\n\nexport const MORPH_DISABLED = 1e9;\n\n/**\n * @param {number[]} thresholds chunk switch distances [T0, T1, T2]\n * @param {number} halfExtent max distance from a chunk centre to its vertices\n * @param {number} [bandFraction] morph band length as a share of the LOD range\n * @returns {{ start: number[], end: number[] }}\n */\nexport function planMorphBands(thresholds, halfExtent, bandFraction = 0.3) {\n const start = [];\n const end = [];\n const margin = Math.max(0, halfExtent) * 1.02;\n for (let level = 0; level < 3; level++) {\n const lower = level === 0 ? 0 : thresholds[level - 1];\n const upper = thresholds[level];\n const bandEnd = upper - margin;\n const earliest = level === 0 ? 0 : lower + margin;\n const bandStart = Math.max(earliest, bandEnd - bandFraction * (upper - lower));\n if (Number.isFinite(bandEnd) && bandEnd > bandStart + 1e-3) {\n start.push(bandStart);\n end.push(bandEnd);\n } else {\n start.push(MORPH_DISABLED);\n end.push(MORPH_DISABLED);\n }\n }\n return { start, end };\n}\n\n/** Write planned bands + the live per-LOD segment ladder into shared uniforms. */\nexport function publishMorphUniforms(uniforms, bands, segments, enabled = true) {\n if (!uniforms?.uLodMorphStart || !uniforms?.uLodMorphEnd) return;\n if (!enabled || !bands) {\n uniforms.uLodMorphStart.value.set(MORPH_DISABLED, MORPH_DISABLED, MORPH_DISABLED);\n uniforms.uLodMorphEnd.value.set(MORPH_DISABLED, MORPH_DISABLED, MORPH_DISABLED);\n return;\n }\n uniforms.uLodMorphStart.value.set(bands.start[0], bands.start[1], bands.start[2]);\n uniforms.uLodMorphEnd.value.set(bands.end[0], bands.end[1], bands.end[2]);\n if (uniforms.uLodGridSegments && segments?.length >= 4) {\n uniforms.uLodGridSegments.value.set(segments[0], segments[1], segments[2], segments[3]);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Temporal geomorph (Planet, Infinite World). LOD *decisions* stay exactly as\n// before; each change is animated over a short duration instead of popping.\n// chunk.lod is the rendered grid level and chunk.morph (0..1) how far its odd\n// vertices have slid onto the next-coarser grid:\n// coarsen: morph 0 -> 1 on the finer grid, then swap (identical shape)\n// refine: swap to the finer grid at morph 1 (identical shape), then 1 -> 0\n// At rest morph is 0, so settled geometry is unchanged.\n\n/** True when level L -> L+1 is an exact 2:1 grid ladder (morphable). */\nexport function morphLadder(segments, level) {\n return level >= 0 && level < 3 && segments[level] === segments[level + 1] * 2;\n}\n\n/**\n * Advance one chunk toward `target`. Returns true when its rendered state\n * (lod or morph) changed this step.\n */\nexport function stepTemporalLod(chunk, target, step, segments, enabled = true) {\n const lod = chunk.lod;\n const morph = chunk.morph || 0;\n if (chunk.fresh) {\n // A chunk that just appeared has no previous shape to preserve.\n chunk.fresh = false;\n chunk.lod = target;\n chunk.morph = 0;\n } else if (!enabled) {\n chunk.lod = target;\n chunk.morph = 0;\n } else if (target > lod) {\n if (!morphLadder(segments, lod)) {\n chunk.lod = target;\n chunk.morph = 0;\n } else {\n chunk.morph = Math.min(1, morph + step);\n if (chunk.morph >= 1) {\n chunk.lod = lod + 1;\n chunk.morph = 0;\n }\n }\n } else if (morph > 0) {\n // settle back onto the current grid (also undoes an aborted coarsen)\n chunk.morph = Math.max(0, morph - step);\n } else if (target < lod) {\n if (!morphLadder(segments, lod - 1)) {\n chunk.lod = target;\n } else {\n chunk.lod = lod - 1;\n chunk.morph = 1;\n }\n }\n return chunk.lod !== lod || (chunk.morph || 0) !== morph;\n}\n","import * as THREE from 'three';\nimport { buildChunkGeometry, setChunkBounds } from './ChunkGeometry.js';\nimport { createCullingContext, cullChunks } from './InfiniteTerrainCulling.js';\nimport { MORPH_DISABLED, planMorphBands, publishMorphUniforms } from './LodMorph.js';\n\n// ============================================================================\n// ONE fixed terrain board. The board never moves, never streams, and is\n// never created/destroyed around the camera. It is split into an internal\n// N x N chunk grid purely so each chunk can pick a geometry LOD based on\n// camera distance. All chunks share 4 geometries (one per LOD) and a single\n// shader material; their world position comes from the mesh transform.\n// ============================================================================\n\nexport const LOD_RESOLUTIONS = [64, 32, 16, 8]; // quads per chunk side\n// × chunkSize. Geomorphing makes LOD swaps invisible, so the bands follow a\n// screen-space target (~3 px quads at each switch at 1080p-class FOV) instead\n// of hiding pops at a distance; the earlier [8, 15, 24] rendered ~1.7 px\n// triangles near the LOD0 edge and paid for it in quad overshading.\nconst BASE_DISTANCE_BANDS = [5.2, 9.75, 15.6];\n\nexport class TerrainBoard {\n constructor(scene, material) {\n this.scene = scene;\n this.material = material;\n this.group = new THREE.Group();\n this.group.name = 'terrain-board';\n this.scene.add(this.group);\n\n this.geometries = []; // one per LOD, shared by all chunks\n this.chunks = []; // { mesh, center: Vector3, lod, cellKey }\n this._cells = []; // occupied tile cells currently owned by chunks/queue\n this.lodCounts = [0, 0, 0, 0];\n this.chunkCount = 0;\n this.chunkSize = 0;\n this.boardSize = 0;\n this.activeChunkCount = 0;\n this.targetChunkCount = 0;\n this.lodThresholds = [0, 0, 0];\n this.lodSegments = [...LOD_RESOLUTIONS];\n // Geomorphing (smooth LOD transitions) — see LodMorph.js\n this.morphEnabled = true;\n this.morphBands = null;\n\n this._distanceScale = 1.0;\n this._maxHeight = 0;\n this._skirtDepth = 0;\n this._circularBoundary = null;\n this._circularBoundaryGeometry = null;\n this._circularBoundarySegments = 0;\n\n // Gradual LOD geometry rebuild (one level per updateLOD call)\n this._lodRebuildQueue = [];\n this._targetSegments = null;\n this._buildQueue = [];\n this._building = false;\n\n this.cullingEnabled = true;\n this.behindCameraCulling = true;\n this.cullingAggressiveness = 1.0;\n this.visibleChunkCount = 0;\n this.culledChunkCount = 0;\n this._cullingContext = {};\n this._cullChunks = [];\n\n // --- Merge layer (quadtree chunked-LOD) ---------------------------------\n // The chunks are the leaves of a quadtree. Each internal node covers a\n // square block of chunks and can fold into ONE flat-grid mesh once the\n // camera is far enough for its size. Folding happens 2x2 at a time as you\n // descend/ascend the tree, so the visible set is always a smooth \"cut\":\n // fine chunks near the camera, progressively larger merged blocks outward,\n // never a hard jump from one mesh to many. Height is GPU-driven, so a\n // merged node is just a bigger unit grid using the same material — no\n // baking/cache/async needed. Cuts draw calls / matrix updates / frustum\n // checks (the CPU cost), not GPU triangles.\n this.mergeEnabled = true;\n this.mergeQuadsPerChunk = 8; // merged grid density per chunk span (8 == LOD3)\n this.mergeDistance = 4; // a node folds when nearest > spanWorld × this\n this.macroProxyEnabled = true; // allow the root (whole board) to fold to 1 mesh\n this._mergedGeo = new Map(); // \"res:aLod\" -> shared BufferGeometry\n this._root = null;\n this._treeDirty = true;\n this._mergedNodes = []; // nodes folded this frame (for culling/stats)\n this._hiddenByMerge = 0;\n this._boardMin = new THREE.Vector3();\n this._boardMax = new THREE.Vector3();\n this.mergedGroupCount = 0;\n this.savedDrawCalls = 0;\n\n // Debug: tint folded terrain by merge level via the shader's uMergeDebug.\n this._mergeDebug = false;\n\n this._tmp = new THREE.Vector3();\n this._bootFrustum = new THREE.Frustum();\n this._bootProjection = new THREE.Matrix4();\n this._bootBounds = new THREE.Box3();\n }\n\n // (Re)build the chunk grid. Only called when chunk count / size changes or a\n // full reset is requested. Tile-only changes use syncCells() so already-built\n // cells stay alive and only added/removed cells are touched.\n build({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments, cells, progressive = false, initialBatchSize = 64 }) {\n this.dispose();\n this._setLayout({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments });\n this._createSharedGeometries();\n this._applyCellDiff({ cells, progressive, initialBatchSize });\n }\n\n // Incrementally match the occupied tile-cell list. If the chunk layout itself\n // changed, fall back to build(); otherwise preserve existing chunks.\n syncCells({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments, cells, progressive = true, initialBatchSize = 64 }) {\n const needsFullBuild = !this.geometries.length\n || this.chunkCount !== chunkCount\n || this.chunkSize !== chunkSize;\n if (needsFullBuild) {\n this.build({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments, cells, progressive, initialBatchSize });\n return { rebuilt: true, added: this._cells.length, removed: 0 };\n }\n\n this._maxHeight = maxHeight;\n this._skirtDepth = skirtDepth;\n if (lodSegments && !this._sameSegments(lodSegments)) this.setLodSegments(lodSegments);\n this._recalcThresholds();\n this.updateBounds(maxHeight, skirtDepth);\n return this._applyCellDiff({ cells, progressive, initialBatchSize });\n }\n\n _setLayout({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments }) {\n this.chunkCount = chunkCount;\n this.chunkSize = chunkSize;\n this.boardSize = chunkCount * chunkSize; // one cell\n this._maxHeight = maxHeight;\n this._skirtDepth = skirtDepth;\n if (lodSegments) this.lodSegments = [...lodSegments];\n this._recalcThresholds();\n }\n\n _createSharedGeometries() {\n this.geometries = this.lodSegments.map((res, lodIndex) => {\n const geo = buildChunkGeometry(res, lodIndex, { morph: true });\n setChunkBounds(geo, this.chunkSize, this._maxHeight, this._skirtDepth);\n return geo;\n });\n }\n\n _sameSegments(segments) {\n return segments.length === this.lodSegments.length\n && segments.every((s, i) => s === this.lodSegments[i]);\n }\n\n _cellKey(cell) {\n return `${cell.cx},${cell.cz}`;\n }\n\n _normalizeCells(cells) {\n const list = (cells && cells.length) ? cells : [{ cx: 0, cz: 0 }];\n const out = [];\n const seen = new Set();\n for (const cell of list) {\n const cx = Math.trunc(Number(cell?.cx));\n const cz = Math.trunc(Number(cell?.cz));\n if (!Number.isFinite(cx) || !Number.isFinite(cz)) continue;\n const key = `${cx},${cz}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push({ cx, cz });\n }\n return out.length ? out : [{ cx: 0, cz: 0 }];\n }\n\n _jobsForCell(cell) {\n const jobs = [];\n const half = this.boardSize / 2;\n const cellKey = this._cellKey(cell);\n // cell (cx,cz) center sits at (cx*cellSize, cz*cellSize); its min corner\n // is that minus half. Chunks tile the cell from the corner.\n const originX = cell.cx * this.boardSize - half;\n const originZ = cell.cz * this.boardSize - half;\n for (let cz = 0; cz < this.chunkCount; cz++) {\n for (let cx = 0; cx < this.chunkCount; cx++) {\n const x = originX + cx * this.chunkSize;\n const z = originZ + cz * this.chunkSize;\n jobs.push({\n x,\n z,\n centerX: x + this.chunkSize / 2,\n centerZ: z + this.chunkSize / 2,\n cellCx: cell.cx,\n cellCz: cell.cz,\n cellKey,\n });\n }\n }\n return jobs;\n }\n\n _sortJobsNearestFirst(jobs) {\n jobs.sort((a, b) =>\n Math.hypot(a.centerX, a.centerZ) - Math.hypot(b.centerX, b.centerZ)\n );\n }\n\n _applyCellDiff({ cells, progressive = true, initialBatchSize = 64 }) {\n const nextCells = this._normalizeCells(cells);\n const nextKeys = new Set(nextCells.map((cell) => this._cellKey(cell)));\n const prevKeys = new Set(this._cells.map((cell) => this._cellKey(cell)));\n const removeKeys = new Set([...prevKeys].filter((key) => !nextKeys.has(key)));\n const addedCells = nextCells.filter((cell) => !prevKeys.has(this._cellKey(cell)));\n\n if (removeKeys.size) {\n this._buildQueue = this._buildQueue.filter((job) => !removeKeys.has(job.cellKey));\n const kept = [];\n for (const chunk of this.chunks) {\n if (removeKeys.has(chunk.cellKey)) {\n this.group.remove(chunk.mesh);\n } else {\n kept.push(chunk);\n }\n }\n this.chunks = kept;\n this._treeDirty = true;\n this._disposeNodeMeshes();\n }\n\n if (addedCells.length) {\n const jobs = addedCells.flatMap((cell) => this._jobsForCell(cell));\n // Build nearest chunks first so the first visible board is useful, then\n // stream the edges in behind it.\n this._sortJobsNearestFirst(jobs);\n this._buildQueue.push(...jobs);\n }\n\n this._cells = nextCells;\n this.targetChunkCount = nextCells.length * this.chunkCount * this.chunkCount;\n this.activeChunkCount = this.chunks.length;\n this._building = this._buildQueue.length > 0;\n\n if (addedCells.length && this._buildQueue.length) {\n const batchSize = progressive && this._buildQueue.length > initialBatchSize\n ? initialBatchSize\n : this._buildQueue.length;\n this.processBuildQueue({ maxItems: batchSize, maxMs: Infinity });\n }\n\n return { rebuilt: false, added: addedCells.length, removed: removeKeys.size };\n }\n\n get isBuilding() { return this._building; }\n get remainingChunks() { return this._buildQueue.length; }\n get buildProgress() {\n return this.targetChunkCount\n ? this.activeChunkCount / this.targetChunkCount\n : 1;\n }\n\n processBuildQueue({ maxItems = 16, maxMs = 6 } = {}) {\n if (!this._buildQueue.length) {\n this._building = false;\n return 0;\n }\n const start = typeof performance !== 'undefined' ? performance.now() : Date.now();\n let created = 0;\n while (this._buildQueue.length && created < maxItems) {\n if (maxMs !== Infinity) {\n const now = typeof performance !== 'undefined' ? performance.now() : Date.now();\n if (created > 0 && now - start >= maxMs) break;\n }\n this._createChunk(this._buildQueue.shift());\n created++;\n }\n this.activeChunkCount = this.chunks.length;\n this._building = this._buildQueue.length > 0;\n return created;\n }\n\n _setBootFrustum(camera) {\n camera.updateMatrixWorld(true);\n this._bootProjection.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n this._bootFrustum.setFromProjectionMatrix(this._bootProjection);\n }\n\n _bootJobVisible(job, dependencyHalo = 1.5) {\n const halo = Math.max(0, dependencyHalo) * this.chunkSize;\n this._bootBounds.min.set(\n job.x - halo,\n -Math.max(this._skirtDepth, halo),\n job.z - halo,\n );\n this._bootBounds.max.set(\n job.x + this.chunkSize + halo,\n this._maxHeight + halo,\n job.z + this.chunkSize + halo,\n );\n return this._bootFrustum.intersectsBox(this._bootBounds);\n }\n\n /**\n * Put launch-camera contributors first without forcing the whole board to be\n * constructed before first reveal. The halo includes neighbouring shadow,\n * shoreline and reflection contributors used by the final camera pipeline.\n */\n prioritizeInitialCameraSet(camera, { dependencyHalo = 1.5 } = {}) {\n if (!camera || !this._buildQueue.length) return 0;\n this._setBootFrustum(camera);\n const visible = [];\n const deferred = [];\n for (const job of this._buildQueue) {\n (this._bootJobVisible(job, dependencyHalo) ? visible : deferred).push(job);\n }\n visible.sort((a, b) => camera.position.distanceToSquared({\n x: a.centerX, y: 0, z: a.centerZ,\n }) - camera.position.distanceToSquared({\n x: b.centerX, y: 0, z: b.centerZ,\n }));\n this._buildQueue = [...visible, ...deferred];\n return visible.length;\n }\n\n initialCameraSetReady(camera, { dependencyHalo = 1.5 } = {}) {\n if (!camera || !this._buildQueue.length) return true;\n this._setBootFrustum(camera);\n return !this._buildQueue.some((job) => this._bootJobVisible(job, dependencyHalo));\n }\n\n _createChunk(job) {\n const mesh = new THREE.Mesh(this.geometries[3], this.material);\n mesh.position.set(job.x, 0, job.z);\n mesh.scale.setScalar(this.chunkSize);\n mesh.matrixAutoUpdate = false;\n mesh.updateMatrix();\n mesh.updateMatrixWorld(true);\n this.group.add(mesh);\n this.chunks.push({\n mesh,\n center: new THREE.Vector3(job.centerX, 0, job.centerZ),\n lod: 3,\n cellCx: job.cellCx,\n cellCz: job.cellCz,\n cellKey: job.cellKey,\n merged: false,\n node: null,\n });\n this._treeDirty = true;\n }\n\n _recalcThresholds() {\n this.lodThresholds = BASE_DISTANCE_BANDS.map(\n (m) => m * this.chunkSize * this._distanceScale\n );\n // Vertices sit within half a chunk diagonal (horizontally) of the centre\n // the CPU measures from; the shader uses the same horizontal+height metric.\n this.morphBands = planMorphBands(this.lodThresholds, this.chunkSize * Math.SQRT1_2);\n }\n\n // Distance at which every chunk vertex is already shaped like LOD3 — the\n // density of a folded node — so folding/unfolding there is invisible.\n get _losslessFoldDistance() {\n const end = this.morphBands?.end?.[2];\n return Number.isFinite(end) && end < MORPH_DISABLED ? end : this.lodThresholds[2];\n }\n\n // Exact nearest distance from the camera to a node's square, in the metric\n // the vertex shader morphs with (horizontal distance + camera height).\n _nodeMinDistance(node, camPos) {\n const dx = Math.max(node.minX - camPos.x, 0, camPos.x - (node.minX + node.spanX));\n const dz = Math.max(node.minZ - camPos.z, 0, camPos.z - (node.minZ + node.spanZ));\n return Math.hypot(dx, dz, camPos.y);\n }\n\n setMorphEnabled(enabled) {\n this.morphEnabled = !!enabled;\n this._publishMorph();\n }\n\n _publishMorph() {\n publishMorphUniforms(this.material?.uniforms, this.morphBands, this.lodSegments, this.morphEnabled);\n }\n\n // Scale the LOD distance bands (performance setting).\n setLodDistanceScale(m) {\n if (m === this._distanceScale) return;\n this._distanceScale = m;\n if (this.chunkSize) this._recalcThresholds();\n }\n\n // Change per-LOD segment counts. Rebuilds shared geometries gradually —\n // one LOD level per (throttled) updateLOD call, so the UI never freezes.\n setLodSegments(segments) {\n const same = segments.length === this.lodSegments.length\n && segments.every((s, i) => s === this.lodSegments[i])\n && !this._lodRebuildQueue.length;\n if (same) return;\n this._targetSegments = [...segments];\n this._lodRebuildQueue = [3, 2, 1, 0];\n }\n\n _processLodRebuild() {\n if (!this._lodRebuildQueue.length || !this._targetSegments) return;\n if (!this.geometries.length) { this._lodRebuildQueue = []; return; }\n const lod = this._lodRebuildQueue.shift();\n const res = this._targetSegments[lod];\n if (res === this.lodSegments[lod]) return;\n\n const geo = buildChunkGeometry(res, lod, { morph: true });\n setChunkBounds(geo, this.chunkSize, this._maxHeight, this._skirtDepth);\n const old = this.geometries[lod];\n this.geometries[lod] = geo;\n this.lodSegments[lod] = res;\n\n for (const chunk of this.chunks) {\n if (chunk.lod === lod) chunk.mesh.geometry = geo;\n }\n old.dispose();\n }\n\n // Refresh culling bounds when the max terrain height changes.\n updateBounds(maxHeight, skirtDepth) {\n this._maxHeight = maxHeight;\n this._skirtDepth = skirtDepth;\n for (const geo of this.geometries) {\n setChunkBounds(geo, this.chunkSize, maxHeight, skirtDepth);\n }\n if (this._circularBoundaryGeometry) {\n setChunkBounds(this._circularBoundaryGeometry, this.chunkSize, maxHeight, skirtDepth);\n }\n }\n\n // Pick a LOD per chunk from camera distance, then (if enabled) walk the\n // quadtree and fold far blocks into single meshes. Pure view-dependent\n // detail — the height field itself is never touched.\n updateLOD(cameraPos) {\n this._processLodRebuild();\n this._publishMorph();\n\n if (!this.mergeEnabled) {\n this._updateChunkLOD(cameraPos, false);\n return;\n }\n if (this._treeDirty) this._rebuildTree();\n\n this._mergedNodes.length = 0;\n this._hiddenByMerge = 0;\n if (this._root) this._visitNode(this._root, cameraPos);\n\n this.mergedGroupCount = this._mergedNodes.length;\n this.savedDrawCalls = Math.max(0, this._hiddenByMerge - this._mergedNodes.length);\n\n this._updateChunkLOD(cameraPos, true);\n }\n\n setCircularBoundary(boundary = null) {\n const maxLod = Math.max(0, this.geometries.length - 1);\n const lod = Math.max(0, Math.min(\n maxLod,\n Math.round(Number(boundary?.lod) || 0),\n ));\n const next = boundary && Number.isFinite(boundary.radius) && boundary.radius > 0\n ? {\n x: Number(boundary.x) || 0,\n z: Number(boundary.z) || 0,\n radius: Number(boundary.radius),\n lod,\n segments: Math.max(\n 2,\n Math.round(Number(boundary.chunkSegments) || this.lodSegments[lod] || 2),\n ),\n }\n : null;\n const prev = this._circularBoundary;\n const unchanged = (!prev && !next)\n || (prev && next\n && prev.x === next.x\n && prev.z === next.z\n && prev.radius === next.radius\n && prev.lod === next.lod\n && prev.segments === next.segments);\n if (unchanged && (!next || this._circularBoundaryGeometry)) return false;\n\n const previousGeometry = this._circularBoundaryGeometry;\n this._circularBoundary = next;\n this._circularBoundaryGeometry = next\n ? buildChunkGeometry(next.segments, next.lod)\n : null;\n this._circularBoundarySegments = next?.segments ?? 0;\n if (this._circularBoundaryGeometry) {\n setChunkBounds(\n this._circularBoundaryGeometry,\n this.chunkSize,\n this._maxHeight,\n this._skirtDepth,\n );\n }\n\n for (const chunk of this.chunks) {\n const onBoundary = !!next && this._straddlesCircularBoundary(\n chunk.center.x - this.chunkSize * 0.5,\n chunk.center.z - this.chunkSize * 0.5,\n this.chunkSize,\n this.chunkSize,\n );\n if (onBoundary) {\n chunk.lod = next.lod;\n chunk.mesh.geometry = this._circularBoundaryGeometry;\n } else if (chunk.mesh.geometry === previousGeometry) {\n chunk.mesh.geometry = this.geometries[Math.min(maxLod, chunk.lod)];\n }\n }\n previousGeometry?.dispose();\n this._treeDirty = true;\n return true;\n }\n\n _straddlesCircularBoundary(minX, minZ, spanX, spanZ) {\n const circle = this._circularBoundary;\n if (!circle) return false;\n const maxX = minX + spanX;\n const maxZ = minZ + spanZ;\n const nearX = circle.x < minX ? minX - circle.x\n : (circle.x > maxX ? circle.x - maxX : 0);\n const nearZ = circle.z < minZ ? minZ - circle.z\n : (circle.z > maxZ ? circle.z - maxZ : 0);\n const farX = Math.max(Math.abs(minX - circle.x), Math.abs(maxX - circle.x));\n const farZ = Math.max(Math.abs(minZ - circle.z), Math.abs(maxZ - circle.z));\n const radiusSq = circle.radius * circle.radius;\n return nearX * nearX + nearZ * nearZ <= radiusSq\n && farX * farX + farZ * farZ >= radiusSq;\n }\n\n // Recursively decide, per node, whether to fold it into one mesh or descend\n // into its 4 children. A node folds once the camera's nearest distance to it\n // exceeds its world span × mergeDistance (3D distance, so overhead views fold\n // too), with hysteresis so it doesn't flicker at the boundary.\n _visitNode(node, camPos) {\n if (node.leaf) {\n // single detailed chunk — hand it back to the per-chunk LOD pass\n if (node.chunk.merged) { node.chunk.merged = false; node.chunk.mesh.visible = true; }\n return;\n }\n // Only a FULL node (its whole square is tiled by existing chunks) may fold:\n // a partial node straddles the assembly boundary or not-yet-streamed tiles,\n // and folding it would paint terrain across the empty gap with no edge wall.\n const canFold = node.full\n && (this.macroProxyEnabled || node.level > 0)\n && !this._straddlesCircularBoundary(node.minX, node.minZ, node.spanX, node.spanZ);\n if (canFold) {\n const nearest = Math.hypot(node.center.x - camPos.x, camPos.y, node.center.z - camPos.z) - node.half;\n const foldDist = node.spanWorld * this.mergeDistance * this._distanceScale;\n // With geomorphing, a node only folds once every vertex under it is\n // already on the LOD3 grid (the folded mesh's density), and unfolds at\n // that same distance, so folds no longer pop the silhouette. The 3%\n // margin on folding is the hysteresis.\n const lossless = !this.morphEnabled\n || this._nodeMinDistance(node, camPos) >= this._losslessFoldDistance * (node.merged ? 1 : 1.03);\n const want = lossless && (node.merged ? nearest > foldDist * 0.85 : nearest > foldDist);\n if (want) {\n if (!node.merged) this._foldNode(node);\n this._mergedNodes.push(node);\n this._hiddenByMerge += node.chunks.length;\n return;\n }\n }\n if (node.merged) this._unfoldNode(node);\n for (const child of node.children) this._visitNode(child, camPos);\n }\n\n // Distance-based geometry LOD for the detailed chunks. When skipMerged is\n // true, chunks hidden by an active merge/macro state are left untouched.\n _updateChunkLOD(cameraPos, skipMerged) {\n const [t0, t1, t2] = this.lodThresholds;\n const counts = [0, 0, 0, 0];\n for (const chunk of this.chunks) {\n if (skipMerged && chunk.merged) continue;\n const d = this._tmp.copy(chunk.center).sub(cameraPos).length();\n // A circle-straddling chunk uses one stable, budget-aware LOD. This keeps\n // the rim topology independent of camera motion without pinning a large\n // expanded disk to the most expensive geometry.\n const onCircularBoundary = this._straddlesCircularBoundary(\n chunk.center.x - this.chunkSize * 0.5,\n chunk.center.z - this.chunkSize * 0.5,\n this.chunkSize,\n this.chunkSize,\n );\n const lod = onCircularBoundary\n ? Math.min(this.geometries.length - 1, this._circularBoundary.lod)\n : (d < t0 ? 0 : d < t1 ? 1 : d < t2 ? 2 : 3);\n const geometry = onCircularBoundary && this._circularBoundaryGeometry\n ? this._circularBoundaryGeometry\n : this.geometries[lod];\n if (lod !== chunk.lod || chunk.mesh.geometry !== geometry) {\n chunk.lod = lod;\n chunk.mesh.geometry = geometry;\n }\n counts[lod]++;\n }\n this.lodCounts = counts;\n }\n\n // Tune the merge layer (performance settings).\n setMergeOptions({ enabled, quadsPerChunk, mergeDistance, macroEnabled } = {}) {\n if (enabled !== undefined && enabled !== this.mergeEnabled) {\n this.mergeEnabled = !!enabled;\n if (!this.mergeEnabled) this._restoreAll();\n }\n if (quadsPerChunk !== undefined) {\n const v = Math.max(2, Math.round(quadsPerChunk));\n if (v !== this.mergeQuadsPerChunk) {\n this.mergeQuadsPerChunk = v;\n this._disposeNodeMeshes(); // node resolution changed → rebuild lazily\n }\n }\n if (mergeDistance !== undefined) {\n const v = Number(mergeDistance);\n if (Number.isFinite(v)) this.mergeDistance = Math.max(0.5, v);\n }\n if (macroEnabled !== undefined) this.macroProxyEnabled = !!macroEnabled;\n }\n\n // --- Quadtree ------------------------------------------------------------\n // Build a quadtree over the current chunks on their integer grid. Leaves are\n // single chunks; internal nodes cover a power-of-two square block. A node is\n // FULL only when every cell of its square is occupied by an existing chunk —\n // partial nodes (assembly boundary / still-streaming tiles) never fold, so a\n // merged mesh can never paint terrain across an empty gap.\n _rebuildTree() {\n this._treeDirty = false;\n this._disposeNodeMeshes();\n if (!this.chunks.length) { this._root = null; return; }\n\n const cs = this.chunkSize;\n let minX = Infinity, minZ = Infinity;\n for (const c of this.chunks) {\n const x0 = c.center.x - cs / 2, z0 = c.center.z - cs / 2;\n if (x0 < minX) minX = x0;\n if (z0 < minZ) minZ = z0;\n }\n this._gridOriginX = minX;\n this._gridOriginZ = minZ;\n\n // Integer grid index relative to the min corner (consistent for any chunk\n // count / cell layout, since all corners differ by integer × chunkSize).\n let gw = 0, gh = 0;\n for (const c of this.chunks) {\n c.ix = Math.round((c.center.x - cs / 2 - minX) / cs);\n c.iz = Math.round((c.center.z - cs / 2 - minZ) / cs);\n if (c.ix + 1 > gw) gw = c.ix + 1;\n if (c.iz + 1 > gh) gh = c.iz + 1;\n c.node = null;\n c.merged = false;\n c.mesh.visible = true; // folds below re-hide as needed; avoids a gap\n }\n this._boardMin.set(minX, 0, minZ);\n this._boardMax.set(minX + gw * cs, 0, minZ + gh * cs);\n\n let size = 1;\n while (size < Math.max(gw, gh, 1)) size *= 2;\n this._root = this._buildNode(this.chunks, 0, 0, size, 0);\n }\n\n _buildNode(chunks, x0, z0, size, level) {\n if (!chunks.length) return null;\n if (size === 1) return this._leafNode(chunks[0], x0, z0, level);\n\n const half = size / 2;\n const midX = x0 + half, midZ = z0 + half;\n const q = [[], [], [], []];\n for (const c of chunks) {\n const qx = c.ix < midX ? 0 : 1;\n const qz = c.iz < midZ ? 0 : 1;\n q[qz * 2 + qx].push(c);\n }\n const offs = [[x0, z0], [midX, z0], [x0, midZ], [midX, midZ]];\n const children = [];\n for (let i = 0; i < 4; i++) {\n if (!q[i].length) continue;\n const child = this._buildNode(q[i], offs[i][0], offs[i][1], half, level + 1);\n if (child) children.push(child);\n }\n // A square of side `size` is full iff it holds exactly size² distinct chunks.\n const full = chunks.length === size * size;\n if (!full && children.length === 1) return children[0]; // collapse sparse chain\n return this._internalNode(children, chunks, x0, z0, size, level, full);\n }\n\n _leafNode(chunk, x0, z0, level) {\n const cs = this.chunkSize;\n const minX = this._gridOriginX + x0 * cs, minZ = this._gridOriginZ + z0 * cs;\n const node = {\n leaf: true, chunk, children: null, chunks: [chunk], full: true,\n minX, minZ, spanX: cs, spanZ: cs, spanWorld: cs, spanChunks: 1,\n center: new THREE.Vector3(minX + cs / 2, 0, minZ + cs / 2),\n half: cs * 0.7072, level, mesh: null, merged: false,\n };\n chunk.node = node;\n return node;\n }\n\n _internalNode(children, chunks, x0, z0, size, level, full) {\n const cs = this.chunkSize;\n const minX = this._gridOriginX + x0 * cs, minZ = this._gridOriginZ + z0 * cs;\n const span = size * cs;\n return {\n leaf: false, chunk: null, children, chunks, full,\n minX, minZ, spanX: span, spanZ: span, spanWorld: span, spanChunks: size,\n center: new THREE.Vector3(minX + span / 2, 0, minZ + span / 2),\n half: 0.5 * Math.SQRT2 * span, level, mesh: null, merged: false,\n };\n }\n\n // Shared flat unit-grid geometry (with skirts) for a given resolution. aLod\n // encodes the merge tier so the shader can colour folded terrain by level.\n _mergedGeometry(res, aLod) {\n const key = `${res}:${aLod}`;\n let geo = this._mergedGeo.get(key);\n if (!geo) {\n geo = buildChunkGeometry(res, aLod);\n this._mergedGeo.set(key, geo);\n }\n return geo;\n }\n\n // Fold a node into one mesh: show its merged mesh, hide every descendant\n // (chunks + deeper node meshes). Tier (log2 of span in chunks) drives both\n // mesh resolution and the debug colour.\n _foldNode(node) {\n node.merged = true;\n if (!node.mesh) {\n const tier = Math.max(1, Math.round(Math.log2(node.spanChunks)));\n const res = Math.min(160, Math.max(8, node.spanChunks * this.mergeQuadsPerChunk));\n const aLod = 3 + Math.min(5, tier); // 4..8 → colour ramp in shader\n const mesh = new THREE.Mesh(this._mergedGeometry(res, aLod), this.material);\n mesh.position.set(node.minX, 0, node.minZ);\n mesh.scale.set(node.spanX, 1, node.spanZ);\n mesh.matrixAutoUpdate = false;\n mesh.frustumCulled = false;\n mesh.updateMatrix();\n mesh.updateMatrixWorld(true);\n this.group.add(mesh);\n node.mesh = mesh;\n }\n node.mesh.visible = true;\n for (const c of node.chunks) { c.merged = true; c.mesh.visible = false; }\n this._forEachDescendantInternal(node, (d) => {\n d.merged = false;\n if (d.mesh) d.mesh.visible = false;\n });\n }\n\n // Unfold a node: hide its mesh. Children are re-evaluated in the same\n // updateLOD pass (so chunks/child meshes reappear with no one-frame blank).\n _unfoldNode(node) {\n node.merged = false;\n if (node.mesh) node.mesh.visible = false;\n }\n\n _forEachDescendantInternal(node, fn) {\n if (!node.children) return;\n for (const child of node.children) {\n if (child.leaf) continue;\n fn(child);\n this._forEachDescendantInternal(child, fn);\n }\n }\n\n _forEachInternal(fn) {\n const rec = (n) => {\n if (!n || n.leaf) return;\n fn(n);\n for (const c of n.children) rec(c);\n };\n rec(this._root);\n }\n\n _restoreAll() {\n for (const c of this.chunks) { c.merged = false; c.mesh.visible = true; }\n this._forEachInternal((n) => { n.merged = false; if (n.mesh) n.mesh.visible = false; });\n this._mergedNodes.length = 0;\n this.mergedGroupCount = 0;\n this.savedDrawCalls = 0;\n }\n\n _disposeNodeMeshes() {\n this._forEachInternal((n) => {\n if (n.mesh) { this.group.remove(n.mesh); n.mesh = null; }\n n.merged = false;\n });\n this._mergedNodes.length = 0;\n }\n\n // --- Debug overlay -------------------------------------------------------\n // Colour folded terrain by merge level (green = small 2x2 fold → magenta =\n // whole board) via the shared terrain shader's uMergeDebug branch. Merged\n // meshes carry aLod 4..8 (the tier) so the shader can ramp the colour.\n setMergeDebug(on) {\n this._mergeDebug = !!on;\n const u = this.material?.uniforms?.uMergeDebug;\n if (u) u.value = this._mergeDebug ? 1.0 : 0.0;\n }\n\n // Cull invisible terrain meshes based on the camera frustum and facing\n // direction. Detailed chunks and folded node meshes are culled separately;\n // chunks hidden by an active fold are skipped (left invisible).\n // visibleChunkCount / culledChunkCount are reported in draw calls (a folded\n // node counts as one), which is the figure the merge layer is optimising.\n cull(camera) {\n if (!this.cullingEnabled) {\n let visibleCount = 0;\n for (const chunk of this.chunks) {\n if (chunk.merged) { if (chunk.mesh.visible) chunk.mesh.visible = false; continue; }\n if (!chunk.mesh.visible) chunk.mesh.visible = true;\n visibleCount++;\n }\n for (const node of this._mergedNodes) { node.mesh.visible = true; visibleCount++; }\n this.visibleChunkCount = visibleCount;\n this.culledChunkCount = 0;\n return;\n }\n\n camera.updateMatrixWorld(true);\n const cullingContext = createCullingContext(\n camera,\n this.chunkSize,\n this.behindCameraCulling,\n this.cullingAggressiveness,\n this._cullingContext,\n -this._skirtDepth\n );\n this._cullChunks.length = 0;\n for (const chunk of this.chunks) {\n if (!chunk.merged) this._cullChunks.push(chunk);\n }\n const chunkResult = cullChunks(\n this._cullChunks,\n camera,\n this.chunkSize,\n this._maxHeight,\n this.behindCameraCulling,\n this.cullingAggressiveness,\n cullingContext\n );\n let visible = chunkResult.visibleCount;\n let culled = chunkResult.culledCount;\n\n if (this._mergedNodes.length) {\n const mergeResult = cullChunks(\n this._mergedNodes,\n camera,\n this.chunkSize,\n this._maxHeight,\n this.behindCameraCulling,\n this.cullingAggressiveness,\n cullingContext\n );\n visible += mergeResult.visibleCount;\n culled += mergeResult.culledCount;\n }\n\n this.visibleChunkCount = visible;\n this.culledChunkCount = culled;\n }\n\n dispose() {\n this._disposeNodeMeshes();\n for (const geo of this._mergedGeo.values()) geo.dispose();\n this._mergedGeo.clear();\n this._root = null;\n this._treeDirty = true;\n this.mergedGroupCount = 0;\n this.savedDrawCalls = 0;\n for (const chunk of this.chunks) this.group.remove(chunk.mesh);\n this._circularBoundaryGeometry?.dispose();\n this._circularBoundaryGeometry = null;\n this._circularBoundarySegments = 0;\n this._circularBoundary = null;\n for (const geo of this.geometries) geo.dispose();\n this.chunks = [];\n this._cells = [];\n this.geometries = [];\n this._lodRebuildQueue = [];\n this._buildQueue = [];\n this._building = false;\n this.activeChunkCount = 0;\n this.targetChunkCount = 0;\n this.visibleChunkCount = 0;\n this.culledChunkCount = 0;\n this._cullChunks.length = 0;\n this.lodCounts = [0, 0, 0, 0];\n }\n}\n","import { TerrainBoard } from '../engine/terrain/TerrainBoard.js';\n\n// Keep the studio's existing LOD cadence, profiling and build budgets outside\n// this module. The same geometry/LOD/culling path serves the public runtime.\nexport function updateFiniteTerrainView(board, camera, { lod = true, cull = true } = {}) {\n // cull() already refreshes matrices; the combined path also needs them\n // before selecting LOD. Keep split studio profiling calls at their old cost.\n if (lod && cull) camera.updateMatrixWorld(true);\n if (lod) board.updateLOD(camera.position);\n if (cull) board.cull(camera);\n}\n\nexport class FiniteTerrainRuntime {\n constructor(parent, material) {\n this.board = new TerrainBoard(parent, material);\n }\n\n get group() {\n return this.board.group;\n }\n\n update(camera, budget) {\n if (budget && this.board.isBuilding) this.board.processBuildQueue(budget);\n updateFiniteTerrainView(this.board, camera);\n }\n\n dispose() {\n this.board.dispose();\n this.board.group.removeFromParent();\n }\n}\n","import { applyTerrainDetailUniforms, applyTerrainVisualUniforms } from './TerrainAppearance.js';\nimport { DetailPageCache } from '../engine/terrain/detail/DetailPageCache.js';\nimport * as THREE from 'three';\nimport { createTerrainMaterial, createTerrainUniforms } from '../engine/terrain/TerrainMaterial.js';\nimport { TerrainHeightSampler } from '../engine/terrain/TerrainHeightSampler.js';\nimport { buildChunkGeometry } from '../engine/terrain/ChunkGeometry.js';\nimport { applyPlanetStyleToUniforms } from '../engine/style/PaletteUniforms.js';\nimport { validatePrograms, programHealthError } from '../engine/render/ProgramHealthGate.js';\nimport { TerrainSource } from './TerrainSources.js';\nimport { resolveSurfaceReference } from '../engine/terrain/surface/SurfaceDocument.js';\nimport { FiniteTerrainRuntime } from './FiniteTerrainRuntime.js';\nimport { applyTerrainShapeUniforms, applyTerrainShadingUniforms } from './TerrainParameters.js';\nimport { normalizeConfiguration, configurationParameters } from './FiniteTerrainConfiguration.js';\n\nconst error = (code, message) => Object.assign(new Error(message), { code });\nconst checkSignal = (signal) => {\n if (signal?.aborted) throw error('TERRAIN_CANCELLED', 'Terrain operation cancelled');\n};\n\n/** Browser WebGL2 runtime. Importing this module has no browser side effects. */\nexport class FiniteTerrain {\n constructor({ renderer, configuration = {}, signal, resources, _world = {} } = {}) {\n checkSignal(signal);\n if (!renderer?.isWebGLRenderer)\n throw new TypeError('A caller-owned THREE.WebGLRenderer is required');\n this._world = _world;\n this.mode = _world.mode ?? 'finite';\n this._layers = new Set();\n if (resources?.renderer && resources.renderer !== renderer)\n throw new TypeError('Resources and terrain must use the same renderer');\n this.resources = resources ?? null;\n this._surface = null;\n this._materialSurface = null;\n this._configuration = normalizeConfiguration(configuration, undefined, _world);\n this._requestedConfiguration = this._configuration;\n this._renderer = renderer;\n this._disposed = false;\n this._revision = 0;\n this._jobs = new Set();\n this._compilingMaterials = new Map();\n this._retiredMaterials = new Set();\n this._cameraPosition = new THREE.Vector3();\n this._viewCamera = null;\n this._worldCamera = null;\n this._viewport = new THREE.Vector4();\n this._prepared = false;\n this._onContextRestored = () => this._detailPageCache?.onContextRestored();\n renderer.domElement?.addEventListener?.('webglcontextrestored', this._onContextRestored);\n this._fallback = new THREE.DataTexture(new Uint8Array([128, 128, 128, 255]), 1, 1);\n this._fallback.needsUpdate = true;\n this._uniforms = createTerrainUniforms({ surfaceFallback: this._fallback });\n this._ownedTextures = new Set(\n Object.values(this._uniforms)\n .map((u) => u.value)\n .filter((v) => v?.isTexture),\n );\n this._source = new TerrainSource(this._configuration, this.mode);\n this._stack = this._source.stack;\n this._stackGLSL = this._source.program;\n this._material = this._makeMaterial(this._configuration.source.octaves);\n this._material.uniforms = this._uniforms;\n this.object = new THREE.Group();\n this.object.name = 'procedural-terrain';\n this._runtime =\n _world.createRuntime?.(this) ?? new FiniteTerrainRuntime(this.object, this._material);\n this._sampler = new TerrainHeightSampler(\n this._uniforms,\n () => ({\n octaves: this._configuration.source.octaves,\n infinite: this.mode === 'infinite',\n }),\n this._stack,\n );\n this._apply(this._configuration);\n this._source.install(this._uniforms, this._sampler);\n }\n\n get configuration() {\n return this._configuration;\n }\n\n addLayer(layer) {\n this._assertAlive();\n this._layers.add(layer);\n return () => this._layers.delete(layer);\n }\n\n sampleHeight3D(x, y, z) {\n this._assertAlive();\n if (this.mode !== 'planet') throw new TypeError('sampleHeight3D requires a planet terrain');\n if (![x, y, z].every(Number.isFinite) || Math.hypot(x, y, z) < 1e-9)\n throw new TypeError('A nonzero finite direction is required');\n const length = Math.hypot(x, y, z);\n return this._world.sample(this, x / length, y / length, z / length);\n }\n\n setImagery(texture, { blend = 1 } = {}) {\n this._assertAlive();\n if (this.mode !== 'finite') throw new TypeError('Imagery requires finite terrain');\n if (texture && !texture.isTexture) throw new TypeError('A THREE.Texture is required');\n if (!Number.isFinite(blend) || blend < 0 || blend > 1)\n throw new RangeError('blend must be 0..1');\n if (this._source.variant === 'manual-empty-base' && texture)\n throw new TypeError('Flat manual terrain does not support imagery; use a heightmap source');\n const size = this.configuration.layout.chunkCount * this.configuration.layout.chunkSize;\n const u = this._uniforms;\n u.uImportImageryTex.value = texture;\n u.uImportImageryMode.value = texture ? 3 : 0;\n u.uImportImageryBlend.value = blend;\n u.uImportHeightRegion.value.set(-size / 2, -size / 2, size, size);\n }\n\n _installSurface(surface, u = this._uniforms) {\n u.uSurfDiffuse.value = surface.diffuse;\n u.uSurfProps.value = surface.props;\n u.uSurfaceArrayMode.value = surface.backend === 'array' ? 1 : 0;\n u.uSurfaceRoleMap.value = surface.mapping ?? u.uSurfaceRoleMap.value;\n u.uSurfaceRoleTint.value = surface.tints ?? u.uSurfaceRoleTint.value;\n u.uSurfaceAssetSize.value = surface.sizes\n ? [...surface.sizes, ...new Array(Math.max(0, 64 - surface.sizes.length)).fill(2)]\n : u.uSurfaceAssetSize.value;\n u.uSurfaceGraphCode.value = surface.graph?.body ?? '';\n u.uSurfaceGraphParams.value = Array.from(\n { length: 128 },\n (_, i) => new THREE.Vector4(...(surface.graph?.values[i] ?? [0, 0, 0, 0])),\n );\n u.uSurfaceContributions.value = surface.budget?.contributions ?? 4;\n u.uSurfPresent.value = surface.present ?? u.uSurfPresent.value;\n u.uSurfRolePresent.value = surface.rolePresent ?? u.uSurfRolePresent.value;\n u.uSurfTile.value = surface.tile ?? u.uSurfTile.value;\n if (surface.paint?.layers) {\n const items = (slot) => {\n const layer = surface.paint.layers.find((l) => l.slot === slot);\n return layer ? resolveSurfaceReference(layer.materialInstanceId, surface.document) : null;\n };\n u.uSurfacePaintMap.value = Array.from({ length: 32 }, (_, slot) => {\n const refs = items(slot);\n return refs\n ? new THREE.Vector4(\n surface.slots[refs[0].assetId],\n refs[1] ? surface.slots[refs[1].assetId] : -1,\n refs[0].wetness ?? 0,\n refs[0].scale ?? 1,\n )\n : new THREE.Vector4(-1, -1, 0, 1);\n });\n u.uSurfacePaintTint.value = Array.from(\n { length: 32 },\n (_, slot) => new THREE.Vector3(...(items(slot)?.[0].tint ?? [1, 1, 1])),\n );\n }\n u.uSurfMode.value = 1;\n u.uSurfAmount.value = 1;\n u.uSurfReveal.value = 1;\n }\n\n async setSurface(surface, options = {}) {\n this._assertAlive();\n if (\n surface &&\n (!surface.diffuse?.isTexture || !surface.props?.isTexture || surface.backend !== 'array')\n )\n throw new TypeError('A valid surface array resource is required');\n this._surface = surface;\n try {\n await this.configure({}, options);\n } catch (error) {\n if (this._surface === surface) this._surface = this._materialSurface;\n throw error;\n }\n }\n\n _assertAlive() {\n if (this._disposed) throw error('TERRAIN_DISPOSED', 'Terrain has been disposed');\n }\n\n _assertIdentity() {\n this.object.updateWorldMatrix(true, false);\n const e = this.object.matrixWorld.elements;\n if (e.some((v, i) => Math.abs(v - (i % 5 === 0 ? 1 : 0)) > 1e-8)) {\n throw error(\n 'TERRAIN_TRANSFORM_UNSUPPORTED',\n 'Terrain worlds require an identity world transform in this release',\n );\n }\n }\n\n _makeMaterial(octaves, source = this._source) {\n const variant = this._surface\n ? source.variant === 'base'\n ? 'surface'\n : source.variant === 'hybrid-base'\n ? 'hybrid-surface'\n : 'manual-surface'\n : source.variant;\n const cloneValue = (value) =>\n value?.isTexture\n ? value\n : Array.isArray(value)\n ? value.map(cloneValue)\n : value?.clone\n ? value.clone()\n : value;\n const uniforms = Object.fromEntries(\n Object.entries(this._uniforms).map(([name, u]) => [name, { value: cloneValue(u.value) }]),\n );\n source.install(uniforms);\n if (this._surface) this._installSurface(this._surface, uniforms);\n else {\n uniforms.uSurfaceArrayMode.value = 0;\n uniforms.uSurfMode.value = 0;\n }\n const material =\n this._world.createMaterial?.({ ...this, _uniforms: uniforms }, octaves, source.program) ??\n createTerrainMaterial(uniforms, octaves, source.program, { variant, worldMode: 'studio' });\n // The existing shader writes display-encoded colour itself. Do not apply\n // host tone mapping to it a second time.\n material.toneMapped = false;\n return material;\n }\n\n _apply(c, source = this._source) {\n const p = (this._params = configurationParameters(c));\n const size = p.chunkCount * p.chunkSize;\n const skirtDepth = Math.max(24, p.heightScale * 0.08);\n applyTerrainShapeUniforms(this._uniforms, p, size);\n applyTerrainShadingUniforms(this._uniforms, p, {\n size,\n skirtDepth,\n wallThickness: Math.max(10, size * 0.006),\n });\n applyTerrainDetailUniforms(this._uniforms, c.material);\n applyTerrainVisualUniforms(this._uniforms, c.material);\n this._uniforms.uBakeOrigin.value.set(-size / 2, -size / 2);\n this._uniforms.uBakeSpan.value.set(size, size);\n const az = THREE.MathUtils.degToRad(p.sunAzimuth);\n const el = THREE.MathUtils.degToRad(p.sunElevation);\n this._uniforms.uSunDir.value.set(\n Math.cos(el) * Math.sin(az),\n Math.sin(el),\n Math.cos(el) * Math.cos(az),\n );\n this._uniforms.uFogDensity.value = p.fogDensity * 0.0001;\n applyPlanetStyleToUniforms(this._uniforms, { ...c.style, palette: c.palette });\n this._uniforms.uInfiniteMode.value = this.mode === 'infinite' ? 1 : 0;\n if (this._world.apply) {\n this._world.apply(this, c);\n return;\n }\n const b = this._runtime.board;\n b.syncCells({\n chunkCount: p.chunkCount,\n chunkSize: p.chunkSize,\n maxHeight: Math.max(\n p.heightScale * 1.35 + 2,\n source.maxHeight + (source.hasBase ? p.heightScale * 1.35 : 0),\n ),\n skirtDepth: skirtDepth - Math.min(0, source.minHeight),\n lodSegments: c.quality.lodSegments,\n cells: [{ cx: 0, cz: 0 }],\n progressive: false,\n });\n // Public configuration commits are complete; the studio retains its own\n // progressive geometry cadence through the same TerrainBoard implementation.\n while (b._lodRebuildQueue.length) b.updateLOD(this._cameraPosition);\n b.setMorphEnabled(c.quality.morphEnabled);\n b.setLodDistanceScale(c.quality.lodDistanceScale);\n b.setMergeOptions({ enabled: c.quality.mergeEnabled });\n b.cullingEnabled = c.quality.cullingEnabled;\n }\n\n _cancelJobs(code, message) {\n for (const job of this._jobs) job.cancel(error(code, message));\n }\n\n // Cancels the public operation immediately. Driver compilation cannot be\n // interrupted; its candidate resources are retired once it actually settles.\n _operation(task, signal) {\n checkSignal(signal);\n let cancel, reason;\n const cancelled = new Promise((_, reject) => {\n cancel = (error) => {\n reason = error;\n reject(error);\n };\n });\n const job = { cancel };\n const onAbort = () => cancel(error('TERRAIN_CANCELLED', 'Terrain operation cancelled'));\n signal?.addEventListener('abort', onAbort, { once: true });\n this._jobs.add(job);\n const work = Promise.resolve().then(() => {\n if (reason) throw reason;\n this._assertAlive();\n checkSignal(signal);\n return task();\n });\n return Promise.race([work, cancelled]).finally(() => {\n signal?.removeEventListener('abort', onAbort);\n this._jobs.delete(job);\n });\n }\n\n _retireMaterial(material) {\n if (this._compilingMaterials.has(material)) this._retiredMaterials.add(material);\n else material.dispose();\n }\n\n async _compile(material, camera) {\n this._compilingMaterials.set(material, (this._compilingMaterials.get(material) ?? 0) + 1);\n const probe = this._world.createProbe?.(this, material);\n const geometry = probe?.geometry ?? buildChunkGeometry(2, 0, { morph: true });\n const scene = new THREE.Scene();\n scene.add(probe?.mesh ?? new THREE.Mesh(geometry, material));\n try {\n await this._renderer.compileAsync(scene, camera);\n const health = await validatePrograms({ renderer: this._renderer, materials: [material] });\n if (!health.ok) throw programHealthError(health);\n } finally {\n geometry.dispose();\n const count = this._compilingMaterials.get(material) - 1;\n if (count) this._compilingMaterials.set(material, count);\n else {\n this._compilingMaterials.delete(material);\n if (this._retiredMaterials.delete(material)) material.dispose();\n }\n }\n }\n\n async prepare(camera, { signal } = {}) {\n this._assertAlive();\n this._assertIdentity();\n if (!camera?.isCamera) throw new TypeError('A THREE.Camera is required');\n this._viewCamera = camera;\n camera.updateWorldMatrix(true, false);\n camera.getWorldPosition(this._cameraPosition);\n checkSignal(signal);\n const revision = this._revision;\n await this._operation(async () => {\n await this._compile(this._material, camera);\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain preparation superseded');\n await this._world.prepare?.(this, camera, signal, () => {\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain preparation superseded');\n });\n for (const layer of this._layers) await layer.prepare?.(camera, { signal });\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain preparation superseded');\n this._prepared = true;\n }, signal);\n }\n\n async configure(patch, { signal } = {}) {\n this._assertAlive();\n checkSignal(signal);\n const next = normalizeConfiguration(patch, this._requestedConfiguration, this._world);\n this._cancelJobs('TERRAIN_SUPERSEDED', 'Terrain configuration superseded');\n const revision = ++this._revision;\n this._requestedConfiguration = next;\n const wasPrepared = this._prepared;\n const sameLayout = JSON.stringify(next.layout) === JSON.stringify(this._configuration.layout);\n const reuseSource = next.source === this._configuration.source && sameLayout;\n const nextSource = reuseSource ? this._source : new TerrainSource(next, this.mode);\n const sourceChanged = !reuseSource || next.heightScale !== this._configuration.heightScale\n || next.terrainFormationSeaLevel !== this._configuration.terrainFormationSeaLevel\n || ['biomeScale', 'moistScale', 'moistBias', 'tempBias'].some(\n key => next.material[key] !== this._configuration.material[key]);\n const changedProgram =\n nextSource.signature !== this._source.signature || this._materialSurface !== this._surface;\n const candidate = changedProgram ? this._makeMaterial(next.source.octaves, nextSource) : null;\n let published = false,\n started = false;\n try {\n await this._operation(async () => {\n started = true;\n try {\n if (candidate)\n await this._compile(candidate, this._viewCamera || new THREE.PerspectiveCamera());\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain configuration superseded');\n this._assertIdentity();\n this._apply(next, nextSource);\n const previousSource = this._source;\n this._source = nextSource;\n this._stack = nextSource.stack;\n this._stackGLSL = nextSource.program;\n nextSource.install(this._uniforms, this._sampler);\n if (this._surface) this._installSurface(this._surface);\n else {\n this._uniforms.uSurfMode.value = 0;\n this._uniforms.uSurfaceArrayMode.value = 0;\n }\n if (candidate) {\n const old = this._material;\n if (this._runtime.board) this._runtime.board.material = candidate;\n candidate.uniforms = this._uniforms;\n this._material = candidate;\n this._runtime.group.traverse((o) => {\n if (o.isMesh && o.material === old) o.material = candidate;\n });\n this._retireMaterial(old);\n }\n this._configuration = next;\n this._materialSurface = this._surface;\n // Publication is synchronous. Failed/cancelled optional warm-ups must\n // never retire resources already bound to the live meshes.\n published = true;\n if (previousSource !== nextSource) previousSource.dispose();\n const check = () => {\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain configuration superseded');\n };\n this._prepared = false;\n await this._world.sourceChanged?.(this, nextSource, { signal, check, sourceChanged });\n check();\n for (const layer of this._layers) {\n await layer.onTerrainChanged?.({\n signal,\n sourceChanged,\n programChanged: changedProgram,\n });\n check();\n }\n this._prepared = wasPrepared || !!candidate;\n } finally {\n if (!published) {\n candidate?.dispose();\n if (!reuseSource) nextSource.dispose();\n }\n }\n }, signal);\n } catch (err) {\n if (!started) {\n candidate?.dispose();\n if (!reuseSource) nextSource.dispose();\n }\n if (revision === this._revision) this._requestedConfiguration = this._configuration;\n throw err;\n }\n }\n\n update(deltaSeconds, { camera } = {}) {\n this._assertAlive();\n this._assertIdentity();\n if (!Number.isFinite(deltaSeconds) || deltaSeconds < 0)\n throw new RangeError('deltaSeconds must be nonnegative');\n if (!camera?.isCamera) throw new TypeError('A THREE.Camera is required');\n this._viewCamera = camera;\n camera.updateWorldMatrix(true, false);\n camera.getWorldPosition(this._cameraPosition);\n // TerrainBoard consumes world camera coordinates. For a parented camera,\n // a detached view camera preserves its projection without changing the host.\n let view = camera;\n if (camera.parent) {\n if (!this._worldCamera || this._worldCamera.type !== camera.type)\n this._worldCamera = camera.clone(false);\n view = this._worldCamera;\n view.projectionMatrix.copy(camera.projectionMatrix);\n view.projectionMatrixInverse.copy(camera.projectionMatrixInverse);\n camera.matrixWorld.decompose(view.position, view.quaternion, view.scale);\n view.updateMatrix();\n view.updateMatrixWorld(true);\n }\n const detail = this.configuration.material;\n if (!this._externalDetailCache && detail.terrainDetailQuality > 0 && typeof Worker === 'function' && this._renderer.initTexture) {\n this._detailPageCache ??= new DetailPageCache({ renderer: this._renderer, uniforms: this._uniforms });\n const seed = this._uniforms.uSeedOffset.value;\n this._detailPageCache.update({ camera: view, mode: this.mode === 'finite' ? 'studio' : this.mode,\n generation: this._revision,\n scale: detail.terrainDetailScale * (0.55 + 0.70 * Math.min(1, detail.terrainDetailQuality / 3)),\n seedX: seed.x, seedY: seed.y, active: true, allowUpload: !this._compilingMaterials.size,\n dt: Math.min(deltaSeconds, 0.1) });\n } else if (!this._externalDetailCache && this._detailPageCache) {\n this._uniforms.uDetailGlobalBlend.value = 0;\n }\n this._uniforms.uTime.value += Math.min(deltaSeconds, 0.1);\n this._runtime.update(view);\n this._world.update?.(this, view);\n for (const layer of this._layers) layer.update?.(Math.min(deltaSeconds, 0.1), { camera: view });\n const viewport = this._renderer.getCurrentViewport(this._viewport);\n this._uniforms.uPixelWorldPerDist.value = camera.isPerspectiveCamera\n ? (2 * Math.tan(THREE.MathUtils.degToRad(camera.fov) * 0.5)) /\n (Math.max(camera.zoom, 1e-6) * Math.max(1, viewport.w))\n : 0;\n }\n\n sampleHeight(x, z) {\n this._assertAlive();\n this._assertIdentity();\n if (!Number.isFinite(x) || !Number.isFinite(z))\n throw new TypeError('Coordinates must be finite');\n if (this.mode === 'planet') throw new TypeError('Use sampleHeight3D for planet terrains');\n const half = (this._configuration.layout.chunkCount * this._configuration.layout.chunkSize) / 2;\n return this.mode !== 'infinite' && (Math.abs(x) > half || Math.abs(z) > half)\n ? null\n : this._source.sample(x, z, (a, b) => this._sampler.heightAt(a, b));\n }\n\n serialize() {\n this._assertAlive();\n return {\n format: 'procedural-terrains',\n schemaVersion: 1,\n kind: this.mode,\n extensions: [...this._layers].map((layer) => layer.serialize?.()).filter(Boolean),\n configuration: JSON.parse(JSON.stringify(this._configuration)),\n };\n }\n\n getDiagnostics() {\n const b = this._runtime.board;\n if (!b)\n return {\n disposed: this._disposed,\n prepared: this._prepared,\n revision: this._revision,\n mode: this.mode,\n ...this._runtime.diagnostics(),\n };\n return {\n disposed: this._disposed,\n prepared: this._prepared,\n revision: this._revision,\n chunks: b.activeChunkCount,\n visible: b.visibleChunkCount,\n culled: b.culledChunkCount,\n lodCounts: [...b.lodCounts],\n mergedGroups: b.mergedGroupCount,\n savedDrawCalls: b.savedDrawCalls,\n };\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n ++this._revision;\n this._cancelJobs('TERRAIN_DISPOSED', 'Terrain has been disposed');\n for (const layer of [...this._layers]) layer.dispose();\n this._layers.clear();\n this._world.dispose?.(this);\n this._runtime.dispose();\n this._source.dispose();\n this._detailPageCache?.dispose();\n this._renderer.domElement?.removeEventListener?.('webglcontextrestored', this._onContextRestored);\n this.object.removeFromParent();\n this._retireMaterial(this._material);\n for (const texture of this._ownedTextures) texture.dispose();\n this._ownedTextures.clear();\n this._viewCamera = null;\n this._worldCamera = null;\n }\n}\n\nexport async function createTerrain(options) {\n return new FiniteTerrain(options);\n}\n"],"names":["error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FiniteTerrain-B5_3y6xX.js","sources":["../../../src/engine/terrain/TerrainHeightSampler.js","../../../src/engine/terrain/ChunkGeometry.js","../../../src/engine/terrain/InfiniteTerrainCulling.js","../../../src/engine/terrain/LodMorph.js","../../../src/engine/terrain/TerrainBoard.js","../../../src/runtime/FiniteTerrainRuntime.js","../../../src/runtime/FiniteTerrain.js"],"sourcesContent":["// ============================================================================\n// CPU-side terrain height sampler — exact JS port of the GLSL height field\n// (terrainGLSL.js + biomeGLSL.js). Reads the LIVE shared uniform objects so\n// it always matches what the GPU renders, in both studio and infinite mode,\n// across chunk borders, for any seed / preset / octave count.\n//\n// IMPORTANT: every arithmetic step goes through Math.fround to emulate the\n// GPU's float32 precision. The Dave Hoskins hash relies on fract() of large\n// products, so its output is a function of the exact 32-bit rounding — a\n// double-precision evaluation produces different per-cell noise values and\n// heights drift tens of units away from the rendered mesh. With f32\n// emulation the CPU result tracks the GPU to within rounding noise.\n//\n// Used by the player physics controller for ground detection. A handful of\n// samples per frame — no raycasting against chunk meshes is ever needed.\n// ============================================================================\n\nconst f = Math.fround;\n\nfunction fract32(v) { return f(v - Math.floor(v)); }\nfunction clamp(v, a, b) { return v < a ? a : v > b ? b : v; }\n// Terrain Detail twins of octaveKeep / creaseAbs (TERRAIN_DETAIL_GLSL), f32.\nfunction octaveKeep32(i, n, cut) {\n return clamp(f(f(n - i) - f(cut * f(n - 1))), 0, 1);\n}\nfunction creaseAbs32(x, cut) {\n const s = f(f(cut * cut) * 0.04);\n return s > 0 ? f(f(Math.sqrt(f(f(x * x) + s))) - f(Math.sqrt(s))) : Math.abs(x);\n}\nfunction mix32(a, b, t) { return f(a + f(f(b - a) * t)); }\nfunction smoothstep32(e0, e1, x) {\n const t = clamp(f(f(x - e0) / f(e1 - e0)), 0, 1);\n return f(f(t * t) * f(3 - f(2 * t)));\n}\n\nfunction stackSoftClamp(h) {\n if (h <= 0) return 0;\n if (h <= 1) return f(h);\n return f(Math.min(1.35, f(1 + f(0.35 * f(1 - Math.exp(f(-(h - 1) / 0.35)))))));\n}\n\nfunction finalizeStackHeight(h, u) {\n if ((u.uStackNormalize?.value ?? 0) < 0.5) return clamp(h, 0, 1.35);\n const outMin = f(u.uStackOutMin?.value ?? 0);\n const outMax = Math.max(f(u.uStackOutMax?.value ?? 1.35), f(outMin + 0.0001));\n return stackSoftClamp(f(f(h - outMin) / f(outMax - outMin)));\n}\n\n// GLSL: mat2(0.80,-0.60,0.60,0.80) * p => (0.80x + 0.60y, -0.60x + 0.80y)\nfunction rot2x(x, y) { return f(f(0.80 * x) + f(0.60 * y)); }\nfunction rot2y(x, y) { return f(f(-0.60 * x) + f(0.80 * y)); }\n\n// --- hash without sine precision issues (Dave Hoskins) — port of hash12 ----\nfunction hash12(px, py) {\n let p3x = fract32(f(px * 0.1031));\n let p3y = fract32(f(py * 0.1031));\n let p3z = p3x; // vec3(p.xyx)\n // dot(p3, p3.yzx + 33.33)\n const d = f(\n f(f(p3x * f(p3y + 33.33)) + f(p3y * f(p3z + 33.33))) + f(p3z * f(p3x + 33.33))\n );\n p3x = f(p3x + d); p3y = f(p3y + d); p3z = f(p3z + d);\n return fract32(f(f(p3x + p3y) * p3z));\n}\n\n// --- quintic value noise ----------------------------------------------------\nfunction vnoise(px, py) {\n const ix = Math.floor(px), iy = Math.floor(py);\n const fx = f(px - ix), fy = f(py - iy);\n // u = f*f*f*(f*(f*6-15)+10)\n const ux = f(f(f(fx * fx) * fx) * f(f(fx * f(f(fx * 6) - 15)) + 10));\n const uy = f(f(f(fy * fy) * fy) * f(f(fy * f(f(fy * 6) - 15)) + 10));\n const a = hash12(ix, iy);\n const b = hash12(f(ix + 1), iy);\n const c = hash12(ix, f(iy + 1));\n const d = hash12(f(ix + 1), f(iy + 1));\n return mix32(mix32(a, b, ux), mix32(c, d, ux), uy);\n}\n\nimport { evalStack2D } from './noise/noiseStackCodegen.js';\nimport { setNoiseDetailCut } from './noise/cpuNoise.js';\nimport { isLegacyStack } from './noise/NoiseStack.js';\nimport { miniComposeCPU } from '../mini/miniCompositionGLSL.js';\n\nexport class TerrainHeightSampler {\n /**\n * @param {object} uniforms shared terrain uniform objects (live references)\n * @param {function} getEnv () => ({ octaves:number, infinite:boolean })\n * @param {object} [stack] live NoiseStack (custom stacks use the f64 evaluator)\n */\n constructor(uniforms, getEnv, stack = null) {\n this.u = uniforms;\n this.getEnv = getEnv;\n this.stack = stack;\n this.heightProgram = null;\n // Optional erosion height-offset field (CPU mirror of the GLSL\n // erosionOffsetAt). When set and enabled, heightAt adds its signed\n // world-unit delta so CPU physics/props track the eroded mesh. null = none.\n this.erosion = null;\n this.destruction = null;\n }\n\n setStack(stack) { this.stack = stack; }\n setHeightProgram(program) { this.heightProgram = program?.kind === 'graph' ? program : null; }\n\n _rimFalloff(t) {\n t = clamp(t, 0, 1);\n return f(f(t * t) * f(3 - f(2 * t)));\n }\n\n _applyEdgeProfile(h, x, z, rim, octaves) {\n if ((this.u.uEdgeFalloffMode?.value ?? 0) < 0.5) return f(h * rim);\n const edgeMask = f(1 - rim);\n const freq = f(this.u.uFrequency.value);\n const px = f(f(f(x * freq) + f(this.u.uSeedOffset.value.x)) + 173.7);\n const pz = f(f(f(z * freq) + f(this.u.uSeedOffset.value.y)) + 419.2);\n const mountains = f(Math.pow(this._ridgedFBM(f(px * 2.35), f(pz * 2.35), octaves), 1.25));\n const breakup = vnoise(f(f(px * 5.1) + 61.4), f(f(pz * 5.1) + 27.8));\n const added = f(f(f(mountains * 0.55) + f(breakup * 0.12)) * edgeMask);\n const fall = clamp(f(this.u.uFalloff.value), 0, 1);\n return f(h + f(f(added * f(this.u.uAmplitude.value)) * fall));\n }\n\n _tileOccAt(cx, cz) {\n const tex = this.u.uTileOccupancy?.value;\n const dim = this.u.uTileGridDim?.value;\n const w = Math.max(1, Math.round(dim?.x ?? 1));\n const h = Math.max(1, Math.round(dim?.y ?? 1));\n if (cx < 0 || cz < 0 || cx >= w || cz >= h) return 0;\n return (tex?.image?.data?.[cz * w + cx] ?? 0) >= 128 ? 1 : 0;\n }\n\n _tileFalloff(x, z) {\n if (f(this.u.uFalloff.value) <= 0) return 1; // no edge attenuation\n const cs = f(this.u.uTileCellSize?.value ?? f(this.u.uBoardHalf.value * 2));\n const ox = f(this.u.uTileGridOrigin?.value?.x ?? -f(cs * 0.5));\n const oz = f(this.u.uTileGridOrigin?.value?.y ?? -f(cs * 0.5));\n const rx = f(f(x - ox) / cs), rz = f(f(z - oz) / cs);\n const cx = Math.floor(rx), cz = Math.floor(rz);\n const lx = f(f(rx - cx) * 2 - 1), lz = f(f(rz - cz) * 2 - 1);\n const band = f(this.u.uFalloff.value);\n const fXp = mix32(smoothstep32(0, band, f(1 - lx)), 1, this._tileOccAt(cx + 1, cz));\n const fXn = mix32(smoothstep32(0, band, f(1 + lx)), 1, this._tileOccAt(cx - 1, cz));\n const fZp = mix32(smoothstep32(0, band, f(1 - lz)), 1, this._tileOccAt(cx, cz + 1));\n const fZn = mix32(smoothstep32(0, band, f(1 + lz)), 1, this._tileOccAt(cx, cz - 1));\n return f(f(fXp * fXn) * f(fZp * fZn));\n }\n\n _assemblyFalloff(x, z) {\n if ((this.u.uTileShape?.value ?? 0) >= 0.5) {\n // inward disk island profile: fades to 0 exactly at the perimeter (no\n // half-height boundary), and uFalloff == 0 disables it entirely.\n const fall = f(this.u.uFalloff.value);\n if (fall <= 0) return 1;\n const radius = f(this.u.uTileDiskRadius?.value ?? this.u.uBoardHalf.value);\n const cs = f(this.u.uTileCellSize?.value ?? f(this.u.uBoardHalf.value * 2));\n const band = f(fall * cs);\n const t = clamp(f(f(radius - f(Math.hypot(x, z))) / band), 0, 1);\n return this._rimFalloff(t);\n }\n return this._tileFalloff(x, z);\n }\n\n\n // detail = false: the 4-octave warp/mask FBM, never thinned (fbm4 in GLSL)\n _fbm(px, py, octaves, detail = true) {\n const pers = f(this.u.uPersistence.value);\n const lac = f(this.u.uLacunarity.value);\n const cut = detail ? f(this.u.uTerrainDetailCut?.value ?? 0) : 0;\n let amp = 0.5, sum = 0, norm = 0;\n for (let i = 0; i < octaves; i++) {\n const w = f(amp * octaveKeep32(i, octaves, cut));\n sum = f(sum + f(w * vnoise(px, py)));\n norm = f(norm + w);\n amp = f(amp * pers);\n const nx = f(rot2x(px, py) * lac), ny = f(rot2y(px, py) * lac);\n px = nx; py = ny;\n }\n return f(sum / Math.max(norm, 1e-4));\n }\n\n _fbm4(px, py) { return this._fbm(px, py, 4, false); }\n\n // 3-octave climate FBM with hardcoded gain/lacunarity (matches fbm3 in GLSL)\n _fbm3(px, py) {\n let v = f(vnoise(px, py) * 0.55);\n const nx = f(rot2x(px, py) * 2.13), ny = f(rot2y(px, py) * 2.13);\n v = f(v + f(vnoise(nx, ny) * 0.30));\n const mx = f(rot2x(nx, ny) * 2.13), my = f(rot2y(nx, ny) * 2.13);\n v = f(v + f(vnoise(mx, my) * 0.15));\n return v;\n }\n\n _ridgedFBM(px, py, octaves) {\n const pers = f(this.u.uPersistence.value);\n const lac = f(this.u.uLacunarity.value);\n const cut = f(this.u.uTerrainDetailCut?.value ?? 0);\n let amp = 0.5, sum = 0, norm = 0, carry = 1;\n for (let i = 0; i < octaves; i++) {\n const w = f(amp * octaveKeep32(i, octaves, cut));\n let v = f(1 - creaseAbs32(f(f(vnoise(px, py) * 2) - 1), cut));\n v = f(v * v);\n sum = f(sum + f(f(w * v) * carry));\n carry = clamp(f(v * 1.4), 0, 1);\n norm = f(norm + w);\n amp = f(amp * pers);\n const nx = f(rot2x(px, py) * lac), ny = f(rot2y(px, py) * lac);\n px = nx; py = ny;\n }\n return f(sum / Math.max(norm, 1e-4));\n }\n\n _climateAt(px, py) {\n const u = this.u;\n const bs = f(u.uBiomeScale.value);\n const bx = f(px * bs), by = f(py * bs);\n const cont = this._fbm3(f(f(bx * 0.085) + 211.3), f(f(by * 0.085) + 57.9));\n const temp = clamp(f(f(f(this._fbm3(f(f(bx * 0.150) + 71.7), f(f(by * 0.150) + 313.1)) * 1.5) - 0.25) + f(u.uTempBias.value)), 0, 1);\n const ms = f(0.130 * f(u.uMoistScale.value));\n const moist = clamp(f(f(f(this._fbm3(f(f(bx * ms) + 91.7), f(f(by * ms) + 53.9)) * 1.5) - 0.25) + f(u.uMoistBias.value)), 0, 1);\n const erosion = this._fbm3(f(f(bx * 0.190) + 157.1), f(f(by * 0.190) + 423.7));\n const region = this._fbm3(f(f(px * 0.700) + 631.4), f(f(py * 0.700) + 199.2));\n return { temp, moist, cont, erosion, region };\n }\n\n _biomeWeights(c) {\n const j = f(f(c.region - 0.5) * 0.16);\n const hot = smoothstep32(0.52, 0.74, f(c.temp + j));\n const dry = smoothstep32(0.55, 0.30, f(c.moist - j));\n const wet = smoothstep32(0.55, 0.78, f(c.moist + j));\n const lowC = smoothstep32(0.55, 0.32, c.cont);\n const eroded = smoothstep32(0.40, 0.70, f(c.erosion + f(j * 0.5)));\n return {\n desert: f(f(hot * dry) * f(1 - f(eroded * 0.55))),\n canyon: f(f(dry * eroded) * smoothstep32(0.30, 0.55, c.cont)),\n wetland: f(f(wet * lowC) * f(1 - f(hot * 0.4))),\n mountains: f(smoothstep32(0.38, 0.62, c.cont) * f(1 - f(eroded * 0.7))),\n };\n }\n\n _dominantBiome(weights, overrides = null) {\n const painted = overrides ? {\n desert: clamp((weights.desert ?? 0) + (overrides.desert ?? 0), 0, 1),\n canyon: clamp((weights.canyon ?? 0) + (overrides.canyon ?? 0), 0, 1),\n wetland: clamp((weights.wetland ?? 0) + (overrides.wetland ?? 0), 0, 1),\n mountains: clamp((weights.mountains ?? 0) + (overrides.mountains ?? 0), 0, 1),\n } : weights;\n let label = 'Forest';\n let score = 0.18;\n for (const [key, value] of Object.entries(painted)) {\n if (value > score) {\n score = value;\n label = key[0].toUpperCase() + key.slice(1);\n }\n }\n return { label, weights: painted };\n }\n\n _terrace(h, steps) {\n const t = f(h * steps);\n const s = smoothstep32(0.20, 0.80, fract32(t));\n return f(f(Math.floor(t) + s) / steps);\n }\n\n // ctx for the generic f64 stack evaluator. legacy2d delegates back to the\n // exact f32 legacy recipe so a legacy layer inside a custom stack matches.\n _ctx() {\n if (!this._ctxObj) {\n this._ctxObj = { uniforms: this.u, legacy2d: (x, z) => this._legacyShape2D(x, z) };\n }\n return this._ctxObj;\n }\n\n /** World-space terrain height at world position (x, z). */\n heightAt(x, z) {\n const u = this.u;\n const env = this.getEnv();\n\n let h = this._smoothedStackHeightAt(x, z);\n\n // island falloff (studio board only) + clamp + world height scale\n if (!env.infinite) {\n let rim = 1;\n if ((u.uUseTiles?.value ?? 0) > 0.5) {\n rim = this._assemblyFalloff(x, z);\n } else if (f(u.uFalloff.value) > 0) {\n const half = f(u.uBoardHalf.value);\n const ex = f(Math.abs(f(x)) / half), ey = f(Math.abs(f(z)) / half);\n const edge = mix32(Math.max(ex, ey), f(Math.hypot(ex, ey) * 0.7071), 0.5);\n const t = clamp(f(f(1 - edge) / f(u.uFalloff.value)), 0, 1);\n rim = this._rimFalloff(t);\n }\n h = this._applyEdgeProfile(h, x, z, rim, env.octaves);\n }\n // World-unit height, then the erosion delta on top (matches GLSL heightAt:\n // the offset is added after the clamp/scale, in world units).\n let h01 = finalizeStackHeight(h, u);\n if (!env.infinite) h01 = miniComposeCPU(u, x, z, h01);\n return f(f(f(h01 * f(u.uHeightScale.value)) + this._erosionOffset(x, z)) + this._destructionOffset(x, z));\n }\n\n _erosionOffset(x, z) {\n const e = this.erosion;\n return (e && e.enabled) ? f(e.offsetAt(x, z)) : 0;\n }\n\n _destructionOffset(x, z) {\n const field = this.destruction;\n return (field && field.enabled) ? f(field.offsetAt(x, z)) : 0;\n }\n\n shapeAt(x, z) {\n return this._smoothedStackHeightAt(x, z);\n }\n\n _rawStackHeightAt(x, z) {\n const u = this.u;\n if (this.heightProgram?.evaluate2D) return this.heightProgram.evaluate2D(x, z, this._ctx());\n setNoiseDetailCut(u.uTerrainDetailCut?.value ?? 0);\n return (this.stack && !isLegacyStack(this.stack))\n ? evalStack2D(this.stack, x, z, this._ctx())\n : f(this._legacyShape2D(x, z) * f(u.uAmplitude.value));\n }\n\n _smoothedStackHeightAt(x, z) {\n const h = this._rawStackHeightAt(x, z);\n const amt = clamp(f(this.u.uTerrainSmoothing?.value ?? 0), 0, 1);\n if (amt <= 0.0001) return h;\n const t = clamp(f(h / 1.35), 0, 1);\n const peakStart = 0.42;\n const peak = Math.max(f(t - peakStart), 0);\n const peakMask = smoothstep32(peakStart, 0.72, t);\n const compressed = f(peakStart + f(peak / f(1 + f(f(f(amt * 3.2) * peak) / f(1 - peakStart)))));\n return mix32(h, f(compressed * 1.35), f(peakMask * amt));\n }\n\n biomeAt(x, z, overrides = null) {\n const u = this.u;\n const freq = f(u.uFrequency.value);\n const px = f(f(f(x) * freq) + f(u.uSeedOffset.value.x));\n const py = f(f(f(z) * freq) + f(u.uSeedOffset.value.y));\n const climate = this._climateAt(px, py);\n const weights = this._biomeWeights(climate);\n return this._dominantBiome(weights, overrides);\n }\n\n /** Public climate at world (x,z): { temp, moist, cont, erosion, region }. */\n climateAt(x, z) {\n const u = this.u;\n const freq = f(u.uFrequency.value);\n const px = f(f(f(x) * freq) + f(u.uSeedOffset.value.x));\n const py = f(f(f(z) * freq) + f(u.uSeedOffset.value.y));\n return this._climateAt(px, py);\n }\n\n /** Legacy biome-coupled recipe (layers 1-6), h in ~0..1.35 (pre falloff/scale). */\n _legacyShape2D(x, z) {\n const u = this.u;\n const env = this.getEnv();\n const octaves = env.octaves;\n\n const freq = f(u.uFrequency.value);\n const px = f(f(f(x) * freq) + f(u.uSeedOffset.value.x));\n const py = f(f(f(z) * freq) + f(u.uSeedOffset.value.y));\n\n const c = this._climateAt(px, py);\n const bw = this._biomeWeights(c);\n\n // layer 1: domain warp\n const wx = this._fbm4(f(px + 13.7), f(py + 41.3));\n const wy = this._fbm4(f(px + 87.2), f(py + 9.1));\n const warp = f(f(u.uWarp.value) * f(1 - f(bw.canyon * 0.5)));\n const qx = f(px + f(f(wx - 0.5) * warp));\n const qy = f(py + f(f(wy - 0.5) * warp));\n\n // layer 2: rolling base\n const base = this._fbm(qx, qy, octaves);\n const baseAmp = f(f(0.30 * f(1 - f(bw.desert * 0.45))) * f(1 - f(bw.wetland * 0.75)));\n let h = f(f(base * baseAmp) + 0.06);\n\n // layer 3: desert dunes\n const dnx = f(f(f(qx * 2.2) + f(qy * 0.4)) + 311.7);\n const dny = f(f(qy * 0.8) + 89.1);\n const dune = f(1 - Math.abs(f(f(vnoise(dnx, dny) * 2) - 1)));\n h = f(h + f(f(f(dune * dune) * 0.05) * bw.desert));\n\n // layer 4: ridged mountain chains\n const ridge = this._ridgedFBM(f(f(qx * 1.7) + 31.4), f(f(qy * 1.7) + 27.2), octaves);\n const smoothAmt = clamp(f(u.uTerrainSmoothing?.value ?? 0), 0, 1);\n const ridgeNeedle = f(Math.pow(ridge, 1.35));\n const ridgeRounded = f(f(Math.pow(ridge, 0.62)) * 0.58);\n const ridgeShape = mix32(ridgeNeedle, ridgeRounded, smoothAmt);\n const chain = smoothstep32(0.34, 0.66, this._fbm4(f(f(qx * 0.35) + 5.1), f(f(qy * 0.35) + 17.7)));\n const mountains = f(f(f(chain * mix32(0.35, 1.0, bw.mountains))\n * f(1 - f(bw.desert * 0.85)))\n * f(1 - bw.wetland));\n h = f(h + f(f(f(ridgeShape * mountains) * f(u.uRidge.value)) * mix32(1.15, 0.82, smoothAmt)));\n\n // layer 5: wetlands use the frozen formation baseline. Fall back to the\n // live sea uniform only for older standalone sampler callers.\n const formationSeaLevel = u.uTerrainFormationSeaLevel?.value\n ?? u.uSeaLevel.value;\n const sea01 = f(f(formationSeaLevel) / Math.max(f(u.uHeightScale.value), 1));\n h = mix32(h, f(f(sea01 + 0.012) + f(base * 0.03)), f(bw.wetland * 0.85));\n\n // layer 6: canyon strata terracing\n h = mix32(h, this._terrace(h, 14.0), f(bw.canyon * 0.75));\n\n return h;\n }\n\n /**\n * Approximate surface normal at (x, z) via central differences.\n * @returns {{x:number, y:number, z:number}} normalized\n */\n normalAt(x, z, eps = 1.0) {\n const hL = this.heightAt(x - eps, z);\n const hR = this.heightAt(x + eps, z);\n const hD = this.heightAt(x, z - eps);\n const hU = this.heightAt(x, z + eps);\n let nx = hL - hR, ny = 2 * eps, nz = hD - hU;\n const len = Math.hypot(nx, ny, nz) || 1;\n return { x: nx / len, y: ny / len, z: nz / len };\n }\n\n sampleSurfaceInfo(x, z, {\n waterLevel = 0,\n paintHeightOffset = 0,\n paintBiomeWeights = null,\n eps = 2.0,\n } = {}) {\n const baseHeight = this.heightAt(x, z);\n const height = baseHeight + paintHeightOffset;\n const normal = this.normalAt(x, z, eps);\n const slope = clamp(1 - normal.y, 0, 1);\n const biome = this.biomeAt(x, z, paintBiomeWeights);\n return {\n baseHeight,\n height,\n normal,\n slope,\n water: height <= waterLevel + 0.01,\n biome: biome.label,\n biomeWeights: biome.weights,\n noise: this.shapeAt(x, z),\n };\n }\n}\n","import * as THREE from 'three';\n\n// ============================================================================\n// One chunk geometry = a unit grid in local space ([0,1] on X/Z, Y handled\n// entirely in the vertex shader) plus a duplicated border ring (\"skirt\").\n// The shader drops skirt vertices down by uSkirtDepth, which hides any\n// T-junction cracks between neighbouring chunks at different LOD levels.\n// Geometries are shared: every chunk currently at LOD n uses the same one.\n// ============================================================================\n\n// `morph` marks the shared per-LOD grids that take part in geomorphing\n// (aMorph = 1): their odd vertices slide onto the next-coarser grid as they\n// approach the LOD switch distance. Merged/boundary/export meshes leave it 0\n// (or omit the attribute, which WebGL reads as 0).\nexport function buildChunkGeometry(res, lodIndex, { morph = false } = {}) {\n const vps = res + 1; // vertices per side\n const gridCount = vps * vps;\n\n // border ring vertex indices, walked clockwise around the perimeter\n const ring = [];\n for (let x = 0; x < res; x++) ring.push(x); // top row →\n for (let z = 0; z < res; z++) ring.push(z * vps + res); // right col ↓\n for (let x = res; x > 0; x--) ring.push(res * vps + x); // bottom row ←\n for (let z = res; z > 0; z--) ring.push(z * vps); // left col ↑\n const ringCount = ring.length; // 4 * res\n\n const total = gridCount + ringCount;\n const positions = new Float32Array(total * 3);\n const uvs = new Float32Array(total * 2);\n const skirt = new Float32Array(total); // 0 = surface, 1 = skirt\n const lod = new Float32Array(total).fill(lodIndex);\n\n let i = 0;\n for (let z = 0; z < vps; z++) {\n for (let x = 0; x < vps; x++) {\n positions[i * 3 + 0] = x / res;\n positions[i * 3 + 1] = 0;\n positions[i * 3 + 2] = z / res;\n uvs[i * 2 + 0] = x / res;\n uvs[i * 2 + 1] = z / res;\n i++;\n }\n }\n // skirt vertices: same XZ as the border vertex they duplicate\n for (let k = 0; k < ringCount; k++) {\n const src = ring[k];\n const dst = gridCount + k;\n positions[dst * 3 + 0] = positions[src * 3 + 0];\n positions[dst * 3 + 1] = 0;\n positions[dst * 3 + 2] = positions[src * 3 + 2];\n uvs[dst * 2 + 0] = uvs[src * 2 + 0];\n uvs[dst * 2 + 1] = uvs[src * 2 + 1];\n skirt[dst] = 1;\n }\n\n const indices = [];\n for (let z = 0; z < res; z++) {\n for (let x = 0; x < res; x++) {\n const a = z * vps + x;\n const b = a + 1;\n const c = a + vps;\n const d = c + 1;\n indices.push(a, c, b, b, c, d);\n }\n }\n // skirt wall quads between each border vertex and its dropped duplicate\n for (let k = 0; k < ringCount; k++) {\n const a = ring[k];\n const b = ring[(k + 1) % ringCount];\n const a2 = gridCount + k;\n const b2 = gridCount + ((k + 1) % ringCount);\n indices.push(a, a2, b, b, a2, b2);\n }\n\n const geo = new THREE.BufferGeometry();\n geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));\n geo.setAttribute('aSkirt', new THREE.BufferAttribute(skirt, 1));\n geo.setAttribute('aLod', new THREE.BufferAttribute(lod, 1));\n // aWall stays 0 for terrain chunks; only the dedicated circular radial wall\n // mesh sets it to 1 so the shared terrain shader can tell them apart.\n geo.setAttribute('aWall', new THREE.BufferAttribute(new Float32Array(total), 1));\n if (morph) geo.setAttribute('aMorph', new THREE.BufferAttribute(new Float32Array(total).fill(1), 1));\n geo.setIndex(new THREE.BufferAttribute(new Uint32Array(indices), 1));\n return geo;\n}\n\n// Bounding sphere covering the displaced chunk so three.js frustum culling\n// stays correct. Local space: XZ in [0,1], Y in [-skirt, maxHeight] before\n// the uniform chunk-size scale is applied by the mesh's world matrix.\nexport function setChunkBounds(geometry, chunkSize, maxHeight, skirtDepth) {\n const yMaxL = maxHeight / chunkSize;\n const yMinL = -skirtDepth / chunkSize;\n const cy = (yMaxL + yMinL) / 2;\n const radius = Math.hypot(0.5, 0.5, (yMaxL - yMinL) / 2) * 1.05;\n geometry.boundingSphere = new THREE.Sphere(new THREE.Vector3(0.5, cy, 0.5), radius);\n}\n","import * as THREE from 'three';\n\n// ============================================================================\n// Shared visibility context for flat terrain chunks and merged nodes. Hosts\n// build it once per frame, then reuse the same projection matrix and frustum\n// for every terrain collection.\n// ============================================================================\n\n/**\n * Update (or create) a reusable culling context from the camera's latest\n * transform. Call camera.updateMatrixWorld(true) before this function.\n */\nexport function createCullingContext(\n camera,\n chunkSize,\n behindCameraCulling,\n aggressiveness = 1,\n target = {},\n minHeight = 0\n) {\n const context = target;\n context.frustum ||= new THREE.Frustum();\n context.projScreenMatrix ||= new THREE.Matrix4();\n context.sphere ||= new THREE.Sphere();\n context.camFwd ||= new THREE.Vector3();\n\n context.projScreenMatrix.multiplyMatrices(\n camera.projectionMatrix,\n camera.matrixWorldInverse\n );\n context.frustum.setFromProjectionMatrix(context.projScreenMatrix);\n context.camFwd.set(0, 0, -1).applyQuaternion(camera.quaternion);\n context.cameraX = camera.position.x;\n context.cameraY = camera.position.y;\n context.cameraZ = camera.position.z;\n context.behindCameraCulling = !!behindCameraCulling;\n context.minHeight = minHeight;\n\n // The player neighborhood is measured only in the ground plane. Including\n // altitude here used to remove the chunk directly below a walking/flying\n // camera when its center happened to be behind the view direction.\n const protectionMargin = chunkSize * Math.max(1, 2 - aggressiveness * 0.5);\n context.protectionMargin2 = protectionMargin * protectionMargin;\n\n // Extra margin behind the camera plane. The item loop projects the complete\n // 3D bounds on that plane, so camera pitch and tall terrain remain safe.\n context.backMargin = chunkSize * Math.max(0.1, 0.7 - aggressiveness * 0.25);\n return context;\n}\n\nfunction setItemVisible(item, visible) {\n const changed = item.visible !== visible;\n item.visible = visible;\n if (item.mesh) item.mesh.visible = visible;\n return changed;\n}\n\n/**\n * Cull terrain records or quadtree nodes. spanWorld is honored when present,\n * so a folded 2×2 node and a folded 16×16 node no longer share a world-sized\n * conservative sphere.\n *\n * The optional context keeps the legacy call sites compatible while allowing\n * callers with two collections to build the frustum only once.\n */\nexport function cullChunks(\n chunks,\n camera,\n chunkSize,\n maxHeight,\n behindCameraCulling,\n aggressiveness = 1,\n sharedContext = null,\n minHeight = 0\n) {\n if (!sharedContext) camera.updateMatrixWorld(true);\n const context = sharedContext || createCullingContext(\n camera,\n chunkSize,\n behindCameraCulling,\n aggressiveness,\n {},\n minHeight\n );\n\n let visibleCount = 0;\n let culledCount = 0;\n let changedCount = 0;\n const values = chunks.values ? chunks.values() : chunks;\n\n for (const item of values) {\n const centerX = item.centerX ?? item.center?.x ?? 0;\n const centerZ = item.centerZ ?? item.center?.z ?? 0;\n const spanX = item.spanX ?? item.spanWorld ?? chunkSize;\n const spanZ = item.spanZ ?? item.spanWorld ?? chunkSize;\n const halfX = spanX * 0.5;\n const halfZ = spanZ * 0.5;\n const dx = centerX - context.cameraX;\n const dz = centerZ - context.cameraZ;\n\n // Keep the chunk containing the player and a small ring around it alive,\n // independently of frustum/back tests. Distance is measured to the nearest\n // point of the chunk footprint rather than to its center.\n const outsideX = Math.max(0, Math.abs(dx) - halfX);\n const outsideZ = Math.max(0, Math.abs(dz) - halfZ);\n const protectedByProximity = (\n outsideX * outsideX + outsideZ * outsideZ\n ) <= context.protectionMargin2;\n if (protectedByProximity) {\n if (setItemVisible(item, true)) changedCount++;\n visibleCount++;\n continue;\n }\n\n const verticalMin = item.minHeight ?? context.minHeight ?? minHeight;\n const verticalMax = item.maxHeight ?? maxHeight;\n const verticalCenter = (verticalMin + verticalMax) * 0.5;\n const verticalHalf = Math.max(0, verticalMax - verticalMin) * 0.5;\n const radius = item.boundingRadius\n ?? Math.hypot(halfX, verticalHalf, halfZ) * 1.05;\n\n context.sphere.center.set(centerX, verticalCenter, centerZ);\n context.sphere.radius = radius;\n\n if (!context.frustum.intersectsSphere(context.sphere)) {\n if (setItemVisible(item, false)) changedCount++;\n culledCount++;\n continue;\n }\n\n if (context.behindCameraCulling) {\n const dy = verticalCenter - context.cameraY;\n const forwardDistance = (\n dx * context.camFwd.x\n + dy * context.camFwd.y\n + dz * context.camFwd.z\n );\n // Project the complete 3D AABB onto the camera-forward axis. Cull only\n // when every point in the terrain bound is safely behind the camera.\n const projectedHalfExtent = (\n Math.abs(context.camFwd.x) * halfX\n + Math.abs(context.camFwd.y) * verticalHalf\n + Math.abs(context.camFwd.z) * halfZ\n );\n if (forwardDistance + projectedHalfExtent < -context.backMargin) {\n if (setItemVisible(item, false)) changedCount++;\n culledCount++;\n continue;\n }\n }\n\n if (setItemVisible(item, true)) changedCount++;\n visibleCount++;\n }\n\n return { visibleCount, culledCount, changedCount };\n}\n","// ============================================================================\n// Geomorph (CDLOD-style) band planning shared by the Tile board, Infinite\n// World and Planet chunk systems.\n//\n// Chunks pick LOD L while their centre distance d_c lies in [T_{L-1}, T_L).\n// Every vertex of such a chunk is within `halfExtent` of the centre, so its own\n// distance lies in [d_c - halfExtent, d_c + halfExtent]. The vertex shader\n// morphs an LOD L vertex onto the LOD L+1 grid over [start_L, end_L]:\n//\n// end_L = T_L - halfExtent → at the L→L+1 swap every vertex is fully\n// on the coarser grid (identical shape)\n// start_L ≥ T_{L-1} + halfExtent → right after the L-1→L swap no vertex has\n// started morphing (identical shape)\n//\n// so geometry swaps in either direction are invisible. Levels whose spacing is\n// too tight for a band get no morph (start = end = DISABLED).\n// ============================================================================\n\nexport const MORPH_DISABLED = 1e9;\n\n/**\n * @param {number[]} thresholds chunk switch distances [T0, T1, T2]\n * @param {number} halfExtent max distance from a chunk centre to its vertices\n * @param {number} [bandFraction] morph band length as a share of the LOD range\n * @returns {{ start: number[], end: number[] }}\n */\nexport function planMorphBands(thresholds, halfExtent, bandFraction = 0.3) {\n const start = [];\n const end = [];\n const margin = Math.max(0, halfExtent) * 1.02;\n for (let level = 0; level < 3; level++) {\n const lower = level === 0 ? 0 : thresholds[level - 1];\n const upper = thresholds[level];\n const bandEnd = upper - margin;\n const earliest = level === 0 ? 0 : lower + margin;\n const bandStart = Math.max(earliest, bandEnd - bandFraction * (upper - lower));\n if (Number.isFinite(bandEnd) && bandEnd > bandStart + 1e-3) {\n start.push(bandStart);\n end.push(bandEnd);\n } else {\n start.push(MORPH_DISABLED);\n end.push(MORPH_DISABLED);\n }\n }\n return { start, end };\n}\n\n/** Write planned bands + the live per-LOD segment ladder into shared uniforms. */\nexport function publishMorphUniforms(uniforms, bands, segments, enabled = true) {\n if (!uniforms?.uLodMorphStart || !uniforms?.uLodMorphEnd) return;\n if (!enabled || !bands) {\n uniforms.uLodMorphStart.value.set(MORPH_DISABLED, MORPH_DISABLED, MORPH_DISABLED);\n uniforms.uLodMorphEnd.value.set(MORPH_DISABLED, MORPH_DISABLED, MORPH_DISABLED);\n return;\n }\n uniforms.uLodMorphStart.value.set(bands.start[0], bands.start[1], bands.start[2]);\n uniforms.uLodMorphEnd.value.set(bands.end[0], bands.end[1], bands.end[2]);\n if (uniforms.uLodGridSegments && segments?.length >= 4) {\n uniforms.uLodGridSegments.value.set(segments[0], segments[1], segments[2], segments[3]);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Temporal geomorph (Planet, Infinite World). LOD *decisions* stay exactly as\n// before; each change is animated over a short duration instead of popping.\n// chunk.lod is the rendered grid level and chunk.morph (0..1) how far its odd\n// vertices have slid onto the next-coarser grid:\n// coarsen: morph 0 -> 1 on the finer grid, then swap (identical shape)\n// refine: swap to the finer grid at morph 1 (identical shape), then 1 -> 0\n// At rest morph is 0, so settled geometry is unchanged.\n\n/** True when level L -> L+1 is an exact 2:1 grid ladder (morphable). */\nexport function morphLadder(segments, level) {\n return level >= 0 && level < 3 && segments[level] === segments[level + 1] * 2;\n}\n\n/**\n * Advance one chunk toward `target`. Returns true when its rendered state\n * (lod or morph) changed this step.\n */\nexport function stepTemporalLod(chunk, target, step, segments, enabled = true) {\n const lod = chunk.lod;\n const morph = chunk.morph || 0;\n if (chunk.fresh) {\n // A chunk that just appeared has no previous shape to preserve.\n chunk.fresh = false;\n chunk.lod = target;\n chunk.morph = 0;\n } else if (!enabled) {\n chunk.lod = target;\n chunk.morph = 0;\n } else if (target > lod) {\n if (!morphLadder(segments, lod)) {\n chunk.lod = target;\n chunk.morph = 0;\n } else {\n chunk.morph = Math.min(1, morph + step);\n if (chunk.morph >= 1) {\n chunk.lod = lod + 1;\n chunk.morph = 0;\n }\n }\n } else if (morph > 0) {\n // settle back onto the current grid (also undoes an aborted coarsen)\n chunk.morph = Math.max(0, morph - step);\n } else if (target < lod) {\n if (!morphLadder(segments, lod - 1)) {\n chunk.lod = target;\n } else {\n chunk.lod = lod - 1;\n chunk.morph = 1;\n }\n }\n return chunk.lod !== lod || (chunk.morph || 0) !== morph;\n}\n","import * as THREE from 'three';\nimport { buildChunkGeometry, setChunkBounds } from './ChunkGeometry.js';\nimport { createCullingContext, cullChunks } from './InfiniteTerrainCulling.js';\nimport { MORPH_DISABLED, planMorphBands, publishMorphUniforms } from './LodMorph.js';\n\n// ============================================================================\n// ONE fixed terrain board. The board never moves, never streams, and is\n// never created/destroyed around the camera. It is split into an internal\n// N x N chunk grid purely so each chunk can pick a geometry LOD based on\n// camera distance. All chunks share 4 geometries (one per LOD) and a single\n// shader material; their world position comes from the mesh transform.\n// ============================================================================\n\nexport const LOD_RESOLUTIONS = [64, 32, 16, 8]; // quads per chunk side\n// × chunkSize. Geomorphing makes LOD swaps invisible, so the bands follow a\n// screen-space target (~3 px quads at each switch at 1080p-class FOV) instead\n// of hiding pops at a distance; the earlier [8, 15, 24] rendered ~1.7 px\n// triangles near the LOD0 edge and paid for it in quad overshading.\nconst BASE_DISTANCE_BANDS = [5.2, 9.75, 15.6];\n\nexport class TerrainBoard {\n constructor(scene, material) {\n this.scene = scene;\n this.material = material;\n this.group = new THREE.Group();\n this.group.name = 'terrain-board';\n this.scene.add(this.group);\n\n this.geometries = []; // one per LOD, shared by all chunks\n this.chunks = []; // { mesh, center: Vector3, lod, cellKey }\n this._cells = []; // occupied tile cells currently owned by chunks/queue\n this.lodCounts = [0, 0, 0, 0];\n this.chunkCount = 0;\n this.chunkSize = 0;\n this.boardSize = 0;\n this.activeChunkCount = 0;\n this.targetChunkCount = 0;\n this.lodThresholds = [0, 0, 0];\n this.lodSegments = [...LOD_RESOLUTIONS];\n // Geomorphing (smooth LOD transitions) — see LodMorph.js\n this.morphEnabled = true;\n this.morphBands = null;\n\n this._distanceScale = 1.0;\n this._maxHeight = 0;\n this._skirtDepth = 0;\n this._circularBoundary = null;\n this._circularBoundaryGeometry = null;\n this._circularBoundarySegments = 0;\n\n // Gradual LOD geometry rebuild (one level per updateLOD call)\n this._lodRebuildQueue = [];\n this._targetSegments = null;\n this._buildQueue = [];\n this._building = false;\n\n this.cullingEnabled = true;\n this.behindCameraCulling = true;\n this.cullingAggressiveness = 1.0;\n this.visibleChunkCount = 0;\n this.culledChunkCount = 0;\n this._cullingContext = {};\n this._cullChunks = [];\n\n // --- Merge layer (quadtree chunked-LOD) ---------------------------------\n // The chunks are the leaves of a quadtree. Each internal node covers a\n // square block of chunks and can fold into ONE flat-grid mesh once the\n // camera is far enough for its size. Folding happens 2x2 at a time as you\n // descend/ascend the tree, so the visible set is always a smooth \"cut\":\n // fine chunks near the camera, progressively larger merged blocks outward,\n // never a hard jump from one mesh to many. Height is GPU-driven, so a\n // merged node is just a bigger unit grid using the same material — no\n // baking/cache/async needed. Cuts draw calls / matrix updates / frustum\n // checks (the CPU cost), not GPU triangles.\n this.mergeEnabled = true;\n this.mergeQuadsPerChunk = 8; // merged grid density per chunk span (8 == LOD3)\n this.mergeDistance = 4; // a node folds when nearest > spanWorld × this\n this.macroProxyEnabled = true; // allow the root (whole board) to fold to 1 mesh\n this._mergedGeo = new Map(); // \"res:aLod\" -> shared BufferGeometry\n this._root = null;\n this._treeDirty = true;\n this._mergedNodes = []; // nodes folded this frame (for culling/stats)\n this._hiddenByMerge = 0;\n this._boardMin = new THREE.Vector3();\n this._boardMax = new THREE.Vector3();\n this.mergedGroupCount = 0;\n this.savedDrawCalls = 0;\n\n // Debug: tint folded terrain by merge level via the shader's uMergeDebug.\n this._mergeDebug = false;\n\n this._tmp = new THREE.Vector3();\n this._bootFrustum = new THREE.Frustum();\n this._bootProjection = new THREE.Matrix4();\n this._bootBounds = new THREE.Box3();\n }\n\n // (Re)build the chunk grid. Only called when chunk count / size changes or a\n // full reset is requested. Tile-only changes use syncCells() so already-built\n // cells stay alive and only added/removed cells are touched.\n build({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments, cells, progressive = false, initialBatchSize = 64 }) {\n this.dispose();\n this._setLayout({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments });\n this._createSharedGeometries();\n this._applyCellDiff({ cells, progressive, initialBatchSize });\n }\n\n // Incrementally match the occupied tile-cell list. If the chunk layout itself\n // changed, fall back to build(); otherwise preserve existing chunks.\n syncCells({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments, cells, progressive = true, initialBatchSize = 64 }) {\n const needsFullBuild = !this.geometries.length\n || this.chunkCount !== chunkCount\n || this.chunkSize !== chunkSize;\n if (needsFullBuild) {\n this.build({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments, cells, progressive, initialBatchSize });\n return { rebuilt: true, added: this._cells.length, removed: 0 };\n }\n\n this._maxHeight = maxHeight;\n this._skirtDepth = skirtDepth;\n if (lodSegments && !this._sameSegments(lodSegments)) this.setLodSegments(lodSegments);\n this._recalcThresholds();\n this.updateBounds(maxHeight, skirtDepth);\n return this._applyCellDiff({ cells, progressive, initialBatchSize });\n }\n\n _setLayout({ chunkCount, chunkSize, maxHeight, skirtDepth, lodSegments }) {\n this.chunkCount = chunkCount;\n this.chunkSize = chunkSize;\n this.boardSize = chunkCount * chunkSize; // one cell\n this._maxHeight = maxHeight;\n this._skirtDepth = skirtDepth;\n if (lodSegments) this.lodSegments = [...lodSegments];\n this._recalcThresholds();\n }\n\n _createSharedGeometries() {\n this.geometries = this.lodSegments.map((res, lodIndex) => {\n const geo = buildChunkGeometry(res, lodIndex, { morph: true });\n setChunkBounds(geo, this.chunkSize, this._maxHeight, this._skirtDepth);\n return geo;\n });\n }\n\n _sameSegments(segments) {\n return segments.length === this.lodSegments.length\n && segments.every((s, i) => s === this.lodSegments[i]);\n }\n\n _cellKey(cell) {\n return `${cell.cx},${cell.cz}`;\n }\n\n _normalizeCells(cells) {\n const list = (cells && cells.length) ? cells : [{ cx: 0, cz: 0 }];\n const out = [];\n const seen = new Set();\n for (const cell of list) {\n const cx = Math.trunc(Number(cell?.cx));\n const cz = Math.trunc(Number(cell?.cz));\n if (!Number.isFinite(cx) || !Number.isFinite(cz)) continue;\n const key = `${cx},${cz}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push({ cx, cz });\n }\n return out.length ? out : [{ cx: 0, cz: 0 }];\n }\n\n _jobsForCell(cell) {\n const jobs = [];\n const half = this.boardSize / 2;\n const cellKey = this._cellKey(cell);\n // cell (cx,cz) center sits at (cx*cellSize, cz*cellSize); its min corner\n // is that minus half. Chunks tile the cell from the corner.\n const originX = cell.cx * this.boardSize - half;\n const originZ = cell.cz * this.boardSize - half;\n for (let cz = 0; cz < this.chunkCount; cz++) {\n for (let cx = 0; cx < this.chunkCount; cx++) {\n const x = originX + cx * this.chunkSize;\n const z = originZ + cz * this.chunkSize;\n jobs.push({\n x,\n z,\n centerX: x + this.chunkSize / 2,\n centerZ: z + this.chunkSize / 2,\n cellCx: cell.cx,\n cellCz: cell.cz,\n cellKey,\n });\n }\n }\n return jobs;\n }\n\n _sortJobsNearestFirst(jobs) {\n jobs.sort((a, b) =>\n Math.hypot(a.centerX, a.centerZ) - Math.hypot(b.centerX, b.centerZ)\n );\n }\n\n _applyCellDiff({ cells, progressive = true, initialBatchSize = 64 }) {\n const nextCells = this._normalizeCells(cells);\n const nextKeys = new Set(nextCells.map((cell) => this._cellKey(cell)));\n const prevKeys = new Set(this._cells.map((cell) => this._cellKey(cell)));\n const removeKeys = new Set([...prevKeys].filter((key) => !nextKeys.has(key)));\n const addedCells = nextCells.filter((cell) => !prevKeys.has(this._cellKey(cell)));\n\n if (removeKeys.size) {\n this._buildQueue = this._buildQueue.filter((job) => !removeKeys.has(job.cellKey));\n const kept = [];\n for (const chunk of this.chunks) {\n if (removeKeys.has(chunk.cellKey)) {\n this.group.remove(chunk.mesh);\n } else {\n kept.push(chunk);\n }\n }\n this.chunks = kept;\n this._treeDirty = true;\n this._disposeNodeMeshes();\n }\n\n if (addedCells.length) {\n const jobs = addedCells.flatMap((cell) => this._jobsForCell(cell));\n // Build nearest chunks first so the first visible board is useful, then\n // stream the edges in behind it.\n this._sortJobsNearestFirst(jobs);\n this._buildQueue.push(...jobs);\n }\n\n this._cells = nextCells;\n this.targetChunkCount = nextCells.length * this.chunkCount * this.chunkCount;\n this.activeChunkCount = this.chunks.length;\n this._building = this._buildQueue.length > 0;\n\n if (addedCells.length && this._buildQueue.length) {\n const batchSize = progressive && this._buildQueue.length > initialBatchSize\n ? initialBatchSize\n : this._buildQueue.length;\n this.processBuildQueue({ maxItems: batchSize, maxMs: Infinity });\n }\n\n return { rebuilt: false, added: addedCells.length, removed: removeKeys.size };\n }\n\n get isBuilding() { return this._building; }\n get remainingChunks() { return this._buildQueue.length; }\n get buildProgress() {\n return this.targetChunkCount\n ? this.activeChunkCount / this.targetChunkCount\n : 1;\n }\n\n processBuildQueue({ maxItems = 16, maxMs = 6 } = {}) {\n if (!this._buildQueue.length) {\n this._building = false;\n return 0;\n }\n const start = typeof performance !== 'undefined' ? performance.now() : Date.now();\n let created = 0;\n while (this._buildQueue.length && created < maxItems) {\n if (maxMs !== Infinity) {\n const now = typeof performance !== 'undefined' ? performance.now() : Date.now();\n if (created > 0 && now - start >= maxMs) break;\n }\n this._createChunk(this._buildQueue.shift());\n created++;\n }\n this.activeChunkCount = this.chunks.length;\n this._building = this._buildQueue.length > 0;\n return created;\n }\n\n _setBootFrustum(camera) {\n camera.updateMatrixWorld(true);\n this._bootProjection.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n this._bootFrustum.setFromProjectionMatrix(this._bootProjection);\n }\n\n _bootJobVisible(job, dependencyHalo = 1.5) {\n const halo = Math.max(0, dependencyHalo) * this.chunkSize;\n this._bootBounds.min.set(\n job.x - halo,\n -Math.max(this._skirtDepth, halo),\n job.z - halo,\n );\n this._bootBounds.max.set(\n job.x + this.chunkSize + halo,\n this._maxHeight + halo,\n job.z + this.chunkSize + halo,\n );\n return this._bootFrustum.intersectsBox(this._bootBounds);\n }\n\n /**\n * Put launch-camera contributors first without forcing the whole board to be\n * constructed before first reveal. The halo includes neighbouring shadow,\n * shoreline and reflection contributors used by the final camera pipeline.\n */\n prioritizeInitialCameraSet(camera, { dependencyHalo = 1.5 } = {}) {\n if (!camera || !this._buildQueue.length) return 0;\n this._setBootFrustum(camera);\n const visible = [];\n const deferred = [];\n for (const job of this._buildQueue) {\n (this._bootJobVisible(job, dependencyHalo) ? visible : deferred).push(job);\n }\n visible.sort((a, b) => camera.position.distanceToSquared({\n x: a.centerX, y: 0, z: a.centerZ,\n }) - camera.position.distanceToSquared({\n x: b.centerX, y: 0, z: b.centerZ,\n }));\n this._buildQueue = [...visible, ...deferred];\n return visible.length;\n }\n\n initialCameraSetReady(camera, { dependencyHalo = 1.5 } = {}) {\n if (!camera || !this._buildQueue.length) return true;\n this._setBootFrustum(camera);\n return !this._buildQueue.some((job) => this._bootJobVisible(job, dependencyHalo));\n }\n\n _createChunk(job) {\n const mesh = new THREE.Mesh(this.geometries[3], this.material);\n mesh.position.set(job.x, 0, job.z);\n mesh.scale.setScalar(this.chunkSize);\n mesh.matrixAutoUpdate = false;\n mesh.updateMatrix();\n mesh.updateMatrixWorld(true);\n this.group.add(mesh);\n this.chunks.push({\n mesh,\n center: new THREE.Vector3(job.centerX, 0, job.centerZ),\n lod: 3,\n cellCx: job.cellCx,\n cellCz: job.cellCz,\n cellKey: job.cellKey,\n merged: false,\n node: null,\n });\n this._treeDirty = true;\n }\n\n _recalcThresholds() {\n this.lodThresholds = BASE_DISTANCE_BANDS.map(\n (m) => m * this.chunkSize * this._distanceScale\n );\n // Vertices sit within half a chunk diagonal (horizontally) of the centre\n // the CPU measures from; the shader uses the same horizontal+height metric.\n this.morphBands = planMorphBands(this.lodThresholds, this.chunkSize * Math.SQRT1_2);\n }\n\n // Distance at which every chunk vertex is already shaped like LOD3 — the\n // density of a folded node — so folding/unfolding there is invisible.\n get _losslessFoldDistance() {\n const end = this.morphBands?.end?.[2];\n return Number.isFinite(end) && end < MORPH_DISABLED ? end : this.lodThresholds[2];\n }\n\n // Exact nearest distance from the camera to a node's square, in the metric\n // the vertex shader morphs with (horizontal distance + camera height).\n _nodeMinDistance(node, camPos) {\n const dx = Math.max(node.minX - camPos.x, 0, camPos.x - (node.minX + node.spanX));\n const dz = Math.max(node.minZ - camPos.z, 0, camPos.z - (node.minZ + node.spanZ));\n return Math.hypot(dx, dz, camPos.y);\n }\n\n setMorphEnabled(enabled) {\n this.morphEnabled = !!enabled;\n this._publishMorph();\n }\n\n _publishMorph() {\n publishMorphUniforms(this.material?.uniforms, this.morphBands, this.lodSegments, this.morphEnabled);\n }\n\n // Scale the LOD distance bands (performance setting).\n setLodDistanceScale(m) {\n if (m === this._distanceScale) return;\n this._distanceScale = m;\n if (this.chunkSize) this._recalcThresholds();\n }\n\n // Change per-LOD segment counts. Rebuilds shared geometries gradually —\n // one LOD level per (throttled) updateLOD call, so the UI never freezes.\n setLodSegments(segments) {\n const same = segments.length === this.lodSegments.length\n && segments.every((s, i) => s === this.lodSegments[i])\n && !this._lodRebuildQueue.length;\n if (same) return;\n this._targetSegments = [...segments];\n this._lodRebuildQueue = [3, 2, 1, 0];\n }\n\n _processLodRebuild() {\n if (!this._lodRebuildQueue.length || !this._targetSegments) return;\n if (!this.geometries.length) { this._lodRebuildQueue = []; return; }\n const lod = this._lodRebuildQueue.shift();\n const res = this._targetSegments[lod];\n if (res === this.lodSegments[lod]) return;\n\n const geo = buildChunkGeometry(res, lod, { morph: true });\n setChunkBounds(geo, this.chunkSize, this._maxHeight, this._skirtDepth);\n const old = this.geometries[lod];\n this.geometries[lod] = geo;\n this.lodSegments[lod] = res;\n\n for (const chunk of this.chunks) {\n if (chunk.lod === lod) chunk.mesh.geometry = geo;\n }\n old.dispose();\n }\n\n // Refresh culling bounds when the max terrain height changes.\n updateBounds(maxHeight, skirtDepth) {\n this._maxHeight = maxHeight;\n this._skirtDepth = skirtDepth;\n for (const geo of this.geometries) {\n setChunkBounds(geo, this.chunkSize, maxHeight, skirtDepth);\n }\n if (this._circularBoundaryGeometry) {\n setChunkBounds(this._circularBoundaryGeometry, this.chunkSize, maxHeight, skirtDepth);\n }\n }\n\n // Pick a LOD per chunk from camera distance, then (if enabled) walk the\n // quadtree and fold far blocks into single meshes. Pure view-dependent\n // detail — the height field itself is never touched.\n updateLOD(cameraPos) {\n this._processLodRebuild();\n this._publishMorph();\n\n if (!this.mergeEnabled) {\n this._updateChunkLOD(cameraPos, false);\n return;\n }\n if (this._treeDirty) this._rebuildTree();\n\n this._mergedNodes.length = 0;\n this._hiddenByMerge = 0;\n if (this._root) this._visitNode(this._root, cameraPos);\n\n this.mergedGroupCount = this._mergedNodes.length;\n this.savedDrawCalls = Math.max(0, this._hiddenByMerge - this._mergedNodes.length);\n\n this._updateChunkLOD(cameraPos, true);\n }\n\n setCircularBoundary(boundary = null) {\n const maxLod = Math.max(0, this.geometries.length - 1);\n const lod = Math.max(0, Math.min(\n maxLod,\n Math.round(Number(boundary?.lod) || 0),\n ));\n const next = boundary && Number.isFinite(boundary.radius) && boundary.radius > 0\n ? {\n x: Number(boundary.x) || 0,\n z: Number(boundary.z) || 0,\n radius: Number(boundary.radius),\n lod,\n segments: Math.max(\n 2,\n Math.round(Number(boundary.chunkSegments) || this.lodSegments[lod] || 2),\n ),\n }\n : null;\n const prev = this._circularBoundary;\n const unchanged = (!prev && !next)\n || (prev && next\n && prev.x === next.x\n && prev.z === next.z\n && prev.radius === next.radius\n && prev.lod === next.lod\n && prev.segments === next.segments);\n if (unchanged && (!next || this._circularBoundaryGeometry)) return false;\n\n const previousGeometry = this._circularBoundaryGeometry;\n this._circularBoundary = next;\n this._circularBoundaryGeometry = next\n ? buildChunkGeometry(next.segments, next.lod)\n : null;\n this._circularBoundarySegments = next?.segments ?? 0;\n if (this._circularBoundaryGeometry) {\n setChunkBounds(\n this._circularBoundaryGeometry,\n this.chunkSize,\n this._maxHeight,\n this._skirtDepth,\n );\n }\n\n for (const chunk of this.chunks) {\n const onBoundary = !!next && this._straddlesCircularBoundary(\n chunk.center.x - this.chunkSize * 0.5,\n chunk.center.z - this.chunkSize * 0.5,\n this.chunkSize,\n this.chunkSize,\n );\n if (onBoundary) {\n chunk.lod = next.lod;\n chunk.mesh.geometry = this._circularBoundaryGeometry;\n } else if (chunk.mesh.geometry === previousGeometry) {\n chunk.mesh.geometry = this.geometries[Math.min(maxLod, chunk.lod)];\n }\n }\n previousGeometry?.dispose();\n this._treeDirty = true;\n return true;\n }\n\n _straddlesCircularBoundary(minX, minZ, spanX, spanZ) {\n const circle = this._circularBoundary;\n if (!circle) return false;\n const maxX = minX + spanX;\n const maxZ = minZ + spanZ;\n const nearX = circle.x < minX ? minX - circle.x\n : (circle.x > maxX ? circle.x - maxX : 0);\n const nearZ = circle.z < minZ ? minZ - circle.z\n : (circle.z > maxZ ? circle.z - maxZ : 0);\n const farX = Math.max(Math.abs(minX - circle.x), Math.abs(maxX - circle.x));\n const farZ = Math.max(Math.abs(minZ - circle.z), Math.abs(maxZ - circle.z));\n const radiusSq = circle.radius * circle.radius;\n return nearX * nearX + nearZ * nearZ <= radiusSq\n && farX * farX + farZ * farZ >= radiusSq;\n }\n\n // Recursively decide, per node, whether to fold it into one mesh or descend\n // into its 4 children. A node folds once the camera's nearest distance to it\n // exceeds its world span × mergeDistance (3D distance, so overhead views fold\n // too), with hysteresis so it doesn't flicker at the boundary.\n _visitNode(node, camPos) {\n if (node.leaf) {\n // single detailed chunk — hand it back to the per-chunk LOD pass\n if (node.chunk.merged) { node.chunk.merged = false; node.chunk.mesh.visible = true; }\n return;\n }\n // Only a FULL node (its whole square is tiled by existing chunks) may fold:\n // a partial node straddles the assembly boundary or not-yet-streamed tiles,\n // and folding it would paint terrain across the empty gap with no edge wall.\n const canFold = node.full\n && (this.macroProxyEnabled || node.level > 0)\n && !this._straddlesCircularBoundary(node.minX, node.minZ, node.spanX, node.spanZ);\n if (canFold) {\n const nearest = Math.hypot(node.center.x - camPos.x, camPos.y, node.center.z - camPos.z) - node.half;\n const foldDist = node.spanWorld * this.mergeDistance * this._distanceScale;\n // With geomorphing, a node only folds once every vertex under it is\n // already on the LOD3 grid (the folded mesh's density), and unfolds at\n // that same distance, so folds no longer pop the silhouette. The 3%\n // margin on folding is the hysteresis.\n const lossless = !this.morphEnabled\n || this._nodeMinDistance(node, camPos) >= this._losslessFoldDistance * (node.merged ? 1 : 1.03);\n const want = lossless && (node.merged ? nearest > foldDist * 0.85 : nearest > foldDist);\n if (want) {\n if (!node.merged) this._foldNode(node);\n this._mergedNodes.push(node);\n this._hiddenByMerge += node.chunks.length;\n return;\n }\n }\n if (node.merged) this._unfoldNode(node);\n for (const child of node.children) this._visitNode(child, camPos);\n }\n\n // Distance-based geometry LOD for the detailed chunks. When skipMerged is\n // true, chunks hidden by an active merge/macro state are left untouched.\n _updateChunkLOD(cameraPos, skipMerged) {\n const [t0, t1, t2] = this.lodThresholds;\n const counts = [0, 0, 0, 0];\n for (const chunk of this.chunks) {\n if (skipMerged && chunk.merged) continue;\n const d = this._tmp.copy(chunk.center).sub(cameraPos).length();\n // A circle-straddling chunk uses one stable, budget-aware LOD. This keeps\n // the rim topology independent of camera motion without pinning a large\n // expanded disk to the most expensive geometry.\n const onCircularBoundary = this._straddlesCircularBoundary(\n chunk.center.x - this.chunkSize * 0.5,\n chunk.center.z - this.chunkSize * 0.5,\n this.chunkSize,\n this.chunkSize,\n );\n const lod = onCircularBoundary\n ? Math.min(this.geometries.length - 1, this._circularBoundary.lod)\n : (d < t0 ? 0 : d < t1 ? 1 : d < t2 ? 2 : 3);\n const geometry = onCircularBoundary && this._circularBoundaryGeometry\n ? this._circularBoundaryGeometry\n : this.geometries[lod];\n if (lod !== chunk.lod || chunk.mesh.geometry !== geometry) {\n chunk.lod = lod;\n chunk.mesh.geometry = geometry;\n }\n counts[lod]++;\n }\n this.lodCounts = counts;\n }\n\n // Tune the merge layer (performance settings).\n setMergeOptions({ enabled, quadsPerChunk, mergeDistance, macroEnabled } = {}) {\n if (enabled !== undefined && enabled !== this.mergeEnabled) {\n this.mergeEnabled = !!enabled;\n if (!this.mergeEnabled) this._restoreAll();\n }\n if (quadsPerChunk !== undefined) {\n const v = Math.max(2, Math.round(quadsPerChunk));\n if (v !== this.mergeQuadsPerChunk) {\n this.mergeQuadsPerChunk = v;\n this._disposeNodeMeshes(); // node resolution changed → rebuild lazily\n }\n }\n if (mergeDistance !== undefined) {\n const v = Number(mergeDistance);\n if (Number.isFinite(v)) this.mergeDistance = Math.max(0.5, v);\n }\n if (macroEnabled !== undefined) this.macroProxyEnabled = !!macroEnabled;\n }\n\n // --- Quadtree ------------------------------------------------------------\n // Build a quadtree over the current chunks on their integer grid. Leaves are\n // single chunks; internal nodes cover a power-of-two square block. A node is\n // FULL only when every cell of its square is occupied by an existing chunk —\n // partial nodes (assembly boundary / still-streaming tiles) never fold, so a\n // merged mesh can never paint terrain across an empty gap.\n _rebuildTree() {\n this._treeDirty = false;\n this._disposeNodeMeshes();\n if (!this.chunks.length) { this._root = null; return; }\n\n const cs = this.chunkSize;\n let minX = Infinity, minZ = Infinity;\n for (const c of this.chunks) {\n const x0 = c.center.x - cs / 2, z0 = c.center.z - cs / 2;\n if (x0 < minX) minX = x0;\n if (z0 < minZ) minZ = z0;\n }\n this._gridOriginX = minX;\n this._gridOriginZ = minZ;\n\n // Integer grid index relative to the min corner (consistent for any chunk\n // count / cell layout, since all corners differ by integer × chunkSize).\n let gw = 0, gh = 0;\n for (const c of this.chunks) {\n c.ix = Math.round((c.center.x - cs / 2 - minX) / cs);\n c.iz = Math.round((c.center.z - cs / 2 - minZ) / cs);\n if (c.ix + 1 > gw) gw = c.ix + 1;\n if (c.iz + 1 > gh) gh = c.iz + 1;\n c.node = null;\n c.merged = false;\n c.mesh.visible = true; // folds below re-hide as needed; avoids a gap\n }\n this._boardMin.set(minX, 0, minZ);\n this._boardMax.set(minX + gw * cs, 0, minZ + gh * cs);\n\n let size = 1;\n while (size < Math.max(gw, gh, 1)) size *= 2;\n this._root = this._buildNode(this.chunks, 0, 0, size, 0);\n }\n\n _buildNode(chunks, x0, z0, size, level) {\n if (!chunks.length) return null;\n if (size === 1) return this._leafNode(chunks[0], x0, z0, level);\n\n const half = size / 2;\n const midX = x0 + half, midZ = z0 + half;\n const q = [[], [], [], []];\n for (const c of chunks) {\n const qx = c.ix < midX ? 0 : 1;\n const qz = c.iz < midZ ? 0 : 1;\n q[qz * 2 + qx].push(c);\n }\n const offs = [[x0, z0], [midX, z0], [x0, midZ], [midX, midZ]];\n const children = [];\n for (let i = 0; i < 4; i++) {\n if (!q[i].length) continue;\n const child = this._buildNode(q[i], offs[i][0], offs[i][1], half, level + 1);\n if (child) children.push(child);\n }\n // A square of side `size` is full iff it holds exactly size² distinct chunks.\n const full = chunks.length === size * size;\n if (!full && children.length === 1) return children[0]; // collapse sparse chain\n return this._internalNode(children, chunks, x0, z0, size, level, full);\n }\n\n _leafNode(chunk, x0, z0, level) {\n const cs = this.chunkSize;\n const minX = this._gridOriginX + x0 * cs, minZ = this._gridOriginZ + z0 * cs;\n const node = {\n leaf: true, chunk, children: null, chunks: [chunk], full: true,\n minX, minZ, spanX: cs, spanZ: cs, spanWorld: cs, spanChunks: 1,\n center: new THREE.Vector3(minX + cs / 2, 0, minZ + cs / 2),\n half: cs * 0.7072, level, mesh: null, merged: false,\n };\n chunk.node = node;\n return node;\n }\n\n _internalNode(children, chunks, x0, z0, size, level, full) {\n const cs = this.chunkSize;\n const minX = this._gridOriginX + x0 * cs, minZ = this._gridOriginZ + z0 * cs;\n const span = size * cs;\n return {\n leaf: false, chunk: null, children, chunks, full,\n minX, minZ, spanX: span, spanZ: span, spanWorld: span, spanChunks: size,\n center: new THREE.Vector3(minX + span / 2, 0, minZ + span / 2),\n half: 0.5 * Math.SQRT2 * span, level, mesh: null, merged: false,\n };\n }\n\n // Shared flat unit-grid geometry (with skirts) for a given resolution. aLod\n // encodes the merge tier so the shader can colour folded terrain by level.\n _mergedGeometry(res, aLod) {\n const key = `${res}:${aLod}`;\n let geo = this._mergedGeo.get(key);\n if (!geo) {\n geo = buildChunkGeometry(res, aLod);\n this._mergedGeo.set(key, geo);\n }\n return geo;\n }\n\n // Fold a node into one mesh: show its merged mesh, hide every descendant\n // (chunks + deeper node meshes). Tier (log2 of span in chunks) drives both\n // mesh resolution and the debug colour.\n _foldNode(node) {\n node.merged = true;\n if (!node.mesh) {\n const tier = Math.max(1, Math.round(Math.log2(node.spanChunks)));\n const res = Math.min(160, Math.max(8, node.spanChunks * this.mergeQuadsPerChunk));\n const aLod = 3 + Math.min(5, tier); // 4..8 → colour ramp in shader\n const mesh = new THREE.Mesh(this._mergedGeometry(res, aLod), this.material);\n mesh.position.set(node.minX, 0, node.minZ);\n mesh.scale.set(node.spanX, 1, node.spanZ);\n mesh.matrixAutoUpdate = false;\n mesh.frustumCulled = false;\n mesh.updateMatrix();\n mesh.updateMatrixWorld(true);\n this.group.add(mesh);\n node.mesh = mesh;\n }\n node.mesh.visible = true;\n for (const c of node.chunks) { c.merged = true; c.mesh.visible = false; }\n this._forEachDescendantInternal(node, (d) => {\n d.merged = false;\n if (d.mesh) d.mesh.visible = false;\n });\n }\n\n // Unfold a node: hide its mesh. Children are re-evaluated in the same\n // updateLOD pass (so chunks/child meshes reappear with no one-frame blank).\n _unfoldNode(node) {\n node.merged = false;\n if (node.mesh) node.mesh.visible = false;\n }\n\n _forEachDescendantInternal(node, fn) {\n if (!node.children) return;\n for (const child of node.children) {\n if (child.leaf) continue;\n fn(child);\n this._forEachDescendantInternal(child, fn);\n }\n }\n\n _forEachInternal(fn) {\n const rec = (n) => {\n if (!n || n.leaf) return;\n fn(n);\n for (const c of n.children) rec(c);\n };\n rec(this._root);\n }\n\n _restoreAll() {\n for (const c of this.chunks) { c.merged = false; c.mesh.visible = true; }\n this._forEachInternal((n) => { n.merged = false; if (n.mesh) n.mesh.visible = false; });\n this._mergedNodes.length = 0;\n this.mergedGroupCount = 0;\n this.savedDrawCalls = 0;\n }\n\n _disposeNodeMeshes() {\n this._forEachInternal((n) => {\n if (n.mesh) { this.group.remove(n.mesh); n.mesh = null; }\n n.merged = false;\n });\n this._mergedNodes.length = 0;\n }\n\n // --- Debug overlay -------------------------------------------------------\n // Colour folded terrain by merge level (green = small 2x2 fold → magenta =\n // whole board) via the shared terrain shader's uMergeDebug branch. Merged\n // meshes carry aLod 4..8 (the tier) so the shader can ramp the colour.\n setMergeDebug(on) {\n this._mergeDebug = !!on;\n const u = this.material?.uniforms?.uMergeDebug;\n if (u) u.value = this._mergeDebug ? 1.0 : 0.0;\n }\n\n // Cull invisible terrain meshes based on the camera frustum and facing\n // direction. Detailed chunks and folded node meshes are culled separately;\n // chunks hidden by an active fold are skipped (left invisible).\n // visibleChunkCount / culledChunkCount are reported in draw calls (a folded\n // node counts as one), which is the figure the merge layer is optimising.\n cull(camera) {\n if (!this.cullingEnabled) {\n let visibleCount = 0;\n for (const chunk of this.chunks) {\n if (chunk.merged) { if (chunk.mesh.visible) chunk.mesh.visible = false; continue; }\n if (!chunk.mesh.visible) chunk.mesh.visible = true;\n visibleCount++;\n }\n for (const node of this._mergedNodes) { node.mesh.visible = true; visibleCount++; }\n this.visibleChunkCount = visibleCount;\n this.culledChunkCount = 0;\n return;\n }\n\n camera.updateMatrixWorld(true);\n const cullingContext = createCullingContext(\n camera,\n this.chunkSize,\n this.behindCameraCulling,\n this.cullingAggressiveness,\n this._cullingContext,\n -this._skirtDepth\n );\n this._cullChunks.length = 0;\n for (const chunk of this.chunks) {\n if (!chunk.merged) this._cullChunks.push(chunk);\n }\n const chunkResult = cullChunks(\n this._cullChunks,\n camera,\n this.chunkSize,\n this._maxHeight,\n this.behindCameraCulling,\n this.cullingAggressiveness,\n cullingContext\n );\n let visible = chunkResult.visibleCount;\n let culled = chunkResult.culledCount;\n\n if (this._mergedNodes.length) {\n const mergeResult = cullChunks(\n this._mergedNodes,\n camera,\n this.chunkSize,\n this._maxHeight,\n this.behindCameraCulling,\n this.cullingAggressiveness,\n cullingContext\n );\n visible += mergeResult.visibleCount;\n culled += mergeResult.culledCount;\n }\n\n this.visibleChunkCount = visible;\n this.culledChunkCount = culled;\n }\n\n dispose() {\n this._disposeNodeMeshes();\n for (const geo of this._mergedGeo.values()) geo.dispose();\n this._mergedGeo.clear();\n this._root = null;\n this._treeDirty = true;\n this.mergedGroupCount = 0;\n this.savedDrawCalls = 0;\n for (const chunk of this.chunks) this.group.remove(chunk.mesh);\n this._circularBoundaryGeometry?.dispose();\n this._circularBoundaryGeometry = null;\n this._circularBoundarySegments = 0;\n this._circularBoundary = null;\n for (const geo of this.geometries) geo.dispose();\n this.chunks = [];\n this._cells = [];\n this.geometries = [];\n this._lodRebuildQueue = [];\n this._buildQueue = [];\n this._building = false;\n this.activeChunkCount = 0;\n this.targetChunkCount = 0;\n this.visibleChunkCount = 0;\n this.culledChunkCount = 0;\n this._cullChunks.length = 0;\n this.lodCounts = [0, 0, 0, 0];\n }\n}\n","import { TerrainBoard } from '../engine/terrain/TerrainBoard.js';\n\n// Keep the studio's existing LOD cadence, profiling and build budgets outside\n// this module. The same geometry/LOD/culling path serves the public runtime.\nexport function updateFiniteTerrainView(board, camera, { lod = true, cull = true } = {}) {\n // cull() already refreshes matrices; the combined path also needs them\n // before selecting LOD. Keep split studio profiling calls at their old cost.\n if (lod && cull) camera.updateMatrixWorld(true);\n if (lod) board.updateLOD(camera.position);\n if (cull) board.cull(camera);\n}\n\nexport class FiniteTerrainRuntime {\n constructor(parent, material) {\n this.board = new TerrainBoard(parent, material);\n }\n\n get group() {\n return this.board.group;\n }\n\n update(camera, budget) {\n if (budget && this.board.isBuilding) this.board.processBuildQueue(budget);\n updateFiniteTerrainView(this.board, camera);\n }\n\n dispose() {\n this.board.dispose();\n this.board.group.removeFromParent();\n }\n}\n","import { applyTerrainDetailUniforms, applyTerrainVisualUniforms } from './TerrainAppearance.js';\nimport { DetailPageCache } from '../engine/terrain/detail/DetailPageCache.js';\nimport * as THREE from 'three';\nimport { createTerrainMaterial, createTerrainUniforms } from '../engine/terrain/TerrainMaterial.js';\nimport { TerrainHeightSampler } from '../engine/terrain/TerrainHeightSampler.js';\nimport { buildChunkGeometry } from '../engine/terrain/ChunkGeometry.js';\nimport { applyPlanetStyleToUniforms } from '../engine/style/PaletteUniforms.js';\nimport { validatePrograms, programHealthError } from '../engine/render/ProgramHealthGate.js';\nimport { TerrainSource } from './TerrainSources.js';\nimport { resolveSurfaceReference } from '../engine/terrain/surface/SurfaceDocument.js';\nimport { FiniteTerrainRuntime } from './FiniteTerrainRuntime.js';\nimport { applyTerrainShapeUniforms, applyTerrainShadingUniforms } from './TerrainParameters.js';\nimport { normalizeConfiguration, configurationParameters } from './FiniteTerrainConfiguration.js';\n\nconst error = (code, message) => Object.assign(new Error(message), { code });\nconst checkSignal = (signal) => {\n if (signal?.aborted) throw error('TERRAIN_CANCELLED', 'Terrain operation cancelled');\n};\n\n/** Browser WebGL2 runtime. Importing this module has no browser side effects. */\nexport class FiniteTerrain {\n constructor({ renderer, configuration = {}, signal, resources, _world = {} } = {}) {\n checkSignal(signal);\n if (!renderer?.isWebGLRenderer)\n throw new TypeError('A caller-owned THREE.WebGLRenderer is required');\n this._world = _world;\n this.mode = _world.mode ?? 'finite';\n this._layers = new Set();\n if (resources?.renderer && resources.renderer !== renderer)\n throw new TypeError('Resources and terrain must use the same renderer');\n this.resources = resources ?? null;\n this._surface = null;\n this._materialSurface = null;\n this._configuration = normalizeConfiguration(configuration, undefined, _world);\n this._requestedConfiguration = this._configuration;\n this._renderer = renderer;\n this._disposed = false;\n this._revision = 0;\n this._jobs = new Set();\n this._compilingMaterials = new Map();\n this._retiredMaterials = new Set();\n this._cameraPosition = new THREE.Vector3();\n this._viewCamera = null;\n this._worldCamera = null;\n this._viewport = new THREE.Vector4();\n this._prepared = false;\n this._onContextRestored = () => this._detailPageCache?.onContextRestored();\n renderer.domElement?.addEventListener?.('webglcontextrestored', this._onContextRestored);\n this._fallback = new THREE.DataTexture(new Uint8Array([128, 128, 128, 255]), 1, 1);\n this._fallback.needsUpdate = true;\n this._uniforms = createTerrainUniforms({ surfaceFallback: this._fallback });\n this._ownedTextures = new Set(\n Object.values(this._uniforms)\n .map((u) => u.value)\n .filter((v) => v?.isTexture),\n );\n this._source = new TerrainSource(this._configuration, this.mode);\n this._stack = this._source.stack;\n this._stackGLSL = this._source.program;\n this._material = this._makeMaterial(this._configuration.source.octaves);\n this._material.uniforms = this._uniforms;\n this.object = new THREE.Group();\n this.object.name = 'procedural-terrain';\n this._runtime =\n _world.createRuntime?.(this) ?? new FiniteTerrainRuntime(this.object, this._material);\n this._sampler = new TerrainHeightSampler(\n this._uniforms,\n () => ({\n octaves: this._configuration.source.octaves,\n infinite: this.mode === 'infinite',\n }),\n this._stack,\n );\n this._apply(this._configuration);\n this._source.install(this._uniforms, this._sampler);\n }\n\n get configuration() {\n return this._configuration;\n }\n\n addLayer(layer) {\n this._assertAlive();\n this._layers.add(layer);\n return () => this._layers.delete(layer);\n }\n\n sampleHeight3D(x, y, z) {\n this._assertAlive();\n if (this.mode !== 'planet') throw new TypeError('sampleHeight3D requires a planet terrain');\n if (![x, y, z].every(Number.isFinite) || Math.hypot(x, y, z) < 1e-9)\n throw new TypeError('A nonzero finite direction is required');\n const length = Math.hypot(x, y, z);\n return this._world.sample(this, x / length, y / length, z / length);\n }\n\n setImagery(texture, { blend = 1 } = {}) {\n this._assertAlive();\n if (this.mode !== 'finite') throw new TypeError('Imagery requires finite terrain');\n if (texture && !texture.isTexture) throw new TypeError('A THREE.Texture is required');\n if (!Number.isFinite(blend) || blend < 0 || blend > 1)\n throw new RangeError('blend must be 0..1');\n if (this._source.variant === 'manual-empty-base' && texture)\n throw new TypeError('Flat manual terrain does not support imagery; use a heightmap source');\n const size = this.configuration.layout.chunkCount * this.configuration.layout.chunkSize;\n const u = this._uniforms;\n u.uImportImageryTex.value = texture;\n u.uImportImageryMode.value = texture ? 3 : 0;\n u.uImportImageryBlend.value = blend;\n u.uImportHeightRegion.value.set(-size / 2, -size / 2, size, size);\n }\n\n _installSurface(surface, u = this._uniforms) {\n u.uSurfDiffuse.value = surface.diffuse;\n u.uSurfProps.value = surface.props;\n u.uSurfaceArrayMode.value = surface.backend === 'array' ? 1 : 0;\n u.uSurfaceRoleMap.value = surface.mapping ?? u.uSurfaceRoleMap.value;\n u.uSurfaceRoleTint.value = surface.tints ?? u.uSurfaceRoleTint.value;\n u.uSurfaceAssetSize.value = surface.sizes\n ? [...surface.sizes, ...new Array(Math.max(0, 64 - surface.sizes.length)).fill(2)]\n : u.uSurfaceAssetSize.value;\n u.uSurfaceGraphCode.value = surface.graph?.body ?? '';\n u.uSurfaceGraphParams.value = Array.from(\n { length: 128 },\n (_, i) => new THREE.Vector4(...(surface.graph?.values[i] ?? [0, 0, 0, 0])),\n );\n u.uSurfaceContributions.value = surface.budget?.contributions ?? 4;\n u.uSurfPresent.value = surface.present ?? u.uSurfPresent.value;\n u.uSurfRolePresent.value = surface.rolePresent ?? u.uSurfRolePresent.value;\n u.uSurfTile.value = surface.tile ?? u.uSurfTile.value;\n if (surface.paint?.layers) {\n const items = (slot) => {\n const layer = surface.paint.layers.find((l) => l.slot === slot);\n return layer ? resolveSurfaceReference(layer.materialInstanceId, surface.document) : null;\n };\n u.uSurfacePaintMap.value = Array.from({ length: 32 }, (_, slot) => {\n const refs = items(slot);\n return refs\n ? new THREE.Vector4(\n surface.slots[refs[0].assetId],\n refs[1] ? surface.slots[refs[1].assetId] : -1,\n refs[0].wetness ?? 0,\n refs[0].scale ?? 1,\n )\n : new THREE.Vector4(-1, -1, 0, 1);\n });\n u.uSurfacePaintTint.value = Array.from(\n { length: 32 },\n (_, slot) => new THREE.Vector3(...(items(slot)?.[0].tint ?? [1, 1, 1])),\n );\n }\n u.uSurfMode.value = 1;\n u.uSurfAmount.value = 1;\n u.uSurfReveal.value = 1;\n }\n\n async setSurface(surface, options = {}) {\n this._assertAlive();\n if (\n surface &&\n (!surface.diffuse?.isTexture || !surface.props?.isTexture || surface.backend !== 'array')\n )\n throw new TypeError('A valid surface array resource is required');\n this._surface = surface;\n try {\n await this.configure({}, options);\n } catch (error) {\n if (this._surface === surface) this._surface = this._materialSurface;\n throw error;\n }\n }\n\n _assertAlive() {\n if (this._disposed) throw error('TERRAIN_DISPOSED', 'Terrain has been disposed');\n }\n\n _assertIdentity() {\n this.object.updateWorldMatrix(true, false);\n const e = this.object.matrixWorld.elements;\n if (e.some((v, i) => Math.abs(v - (i % 5 === 0 ? 1 : 0)) > 1e-8)) {\n throw error(\n 'TERRAIN_TRANSFORM_UNSUPPORTED',\n 'Terrain worlds require an identity world transform in this release',\n );\n }\n }\n\n _makeMaterial(octaves, source = this._source) {\n const variant = this._surface\n ? source.variant === 'base'\n ? 'surface'\n : source.variant === 'hybrid-base'\n ? 'hybrid-surface'\n : 'manual-surface'\n : source.variant;\n const cloneValue = (value) =>\n value?.isTexture\n ? value\n : Array.isArray(value)\n ? value.map(cloneValue)\n : value?.clone\n ? value.clone()\n : value;\n const uniforms = Object.fromEntries(\n Object.entries(this._uniforms).map(([name, u]) => [name, { value: cloneValue(u.value) }]),\n );\n source.install(uniforms);\n if (this._surface) this._installSurface(this._surface, uniforms);\n else {\n uniforms.uSurfaceArrayMode.value = 0;\n uniforms.uSurfMode.value = 0;\n }\n const material =\n this._world.createMaterial?.({ ...this, _uniforms: uniforms }, octaves, source.program) ??\n createTerrainMaterial(uniforms, octaves, source.program, { variant, worldMode: 'studio' });\n // The existing shader writes display-encoded colour itself. Do not apply\n // host tone mapping to it a second time.\n material.toneMapped = false;\n return material;\n }\n\n _apply(c, source = this._source) {\n const p = (this._params = configurationParameters(c));\n const size = p.chunkCount * p.chunkSize;\n const skirtDepth = Math.max(24, p.heightScale * 0.08);\n applyTerrainShapeUniforms(this._uniforms, p, size);\n applyTerrainShadingUniforms(this._uniforms, p, {\n size,\n skirtDepth,\n wallThickness: Math.max(10, size * 0.006),\n });\n applyTerrainDetailUniforms(this._uniforms, c.material);\n applyTerrainVisualUniforms(this._uniforms, c.material);\n this._uniforms.uBakeOrigin.value.set(-size / 2, -size / 2);\n this._uniforms.uBakeSpan.value.set(size, size);\n const az = THREE.MathUtils.degToRad(p.sunAzimuth);\n const el = THREE.MathUtils.degToRad(p.sunElevation);\n this._uniforms.uSunDir.value.set(\n Math.cos(el) * Math.sin(az),\n Math.sin(el),\n Math.cos(el) * Math.cos(az),\n );\n this._uniforms.uFogDensity.value = p.fogDensity * 0.0001;\n applyPlanetStyleToUniforms(this._uniforms, { ...c.style, palette: c.palette });\n this._uniforms.uInfiniteMode.value = this.mode === 'infinite' ? 1 : 0;\n if (this._world.apply) {\n this._world.apply(this, c);\n return;\n }\n const b = this._runtime.board;\n b.syncCells({\n chunkCount: p.chunkCount,\n chunkSize: p.chunkSize,\n maxHeight: Math.max(\n p.heightScale * 1.35 + 2,\n source.maxHeight + (source.hasBase ? p.heightScale * 1.35 : 0),\n ),\n skirtDepth: skirtDepth - Math.min(0, source.minHeight),\n lodSegments: c.quality.lodSegments,\n cells: [{ cx: 0, cz: 0 }],\n progressive: false,\n });\n // Public configuration commits are complete; the studio retains its own\n // progressive geometry cadence through the same TerrainBoard implementation.\n while (b._lodRebuildQueue.length) b.updateLOD(this._cameraPosition);\n b.setMorphEnabled(c.quality.morphEnabled);\n b.setLodDistanceScale(c.quality.lodDistanceScale);\n b.setMergeOptions({ enabled: c.quality.mergeEnabled });\n b.cullingEnabled = c.quality.cullingEnabled;\n }\n\n _cancelJobs(code, message) {\n for (const job of this._jobs) job.cancel(error(code, message));\n }\n\n // Cancels the public operation immediately. Driver compilation cannot be\n // interrupted; its candidate resources are retired once it actually settles.\n _operation(task, signal) {\n checkSignal(signal);\n let cancel, reason;\n const cancelled = new Promise((_, reject) => {\n cancel = (error) => {\n reason = error;\n reject(error);\n };\n });\n const job = { cancel };\n const onAbort = () => cancel(error('TERRAIN_CANCELLED', 'Terrain operation cancelled'));\n signal?.addEventListener('abort', onAbort, { once: true });\n this._jobs.add(job);\n const work = Promise.resolve().then(() => {\n if (reason) throw reason;\n this._assertAlive();\n checkSignal(signal);\n return task();\n });\n return Promise.race([work, cancelled]).finally(() => {\n signal?.removeEventListener('abort', onAbort);\n this._jobs.delete(job);\n });\n }\n\n _retireMaterial(material) {\n if (this._compilingMaterials.has(material)) this._retiredMaterials.add(material);\n else material.dispose();\n }\n\n async _compile(material, camera) {\n this._compilingMaterials.set(material, (this._compilingMaterials.get(material) ?? 0) + 1);\n const probe = this._world.createProbe?.(this, material);\n const geometry = probe?.geometry ?? buildChunkGeometry(2, 0, { morph: true });\n const scene = new THREE.Scene();\n scene.add(probe?.mesh ?? new THREE.Mesh(geometry, material));\n try {\n await this._renderer.compileAsync(scene, camera);\n const health = await validatePrograms({ renderer: this._renderer, materials: [material] });\n if (!health.ok) throw programHealthError(health);\n } finally {\n geometry.dispose();\n const count = this._compilingMaterials.get(material) - 1;\n if (count) this._compilingMaterials.set(material, count);\n else {\n this._compilingMaterials.delete(material);\n if (this._retiredMaterials.delete(material)) material.dispose();\n }\n }\n }\n\n async prepare(camera, { signal } = {}) {\n this._assertAlive();\n this._assertIdentity();\n if (!camera?.isCamera) throw new TypeError('A THREE.Camera is required');\n this._viewCamera = camera;\n camera.updateWorldMatrix(true, false);\n camera.getWorldPosition(this._cameraPosition);\n checkSignal(signal);\n const revision = this._revision;\n await this._operation(async () => {\n await this._compile(this._material, camera);\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain preparation superseded');\n await this._world.prepare?.(this, camera, signal, () => {\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain preparation superseded');\n });\n for (const layer of this._layers) await layer.prepare?.(camera, { signal });\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain preparation superseded');\n this._prepared = true;\n }, signal);\n }\n\n async configure(patch, { signal } = {}) {\n this._assertAlive();\n checkSignal(signal);\n const next = normalizeConfiguration(patch, this._requestedConfiguration, this._world);\n this._cancelJobs('TERRAIN_SUPERSEDED', 'Terrain configuration superseded');\n const revision = ++this._revision;\n this._requestedConfiguration = next;\n const wasPrepared = this._prepared;\n const sameLayout = JSON.stringify(next.layout) === JSON.stringify(this._configuration.layout);\n const reuseSource = next.source === this._configuration.source && sameLayout;\n const nextSource = reuseSource ? this._source : new TerrainSource(next, this.mode);\n const sourceChanged = !reuseSource || next.heightScale !== this._configuration.heightScale\n || next.terrainFormationSeaLevel !== this._configuration.terrainFormationSeaLevel\n || ['biomeScale', 'moistScale', 'moistBias', 'tempBias'].some(\n key => next.material[key] !== this._configuration.material[key]);\n const changedProgram =\n nextSource.signature !== this._source.signature || this._materialSurface !== this._surface;\n const candidate = changedProgram ? this._makeMaterial(next.source.octaves, nextSource) : null;\n let published = false,\n started = false;\n try {\n await this._operation(async () => {\n started = true;\n try {\n if (candidate)\n await this._compile(candidate, this._viewCamera || new THREE.PerspectiveCamera());\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain configuration superseded');\n this._assertIdentity();\n this._apply(next, nextSource);\n const previousSource = this._source;\n this._source = nextSource;\n this._stack = nextSource.stack;\n this._stackGLSL = nextSource.program;\n nextSource.install(this._uniforms, this._sampler);\n if (this._surface) this._installSurface(this._surface);\n else {\n this._uniforms.uSurfMode.value = 0;\n this._uniforms.uSurfaceArrayMode.value = 0;\n }\n if (candidate) {\n const old = this._material;\n if (this._runtime.board) this._runtime.board.material = candidate;\n candidate.uniforms = this._uniforms;\n this._material = candidate;\n this._runtime.group.traverse((o) => {\n if (o.isMesh && o.material === old) o.material = candidate;\n });\n this._retireMaterial(old);\n }\n this._configuration = next;\n this._materialSurface = this._surface;\n // Publication is synchronous. Failed/cancelled optional warm-ups must\n // never retire resources already bound to the live meshes.\n published = true;\n if (previousSource !== nextSource) previousSource.dispose();\n const check = () => {\n this._assertAlive();\n checkSignal(signal);\n if (revision !== this._revision)\n throw error('TERRAIN_SUPERSEDED', 'Terrain configuration superseded');\n };\n this._prepared = false;\n await this._world.sourceChanged?.(this, nextSource, { signal, check, sourceChanged });\n check();\n for (const layer of this._layers) {\n await layer.onTerrainChanged?.({\n signal,\n sourceChanged,\n programChanged: changedProgram,\n });\n check();\n }\n this._prepared = wasPrepared || !!candidate;\n } finally {\n if (!published) {\n candidate?.dispose();\n if (!reuseSource) nextSource.dispose();\n }\n }\n }, signal);\n } catch (err) {\n if (!started) {\n candidate?.dispose();\n if (!reuseSource) nextSource.dispose();\n }\n if (revision === this._revision) this._requestedConfiguration = this._configuration;\n throw err;\n }\n }\n\n update(deltaSeconds, { camera } = {}) {\n this._assertAlive();\n this._assertIdentity();\n if (!Number.isFinite(deltaSeconds) || deltaSeconds < 0)\n throw new RangeError('deltaSeconds must be nonnegative');\n if (!camera?.isCamera) throw new TypeError('A THREE.Camera is required');\n this._viewCamera = camera;\n camera.updateWorldMatrix(true, false);\n camera.getWorldPosition(this._cameraPosition);\n // TerrainBoard consumes world camera coordinates. For a parented camera,\n // a detached view camera preserves its projection without changing the host.\n let view = camera;\n if (camera.parent) {\n if (!this._worldCamera || this._worldCamera.type !== camera.type)\n this._worldCamera = camera.clone(false);\n view = this._worldCamera;\n view.projectionMatrix.copy(camera.projectionMatrix);\n view.projectionMatrixInverse.copy(camera.projectionMatrixInverse);\n camera.matrixWorld.decompose(view.position, view.quaternion, view.scale);\n view.updateMatrix();\n view.updateMatrixWorld(true);\n }\n const detail = this.configuration.material;\n if (!this._externalDetailCache && detail.terrainDetailQuality > 0 && typeof Worker === 'function' && this._renderer.initTexture) {\n this._detailPageCache ??= new DetailPageCache({ renderer: this._renderer, uniforms: this._uniforms });\n const seed = this._uniforms.uSeedOffset.value;\n this._detailPageCache.update({ camera: view, mode: this.mode === 'finite' ? 'studio' : this.mode,\n generation: this._revision,\n scale: detail.terrainDetailScale * (0.55 + 0.70 * Math.min(1, detail.terrainDetailQuality / 3)),\n seedX: seed.x, seedY: seed.y, active: true, allowUpload: !this._compilingMaterials.size,\n dt: Math.min(deltaSeconds, 0.1) });\n } else if (!this._externalDetailCache && this._detailPageCache) {\n this._uniforms.uDetailGlobalBlend.value = 0;\n }\n this._uniforms.uTime.value += Math.min(deltaSeconds, 0.1);\n this._runtime.update(view);\n this._world.update?.(this, view);\n for (const layer of this._layers) layer.update?.(Math.min(deltaSeconds, 0.1), { camera: view });\n const viewport = this._renderer.getCurrentViewport(this._viewport);\n this._uniforms.uPixelWorldPerDist.value = camera.isPerspectiveCamera\n ? (2 * Math.tan(THREE.MathUtils.degToRad(camera.fov) * 0.5)) /\n (Math.max(camera.zoom, 1e-6) * Math.max(1, viewport.w))\n : 0;\n }\n\n sampleHeight(x, z) {\n this._assertAlive();\n this._assertIdentity();\n if (!Number.isFinite(x) || !Number.isFinite(z))\n throw new TypeError('Coordinates must be finite');\n if (this.mode === 'planet') throw new TypeError('Use sampleHeight3D for planet terrains');\n const half = (this._configuration.layout.chunkCount * this._configuration.layout.chunkSize) / 2;\n return this.mode !== 'infinite' && (Math.abs(x) > half || Math.abs(z) > half)\n ? null\n : this._source.sample(x, z, (a, b) => this._sampler.heightAt(a, b));\n }\n\n serialize() {\n this._assertAlive();\n return {\n format: 'procedural-terrains',\n schemaVersion: 1,\n kind: this.mode,\n extensions: [...this._layers].map((layer) => layer.serialize?.()).filter(Boolean),\n configuration: JSON.parse(JSON.stringify(this._configuration)),\n };\n }\n\n getDiagnostics() {\n const b = this._runtime.board;\n if (!b)\n return {\n disposed: this._disposed,\n prepared: this._prepared,\n revision: this._revision,\n mode: this.mode,\n ...this._runtime.diagnostics(),\n };\n return {\n disposed: this._disposed,\n prepared: this._prepared,\n revision: this._revision,\n chunks: b.activeChunkCount,\n visible: b.visibleChunkCount,\n culled: b.culledChunkCount,\n lodCounts: [...b.lodCounts],\n mergedGroups: b.mergedGroupCount,\n savedDrawCalls: b.savedDrawCalls,\n };\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n ++this._revision;\n this._cancelJobs('TERRAIN_DISPOSED', 'Terrain has been disposed');\n for (const layer of [...this._layers]) layer.dispose();\n this._layers.clear();\n this._world.dispose?.(this);\n this._runtime.dispose();\n this._source.dispose();\n this._detailPageCache?.dispose();\n this._renderer.domElement?.removeEventListener?.('webglcontextrestored', this._onContextRestored);\n this.object.removeFromParent();\n this._retireMaterial(this._material);\n for (const texture of this._ownedTextures) texture.dispose();\n this._ownedTextures.clear();\n this._viewCamera = null;\n this._worldCamera = null;\n }\n}\n\nexport async function createTerrain(options) {\n return new FiniteTerrain(options);\n}\n"],"names":["error"],"mappings":"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"}
|