minerender 2.1.0-alpha.127 → 2.1.0-alpha.129

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.
@@ -178,9 +178,10 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
178
178
 
179
179
  // src/world/SectionGeometry.ts
180
180
  function buildSectionGeometry(input) {
181
- const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion } = input;
181
+ const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
182
182
  if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
183
183
  if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
184
+ if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
184
185
  if (fluids && fluids.cells.length !== 5832) throw new RangeError("Section fluid cells must cover an 18\xD718\xD718 neighborhood");
185
186
  if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError("Section water tints must contain RGB for 4096 cells");
186
187
  if (light && (light.length !== 5832 || light.some((level) => level > 15 && level !== 255))) {
@@ -195,7 +196,7 @@ function buildSectionGeometry(input) {
195
196
  const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
196
197
  for (const template of templateData) {
197
198
  const { quads } = template;
198
- if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads) {
199
+ if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads || template.biomeTint && template.biomeTint.length !== quads) {
199
200
  throw new RangeError("Section template arrays do not match its quad count");
200
201
  }
201
202
  }
@@ -305,6 +306,7 @@ function buildSectionGeometry(input) {
305
306
  blockIndices[indexOffset / 6] = indices[entry];
306
307
  if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness2);
307
308
  const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;
309
+ const tint = biomeTints && template.biomeTint?.[quad] && !Number.isNaN(biomeTints[entry * 3]) ? entry * 3 : void 0;
308
310
  const start = vertex;
309
311
  for (let corner = 0; corner < 4; corner++, vertex++) {
310
312
  const source = quad * 4 + corner;
@@ -321,9 +323,9 @@ function buildSectionGeometry(input) {
321
323
  uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);
322
324
  uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);
323
325
  const factor = brightness * (ambientMask ? cornerBrightness2[corner] : 1);
324
- colors[vertex * 3] = template.colors[source * 3] * factor;
325
- colors[vertex * 3 + 1] = template.colors[source * 3 + 1] * factor;
326
- colors[vertex * 3 + 2] = template.colors[source * 3 + 2] * factor;
326
+ colors[vertex * 3] = (tint === void 0 ? template.colors[source * 3] : biomeTints[tint]) * factor;
327
+ colors[vertex * 3 + 1] = (tint === void 0 ? template.colors[source * 3 + 1] : biomeTints[tint + 1]) * factor;
328
+ colors[vertex * 3 + 2] = (tint === void 0 ? template.colors[source * 3 + 2] : biomeTints[tint + 2]) * factor;
327
329
  }
328
330
  for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];
329
331
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/model/fluid/FluidQuads.ts","../../src/world/_light/AmbientOcclusion.ts","../../src/world/_light/FaceLight.ts","../../src/world/SectionGeometry.ts","../../src/env/browser/section.worker.ts"],"sourcesContent":["import type { DoubleArray, TripleArray } from \"../Model\";\n\nexport type FluidKind = \"water\" | \"lava\";\n\n/** Reads the fluid kind from bits 4 and 5 of a section cell byte. */\nexport function fluidKindOf(byte: number): FluidKind | undefined {\n const kind = byte & 48;\n return kind === 16 ? \"water\" : kind === 32 ? \"lava\" : undefined;\n}\n\n/** A neighboring cell's fluid level and full-cube occlusion state. */\nexport interface FluidSample {\n fluid?: FluidKind;\n level?: number;\n solid?: boolean;\n}\n\n/** Reads cells at integer block offsets relative to the fluid being rendered, with `(0, 0, 0)` as the center. */\nexport type FluidSampler = (x: number, y: number, z: number) => FluidSample;\n\nconst HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]] as const;\nconst EPSILON = 0.001;\n\nfunction ownHeight(sample: FluidSample): number {\n const level = sample.level ?? 0;\n return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;\n}\n\n/** Fluid faces as quads centered on the block, four vertices each, in emission order. */\nexport interface FluidQuads {\n positions: number[];\n normals: number[];\n uvs: number[];\n sprites: number[];\n}\n\n/** Builds centered fluid quads with sprite 0 (still) or 1 (flowing). */\nexport function buildFluidQuads(kind: FluidKind, sample: FluidSampler): FluidQuads {\n const positions: number[] = [], normals: number[] = [], uvs: number[] = [], sprites: number[] = [];\n const self = sample(0, 0, 0);\n const height = (x: number, z: number): number => {\n const state = sample(x, 0, z);\n if (state.fluid !== kind) return state.solid ? -1 : 0;\n return sample(x, 1, z).fluid === kind ? 1 : ownHeight(state);\n };\n const selfHeight = height(0, 0);\n const corner = (x: number, z: number): number => {\n if (selfHeight >= 1) return 1;\n const adjacent = [height(x, 0), height(0, z)];\n if (adjacent.some(value => value >= 1)) return 1;\n const values = [selfHeight, ...adjacent];\n if (adjacent.some(value => value > 0)) {\n const diagonal = height(x, z);\n if (diagonal >= 1) return 1;\n values.push(diagonal);\n }\n let sum = 0, weights = 0;\n for (const value of values) {\n if (value < 0) continue;\n const weight = value >= 0.8 ? 10 : 1;\n sum += value * weight;\n weights += weight;\n }\n return sum / weights;\n };\n const heights = [corner(-1, -1), corner(-1, 1), corner(1, 1), corner(1, -1)];\n const above = sample(0, 1, 0), below = sample(0, -1, 0);\n const renderTop = above.fluid !== kind && !(above.solid && Math.min(...heights) >= 1);\n const renderBottom = below.fluid !== kind && !below.solid;\n const bottom = renderBottom ? EPSILON : 0;\n const face = (vertices: TripleArray[], uv: DoubleArray[], normal: TripleArray, material: number) => {\n sprites.push(material);\n for (let i = 0; i < 4; i++) {\n positions.push(...vertices[i].map(value => value * 16 - 8));\n normals.push(...normal);\n uvs.push(uv[i][0], 1 - uv[i][1]);\n }\n };\n\n if (renderTop) {\n for (let i = 0; i < heights.length; i++) heights[i] -= EPSILON;\n let flowX = 0, flowZ = 0;\n for (const [x, z] of HORIZONTAL) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid && neighbor.fluid !== kind) continue;\n let difference = 0;\n if (neighbor.fluid === kind) {\n difference = ownHeight(self) - ownHeight(neighbor);\n } else if (!neighbor.solid) {\n const lower = sample(x, -1, z);\n if (lower.fluid === kind) difference = ownHeight(self) - (ownHeight(lower) - 8 / 9);\n }\n flowX += x * difference;\n flowZ += z * difference;\n }\n const flowing = flowX !== 0 || flowZ !== 0;\n let uv: DoubleArray[] = [[0, 0], [0, 1], [1, 1], [1, 0]];\n if (flowing) {\n const angle = Math.atan2(flowZ, flowX) - Math.PI / 2;\n const s = Math.sin(angle) / 4, c = Math.cos(angle) / 4;\n uv = [[0.5 - c - s, 0.5 - c + s], [0.5 - c + s, 0.5 + c + s],\n [0.5 + c + s, 0.5 + c - s], [0.5 + c - s, 0.5 - c - s]];\n }\n face([[0, heights[0], 0], [0, heights[1], 1], [1, heights[2], 1], [1, heights[3], 0]], uv, [0, 1, 0], flowing ? 1 : 0);\n }\n if (renderBottom) {\n face([[0, bottom, 0], [1, bottom, 0], [1, bottom, 1], [0, bottom, 1]],\n [[0, 0], [1, 0], [1, 1], [0, 1]], [0, -1, 0], 0);\n }\n const sides = [\n { x: 0, z: -1, corners: [0, 3], edge: [[0, EPSILON], [1, EPSILON]] },\n { x: 0, z: 1, corners: [2, 1], edge: [[1, 1 - EPSILON], [0, 1 - EPSILON]] },\n { x: -1, z: 0, corners: [1, 0], edge: [[EPSILON, 1], [EPSILON, 0]] },\n { x: 1, z: 0, corners: [3, 2], edge: [[1 - EPSILON, 0], [1 - EPSILON, 1]] }\n ];\n for (const { x, z, corners, edge } of sides) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid === kind || neighbor.solid) continue;\n const [h0, h1] = corners.map(index => heights[index]);\n const [[x0, z0], [x1, z1]] = edge;\n face([[x0, h0, z0], [x1, h1, z1], [x1, bottom, z1], [x0, bottom, z0]],\n [[0, (1 - h0) / 2], [0.5, (1 - h1) / 2], [0.5, 0.5], [0, 0.5]], [x, 0, z], 1);\n }\n return { positions, normals, uvs, sprites };\n}\n","const AXIS_STRIDES = [1, 9, 3] as const;\n\n/** Reads the edge and corner blockers around one cell in an 18×18×18 section neighborhood. */\nexport function sectionAmbientOcclusionMask(cells: Uint8Array, center: number): number {\n let mask = 0;\n for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) for (let x = -1; x <= 1; x++) {\n if (Math.abs(x) + Math.abs(y) + Math.abs(z) < 2) continue;\n if (cells[center + y * 324 + z * 18 + x]) mask |= 1 << ((y + 1) * 9 + (z + 1) * 3 + x + 1);\n }\n return mask;\n}\n\nfunction cornerBrightness(mask: number, center: number, u: number, v: number): number {\n const sideU = (mask >>> (center + u)) & 1;\n const sideV = (mask >>> (center + v)) & 1;\n const corner = sideU && sideV ? 1 : (mask >>> (center + u + v)) & 1;\n return 1 - (sideU + sideV + corner) * 0.2;\n}\n\n/** Writes four linear AO factors for a boundary quad; inset or non-axis-aligned quads remain unchanged. */\nexport function quadAmbientOcclusion(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number,\n mask: number, output: Float32Array): void {\n output.fill(1);\n if (!mask) return;\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const uAxis = (axis + 1) % 3, vAxis = (axis + 2) % 3;\n if (Math.abs(Math.abs(normals[start + axis]) - 1) > 1e-6 ||\n Math.abs(normals[start + uAxis]) > 1e-6 || Math.abs(normals[start + vAxis]) > 1e-6) return;\n const sign = normals[start + axis] > 0 ? 1 : -1;\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n if (Math.abs(positions[offset + axis] - sign * 8) > 0.0016 ||\n Math.abs(positions[offset + uAxis]) > 8.0016 || Math.abs(positions[offset + vAxis]) > 8.0016) return;\n }\n const center = 13 + sign * AXIS_STRIDES[axis];\n const u = AXIS_STRIDES[uAxis], v = AXIS_STRIDES[vAxis];\n const lowLow = cornerBrightness(mask, center, -u, -v);\n const highLow = cornerBrightness(mask, center, u, -v);\n const lowHigh = cornerBrightness(mask, center, -u, v);\n const highHigh = cornerBrightness(mask, center, u, v);\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n const a = Math.max(0, Math.min(1, (positions[offset + uAxis] + 8) / 16));\n const b = Math.max(0, Math.min(1, (positions[offset + vAxis] + 8) / 16));\n output[vertex] = (lowLow * (1 - a) + highLow * a) * (1 - b) + (lowHigh * (1 - a) + highHigh * a) * b;\n }\n}\n","/** Converts a saved light level to linear brightness; unknown samples retain preview brightness. */\nexport function lightBrightness(level: number, ambient = 0): number {\n if (level === 255) return 1;\n const curve = level / (60 - 3 * level);\n return curve + ambient * (1 - curve);\n}\n\n/** Selects the adjacent light sample for a boundary quad, or the center sample for an inset quad. */\nexport function quadLightIndex(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number): number {\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const positive = normals[start + axis] > 0;\n const boundary = positive ? 8 : -8;\n for (let vertex = 0; vertex < 4; vertex++) {\n if (Math.abs(positions[start + vertex * 3 + axis] - boundary) > 0.0016) return 0;\n }\n return axis * 2 + (positive ? 1 : 2);\n}\n\n/** Fluids sample the brighter of their own cell and the cell above, or below for bottom faces. */\nexport function fluidLightLevel(center: number, neighbor: number): number {\n return Math.max(center === 255 ? 15 : center, neighbor === 255 ? 15 : neighbor);\n}\n\n/** Offsets for center and face samples in an 18×18×18 section neighborhood. */\nexport const LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18] as const;\n","import { buildFluidQuads, fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport type { FluidKind, FluidQuads } from \"../model/fluid/FluidQuads\";\nimport { quadAmbientOcclusion, sectionAmbientOcclusionMask } from \"./_light/AmbientOcclusion\";\nimport { fluidLightLevel, LIGHT_SAMPLE_OFFSETS, lightBrightness, quadLightIndex } from \"./_light/FaceLight\";\n\n/** Static model geometry as quads: four vertices per quad, in quad order. */\nexport interface SectionTemplateData {\n quads: number;\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint16Array;\n cullFaces: Uint8Array;\n atlas: number;\n layer: number;\n ambientOcclusion?: boolean;\n}\n\n/** The pixel dimensions and animation state of a source atlas. */\nexport interface SectionAtlasSize {\n width: number;\n height: number;\n animated: boolean;\n}\n\n/** One fluid kind's sprite rectangles in atlas pixels and its linear-light vertex tint. */\nexport interface SectionFluidKind {\n atlas: number;\n still: [x: number, y: number, width: number, height: number];\n flow: [x: number, y: number, width: number, height: number];\n tint: [r: number, g: number, b: number];\n}\n\n/** Fluid cells of the section plus a one-cell shell, 18×18×18, x fastest, then z, then y. */\nexport interface SectionFluidInput {\n /** Bit 128 marks a surface rendered elsewhere; the cell still supplies neighbor fluid samples. */\n cells: Uint8Array;\n /** Linear RGB per section cell, indexed by (x + 16z + 256y) * 3. Omission uses the water kind's tint. */\n waterTints?: Float32Array;\n water?: SectionFluidKind;\n lava?: SectionFluidKind;\n}\n\n/** Section placements and their shared templates, ready for geometry building. */\nexport interface SectionGeometryInput {\n count: number;\n indices: Uint16Array;\n templates: Uint16Array;\n cullMasks: Uint8Array;\n templateData: SectionTemplateData[];\n atlases: SectionAtlasSize[];\n maxAtlasSize: number;\n fluids?: SectionFluidInput;\n /** Saved brightness levels for an 18×18×18 neighborhood; 255 means unknown/full brightness. */\n light?: Uint8Array;\n /** Minimum brightness for known light levels, from 0 to 1. */\n ambientLight?: number;\n /** Opaque full cubes in an 18×18×18 neighborhood, stored as zero or one. */\n ambientOcclusion?: Uint8Array;\n}\n\n/** Merged quads and source-atlas placements for one atlas page. */\nexport interface SectionGeometryPage {\n layer: number;\n width: number;\n height: number;\n placements: { atlas: number; x: number; y: number }[];\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint32Array;\n /** Owning section cell for each quad; each quad contributes two consecutive triangles. */\n blockIndices: Uint16Array;\n}\n\n/** Builds section-local geometry from visible quads, with bounded atlas pages per layer. */\nexport function buildSectionGeometry(input: SectionGeometryInput): SectionGeometryPage[] {\n const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion } = input;\n if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError(\"Section atlas size must be a positive integer\");\n if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError(\"Section entry count exceeds its arrays\");\n if (fluids && fluids.cells.length !== 5832) throw new RangeError(\"Section fluid cells must cover an 18×18×18 neighborhood\");\n if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError(\"Section water tints must contain RGB for 4096 cells\");\n if (light && (light.length !== 5832 || light.some(level => level > 15 && level !== 255))) {\n throw new RangeError(\"Section light must cover an 18×18×18 neighborhood with levels from 0 to 15 or 255\");\n }\n if (ambientLight !== undefined && (!Number.isFinite(ambientLight) || ambientLight < 0 || ambientLight > 1)) {\n throw new RangeError(\"Section ambient light must be a number from 0 to 1\");\n }\n if (ambientOcclusion && (ambientOcclusion.length !== 5832 || ambientOcclusion.some(value => value > 1))) {\n throw new RangeError(\"Section ambient occlusion must cover an 18×18×18 neighborhood with zero or one per cell\");\n }\n const cornerBrightness = ambientOcclusion ? new Float32Array(4) : undefined;\n for (const template of templateData) {\n const { quads } = template;\n if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 ||\n template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 ||\n template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads) {\n throw new RangeError(\"Section template arrays do not match its quad count\");\n }\n }\n const visible: number[] = [];\n const visibleAtlases = new Map<number, Set<number>>();\n for (let entry = 0; entry < count; entry++) {\n const template = templateData[templates[entry]];\n if (!template.cullFaces.some(direction => !(cullMasks[entry] & direction))) continue;\n visible.push(entry);\n if (!visibleAtlases.has(template.layer)) visibleAtlases.set(template.layer, new Set());\n visibleAtlases.get(template.layer)!.add(template.atlas);\n }\n const pages: {\n layer: number; placements: SectionGeometryPage[\"placements\"]; entries: number[];\n fluids: { quads: FluidQuads; x: number; y: number; z: number; data: SectionFluidKind; tint: ArrayLike<number> }[];\n x: number; y: number; rowHeight: number; width: number; height: number;\n }[] = [];\n const locations = new Map<number, { page: number; x: number; y: number }>();\n for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {\n const firstPage = pages.length;\n for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases[a].animated) - Number(atlases[b].animated) ||\n (atlases[a].animated ? a - b : atlases[b].height - atlases[a].height))) {\n const { width, height, animated } = atlases[atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n let selected = -1;\n for (let i = firstPage; !animated && i < pages.length; i++) {\n const page = pages[i];\n const nextRow = page.x + width > maxAtlasSize;\n if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;\n if (nextRow) {\n page.y += page.rowHeight;\n page.x = 0;\n page.rowHeight = 0;\n }\n selected = i;\n break;\n }\n if (selected < 0) {\n selected = pages.length;\n pages.push({ layer, placements: [], entries: [], fluids: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 });\n }\n const page = pages[selected];\n page.placements.push({ atlas, x: page.x, y: page.y });\n locations.set(atlas, { page: selected, x: page.x, y: page.y });\n page.x += width;\n page.rowHeight = Math.max(page.rowHeight, height);\n page.width = Math.max(page.width, page.x);\n page.height = Math.max(page.height, page.y + height);\n }\n }\n for (const entry of visible) pages[locations.get(templateData[templates[entry]].atlas)!.page].entries.push(entry);\n\n if (fluids) {\n const fluidPages = new Map<FluidKind, (typeof pages)[number]>();\n for (let y = 0; y < 16; y++) for (let z = 0; z < 16; z++) for (let x = 0; x < 16; x++) {\n const byte = fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1];\n const fluid = fluidKindOf(byte);\n if (!fluid || (byte & 128)) continue;\n const data = fluids[fluid];\n if (!data) throw new RangeError(\"Section fluid input lacks the atlas for a present fluid\");\n const quads = buildFluidQuads(fluid, (dx, dy, dz) => {\n const cell = fluids.cells[(y + 1 + dy) * 324 + (z + 1 + dz) * 18 + x + 1 + dx];\n return { fluid: fluidKindOf(cell), level: cell & 15, solid: !!(cell & 64) };\n });\n if (!quads.sprites.length) continue;\n if (!fluidPages.has(fluid)) {\n const { width, height } = atlases[data.atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n fluidPages.set(fluid, { layer: 2, placements: [{ atlas: data.atlas, x: 0, y: 0 }], entries: [], fluids: [],\n x: 0, y: 0, rowHeight: 0, width, height });\n }\n const tintIndex = (x + z * 16 + y * 256) * 3;\n const tint = fluid === \"water\" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;\n fluidPages.get(fluid)!.fluids.push({ quads, x, y, z, data, tint });\n }\n pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases[a.placements[0].atlas].animated) -\n Number(atlases[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));\n }\n\n return pages.map(page => {\n let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n for (let quad = 0; quad < template.quads; quad++) {\n if (!(cullMasks[entry] & template.cullFaces[quad])) faces++;\n }\n }\n const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);\n const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);\n const outputIndices = new Uint32Array(faces * 6);\n const blockIndices = new Uint16Array(faces);\n let vertex = 0, indexOffset = 0;\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n const atlas = atlases[template.atlas];\n const placement = locations.get(template.atlas)!;\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const offsetX = (indices[entry] % 16) * 16;\n const offsetY = Math.floor(indices[entry] / 256) * 16;\n const offsetZ = (Math.floor(indices[entry] / 16) % 16) * 16;\n const lightIndex = (offsetY / 16 + 1) * 324 + (offsetZ / 16 + 1) * 18 + offsetX / 16 + 1;\n const ambientMask = ambientOcclusion && template.ambientOcclusion !== false\n ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;\n for (let quad = 0; quad < template.quads; quad++) {\n if (cullMasks[entry] & template.cullFaces[quad]) continue;\n blockIndices[indexOffset / 6] = indices[entry];\n if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness!);\n const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[\n quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = template.positions[source * 3] + offsetX;\n positions[vertex * 3 + 1] = template.positions[source * 3 + 1] + offsetY;\n positions[vertex * 3 + 2] = template.positions[source * 3 + 2] + offsetZ;\n normals[vertex * 3] = template.normals[source * 3];\n normals[vertex * 3 + 1] = template.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = template.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU(template.uvs[source * 2]);\n uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);\n uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);\n uvBounds[vertex * 4 + 1] = mapV(template.uvBounds[source * 4 + 1]);\n uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);\n uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);\n const factor = brightness * (ambientMask ? cornerBrightness![corner] : 1);\n colors[vertex * 3] = template.colors[source * 3] * factor;\n colors[vertex * 3 + 1] = template.colors[source * 3 + 1] * factor;\n colors[vertex * 3 + 2] = template.colors[source * 3 + 2] * factor;\n }\n for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];\n }\n }\n for (const { quads, x, y, z, data, tint } of page.fluids) {\n const atlas = atlases[data.atlas];\n const placement = page.placements[0];\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const lightIndex = (y + 1) * 324 + (z + 1) * 18 + x + 1;\n for (let quad = 0; quad < quads.sprites.length; quad++) {\n blockIndices[indexOffset / 6] = x + z * 16 + y * 256;\n const rect = quads.sprites[quad] === 0 ? data.still : data.flow;\n const brightness = light ? lightBrightness(fluidLightLevel(light[lightIndex],\n light[lightIndex + (quads.normals[quad * 12 + 1] < 0 ? -324 : 324)]), ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = quads.positions[source * 3] + x * 16;\n positions[vertex * 3 + 1] = quads.positions[source * 3 + 1] + y * 16;\n positions[vertex * 3 + 2] = quads.positions[source * 3 + 2] + z * 16;\n normals[vertex * 3] = quads.normals[source * 3];\n normals[vertex * 3 + 1] = quads.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = quads.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU((rect[0] + quads.uvs[source * 2] * rect[2]) / atlas.width);\n uvs[vertex * 2 + 1] = mapV(1 - (rect[1] + (1 - quads.uvs[source * 2 + 1]) * rect[3]) / atlas.height);\n uvBounds.set([mapU(rect[0] / atlas.width), mapV(1 - (rect[1] + rect[3]) / atlas.height),\n mapU((rect[0] + rect[2]) / atlas.width), mapV(1 - rect[1] / atlas.height)], vertex * 4);\n colors[vertex * 3] = tint[0] * brightness;\n colors[vertex * 3 + 1] = tint[1] * brightness;\n colors[vertex * 3 + 2] = tint[2] * brightness;\n }\n outputIndices.set([start, start + 1, start + 2, start, start + 2, start + 3], indexOffset);\n indexOffset += 6;\n }\n }\n return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };\n });\n}\n\n/** Returns the buffers behind each page's typed arrays for transfer to another thread. */\nexport function sectionGeometryTransferables(pages: readonly SectionGeometryPage[]): ArrayBuffer[] {\n return pages.flatMap(page => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);\n}\n","import { buildSectionGeometry, sectionGeometryTransferables, SectionGeometryInput } from \"../../world/SectionGeometry\";\n\naddEventListener(\"message\", (event: MessageEvent<{ id: number; type: \"build\"; input: SectionGeometryInput }>) => {\n const { id, input } = event.data;\n try {\n const pages = buildSectionGeometry(input);\n postMessage({ id, type: \"pages\", pages }, { transfer: sectionGeometryTransferables(pages) });\n } catch (error) {\n postMessage({ id, type: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n});\n"],"mappings":"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","names":["cornerBrightness","page"]}
1
+ {"version":3,"sources":["../../src/model/fluid/FluidQuads.ts","../../src/world/_light/AmbientOcclusion.ts","../../src/world/_light/FaceLight.ts","../../src/world/SectionGeometry.ts","../../src/env/browser/section.worker.ts"],"sourcesContent":["import type { DoubleArray, TripleArray } from \"../Model\";\n\nexport type FluidKind = \"water\" | \"lava\";\n\n/** Reads the fluid kind from bits 4 and 5 of a section cell byte. */\nexport function fluidKindOf(byte: number): FluidKind | undefined {\n const kind = byte & 48;\n return kind === 16 ? \"water\" : kind === 32 ? \"lava\" : undefined;\n}\n\n/** A neighboring cell's fluid level and full-cube occlusion state. */\nexport interface FluidSample {\n fluid?: FluidKind;\n level?: number;\n solid?: boolean;\n}\n\n/** Reads cells at integer block offsets relative to the fluid being rendered, with `(0, 0, 0)` as the center. */\nexport type FluidSampler = (x: number, y: number, z: number) => FluidSample;\n\nconst HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]] as const;\nconst EPSILON = 0.001;\n\nfunction ownHeight(sample: FluidSample): number {\n const level = sample.level ?? 0;\n return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;\n}\n\n/** Fluid faces as quads centered on the block, four vertices each, in emission order. */\nexport interface FluidQuads {\n positions: number[];\n normals: number[];\n uvs: number[];\n sprites: number[];\n}\n\n/** Builds centered fluid quads with sprite 0 (still) or 1 (flowing). */\nexport function buildFluidQuads(kind: FluidKind, sample: FluidSampler): FluidQuads {\n const positions: number[] = [], normals: number[] = [], uvs: number[] = [], sprites: number[] = [];\n const self = sample(0, 0, 0);\n const height = (x: number, z: number): number => {\n const state = sample(x, 0, z);\n if (state.fluid !== kind) return state.solid ? -1 : 0;\n return sample(x, 1, z).fluid === kind ? 1 : ownHeight(state);\n };\n const selfHeight = height(0, 0);\n const corner = (x: number, z: number): number => {\n if (selfHeight >= 1) return 1;\n const adjacent = [height(x, 0), height(0, z)];\n if (adjacent.some(value => value >= 1)) return 1;\n const values = [selfHeight, ...adjacent];\n if (adjacent.some(value => value > 0)) {\n const diagonal = height(x, z);\n if (diagonal >= 1) return 1;\n values.push(diagonal);\n }\n let sum = 0, weights = 0;\n for (const value of values) {\n if (value < 0) continue;\n const weight = value >= 0.8 ? 10 : 1;\n sum += value * weight;\n weights += weight;\n }\n return sum / weights;\n };\n const heights = [corner(-1, -1), corner(-1, 1), corner(1, 1), corner(1, -1)];\n const above = sample(0, 1, 0), below = sample(0, -1, 0);\n const renderTop = above.fluid !== kind && !(above.solid && Math.min(...heights) >= 1);\n const renderBottom = below.fluid !== kind && !below.solid;\n const bottom = renderBottom ? EPSILON : 0;\n const face = (vertices: TripleArray[], uv: DoubleArray[], normal: TripleArray, material: number) => {\n sprites.push(material);\n for (let i = 0; i < 4; i++) {\n positions.push(...vertices[i].map(value => value * 16 - 8));\n normals.push(...normal);\n uvs.push(uv[i][0], 1 - uv[i][1]);\n }\n };\n\n if (renderTop) {\n for (let i = 0; i < heights.length; i++) heights[i] -= EPSILON;\n let flowX = 0, flowZ = 0;\n for (const [x, z] of HORIZONTAL) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid && neighbor.fluid !== kind) continue;\n let difference = 0;\n if (neighbor.fluid === kind) {\n difference = ownHeight(self) - ownHeight(neighbor);\n } else if (!neighbor.solid) {\n const lower = sample(x, -1, z);\n if (lower.fluid === kind) difference = ownHeight(self) - (ownHeight(lower) - 8 / 9);\n }\n flowX += x * difference;\n flowZ += z * difference;\n }\n const flowing = flowX !== 0 || flowZ !== 0;\n let uv: DoubleArray[] = [[0, 0], [0, 1], [1, 1], [1, 0]];\n if (flowing) {\n const angle = Math.atan2(flowZ, flowX) - Math.PI / 2;\n const s = Math.sin(angle) / 4, c = Math.cos(angle) / 4;\n uv = [[0.5 - c - s, 0.5 - c + s], [0.5 - c + s, 0.5 + c + s],\n [0.5 + c + s, 0.5 + c - s], [0.5 + c - s, 0.5 - c - s]];\n }\n face([[0, heights[0], 0], [0, heights[1], 1], [1, heights[2], 1], [1, heights[3], 0]], uv, [0, 1, 0], flowing ? 1 : 0);\n }\n if (renderBottom) {\n face([[0, bottom, 0], [1, bottom, 0], [1, bottom, 1], [0, bottom, 1]],\n [[0, 0], [1, 0], [1, 1], [0, 1]], [0, -1, 0], 0);\n }\n const sides = [\n { x: 0, z: -1, corners: [0, 3], edge: [[0, EPSILON], [1, EPSILON]] },\n { x: 0, z: 1, corners: [2, 1], edge: [[1, 1 - EPSILON], [0, 1 - EPSILON]] },\n { x: -1, z: 0, corners: [1, 0], edge: [[EPSILON, 1], [EPSILON, 0]] },\n { x: 1, z: 0, corners: [3, 2], edge: [[1 - EPSILON, 0], [1 - EPSILON, 1]] }\n ];\n for (const { x, z, corners, edge } of sides) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid === kind || neighbor.solid) continue;\n const [h0, h1] = corners.map(index => heights[index]);\n const [[x0, z0], [x1, z1]] = edge;\n face([[x0, h0, z0], [x1, h1, z1], [x1, bottom, z1], [x0, bottom, z0]],\n [[0, (1 - h0) / 2], [0.5, (1 - h1) / 2], [0.5, 0.5], [0, 0.5]], [x, 0, z], 1);\n }\n return { positions, normals, uvs, sprites };\n}\n","const AXIS_STRIDES = [1, 9, 3] as const;\n\n/** Reads the edge and corner blockers around one cell in an 18×18×18 section neighborhood. */\nexport function sectionAmbientOcclusionMask(cells: Uint8Array, center: number): number {\n let mask = 0;\n for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) for (let x = -1; x <= 1; x++) {\n if (Math.abs(x) + Math.abs(y) + Math.abs(z) < 2) continue;\n if (cells[center + y * 324 + z * 18 + x]) mask |= 1 << ((y + 1) * 9 + (z + 1) * 3 + x + 1);\n }\n return mask;\n}\n\nfunction cornerBrightness(mask: number, center: number, u: number, v: number): number {\n const sideU = (mask >>> (center + u)) & 1;\n const sideV = (mask >>> (center + v)) & 1;\n const corner = sideU && sideV ? 1 : (mask >>> (center + u + v)) & 1;\n return 1 - (sideU + sideV + corner) * 0.2;\n}\n\n/** Writes four linear AO factors for a boundary quad; inset or non-axis-aligned quads remain unchanged. */\nexport function quadAmbientOcclusion(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number,\n mask: number, output: Float32Array): void {\n output.fill(1);\n if (!mask) return;\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const uAxis = (axis + 1) % 3, vAxis = (axis + 2) % 3;\n if (Math.abs(Math.abs(normals[start + axis]) - 1) > 1e-6 ||\n Math.abs(normals[start + uAxis]) > 1e-6 || Math.abs(normals[start + vAxis]) > 1e-6) return;\n const sign = normals[start + axis] > 0 ? 1 : -1;\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n if (Math.abs(positions[offset + axis] - sign * 8) > 0.0016 ||\n Math.abs(positions[offset + uAxis]) > 8.0016 || Math.abs(positions[offset + vAxis]) > 8.0016) return;\n }\n const center = 13 + sign * AXIS_STRIDES[axis];\n const u = AXIS_STRIDES[uAxis], v = AXIS_STRIDES[vAxis];\n const lowLow = cornerBrightness(mask, center, -u, -v);\n const highLow = cornerBrightness(mask, center, u, -v);\n const lowHigh = cornerBrightness(mask, center, -u, v);\n const highHigh = cornerBrightness(mask, center, u, v);\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n const a = Math.max(0, Math.min(1, (positions[offset + uAxis] + 8) / 16));\n const b = Math.max(0, Math.min(1, (positions[offset + vAxis] + 8) / 16));\n output[vertex] = (lowLow * (1 - a) + highLow * a) * (1 - b) + (lowHigh * (1 - a) + highHigh * a) * b;\n }\n}\n","/** Converts a saved light level to linear brightness; unknown samples retain preview brightness. */\nexport function lightBrightness(level: number, ambient = 0): number {\n if (level === 255) return 1;\n const curve = level / (60 - 3 * level);\n return curve + ambient * (1 - curve);\n}\n\n/** Selects the adjacent light sample for a boundary quad, or the center sample for an inset quad. */\nexport function quadLightIndex(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number): number {\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const positive = normals[start + axis] > 0;\n const boundary = positive ? 8 : -8;\n for (let vertex = 0; vertex < 4; vertex++) {\n if (Math.abs(positions[start + vertex * 3 + axis] - boundary) > 0.0016) return 0;\n }\n return axis * 2 + (positive ? 1 : 2);\n}\n\n/** Fluids sample the brighter of their own cell and the cell above, or below for bottom faces. */\nexport function fluidLightLevel(center: number, neighbor: number): number {\n return Math.max(center === 255 ? 15 : center, neighbor === 255 ? 15 : neighbor);\n}\n\n/** Offsets for center and face samples in an 18×18×18 section neighborhood. */\nexport const LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18] as const;\n","import { buildFluidQuads, fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport type { FluidKind, FluidQuads } from \"../model/fluid/FluidQuads\";\nimport { quadAmbientOcclusion, sectionAmbientOcclusionMask } from \"./_light/AmbientOcclusion\";\nimport { fluidLightLevel, LIGHT_SAMPLE_OFFSETS, lightBrightness, quadLightIndex } from \"./_light/FaceLight\";\n\n/** Static model geometry as quads: four vertices per quad, in quad order. */\nexport interface SectionTemplateData {\n quads: number;\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint16Array;\n cullFaces: Uint8Array;\n biomeTint?: Uint8Array;\n atlas: number;\n layer: number;\n ambientOcclusion?: boolean;\n}\n\n/** The pixel dimensions and animation state of a source atlas. */\nexport interface SectionAtlasSize {\n width: number;\n height: number;\n animated: boolean;\n}\n\n/** One fluid kind's sprite rectangles in atlas pixels and its linear-light vertex tint. */\nexport interface SectionFluidKind {\n atlas: number;\n still: [x: number, y: number, width: number, height: number];\n flow: [x: number, y: number, width: number, height: number];\n tint: [r: number, g: number, b: number];\n}\n\n/** Fluid cells of the section plus a one-cell shell, 18×18×18, x fastest, then z, then y. */\nexport interface SectionFluidInput {\n /** Bit 128 marks a surface rendered elsewhere; the cell still supplies neighbor fluid samples. */\n cells: Uint8Array;\n /** Linear RGB per section cell, indexed by (x + 16z + 256y) * 3. Omission uses the water kind's tint. */\n waterTints?: Float32Array;\n water?: SectionFluidKind;\n lava?: SectionFluidKind;\n}\n\n/** Section placements and their shared templates, ready for geometry building. */\nexport interface SectionGeometryInput {\n count: number;\n indices: Uint16Array;\n templates: Uint16Array;\n cullMasks: Uint8Array;\n /** Linear RGB per placement; three NaN values preserve the template's colors. */\n biomeTints?: Float32Array;\n templateData: SectionTemplateData[];\n atlases: SectionAtlasSize[];\n maxAtlasSize: number;\n fluids?: SectionFluidInput;\n /** Saved brightness levels for an 18×18×18 neighborhood; 255 means unknown/full brightness. */\n light?: Uint8Array;\n /** Minimum brightness for known light levels, from 0 to 1. */\n ambientLight?: number;\n /** Opaque full cubes in an 18×18×18 neighborhood, stored as zero or one. */\n ambientOcclusion?: Uint8Array;\n}\n\n/** Merged quads and source-atlas placements for one atlas page. */\nexport interface SectionGeometryPage {\n layer: number;\n width: number;\n height: number;\n placements: { atlas: number; x: number; y: number }[];\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint32Array;\n /** Owning section cell for each quad; each quad contributes two consecutive triangles. */\n blockIndices: Uint16Array;\n}\n\n/** Builds section-local geometry from visible quads, with bounded atlas pages per layer. */\nexport function buildSectionGeometry(input: SectionGeometryInput): SectionGeometryPage[] {\n const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;\n if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError(\"Section atlas size must be a positive integer\");\n if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError(\"Section entry count exceeds its arrays\");\n if (biomeTints && biomeTints.length !== count * 3) throw new RangeError(\"Section biome tints must contain RGB for each placement\");\n if (fluids && fluids.cells.length !== 5832) throw new RangeError(\"Section fluid cells must cover an 18×18×18 neighborhood\");\n if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError(\"Section water tints must contain RGB for 4096 cells\");\n if (light && (light.length !== 5832 || light.some(level => level > 15 && level !== 255))) {\n throw new RangeError(\"Section light must cover an 18×18×18 neighborhood with levels from 0 to 15 or 255\");\n }\n if (ambientLight !== undefined && (!Number.isFinite(ambientLight) || ambientLight < 0 || ambientLight > 1)) {\n throw new RangeError(\"Section ambient light must be a number from 0 to 1\");\n }\n if (ambientOcclusion && (ambientOcclusion.length !== 5832 || ambientOcclusion.some(value => value > 1))) {\n throw new RangeError(\"Section ambient occlusion must cover an 18×18×18 neighborhood with zero or one per cell\");\n }\n const cornerBrightness = ambientOcclusion ? new Float32Array(4) : undefined;\n for (const template of templateData) {\n const { quads } = template;\n if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 ||\n template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 ||\n template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads ||\n (template.biomeTint && template.biomeTint.length !== quads)) {\n throw new RangeError(\"Section template arrays do not match its quad count\");\n }\n }\n const visible: number[] = [];\n const visibleAtlases = new Map<number, Set<number>>();\n for (let entry = 0; entry < count; entry++) {\n const template = templateData[templates[entry]];\n if (!template.cullFaces.some(direction => !(cullMasks[entry] & direction))) continue;\n visible.push(entry);\n if (!visibleAtlases.has(template.layer)) visibleAtlases.set(template.layer, new Set());\n visibleAtlases.get(template.layer)!.add(template.atlas);\n }\n const pages: {\n layer: number; placements: SectionGeometryPage[\"placements\"]; entries: number[];\n fluids: { quads: FluidQuads; x: number; y: number; z: number; data: SectionFluidKind; tint: ArrayLike<number> }[];\n x: number; y: number; rowHeight: number; width: number; height: number;\n }[] = [];\n const locations = new Map<number, { page: number; x: number; y: number }>();\n for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {\n const firstPage = pages.length;\n for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases[a].animated) - Number(atlases[b].animated) ||\n (atlases[a].animated ? a - b : atlases[b].height - atlases[a].height))) {\n const { width, height, animated } = atlases[atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n let selected = -1;\n for (let i = firstPage; !animated && i < pages.length; i++) {\n const page = pages[i];\n const nextRow = page.x + width > maxAtlasSize;\n if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;\n if (nextRow) {\n page.y += page.rowHeight;\n page.x = 0;\n page.rowHeight = 0;\n }\n selected = i;\n break;\n }\n if (selected < 0) {\n selected = pages.length;\n pages.push({ layer, placements: [], entries: [], fluids: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 });\n }\n const page = pages[selected];\n page.placements.push({ atlas, x: page.x, y: page.y });\n locations.set(atlas, { page: selected, x: page.x, y: page.y });\n page.x += width;\n page.rowHeight = Math.max(page.rowHeight, height);\n page.width = Math.max(page.width, page.x);\n page.height = Math.max(page.height, page.y + height);\n }\n }\n for (const entry of visible) pages[locations.get(templateData[templates[entry]].atlas)!.page].entries.push(entry);\n\n if (fluids) {\n const fluidPages = new Map<FluidKind, (typeof pages)[number]>();\n for (let y = 0; y < 16; y++) for (let z = 0; z < 16; z++) for (let x = 0; x < 16; x++) {\n const byte = fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1];\n const fluid = fluidKindOf(byte);\n if (!fluid || (byte & 128)) continue;\n const data = fluids[fluid];\n if (!data) throw new RangeError(\"Section fluid input lacks the atlas for a present fluid\");\n const quads = buildFluidQuads(fluid, (dx, dy, dz) => {\n const cell = fluids.cells[(y + 1 + dy) * 324 + (z + 1 + dz) * 18 + x + 1 + dx];\n return { fluid: fluidKindOf(cell), level: cell & 15, solid: !!(cell & 64) };\n });\n if (!quads.sprites.length) continue;\n if (!fluidPages.has(fluid)) {\n const { width, height } = atlases[data.atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n fluidPages.set(fluid, { layer: 2, placements: [{ atlas: data.atlas, x: 0, y: 0 }], entries: [], fluids: [],\n x: 0, y: 0, rowHeight: 0, width, height });\n }\n const tintIndex = (x + z * 16 + y * 256) * 3;\n const tint = fluid === \"water\" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;\n fluidPages.get(fluid)!.fluids.push({ quads, x, y, z, data, tint });\n }\n pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases[a.placements[0].atlas].animated) -\n Number(atlases[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));\n }\n\n return pages.map(page => {\n let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n for (let quad = 0; quad < template.quads; quad++) {\n if (!(cullMasks[entry] & template.cullFaces[quad])) faces++;\n }\n }\n const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);\n const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);\n const outputIndices = new Uint32Array(faces * 6);\n const blockIndices = new Uint16Array(faces);\n let vertex = 0, indexOffset = 0;\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n const atlas = atlases[template.atlas];\n const placement = locations.get(template.atlas)!;\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const offsetX = (indices[entry] % 16) * 16;\n const offsetY = Math.floor(indices[entry] / 256) * 16;\n const offsetZ = (Math.floor(indices[entry] / 16) % 16) * 16;\n const lightIndex = (offsetY / 16 + 1) * 324 + (offsetZ / 16 + 1) * 18 + offsetX / 16 + 1;\n const ambientMask = ambientOcclusion && template.ambientOcclusion !== false\n ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;\n for (let quad = 0; quad < template.quads; quad++) {\n if (cullMasks[entry] & template.cullFaces[quad]) continue;\n blockIndices[indexOffset / 6] = indices[entry];\n if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness!);\n const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[\n quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;\n const tint = biomeTints && template.biomeTint?.[quad] && !Number.isNaN(biomeTints[entry * 3]) ? entry * 3 : undefined;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = template.positions[source * 3] + offsetX;\n positions[vertex * 3 + 1] = template.positions[source * 3 + 1] + offsetY;\n positions[vertex * 3 + 2] = template.positions[source * 3 + 2] + offsetZ;\n normals[vertex * 3] = template.normals[source * 3];\n normals[vertex * 3 + 1] = template.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = template.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU(template.uvs[source * 2]);\n uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);\n uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);\n uvBounds[vertex * 4 + 1] = mapV(template.uvBounds[source * 4 + 1]);\n uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);\n uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);\n const factor = brightness * (ambientMask ? cornerBrightness![corner] : 1);\n colors[vertex * 3] = (tint === undefined ? template.colors[source * 3] : biomeTints![tint]) * factor;\n colors[vertex * 3 + 1] = (tint === undefined ? template.colors[source * 3 + 1] : biomeTints![tint + 1]) * factor;\n colors[vertex * 3 + 2] = (tint === undefined ? template.colors[source * 3 + 2] : biomeTints![tint + 2]) * factor;\n }\n for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];\n }\n }\n for (const { quads, x, y, z, data, tint } of page.fluids) {\n const atlas = atlases[data.atlas];\n const placement = page.placements[0];\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const lightIndex = (y + 1) * 324 + (z + 1) * 18 + x + 1;\n for (let quad = 0; quad < quads.sprites.length; quad++) {\n blockIndices[indexOffset / 6] = x + z * 16 + y * 256;\n const rect = quads.sprites[quad] === 0 ? data.still : data.flow;\n const brightness = light ? lightBrightness(fluidLightLevel(light[lightIndex],\n light[lightIndex + (quads.normals[quad * 12 + 1] < 0 ? -324 : 324)]), ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = quads.positions[source * 3] + x * 16;\n positions[vertex * 3 + 1] = quads.positions[source * 3 + 1] + y * 16;\n positions[vertex * 3 + 2] = quads.positions[source * 3 + 2] + z * 16;\n normals[vertex * 3] = quads.normals[source * 3];\n normals[vertex * 3 + 1] = quads.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = quads.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU((rect[0] + quads.uvs[source * 2] * rect[2]) / atlas.width);\n uvs[vertex * 2 + 1] = mapV(1 - (rect[1] + (1 - quads.uvs[source * 2 + 1]) * rect[3]) / atlas.height);\n uvBounds.set([mapU(rect[0] / atlas.width), mapV(1 - (rect[1] + rect[3]) / atlas.height),\n mapU((rect[0] + rect[2]) / atlas.width), mapV(1 - rect[1] / atlas.height)], vertex * 4);\n colors[vertex * 3] = tint[0] * brightness;\n colors[vertex * 3 + 1] = tint[1] * brightness;\n colors[vertex * 3 + 2] = tint[2] * brightness;\n }\n outputIndices.set([start, start + 1, start + 2, start, start + 2, start + 3], indexOffset);\n indexOffset += 6;\n }\n }\n return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };\n });\n}\n\n/** Returns the buffers behind each page's typed arrays for transfer to another thread. */\nexport function sectionGeometryTransferables(pages: readonly SectionGeometryPage[]): ArrayBuffer[] {\n return pages.flatMap(page => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);\n}\n","import { buildSectionGeometry, sectionGeometryTransferables, SectionGeometryInput } from \"../../world/SectionGeometry\";\n\naddEventListener(\"message\", (event: MessageEvent<{ id: number; type: \"build\"; input: SectionGeometryInput }>) => {\n const { id, input } = event.data;\n try {\n const pages = buildSectionGeometry(input);\n postMessage({ id, type: \"pages\", pages }, { transfer: sectionGeometryTransferables(pages) });\n } catch (error) {\n postMessage({ id, type: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n});\n"],"mappings":"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","names":["cornerBrightness","page"]}
@@ -178,9 +178,10 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
178
178
 
179
179
  // src/world/SectionGeometry.ts
180
180
  function buildSectionGeometry(input) {
181
- const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion } = input;
181
+ const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
182
182
  if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
183
183
  if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
184
+ if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
184
185
  if (fluids && fluids.cells.length !== 5832) throw new RangeError("Section fluid cells must cover an 18\xD718\xD718 neighborhood");
185
186
  if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError("Section water tints must contain RGB for 4096 cells");
186
187
  if (light && (light.length !== 5832 || light.some((level) => level > 15 && level !== 255))) {
@@ -195,7 +196,7 @@ function buildSectionGeometry(input) {
195
196
  const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
196
197
  for (const template of templateData) {
197
198
  const { quads } = template;
198
- if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads) {
199
+ if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads || template.biomeTint && template.biomeTint.length !== quads) {
199
200
  throw new RangeError("Section template arrays do not match its quad count");
200
201
  }
201
202
  }
@@ -305,6 +306,7 @@ function buildSectionGeometry(input) {
305
306
  blockIndices[indexOffset / 6] = indices[entry];
306
307
  if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness2);
307
308
  const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;
309
+ const tint = biomeTints && template.biomeTint?.[quad] && !Number.isNaN(biomeTints[entry * 3]) ? entry * 3 : void 0;
308
310
  const start = vertex;
309
311
  for (let corner = 0; corner < 4; corner++, vertex++) {
310
312
  const source = quad * 4 + corner;
@@ -321,9 +323,9 @@ function buildSectionGeometry(input) {
321
323
  uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);
322
324
  uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);
323
325
  const factor = brightness * (ambientMask ? cornerBrightness2[corner] : 1);
324
- colors[vertex * 3] = template.colors[source * 3] * factor;
325
- colors[vertex * 3 + 1] = template.colors[source * 3 + 1] * factor;
326
- colors[vertex * 3 + 2] = template.colors[source * 3 + 2] * factor;
326
+ colors[vertex * 3] = (tint === void 0 ? template.colors[source * 3] : biomeTints[tint]) * factor;
327
+ colors[vertex * 3 + 1] = (tint === void 0 ? template.colors[source * 3 + 1] : biomeTints[tint + 1]) * factor;
328
+ colors[vertex * 3 + 2] = (tint === void 0 ? template.colors[source * 3 + 2] : biomeTints[tint + 2]) * factor;
327
329
  }
328
330
  for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];
329
331
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/model/fluid/FluidQuads.ts","../../src/world/_light/AmbientOcclusion.ts","../../src/world/_light/FaceLight.ts","../../src/world/SectionGeometry.ts","../../src/env/browser/section.worker.ts"],"sourcesContent":["import type { DoubleArray, TripleArray } from \"../Model\";\n\nexport type FluidKind = \"water\" | \"lava\";\n\n/** Reads the fluid kind from bits 4 and 5 of a section cell byte. */\nexport function fluidKindOf(byte: number): FluidKind | undefined {\n const kind = byte & 48;\n return kind === 16 ? \"water\" : kind === 32 ? \"lava\" : undefined;\n}\n\n/** A neighboring cell's fluid level and full-cube occlusion state. */\nexport interface FluidSample {\n fluid?: FluidKind;\n level?: number;\n solid?: boolean;\n}\n\n/** Reads cells at integer block offsets relative to the fluid being rendered, with `(0, 0, 0)` as the center. */\nexport type FluidSampler = (x: number, y: number, z: number) => FluidSample;\n\nconst HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]] as const;\nconst EPSILON = 0.001;\n\nfunction ownHeight(sample: FluidSample): number {\n const level = sample.level ?? 0;\n return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;\n}\n\n/** Fluid faces as quads centered on the block, four vertices each, in emission order. */\nexport interface FluidQuads {\n positions: number[];\n normals: number[];\n uvs: number[];\n sprites: number[];\n}\n\n/** Builds centered fluid quads with sprite 0 (still) or 1 (flowing). */\nexport function buildFluidQuads(kind: FluidKind, sample: FluidSampler): FluidQuads {\n const positions: number[] = [], normals: number[] = [], uvs: number[] = [], sprites: number[] = [];\n const self = sample(0, 0, 0);\n const height = (x: number, z: number): number => {\n const state = sample(x, 0, z);\n if (state.fluid !== kind) return state.solid ? -1 : 0;\n return sample(x, 1, z).fluid === kind ? 1 : ownHeight(state);\n };\n const selfHeight = height(0, 0);\n const corner = (x: number, z: number): number => {\n if (selfHeight >= 1) return 1;\n const adjacent = [height(x, 0), height(0, z)];\n if (adjacent.some(value => value >= 1)) return 1;\n const values = [selfHeight, ...adjacent];\n if (adjacent.some(value => value > 0)) {\n const diagonal = height(x, z);\n if (diagonal >= 1) return 1;\n values.push(diagonal);\n }\n let sum = 0, weights = 0;\n for (const value of values) {\n if (value < 0) continue;\n const weight = value >= 0.8 ? 10 : 1;\n sum += value * weight;\n weights += weight;\n }\n return sum / weights;\n };\n const heights = [corner(-1, -1), corner(-1, 1), corner(1, 1), corner(1, -1)];\n const above = sample(0, 1, 0), below = sample(0, -1, 0);\n const renderTop = above.fluid !== kind && !(above.solid && Math.min(...heights) >= 1);\n const renderBottom = below.fluid !== kind && !below.solid;\n const bottom = renderBottom ? EPSILON : 0;\n const face = (vertices: TripleArray[], uv: DoubleArray[], normal: TripleArray, material: number) => {\n sprites.push(material);\n for (let i = 0; i < 4; i++) {\n positions.push(...vertices[i].map(value => value * 16 - 8));\n normals.push(...normal);\n uvs.push(uv[i][0], 1 - uv[i][1]);\n }\n };\n\n if (renderTop) {\n for (let i = 0; i < heights.length; i++) heights[i] -= EPSILON;\n let flowX = 0, flowZ = 0;\n for (const [x, z] of HORIZONTAL) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid && neighbor.fluid !== kind) continue;\n let difference = 0;\n if (neighbor.fluid === kind) {\n difference = ownHeight(self) - ownHeight(neighbor);\n } else if (!neighbor.solid) {\n const lower = sample(x, -1, z);\n if (lower.fluid === kind) difference = ownHeight(self) - (ownHeight(lower) - 8 / 9);\n }\n flowX += x * difference;\n flowZ += z * difference;\n }\n const flowing = flowX !== 0 || flowZ !== 0;\n let uv: DoubleArray[] = [[0, 0], [0, 1], [1, 1], [1, 0]];\n if (flowing) {\n const angle = Math.atan2(flowZ, flowX) - Math.PI / 2;\n const s = Math.sin(angle) / 4, c = Math.cos(angle) / 4;\n uv = [[0.5 - c - s, 0.5 - c + s], [0.5 - c + s, 0.5 + c + s],\n [0.5 + c + s, 0.5 + c - s], [0.5 + c - s, 0.5 - c - s]];\n }\n face([[0, heights[0], 0], [0, heights[1], 1], [1, heights[2], 1], [1, heights[3], 0]], uv, [0, 1, 0], flowing ? 1 : 0);\n }\n if (renderBottom) {\n face([[0, bottom, 0], [1, bottom, 0], [1, bottom, 1], [0, bottom, 1]],\n [[0, 0], [1, 0], [1, 1], [0, 1]], [0, -1, 0], 0);\n }\n const sides = [\n { x: 0, z: -1, corners: [0, 3], edge: [[0, EPSILON], [1, EPSILON]] },\n { x: 0, z: 1, corners: [2, 1], edge: [[1, 1 - EPSILON], [0, 1 - EPSILON]] },\n { x: -1, z: 0, corners: [1, 0], edge: [[EPSILON, 1], [EPSILON, 0]] },\n { x: 1, z: 0, corners: [3, 2], edge: [[1 - EPSILON, 0], [1 - EPSILON, 1]] }\n ];\n for (const { x, z, corners, edge } of sides) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid === kind || neighbor.solid) continue;\n const [h0, h1] = corners.map(index => heights[index]);\n const [[x0, z0], [x1, z1]] = edge;\n face([[x0, h0, z0], [x1, h1, z1], [x1, bottom, z1], [x0, bottom, z0]],\n [[0, (1 - h0) / 2], [0.5, (1 - h1) / 2], [0.5, 0.5], [0, 0.5]], [x, 0, z], 1);\n }\n return { positions, normals, uvs, sprites };\n}\n","const AXIS_STRIDES = [1, 9, 3] as const;\n\n/** Reads the edge and corner blockers around one cell in an 18×18×18 section neighborhood. */\nexport function sectionAmbientOcclusionMask(cells: Uint8Array, center: number): number {\n let mask = 0;\n for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) for (let x = -1; x <= 1; x++) {\n if (Math.abs(x) + Math.abs(y) + Math.abs(z) < 2) continue;\n if (cells[center + y * 324 + z * 18 + x]) mask |= 1 << ((y + 1) * 9 + (z + 1) * 3 + x + 1);\n }\n return mask;\n}\n\nfunction cornerBrightness(mask: number, center: number, u: number, v: number): number {\n const sideU = (mask >>> (center + u)) & 1;\n const sideV = (mask >>> (center + v)) & 1;\n const corner = sideU && sideV ? 1 : (mask >>> (center + u + v)) & 1;\n return 1 - (sideU + sideV + corner) * 0.2;\n}\n\n/** Writes four linear AO factors for a boundary quad; inset or non-axis-aligned quads remain unchanged. */\nexport function quadAmbientOcclusion(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number,\n mask: number, output: Float32Array): void {\n output.fill(1);\n if (!mask) return;\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const uAxis = (axis + 1) % 3, vAxis = (axis + 2) % 3;\n if (Math.abs(Math.abs(normals[start + axis]) - 1) > 1e-6 ||\n Math.abs(normals[start + uAxis]) > 1e-6 || Math.abs(normals[start + vAxis]) > 1e-6) return;\n const sign = normals[start + axis] > 0 ? 1 : -1;\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n if (Math.abs(positions[offset + axis] - sign * 8) > 0.0016 ||\n Math.abs(positions[offset + uAxis]) > 8.0016 || Math.abs(positions[offset + vAxis]) > 8.0016) return;\n }\n const center = 13 + sign * AXIS_STRIDES[axis];\n const u = AXIS_STRIDES[uAxis], v = AXIS_STRIDES[vAxis];\n const lowLow = cornerBrightness(mask, center, -u, -v);\n const highLow = cornerBrightness(mask, center, u, -v);\n const lowHigh = cornerBrightness(mask, center, -u, v);\n const highHigh = cornerBrightness(mask, center, u, v);\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n const a = Math.max(0, Math.min(1, (positions[offset + uAxis] + 8) / 16));\n const b = Math.max(0, Math.min(1, (positions[offset + vAxis] + 8) / 16));\n output[vertex] = (lowLow * (1 - a) + highLow * a) * (1 - b) + (lowHigh * (1 - a) + highHigh * a) * b;\n }\n}\n","/** Converts a saved light level to linear brightness; unknown samples retain preview brightness. */\nexport function lightBrightness(level: number, ambient = 0): number {\n if (level === 255) return 1;\n const curve = level / (60 - 3 * level);\n return curve + ambient * (1 - curve);\n}\n\n/** Selects the adjacent light sample for a boundary quad, or the center sample for an inset quad. */\nexport function quadLightIndex(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number): number {\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const positive = normals[start + axis] > 0;\n const boundary = positive ? 8 : -8;\n for (let vertex = 0; vertex < 4; vertex++) {\n if (Math.abs(positions[start + vertex * 3 + axis] - boundary) > 0.0016) return 0;\n }\n return axis * 2 + (positive ? 1 : 2);\n}\n\n/** Fluids sample the brighter of their own cell and the cell above, or below for bottom faces. */\nexport function fluidLightLevel(center: number, neighbor: number): number {\n return Math.max(center === 255 ? 15 : center, neighbor === 255 ? 15 : neighbor);\n}\n\n/** Offsets for center and face samples in an 18×18×18 section neighborhood. */\nexport const LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18] as const;\n","import { buildFluidQuads, fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport type { FluidKind, FluidQuads } from \"../model/fluid/FluidQuads\";\nimport { quadAmbientOcclusion, sectionAmbientOcclusionMask } from \"./_light/AmbientOcclusion\";\nimport { fluidLightLevel, LIGHT_SAMPLE_OFFSETS, lightBrightness, quadLightIndex } from \"./_light/FaceLight\";\n\n/** Static model geometry as quads: four vertices per quad, in quad order. */\nexport interface SectionTemplateData {\n quads: number;\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint16Array;\n cullFaces: Uint8Array;\n atlas: number;\n layer: number;\n ambientOcclusion?: boolean;\n}\n\n/** The pixel dimensions and animation state of a source atlas. */\nexport interface SectionAtlasSize {\n width: number;\n height: number;\n animated: boolean;\n}\n\n/** One fluid kind's sprite rectangles in atlas pixels and its linear-light vertex tint. */\nexport interface SectionFluidKind {\n atlas: number;\n still: [x: number, y: number, width: number, height: number];\n flow: [x: number, y: number, width: number, height: number];\n tint: [r: number, g: number, b: number];\n}\n\n/** Fluid cells of the section plus a one-cell shell, 18×18×18, x fastest, then z, then y. */\nexport interface SectionFluidInput {\n /** Bit 128 marks a surface rendered elsewhere; the cell still supplies neighbor fluid samples. */\n cells: Uint8Array;\n /** Linear RGB per section cell, indexed by (x + 16z + 256y) * 3. Omission uses the water kind's tint. */\n waterTints?: Float32Array;\n water?: SectionFluidKind;\n lava?: SectionFluidKind;\n}\n\n/** Section placements and their shared templates, ready for geometry building. */\nexport interface SectionGeometryInput {\n count: number;\n indices: Uint16Array;\n templates: Uint16Array;\n cullMasks: Uint8Array;\n templateData: SectionTemplateData[];\n atlases: SectionAtlasSize[];\n maxAtlasSize: number;\n fluids?: SectionFluidInput;\n /** Saved brightness levels for an 18×18×18 neighborhood; 255 means unknown/full brightness. */\n light?: Uint8Array;\n /** Minimum brightness for known light levels, from 0 to 1. */\n ambientLight?: number;\n /** Opaque full cubes in an 18×18×18 neighborhood, stored as zero or one. */\n ambientOcclusion?: Uint8Array;\n}\n\n/** Merged quads and source-atlas placements for one atlas page. */\nexport interface SectionGeometryPage {\n layer: number;\n width: number;\n height: number;\n placements: { atlas: number; x: number; y: number }[];\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint32Array;\n /** Owning section cell for each quad; each quad contributes two consecutive triangles. */\n blockIndices: Uint16Array;\n}\n\n/** Builds section-local geometry from visible quads, with bounded atlas pages per layer. */\nexport function buildSectionGeometry(input: SectionGeometryInput): SectionGeometryPage[] {\n const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion } = input;\n if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError(\"Section atlas size must be a positive integer\");\n if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError(\"Section entry count exceeds its arrays\");\n if (fluids && fluids.cells.length !== 5832) throw new RangeError(\"Section fluid cells must cover an 18×18×18 neighborhood\");\n if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError(\"Section water tints must contain RGB for 4096 cells\");\n if (light && (light.length !== 5832 || light.some(level => level > 15 && level !== 255))) {\n throw new RangeError(\"Section light must cover an 18×18×18 neighborhood with levels from 0 to 15 or 255\");\n }\n if (ambientLight !== undefined && (!Number.isFinite(ambientLight) || ambientLight < 0 || ambientLight > 1)) {\n throw new RangeError(\"Section ambient light must be a number from 0 to 1\");\n }\n if (ambientOcclusion && (ambientOcclusion.length !== 5832 || ambientOcclusion.some(value => value > 1))) {\n throw new RangeError(\"Section ambient occlusion must cover an 18×18×18 neighborhood with zero or one per cell\");\n }\n const cornerBrightness = ambientOcclusion ? new Float32Array(4) : undefined;\n for (const template of templateData) {\n const { quads } = template;\n if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 ||\n template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 ||\n template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads) {\n throw new RangeError(\"Section template arrays do not match its quad count\");\n }\n }\n const visible: number[] = [];\n const visibleAtlases = new Map<number, Set<number>>();\n for (let entry = 0; entry < count; entry++) {\n const template = templateData[templates[entry]];\n if (!template.cullFaces.some(direction => !(cullMasks[entry] & direction))) continue;\n visible.push(entry);\n if (!visibleAtlases.has(template.layer)) visibleAtlases.set(template.layer, new Set());\n visibleAtlases.get(template.layer)!.add(template.atlas);\n }\n const pages: {\n layer: number; placements: SectionGeometryPage[\"placements\"]; entries: number[];\n fluids: { quads: FluidQuads; x: number; y: number; z: number; data: SectionFluidKind; tint: ArrayLike<number> }[];\n x: number; y: number; rowHeight: number; width: number; height: number;\n }[] = [];\n const locations = new Map<number, { page: number; x: number; y: number }>();\n for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {\n const firstPage = pages.length;\n for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases[a].animated) - Number(atlases[b].animated) ||\n (atlases[a].animated ? a - b : atlases[b].height - atlases[a].height))) {\n const { width, height, animated } = atlases[atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n let selected = -1;\n for (let i = firstPage; !animated && i < pages.length; i++) {\n const page = pages[i];\n const nextRow = page.x + width > maxAtlasSize;\n if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;\n if (nextRow) {\n page.y += page.rowHeight;\n page.x = 0;\n page.rowHeight = 0;\n }\n selected = i;\n break;\n }\n if (selected < 0) {\n selected = pages.length;\n pages.push({ layer, placements: [], entries: [], fluids: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 });\n }\n const page = pages[selected];\n page.placements.push({ atlas, x: page.x, y: page.y });\n locations.set(atlas, { page: selected, x: page.x, y: page.y });\n page.x += width;\n page.rowHeight = Math.max(page.rowHeight, height);\n page.width = Math.max(page.width, page.x);\n page.height = Math.max(page.height, page.y + height);\n }\n }\n for (const entry of visible) pages[locations.get(templateData[templates[entry]].atlas)!.page].entries.push(entry);\n\n if (fluids) {\n const fluidPages = new Map<FluidKind, (typeof pages)[number]>();\n for (let y = 0; y < 16; y++) for (let z = 0; z < 16; z++) for (let x = 0; x < 16; x++) {\n const byte = fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1];\n const fluid = fluidKindOf(byte);\n if (!fluid || (byte & 128)) continue;\n const data = fluids[fluid];\n if (!data) throw new RangeError(\"Section fluid input lacks the atlas for a present fluid\");\n const quads = buildFluidQuads(fluid, (dx, dy, dz) => {\n const cell = fluids.cells[(y + 1 + dy) * 324 + (z + 1 + dz) * 18 + x + 1 + dx];\n return { fluid: fluidKindOf(cell), level: cell & 15, solid: !!(cell & 64) };\n });\n if (!quads.sprites.length) continue;\n if (!fluidPages.has(fluid)) {\n const { width, height } = atlases[data.atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n fluidPages.set(fluid, { layer: 2, placements: [{ atlas: data.atlas, x: 0, y: 0 }], entries: [], fluids: [],\n x: 0, y: 0, rowHeight: 0, width, height });\n }\n const tintIndex = (x + z * 16 + y * 256) * 3;\n const tint = fluid === \"water\" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;\n fluidPages.get(fluid)!.fluids.push({ quads, x, y, z, data, tint });\n }\n pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases[a.placements[0].atlas].animated) -\n Number(atlases[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));\n }\n\n return pages.map(page => {\n let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n for (let quad = 0; quad < template.quads; quad++) {\n if (!(cullMasks[entry] & template.cullFaces[quad])) faces++;\n }\n }\n const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);\n const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);\n const outputIndices = new Uint32Array(faces * 6);\n const blockIndices = new Uint16Array(faces);\n let vertex = 0, indexOffset = 0;\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n const atlas = atlases[template.atlas];\n const placement = locations.get(template.atlas)!;\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const offsetX = (indices[entry] % 16) * 16;\n const offsetY = Math.floor(indices[entry] / 256) * 16;\n const offsetZ = (Math.floor(indices[entry] / 16) % 16) * 16;\n const lightIndex = (offsetY / 16 + 1) * 324 + (offsetZ / 16 + 1) * 18 + offsetX / 16 + 1;\n const ambientMask = ambientOcclusion && template.ambientOcclusion !== false\n ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;\n for (let quad = 0; quad < template.quads; quad++) {\n if (cullMasks[entry] & template.cullFaces[quad]) continue;\n blockIndices[indexOffset / 6] = indices[entry];\n if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness!);\n const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[\n quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = template.positions[source * 3] + offsetX;\n positions[vertex * 3 + 1] = template.positions[source * 3 + 1] + offsetY;\n positions[vertex * 3 + 2] = template.positions[source * 3 + 2] + offsetZ;\n normals[vertex * 3] = template.normals[source * 3];\n normals[vertex * 3 + 1] = template.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = template.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU(template.uvs[source * 2]);\n uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);\n uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);\n uvBounds[vertex * 4 + 1] = mapV(template.uvBounds[source * 4 + 1]);\n uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);\n uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);\n const factor = brightness * (ambientMask ? cornerBrightness![corner] : 1);\n colors[vertex * 3] = template.colors[source * 3] * factor;\n colors[vertex * 3 + 1] = template.colors[source * 3 + 1] * factor;\n colors[vertex * 3 + 2] = template.colors[source * 3 + 2] * factor;\n }\n for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];\n }\n }\n for (const { quads, x, y, z, data, tint } of page.fluids) {\n const atlas = atlases[data.atlas];\n const placement = page.placements[0];\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const lightIndex = (y + 1) * 324 + (z + 1) * 18 + x + 1;\n for (let quad = 0; quad < quads.sprites.length; quad++) {\n blockIndices[indexOffset / 6] = x + z * 16 + y * 256;\n const rect = quads.sprites[quad] === 0 ? data.still : data.flow;\n const brightness = light ? lightBrightness(fluidLightLevel(light[lightIndex],\n light[lightIndex + (quads.normals[quad * 12 + 1] < 0 ? -324 : 324)]), ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = quads.positions[source * 3] + x * 16;\n positions[vertex * 3 + 1] = quads.positions[source * 3 + 1] + y * 16;\n positions[vertex * 3 + 2] = quads.positions[source * 3 + 2] + z * 16;\n normals[vertex * 3] = quads.normals[source * 3];\n normals[vertex * 3 + 1] = quads.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = quads.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU((rect[0] + quads.uvs[source * 2] * rect[2]) / atlas.width);\n uvs[vertex * 2 + 1] = mapV(1 - (rect[1] + (1 - quads.uvs[source * 2 + 1]) * rect[3]) / atlas.height);\n uvBounds.set([mapU(rect[0] / atlas.width), mapV(1 - (rect[1] + rect[3]) / atlas.height),\n mapU((rect[0] + rect[2]) / atlas.width), mapV(1 - rect[1] / atlas.height)], vertex * 4);\n colors[vertex * 3] = tint[0] * brightness;\n colors[vertex * 3 + 1] = tint[1] * brightness;\n colors[vertex * 3 + 2] = tint[2] * brightness;\n }\n outputIndices.set([start, start + 1, start + 2, start, start + 2, start + 3], indexOffset);\n indexOffset += 6;\n }\n }\n return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };\n });\n}\n\n/** Returns the buffers behind each page's typed arrays for transfer to another thread. */\nexport function sectionGeometryTransferables(pages: readonly SectionGeometryPage[]): ArrayBuffer[] {\n return pages.flatMap(page => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);\n}\n","import { buildSectionGeometry, sectionGeometryTransferables, SectionGeometryInput } from \"../../world/SectionGeometry\";\n\naddEventListener(\"message\", (event: MessageEvent<{ id: number; type: \"build\"; input: SectionGeometryInput }>) => {\n const { id, input } = event.data;\n try {\n const pages = buildSectionGeometry(input);\n postMessage({ id, type: \"pages\", pages }, { transfer: sectionGeometryTransferables(pages) });\n } catch (error) {\n postMessage({ id, type: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n});\n"],"mappings":"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","names":["cornerBrightness","page"]}
1
+ {"version":3,"sources":["../../src/model/fluid/FluidQuads.ts","../../src/world/_light/AmbientOcclusion.ts","../../src/world/_light/FaceLight.ts","../../src/world/SectionGeometry.ts","../../src/env/browser/section.worker.ts"],"sourcesContent":["import type { DoubleArray, TripleArray } from \"../Model\";\n\nexport type FluidKind = \"water\" | \"lava\";\n\n/** Reads the fluid kind from bits 4 and 5 of a section cell byte. */\nexport function fluidKindOf(byte: number): FluidKind | undefined {\n const kind = byte & 48;\n return kind === 16 ? \"water\" : kind === 32 ? \"lava\" : undefined;\n}\n\n/** A neighboring cell's fluid level and full-cube occlusion state. */\nexport interface FluidSample {\n fluid?: FluidKind;\n level?: number;\n solid?: boolean;\n}\n\n/** Reads cells at integer block offsets relative to the fluid being rendered, with `(0, 0, 0)` as the center. */\nexport type FluidSampler = (x: number, y: number, z: number) => FluidSample;\n\nconst HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]] as const;\nconst EPSILON = 0.001;\n\nfunction ownHeight(sample: FluidSample): number {\n const level = sample.level ?? 0;\n return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;\n}\n\n/** Fluid faces as quads centered on the block, four vertices each, in emission order. */\nexport interface FluidQuads {\n positions: number[];\n normals: number[];\n uvs: number[];\n sprites: number[];\n}\n\n/** Builds centered fluid quads with sprite 0 (still) or 1 (flowing). */\nexport function buildFluidQuads(kind: FluidKind, sample: FluidSampler): FluidQuads {\n const positions: number[] = [], normals: number[] = [], uvs: number[] = [], sprites: number[] = [];\n const self = sample(0, 0, 0);\n const height = (x: number, z: number): number => {\n const state = sample(x, 0, z);\n if (state.fluid !== kind) return state.solid ? -1 : 0;\n return sample(x, 1, z).fluid === kind ? 1 : ownHeight(state);\n };\n const selfHeight = height(0, 0);\n const corner = (x: number, z: number): number => {\n if (selfHeight >= 1) return 1;\n const adjacent = [height(x, 0), height(0, z)];\n if (adjacent.some(value => value >= 1)) return 1;\n const values = [selfHeight, ...adjacent];\n if (adjacent.some(value => value > 0)) {\n const diagonal = height(x, z);\n if (diagonal >= 1) return 1;\n values.push(diagonal);\n }\n let sum = 0, weights = 0;\n for (const value of values) {\n if (value < 0) continue;\n const weight = value >= 0.8 ? 10 : 1;\n sum += value * weight;\n weights += weight;\n }\n return sum / weights;\n };\n const heights = [corner(-1, -1), corner(-1, 1), corner(1, 1), corner(1, -1)];\n const above = sample(0, 1, 0), below = sample(0, -1, 0);\n const renderTop = above.fluid !== kind && !(above.solid && Math.min(...heights) >= 1);\n const renderBottom = below.fluid !== kind && !below.solid;\n const bottom = renderBottom ? EPSILON : 0;\n const face = (vertices: TripleArray[], uv: DoubleArray[], normal: TripleArray, material: number) => {\n sprites.push(material);\n for (let i = 0; i < 4; i++) {\n positions.push(...vertices[i].map(value => value * 16 - 8));\n normals.push(...normal);\n uvs.push(uv[i][0], 1 - uv[i][1]);\n }\n };\n\n if (renderTop) {\n for (let i = 0; i < heights.length; i++) heights[i] -= EPSILON;\n let flowX = 0, flowZ = 0;\n for (const [x, z] of HORIZONTAL) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid && neighbor.fluid !== kind) continue;\n let difference = 0;\n if (neighbor.fluid === kind) {\n difference = ownHeight(self) - ownHeight(neighbor);\n } else if (!neighbor.solid) {\n const lower = sample(x, -1, z);\n if (lower.fluid === kind) difference = ownHeight(self) - (ownHeight(lower) - 8 / 9);\n }\n flowX += x * difference;\n flowZ += z * difference;\n }\n const flowing = flowX !== 0 || flowZ !== 0;\n let uv: DoubleArray[] = [[0, 0], [0, 1], [1, 1], [1, 0]];\n if (flowing) {\n const angle = Math.atan2(flowZ, flowX) - Math.PI / 2;\n const s = Math.sin(angle) / 4, c = Math.cos(angle) / 4;\n uv = [[0.5 - c - s, 0.5 - c + s], [0.5 - c + s, 0.5 + c + s],\n [0.5 + c + s, 0.5 + c - s], [0.5 + c - s, 0.5 - c - s]];\n }\n face([[0, heights[0], 0], [0, heights[1], 1], [1, heights[2], 1], [1, heights[3], 0]], uv, [0, 1, 0], flowing ? 1 : 0);\n }\n if (renderBottom) {\n face([[0, bottom, 0], [1, bottom, 0], [1, bottom, 1], [0, bottom, 1]],\n [[0, 0], [1, 0], [1, 1], [0, 1]], [0, -1, 0], 0);\n }\n const sides = [\n { x: 0, z: -1, corners: [0, 3], edge: [[0, EPSILON], [1, EPSILON]] },\n { x: 0, z: 1, corners: [2, 1], edge: [[1, 1 - EPSILON], [0, 1 - EPSILON]] },\n { x: -1, z: 0, corners: [1, 0], edge: [[EPSILON, 1], [EPSILON, 0]] },\n { x: 1, z: 0, corners: [3, 2], edge: [[1 - EPSILON, 0], [1 - EPSILON, 1]] }\n ];\n for (const { x, z, corners, edge } of sides) {\n const neighbor = sample(x, 0, z);\n if (neighbor.fluid === kind || neighbor.solid) continue;\n const [h0, h1] = corners.map(index => heights[index]);\n const [[x0, z0], [x1, z1]] = edge;\n face([[x0, h0, z0], [x1, h1, z1], [x1, bottom, z1], [x0, bottom, z0]],\n [[0, (1 - h0) / 2], [0.5, (1 - h1) / 2], [0.5, 0.5], [0, 0.5]], [x, 0, z], 1);\n }\n return { positions, normals, uvs, sprites };\n}\n","const AXIS_STRIDES = [1, 9, 3] as const;\n\n/** Reads the edge and corner blockers around one cell in an 18×18×18 section neighborhood. */\nexport function sectionAmbientOcclusionMask(cells: Uint8Array, center: number): number {\n let mask = 0;\n for (let y = -1; y <= 1; y++) for (let z = -1; z <= 1; z++) for (let x = -1; x <= 1; x++) {\n if (Math.abs(x) + Math.abs(y) + Math.abs(z) < 2) continue;\n if (cells[center + y * 324 + z * 18 + x]) mask |= 1 << ((y + 1) * 9 + (z + 1) * 3 + x + 1);\n }\n return mask;\n}\n\nfunction cornerBrightness(mask: number, center: number, u: number, v: number): number {\n const sideU = (mask >>> (center + u)) & 1;\n const sideV = (mask >>> (center + v)) & 1;\n const corner = sideU && sideV ? 1 : (mask >>> (center + u + v)) & 1;\n return 1 - (sideU + sideV + corner) * 0.2;\n}\n\n/** Writes four linear AO factors for a boundary quad; inset or non-axis-aligned quads remain unchanged. */\nexport function quadAmbientOcclusion(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number,\n mask: number, output: Float32Array): void {\n output.fill(1);\n if (!mask) return;\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const uAxis = (axis + 1) % 3, vAxis = (axis + 2) % 3;\n if (Math.abs(Math.abs(normals[start + axis]) - 1) > 1e-6 ||\n Math.abs(normals[start + uAxis]) > 1e-6 || Math.abs(normals[start + vAxis]) > 1e-6) return;\n const sign = normals[start + axis] > 0 ? 1 : -1;\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n if (Math.abs(positions[offset + axis] - sign * 8) > 0.0016 ||\n Math.abs(positions[offset + uAxis]) > 8.0016 || Math.abs(positions[offset + vAxis]) > 8.0016) return;\n }\n const center = 13 + sign * AXIS_STRIDES[axis];\n const u = AXIS_STRIDES[uAxis], v = AXIS_STRIDES[vAxis];\n const lowLow = cornerBrightness(mask, center, -u, -v);\n const highLow = cornerBrightness(mask, center, u, -v);\n const lowHigh = cornerBrightness(mask, center, -u, v);\n const highHigh = cornerBrightness(mask, center, u, v);\n for (let vertex = 0; vertex < 4; vertex++) {\n const offset = start + vertex * 3;\n const a = Math.max(0, Math.min(1, (positions[offset + uAxis] + 8) / 16));\n const b = Math.max(0, Math.min(1, (positions[offset + vAxis] + 8) / 16));\n output[vertex] = (lowLow * (1 - a) + highLow * a) * (1 - b) + (lowHigh * (1 - a) + highHigh * a) * b;\n }\n}\n","/** Converts a saved light level to linear brightness; unknown samples retain preview brightness. */\nexport function lightBrightness(level: number, ambient = 0): number {\n if (level === 255) return 1;\n const curve = level / (60 - 3 * level);\n return curve + ambient * (1 - curve);\n}\n\n/** Selects the adjacent light sample for a boundary quad, or the center sample for an inset quad. */\nexport function quadLightIndex(positions: ArrayLike<number>, normals: ArrayLike<number>, quad: number): number {\n const start = quad * 12;\n let axis = 0;\n if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;\n if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;\n const positive = normals[start + axis] > 0;\n const boundary = positive ? 8 : -8;\n for (let vertex = 0; vertex < 4; vertex++) {\n if (Math.abs(positions[start + vertex * 3 + axis] - boundary) > 0.0016) return 0;\n }\n return axis * 2 + (positive ? 1 : 2);\n}\n\n/** Fluids sample the brighter of their own cell and the cell above, or below for bottom faces. */\nexport function fluidLightLevel(center: number, neighbor: number): number {\n return Math.max(center === 255 ? 15 : center, neighbor === 255 ? 15 : neighbor);\n}\n\n/** Offsets for center and face samples in an 18×18×18 section neighborhood. */\nexport const LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18] as const;\n","import { buildFluidQuads, fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport type { FluidKind, FluidQuads } from \"../model/fluid/FluidQuads\";\nimport { quadAmbientOcclusion, sectionAmbientOcclusionMask } from \"./_light/AmbientOcclusion\";\nimport { fluidLightLevel, LIGHT_SAMPLE_OFFSETS, lightBrightness, quadLightIndex } from \"./_light/FaceLight\";\n\n/** Static model geometry as quads: four vertices per quad, in quad order. */\nexport interface SectionTemplateData {\n quads: number;\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint16Array;\n cullFaces: Uint8Array;\n biomeTint?: Uint8Array;\n atlas: number;\n layer: number;\n ambientOcclusion?: boolean;\n}\n\n/** The pixel dimensions and animation state of a source atlas. */\nexport interface SectionAtlasSize {\n width: number;\n height: number;\n animated: boolean;\n}\n\n/** One fluid kind's sprite rectangles in atlas pixels and its linear-light vertex tint. */\nexport interface SectionFluidKind {\n atlas: number;\n still: [x: number, y: number, width: number, height: number];\n flow: [x: number, y: number, width: number, height: number];\n tint: [r: number, g: number, b: number];\n}\n\n/** Fluid cells of the section plus a one-cell shell, 18×18×18, x fastest, then z, then y. */\nexport interface SectionFluidInput {\n /** Bit 128 marks a surface rendered elsewhere; the cell still supplies neighbor fluid samples. */\n cells: Uint8Array;\n /** Linear RGB per section cell, indexed by (x + 16z + 256y) * 3. Omission uses the water kind's tint. */\n waterTints?: Float32Array;\n water?: SectionFluidKind;\n lava?: SectionFluidKind;\n}\n\n/** Section placements and their shared templates, ready for geometry building. */\nexport interface SectionGeometryInput {\n count: number;\n indices: Uint16Array;\n templates: Uint16Array;\n cullMasks: Uint8Array;\n /** Linear RGB per placement; three NaN values preserve the template's colors. */\n biomeTints?: Float32Array;\n templateData: SectionTemplateData[];\n atlases: SectionAtlasSize[];\n maxAtlasSize: number;\n fluids?: SectionFluidInput;\n /** Saved brightness levels for an 18×18×18 neighborhood; 255 means unknown/full brightness. */\n light?: Uint8Array;\n /** Minimum brightness for known light levels, from 0 to 1. */\n ambientLight?: number;\n /** Opaque full cubes in an 18×18×18 neighborhood, stored as zero or one. */\n ambientOcclusion?: Uint8Array;\n}\n\n/** Merged quads and source-atlas placements for one atlas page. */\nexport interface SectionGeometryPage {\n layer: number;\n width: number;\n height: number;\n placements: { atlas: number; x: number; y: number }[];\n positions: Float32Array;\n normals: Float32Array;\n uvs: Float32Array;\n uvBounds: Float32Array;\n colors: Float32Array;\n indices: Uint32Array;\n /** Owning section cell for each quad; each quad contributes two consecutive triangles. */\n blockIndices: Uint16Array;\n}\n\n/** Builds section-local geometry from visible quads, with bounded atlas pages per layer. */\nexport function buildSectionGeometry(input: SectionGeometryInput): SectionGeometryPage[] {\n const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;\n if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError(\"Section atlas size must be a positive integer\");\n if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError(\"Section entry count exceeds its arrays\");\n if (biomeTints && biomeTints.length !== count * 3) throw new RangeError(\"Section biome tints must contain RGB for each placement\");\n if (fluids && fluids.cells.length !== 5832) throw new RangeError(\"Section fluid cells must cover an 18×18×18 neighborhood\");\n if (fluids?.waterTints && fluids.waterTints.length !== 4096 * 3) throw new RangeError(\"Section water tints must contain RGB for 4096 cells\");\n if (light && (light.length !== 5832 || light.some(level => level > 15 && level !== 255))) {\n throw new RangeError(\"Section light must cover an 18×18×18 neighborhood with levels from 0 to 15 or 255\");\n }\n if (ambientLight !== undefined && (!Number.isFinite(ambientLight) || ambientLight < 0 || ambientLight > 1)) {\n throw new RangeError(\"Section ambient light must be a number from 0 to 1\");\n }\n if (ambientOcclusion && (ambientOcclusion.length !== 5832 || ambientOcclusion.some(value => value > 1))) {\n throw new RangeError(\"Section ambient occlusion must cover an 18×18×18 neighborhood with zero or one per cell\");\n }\n const cornerBrightness = ambientOcclusion ? new Float32Array(4) : undefined;\n for (const template of templateData) {\n const { quads } = template;\n if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 ||\n template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 ||\n template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads ||\n (template.biomeTint && template.biomeTint.length !== quads)) {\n throw new RangeError(\"Section template arrays do not match its quad count\");\n }\n }\n const visible: number[] = [];\n const visibleAtlases = new Map<number, Set<number>>();\n for (let entry = 0; entry < count; entry++) {\n const template = templateData[templates[entry]];\n if (!template.cullFaces.some(direction => !(cullMasks[entry] & direction))) continue;\n visible.push(entry);\n if (!visibleAtlases.has(template.layer)) visibleAtlases.set(template.layer, new Set());\n visibleAtlases.get(template.layer)!.add(template.atlas);\n }\n const pages: {\n layer: number; placements: SectionGeometryPage[\"placements\"]; entries: number[];\n fluids: { quads: FluidQuads; x: number; y: number; z: number; data: SectionFluidKind; tint: ArrayLike<number> }[];\n x: number; y: number; rowHeight: number; width: number; height: number;\n }[] = [];\n const locations = new Map<number, { page: number; x: number; y: number }>();\n for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {\n const firstPage = pages.length;\n for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases[a].animated) - Number(atlases[b].animated) ||\n (atlases[a].animated ? a - b : atlases[b].height - atlases[a].height))) {\n const { width, height, animated } = atlases[atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n let selected = -1;\n for (let i = firstPage; !animated && i < pages.length; i++) {\n const page = pages[i];\n const nextRow = page.x + width > maxAtlasSize;\n if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;\n if (nextRow) {\n page.y += page.rowHeight;\n page.x = 0;\n page.rowHeight = 0;\n }\n selected = i;\n break;\n }\n if (selected < 0) {\n selected = pages.length;\n pages.push({ layer, placements: [], entries: [], fluids: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 });\n }\n const page = pages[selected];\n page.placements.push({ atlas, x: page.x, y: page.y });\n locations.set(atlas, { page: selected, x: page.x, y: page.y });\n page.x += width;\n page.rowHeight = Math.max(page.rowHeight, height);\n page.width = Math.max(page.width, page.x);\n page.height = Math.max(page.height, page.y + height);\n }\n }\n for (const entry of visible) pages[locations.get(templateData[templates[entry]].atlas)!.page].entries.push(entry);\n\n if (fluids) {\n const fluidPages = new Map<FluidKind, (typeof pages)[number]>();\n for (let y = 0; y < 16; y++) for (let z = 0; z < 16; z++) for (let x = 0; x < 16; x++) {\n const byte = fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1];\n const fluid = fluidKindOf(byte);\n if (!fluid || (byte & 128)) continue;\n const data = fluids[fluid];\n if (!data) throw new RangeError(\"Section fluid input lacks the atlas for a present fluid\");\n const quads = buildFluidQuads(fluid, (dx, dy, dz) => {\n const cell = fluids.cells[(y + 1 + dy) * 324 + (z + 1 + dz) * 18 + x + 1 + dx];\n return { fluid: fluidKindOf(cell), level: cell & 15, solid: !!(cell & 64) };\n });\n if (!quads.sprites.length) continue;\n if (!fluidPages.has(fluid)) {\n const { width, height } = atlases[data.atlas];\n if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError(\"Model atlas exceeds the section atlas size limit\");\n fluidPages.set(fluid, { layer: 2, placements: [{ atlas: data.atlas, x: 0, y: 0 }], entries: [], fluids: [],\n x: 0, y: 0, rowHeight: 0, width, height });\n }\n const tintIndex = (x + z * 16 + y * 256) * 3;\n const tint = fluid === \"water\" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;\n fluidPages.get(fluid)!.fluids.push({ quads, x, y, z, data, tint });\n }\n pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases[a.placements[0].atlas].animated) -\n Number(atlases[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));\n }\n\n return pages.map(page => {\n let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n for (let quad = 0; quad < template.quads; quad++) {\n if (!(cullMasks[entry] & template.cullFaces[quad])) faces++;\n }\n }\n const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);\n const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);\n const outputIndices = new Uint32Array(faces * 6);\n const blockIndices = new Uint16Array(faces);\n let vertex = 0, indexOffset = 0;\n for (const entry of page.entries) {\n const template = templateData[templates[entry]];\n const atlas = atlases[template.atlas];\n const placement = locations.get(template.atlas)!;\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const offsetX = (indices[entry] % 16) * 16;\n const offsetY = Math.floor(indices[entry] / 256) * 16;\n const offsetZ = (Math.floor(indices[entry] / 16) % 16) * 16;\n const lightIndex = (offsetY / 16 + 1) * 324 + (offsetZ / 16 + 1) * 18 + offsetX / 16 + 1;\n const ambientMask = ambientOcclusion && template.ambientOcclusion !== false\n ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;\n for (let quad = 0; quad < template.quads; quad++) {\n if (cullMasks[entry] & template.cullFaces[quad]) continue;\n blockIndices[indexOffset / 6] = indices[entry];\n if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness!);\n const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[\n quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;\n const tint = biomeTints && template.biomeTint?.[quad] && !Number.isNaN(biomeTints[entry * 3]) ? entry * 3 : undefined;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = template.positions[source * 3] + offsetX;\n positions[vertex * 3 + 1] = template.positions[source * 3 + 1] + offsetY;\n positions[vertex * 3 + 2] = template.positions[source * 3 + 2] + offsetZ;\n normals[vertex * 3] = template.normals[source * 3];\n normals[vertex * 3 + 1] = template.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = template.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU(template.uvs[source * 2]);\n uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);\n uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);\n uvBounds[vertex * 4 + 1] = mapV(template.uvBounds[source * 4 + 1]);\n uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);\n uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);\n const factor = brightness * (ambientMask ? cornerBrightness![corner] : 1);\n colors[vertex * 3] = (tint === undefined ? template.colors[source * 3] : biomeTints![tint]) * factor;\n colors[vertex * 3 + 1] = (tint === undefined ? template.colors[source * 3 + 1] : biomeTints![tint + 1]) * factor;\n colors[vertex * 3 + 2] = (tint === undefined ? template.colors[source * 3 + 2] : biomeTints![tint + 2]) * factor;\n }\n for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];\n }\n }\n for (const { quads, x, y, z, data, tint } of page.fluids) {\n const atlas = atlases[data.atlas];\n const placement = page.placements[0];\n const mapU = (u: number) => (placement.x + u * atlas.width) / page.width;\n const mapV = (v: number) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;\n const lightIndex = (y + 1) * 324 + (z + 1) * 18 + x + 1;\n for (let quad = 0; quad < quads.sprites.length; quad++) {\n blockIndices[indexOffset / 6] = x + z * 16 + y * 256;\n const rect = quads.sprites[quad] === 0 ? data.still : data.flow;\n const brightness = light ? lightBrightness(fluidLightLevel(light[lightIndex],\n light[lightIndex + (quads.normals[quad * 12 + 1] < 0 ? -324 : 324)]), ambientLight) : 1;\n const start = vertex;\n for (let corner = 0; corner < 4; corner++, vertex++) {\n const source = quad * 4 + corner;\n positions[vertex * 3] = quads.positions[source * 3] + x * 16;\n positions[vertex * 3 + 1] = quads.positions[source * 3 + 1] + y * 16;\n positions[vertex * 3 + 2] = quads.positions[source * 3 + 2] + z * 16;\n normals[vertex * 3] = quads.normals[source * 3];\n normals[vertex * 3 + 1] = quads.normals[source * 3 + 1];\n normals[vertex * 3 + 2] = quads.normals[source * 3 + 2];\n uvs[vertex * 2] = mapU((rect[0] + quads.uvs[source * 2] * rect[2]) / atlas.width);\n uvs[vertex * 2 + 1] = mapV(1 - (rect[1] + (1 - quads.uvs[source * 2 + 1]) * rect[3]) / atlas.height);\n uvBounds.set([mapU(rect[0] / atlas.width), mapV(1 - (rect[1] + rect[3]) / atlas.height),\n mapU((rect[0] + rect[2]) / atlas.width), mapV(1 - rect[1] / atlas.height)], vertex * 4);\n colors[vertex * 3] = tint[0] * brightness;\n colors[vertex * 3 + 1] = tint[1] * brightness;\n colors[vertex * 3 + 2] = tint[2] * brightness;\n }\n outputIndices.set([start, start + 1, start + 2, start, start + 2, start + 3], indexOffset);\n indexOffset += 6;\n }\n }\n return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };\n });\n}\n\n/** Returns the buffers behind each page's typed arrays for transfer to another thread. */\nexport function sectionGeometryTransferables(pages: readonly SectionGeometryPage[]): ArrayBuffer[] {\n return pages.flatMap(page => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);\n}\n","import { buildSectionGeometry, sectionGeometryTransferables, SectionGeometryInput } from \"../../world/SectionGeometry\";\n\naddEventListener(\"message\", (event: MessageEvent<{ id: number; type: \"build\"; input: SectionGeometryInput }>) => {\n const { id, input } = event.data;\n try {\n const pages = buildSectionGeometry(input);\n postMessage({ id, type: \"pages\", pages }, { transfer: sectionGeometryTransferables(pages) });\n } catch (error) {\n postMessage({ id, type: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n});\n"],"mappings":"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","names":["cornerBrightness","page"]}