minerender 2.1.0-alpha.133 → 2.1.0-alpha.135
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/esm/Materials.mjs +3 -2
- package/dist/browser/esm/Materials.mjs.map +1 -1
- package/dist/browser/esm/assets/AssetDefaults.mjs +8 -0
- package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
- package/dist/browser/esm/assets/AssetKey.mjs +1 -1
- package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
- package/dist/browser/esm/assets/AssetLoader.mjs +1 -1
- package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
- package/dist/browser/esm/assets/Assets.mjs +1 -5
- package/dist/browser/esm/assets/Assets.mjs.map +1 -1
- package/dist/browser/esm/assets/BlockStates.mjs +1 -1
- package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
- package/dist/browser/esm/assets/Entities.mjs +1 -1
- package/dist/browser/esm/assets/Entities.mjs.map +1 -1
- package/dist/browser/esm/assets/Models.mjs +1 -1
- package/dist/browser/esm/assets/Models.mjs.map +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -1
- package/dist/browser/esm/assets/index.mjs +1 -0
- package/dist/browser/esm/assets/index.mjs.map +1 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs +1 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
- package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
- package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +5 -2
- package/dist/browser/esm/model/scene/ModelObject.mjs +4 -0
- package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
- package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
- package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
- package/dist/browser/esm/world/SectionMesh.mjs +4 -0
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +2 -2
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
- package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
- package/dist/browser/index.d.ts +5 -2
- package/dist/browser/index.js +2725 -2710
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +7825 -7807
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +5 -2
- package/dist/node/index.d.ts +5 -2
- package/dist/node/index.js +2746 -2731
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +2735 -2720
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -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 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"]}
|
|
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 shade?: 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 shade: 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.shade && template.shade.length !== quads * 4) ||\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 shade = new Float32Array(faces * 4).fill(1);\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 shade[vertex] = template.shade?.[source] ?? 1;\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, shade, 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.shade.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"]}
|
|
@@ -913,6 +913,9 @@ declare class MinecraftFaceUV {
|
|
|
913
913
|
*/
|
|
914
914
|
declare function shutdown(): void;
|
|
915
915
|
|
|
916
|
+
declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
|
|
917
|
+
declare const DEFAULT_NAMESPACE = "minecraft";
|
|
918
|
+
|
|
916
919
|
/** Runs queued tasks in bounded batches. Idle executors do not keep a timer running. */
|
|
917
920
|
declare class BatchedExecutor {
|
|
918
921
|
readonly interval: number;
|
|
@@ -1057,8 +1060,6 @@ type MultipartCondition = Record<string, string> | {
|
|
|
1057
1060
|
AND: MultipartCondition[];
|
|
1058
1061
|
};
|
|
1059
1062
|
|
|
1060
|
-
declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
|
|
1061
|
-
declare const DEFAULT_NAMESPACE = "minecraft";
|
|
1062
1063
|
/** Convenience accessors for model and blockstate loading. */
|
|
1063
1064
|
declare class Assets {
|
|
1064
1065
|
/**
|
|
@@ -3830,6 +3831,7 @@ interface SectionTemplateData {
|
|
|
3830
3831
|
uvs: Float32Array;
|
|
3831
3832
|
uvBounds: Float32Array;
|
|
3832
3833
|
colors: Float32Array;
|
|
3834
|
+
shade?: Float32Array;
|
|
3833
3835
|
indices: Uint16Array;
|
|
3834
3836
|
cullFaces: Uint8Array;
|
|
3835
3837
|
biomeTint?: Uint8Array;
|
|
@@ -3893,6 +3895,7 @@ interface SectionGeometryPage {
|
|
|
3893
3895
|
uvs: Float32Array;
|
|
3894
3896
|
uvBounds: Float32Array;
|
|
3895
3897
|
colors: Float32Array;
|
|
3898
|
+
shade: Float32Array;
|
|
3896
3899
|
indices: Uint32Array;
|
|
3897
3900
|
/** Owning section cell for each quad; each quad contributes two consecutive triangles. */
|
|
3898
3901
|
blockIndices: Uint16Array;
|
|
@@ -149,6 +149,10 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
149
149
|
this.atlas.model.elements?.forEach((el) => {
|
|
150
150
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
151
151
|
this.geometries.add(elGeo);
|
|
152
|
+
elGeo.setAttribute("shade", new BufferAttribute(
|
|
153
|
+
new Float32Array(elGeo.getAttribute("position").count).fill(!this.originalModel.itemId && el.shade === false ? 0 : 1),
|
|
154
|
+
1
|
|
155
|
+
));
|
|
152
156
|
if (this.options.cullMask) {
|
|
153
157
|
const indices = Array.from(elGeo.getIndex().array);
|
|
154
158
|
elGeo.setIndex(indices.filter((_, index) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/model/scene/ModelObject.ts"],"sourcesContent":["import { SceneObject } from \"../../renderer/SceneObject\";\nimport { ItemModel, Model, TextureAsset, TripleArray } from \"../Model\";\nimport { Materials } from \"../../Materials\";\nimport { Maybe, toRadians } from \"../../util/util\";\nimport { UVMapper } from \"../../UVMapper\";\nimport { TextureAtlas } from \"../../texture/TextureAtlas\";\nimport { BoxGeometry, BoxHelper, BufferAttribute, Color, DoubleSide, EdgesGeometry, Euler, FrontSide, InstancedMesh, LineBasicMaterial, LineSegments, Material, Matrix4, Mesh, MeshBasicMaterial, MeshStandardMaterial, ShaderMaterial } from \"three\";\nimport { mergeBufferGeometries } from \"../../three/BufferGeometryUtils\";\nimport { SceneObjectOptions } from \"../../renderer/SceneObjectOptions\";\nimport { addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation } from \"../../util/model\";\nimport { merge } from \"../../util/_internal/merge\";\nimport type { BufferGeometry, Texture } from \"three\";\nimport { BlockObject } from \"../block/scene/BlockObject\";\nimport { prefix } from \"../../util/log\";\nimport { CUBE_FACES } from \"../../CubeFace\";\nimport { DisplayPosition } from \"../DisplayPosition\";\nimport { DisplayTransforms } from \"../DisplayTransforms\";\nimport { ModelCulling } from \"../ModelCulling\";\nimport type { MineRenderScene } from \"../../renderer/MineRenderScene\";\nimport { SpecialItems } from \"../SpecialItems\";\nimport { EntityObject } from \"../../entity/scene/EntityObject\";\nimport { GuiLight } from \"../GuiLight\";\nimport { ItemTints } from \"../ItemTints\";\nimport { ItemGlint } from \"../ItemGlint\";\n\n\nconst p = prefix(\"ModelObject\");\n\n//TODO: might want to abstract this out into a generic model, and create a separate class for Block models\n/** Builds render geometry from a merged Java model. Create it through {@link MineRenderScene.addModel}. */\nexport class ModelObject extends SceneObject {\n\n public readonly isModelObject: true = true;\n\n public static readonly DEFAULT_OPTIONS: ModelObjectOptions = merge({}, SceneObject.DEFAULT_OPTIONS, <ModelObjectOptions>{});\n public readonly options: ModelObjectOptions;\n\n protected atlas?: TextureAtlas;\n private atlasMaterial?: Material;\n private atlasTexture?: Texture;\n private unsubscribeAtlas?: () => void;\n private readonly specialMaterials = new Map<Material, Material>();\n private readonly geometries = new Set<BufferGeometry>();\n private readonly hasGlint: boolean;\n private glint?: ItemGlint;\n\n public blockParent: Maybe<BlockObject>;\n\n private meshesCreated: boolean = false;\n\n constructor(readonly originalModel: Model, options?: Partial<ModelObjectOptions>) {\n super(options);\n this.options = merge({}, ModelObject.DEFAULT_OPTIONS, options ?? {});\n const item = originalModel as ItemModel;\n const specialType = item.special?.type.replace(/^minecraft:/, \"\");\n this.hasGlint = !item.parts && (!item.special || specialType === \"shield\" || specialType === \"trident\") && ItemGlint.enabled(item.components, item.itemId);\n if (item.special || item.parts || this.hasGlint) this.options.instanceMeshes = false;\n if (this.options.tints) this.options.tints = { ...this.options.tints };\n this.addEventListener(\"added\", () => this.updateAnimationSubscription());\n this.addEventListener(\"removed\", () => this.updateAnimationSubscription());\n }\n\n async init(): Promise<void> {\n const parts = (this.originalModel as ItemModel).parts;\n if (parts) {\n try {\n for (const part of parts) {\n const object = new ModelObject(part, { ...this.options, instanceMeshes: false });\n this.add(object);\n await object.init();\n }\n let order = 0;\n this.iterateAllMeshes(mesh => {\n mesh.renderOrder = order++;\n // Keep composite children in one render pass so their declared order is retained.\n for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {\n material.transparent = true;\n }\n });\n } catch (error) {\n this.disposeAndRemoveAllChildren();\n throw error;\n }\n this.notifyDirty();\n return;\n }\n this.options.tints = await ItemTints.get(this.originalModel, this.options.tints);\n const special = (this.originalModel as ItemModel).special;\n if (special) {\n const parts = await SpecialItems.getParts(special, this.originalModel.key?.root, (this.originalModel as ItemModel).components);\n // A separate display node preserves zero scales without decomposing a singular matrix.\n // Use SceneObject so disposal reaches the parts.\n const display = new SceneObject();\n if (this.options.displayPosition) {\n const transform = DisplayTransforms.getTransform(this.originalModel.display, this.options.displayPosition);\n display.position.copy(transform.position);\n display.quaternion.copy(transform.quaternion);\n display.scale.copy(transform.scale);\n }\n this.add(display);\n const offset = new Matrix4().makeTranslation(-8, -8, -8);\n try {\n const targets: { mesh: Mesh; parent?: Mesh }[] = [];\n for (const part of parts) {\n const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe, tints: part.tints, faces: part.faces });\n object.matrix.multiplyMatrices(offset, part.transform).decompose(object.position, object.quaternion, object.scale);\n display.add(object);\n await object.init(part.material);\n object.iterateAllMeshes(mesh => {\n const source = mesh.material as MeshBasicMaterial;\n let material = this.specialMaterials.get(source);\n if (!material) {\n const front = this.options.displayPosition === DisplayPosition.GUI &&\n (this.originalModel as ItemModel).gui_light === GuiLight.FRONT;\n material = SpecialItems.createMaterial(source, !front);\n // Entity geometry already contains the inward faces used by vanilla's translucent draw.\n if (part.material) material.side = FrontSide;\n this.specialMaterials.set(source, material);\n }\n mesh.material = material;\n });\n for (const [name, rotation] of Object.entries(part.rotations)) {\n object.getGroupByName(name)?.rotation.set(...rotation, \"ZYX\");\n }\n for (const [name, position] of Object.entries(part.positions ?? {})) {\n object.getGroupByName(name)?.position.set(...position);\n }\n if (this.hasGlint) {\n if (special.type === \"shield\" || special.type === \"minecraft:shield\") {\n const mesh = object.getMeshByName(\"plate\", \"main\")!;\n const layers = Object.keys(part.model.layers!);\n if (part.model.layers!.pattern_base) targets.push({ mesh: object.getMeshByName(\"handle\", \"main\")! });\n // Follow the final plate draw so GUI and composite ordering keeps glint above the patterns.\n targets.push({ mesh, parent: object.getMeshByName(\"plate\", layers[layers.length - 1])! });\n } else {\n object.iterateAllMeshes(mesh => targets.push({ mesh }));\n }\n }\n }\n if (targets.length) {\n this.glint = await ItemGlint.create(this, undefined, this.originalModel.key?.root, targets);\n this.updateAnimationSubscription();\n }\n } catch (error) {\n this.disposeAndRemoveAllChildren();\n throw error;\n }\n this.notifyDirty();\n return;\n }\n try {\n // Load the atlas before creating geometry so every pass uses the mapped UVs.\n await this.loadTextures();\n this.createMeshes();\n this.applyTextures();\n if (this.hasGlint && this.atlasTexture) {\n this.glint = await ItemGlint.create(this, this.atlasTexture, this.originalModel.key?.root);\n this.updateAnimationSubscription();\n }\n } catch (error) {\n this.disposeAndRemoveAllChildren();\n throw error;\n }\n }\n\n public get textureAtlas(): Maybe<TextureAtlas> {\n return this.atlas;\n }\n\n public get isOpaqueFullCube(): boolean {\n return !this.options.displayPosition && ModelCulling.isOpaqueFullCube(this.atlas);\n }\n\n //TODO: support for replacing textures\n\n protected async loadTextures(): Promise<void> {\n this.atlas = await UVMapper.getAtlas(this.originalModel);\n }\n\n\n protected createMeshes(force: boolean = false) {\n if (this.meshesCreated && !force) return;\n\n const mat = Materials.MISSING_TEXTURE;\n const displayTransform = this.options.displayPosition\n ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : undefined;\n\n let allGeos: BufferGeometry[] = [];\n\n if (this.atlas) {\n if (this.atlas.model.elements) {\n this.atlas.model.elements?.forEach(el => {\n const elGeo = this._getBoxGeometryFromElement(el).clone();\n this.geometries.add(elGeo);\n if (this.options.cullMask) {\n const indices = Array.from(elGeo.getIndex()!.array);\n elGeo.setIndex(indices.filter((_, index) => {\n const face = CUBE_FACES[Math.floor(index / 6)];\n const direction = CUBE_FACES.findIndex(name => name === el.faces[face]?.cullface);\n return direction < 0 || !(this.options.cullMask! & (1 << direction));\n }));\n elGeo.clearGroups();\n }\n if (this.options.uvLockRotation) {\n UVMapper.lockUvs(elGeo, el.faces, this.atlas!, new Euler(...this.options.uvLockRotation));\n }\n UVMapper.setAtlasUvBounds(elGeo, el.faces, this.atlas!);\n if (this.options.tints) {\n const colors = new Float32Array(elGeo.getAttribute(\"position\").count * 3).fill(1);\n for (const [faceIndex, faceName] of CUBE_FACES.entries()) {\n const tintIndex = el.faces[faceName]?.tintindex;\n if (tintIndex === undefined || tintIndex < 0) continue;\n const tint = this.options.tints[tintIndex];\n if (tint === undefined) continue;\n const color = new Color(tint);\n for (let vertex = 0; vertex < 4; vertex++) {\n color.toArray(colors, (faceIndex * 4 + vertex) * 3);\n }\n }\n elGeo.setAttribute(\"color\", new BufferAttribute(colors, 3));\n }\n\n // elGeo.applyMatrix4(new THREE.Matrix4().makeTranslation(-8,-8,-8));\n\n\n elGeo.applyMatrix4(new Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));\n elGeo.applyMatrix4(new Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));\n\n if (el.rotation) {\n applyElementRotation(el.rotation, elGeo);\n }\n if (this.hasGlint) ItemGlint.mapUvs(elGeo, el.faces, this.atlas!, (this.originalModel as ItemModel).itemId, this.options.displayPosition);\n\n elGeo.applyMatrix4(new Matrix4().makeTranslation(-8, -8, -8));\n if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);\n\n if (this.options.mergeMeshes) {\n allGeos.push(elGeo);\n } else {\n const mesh = this.createAndAddMesh(undefined, undefined, elGeo, mat);\n if (this.options.wireframe) {\n addWireframeToMesh(elGeo, mesh);\n }\n }\n });\n } else {\n console.debug(p, this.atlas.model, \"has no elements\")\n }\n } else {\n console.debug(p, \"Missing atlas for\", this);\n }\n\n if (this.options.mergeMeshes) {\n let combinedGeo: BufferGeometry;\n if (allGeos.length > 0) {\n // if (this.options.wireframe) {\n // allGeos.push(new BoxGeometry(16, 16, 16, 1, 1, 1))\n // }\n\n combinedGeo = mergeBufferGeometries(allGeos);\n for (const geometry of allGeos) {\n this.geometries.delete(geometry);\n }\n } else {\n combinedGeo = new BoxGeometry(16, 16, 16);\n if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);\n }\n this.geometries.add(combinedGeo);\n combinedGeo.computeBoundingBox();\n // combinedGeo.translate(-8, -8, -8);\n // TODO: cache the combined geometry\n let mesh: Mesh;\n if (this.options.instanceMeshes) {\n mesh = this.createInstancedMesh(undefined, combinedGeo, mat, this.options.maxInstanceCount || 50);\n this.add(mesh);\n this._isInstanced = true;\n //TODO\n } else {\n mesh = this.createAndAddMesh(undefined, undefined, combinedGeo, mat)\n }\n if (this.options.wireframe) {\n addWireframeToMesh(combinedGeo, mesh, 0x0000ff, 4);\n addBox3WireframeToObject(combinedGeo.boundingBox!, mesh, 0x00ffff, 3);\n }\n }\n\n if (this.options.wireframe) {\n addWireframeToObject(this, 0x00ff00, 3)\n }\n\n this.meshesCreated = true;\n }\n\n\n protected applyTextures() {\n if (this.atlas) {\n const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas as HTMLCanvasElement, this.atlas.hasTranslucency, false, true);\n mat.side = this.atlas.hasTransparency ? DoubleSide : FrontSide;\n this.atlasMaterial = mat;\n this.atlasTexture = (mat as ShaderMaterial).uniforms?.map?.value ?? (mat as MeshBasicMaterial).map;\n if (this.options.displayPosition === DisplayPosition.GUI &&\n (this.originalModel as ItemModel).gui_light === GuiLight.FRONT && (mat as ShaderMaterial).uniforms?.SHADE) {\n (mat as ShaderMaterial).uniforms.SHADE.value = false;\n }\n this.iterateAllMeshes(mesh => {\n if (mesh.geometry.hasAttribute(\"color\")) mat.vertexColors = true;\n mesh.material = mat;\n });\n this.updateAnimationSubscription();\n }\n }\n\n private updateAnimationSubscription(): void {\n let root: ModelObject = this;\n while (root.parent && isModelObject(root.parent)) root = root.parent;\n const active = !!root.parent && (!this.isInstanced || this.instanceCounter > 0);\n this.glint?.updateSubscription(active);\n if (active && this.atlas?.hasAnimation && this.atlasTexture) {\n if (!this.unsubscribeAtlas) {\n this.atlasTexture.needsUpdate = true;\n this.unsubscribeAtlas = this.atlas.subscribe(() => {\n this.atlasTexture!.needsUpdate = true;\n this.traverseAncestors(parent => {\n if ((parent as MineRenderScene).isMineRenderScene) (parent as MineRenderScene).dirty = true;\n });\n this.notifyDirty();\n });\n }\n } else {\n this.unsubscribeAtlas?.();\n this.unsubscribeAtlas = undefined;\n }\n for (const child of this.children) {\n if (isModelObject(child)) child.updateAnimationSubscription();\n }\n }\n\n nextInstance() {\n const reference = super.nextInstance();\n this.updateAnimationSubscription();\n return reference;\n }\n\n removeInstanceAt(index: number): void {\n super.removeInstanceAt(index);\n this.updateAnimationSubscription();\n }\n\n public disposeAndRemoveAllChildren(): void {\n this.glint?.dispose();\n this.glint = undefined;\n this.unsubscribeAtlas?.();\n this.unsubscribeAtlas = undefined;\n this.atlasTexture?.dispose();\n this.atlasMaterial?.dispose();\n this.atlasTexture = undefined;\n this.atlasMaterial = undefined;\n for (const material of this.specialMaterials.values()) material.dispose();\n this.specialMaterials.clear();\n for (const geometry of this.geometries) geometry.dispose();\n this.geometries.clear();\n super.disposeAndRemoveAllChildren();\n }\n\n}\n\n/** Model settings passed to `scene.addModel(model, options)` or the ModelObject constructor. */\nexport interface ModelObjectOptions extends SceneObjectOptions {\n /** Minecraft display pose applied around the model center, before scene transforms. */\n displayPosition?: DisplayPosition;\n /** Quarter-turn block rotation in radians to compensate when locking UVs. */\n uvLockRotation?: TripleArray;\n /** sRGB 0xRRGGBB colors by face tint index, overriding automatic item or block preview colors. */\n tints?: Record<number, number>;\n /** Hidden neighbor directions in CUBE_FACES order, before the model's block rotation. */\n cullMask?: number;\n}\n\nexport function isModelObject(obj: any): obj is ModelObject {\n return (<ModelObject>obj).isModelObject;\n}\n"],"mappings":"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","names":["parts"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/model/scene/ModelObject.ts"],"sourcesContent":["import { SceneObject } from \"../../renderer/SceneObject\";\nimport { ItemModel, Model, TextureAsset, TripleArray } from \"../Model\";\nimport { Materials } from \"../../Materials\";\nimport { Maybe, toRadians } from \"../../util/util\";\nimport { UVMapper } from \"../../UVMapper\";\nimport { TextureAtlas } from \"../../texture/TextureAtlas\";\nimport { BoxGeometry, BoxHelper, BufferAttribute, Color, DoubleSide, EdgesGeometry, Euler, FrontSide, InstancedMesh, LineBasicMaterial, LineSegments, Material, Matrix4, Mesh, MeshBasicMaterial, MeshStandardMaterial, ShaderMaterial } from \"three\";\nimport { mergeBufferGeometries } from \"../../three/BufferGeometryUtils\";\nimport { SceneObjectOptions } from \"../../renderer/SceneObjectOptions\";\nimport { addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation } from \"../../util/model\";\nimport { merge } from \"../../util/_internal/merge\";\nimport type { BufferGeometry, Texture } from \"three\";\nimport { BlockObject } from \"../block/scene/BlockObject\";\nimport { prefix } from \"../../util/log\";\nimport { CUBE_FACES } from \"../../CubeFace\";\nimport { DisplayPosition } from \"../DisplayPosition\";\nimport { DisplayTransforms } from \"../DisplayTransforms\";\nimport { ModelCulling } from \"../ModelCulling\";\nimport type { MineRenderScene } from \"../../renderer/MineRenderScene\";\nimport { SpecialItems } from \"../SpecialItems\";\nimport { EntityObject } from \"../../entity/scene/EntityObject\";\nimport { GuiLight } from \"../GuiLight\";\nimport { ItemTints } from \"../ItemTints\";\nimport { ItemGlint } from \"../ItemGlint\";\n\n\nconst p = prefix(\"ModelObject\");\n\n//TODO: might want to abstract this out into a generic model, and create a separate class for Block models\n/** Builds render geometry from a merged Java model. Create it through {@link MineRenderScene.addModel}. */\nexport class ModelObject extends SceneObject {\n\n public readonly isModelObject: true = true;\n\n public static readonly DEFAULT_OPTIONS: ModelObjectOptions = merge({}, SceneObject.DEFAULT_OPTIONS, <ModelObjectOptions>{});\n public readonly options: ModelObjectOptions;\n\n protected atlas?: TextureAtlas;\n private atlasMaterial?: Material;\n private atlasTexture?: Texture;\n private unsubscribeAtlas?: () => void;\n private readonly specialMaterials = new Map<Material, Material>();\n private readonly geometries = new Set<BufferGeometry>();\n private readonly hasGlint: boolean;\n private glint?: ItemGlint;\n\n public blockParent: Maybe<BlockObject>;\n\n private meshesCreated: boolean = false;\n\n constructor(readonly originalModel: Model, options?: Partial<ModelObjectOptions>) {\n super(options);\n this.options = merge({}, ModelObject.DEFAULT_OPTIONS, options ?? {});\n const item = originalModel as ItemModel;\n const specialType = item.special?.type.replace(/^minecraft:/, \"\");\n this.hasGlint = !item.parts && (!item.special || specialType === \"shield\" || specialType === \"trident\") && ItemGlint.enabled(item.components, item.itemId);\n if (item.special || item.parts || this.hasGlint) this.options.instanceMeshes = false;\n if (this.options.tints) this.options.tints = { ...this.options.tints };\n this.addEventListener(\"added\", () => this.updateAnimationSubscription());\n this.addEventListener(\"removed\", () => this.updateAnimationSubscription());\n }\n\n async init(): Promise<void> {\n const parts = (this.originalModel as ItemModel).parts;\n if (parts) {\n try {\n for (const part of parts) {\n const object = new ModelObject(part, { ...this.options, instanceMeshes: false });\n this.add(object);\n await object.init();\n }\n let order = 0;\n this.iterateAllMeshes(mesh => {\n mesh.renderOrder = order++;\n // Keep composite children in one render pass so their declared order is retained.\n for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {\n material.transparent = true;\n }\n });\n } catch (error) {\n this.disposeAndRemoveAllChildren();\n throw error;\n }\n this.notifyDirty();\n return;\n }\n this.options.tints = await ItemTints.get(this.originalModel, this.options.tints);\n const special = (this.originalModel as ItemModel).special;\n if (special) {\n const parts = await SpecialItems.getParts(special, this.originalModel.key?.root, (this.originalModel as ItemModel).components);\n // A separate display node preserves zero scales without decomposing a singular matrix.\n // Use SceneObject so disposal reaches the parts.\n const display = new SceneObject();\n if (this.options.displayPosition) {\n const transform = DisplayTransforms.getTransform(this.originalModel.display, this.options.displayPosition);\n display.position.copy(transform.position);\n display.quaternion.copy(transform.quaternion);\n display.scale.copy(transform.scale);\n }\n this.add(display);\n const offset = new Matrix4().makeTranslation(-8, -8, -8);\n try {\n const targets: { mesh: Mesh; parent?: Mesh }[] = [];\n for (const part of parts) {\n const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe, tints: part.tints, faces: part.faces });\n object.matrix.multiplyMatrices(offset, part.transform).decompose(object.position, object.quaternion, object.scale);\n display.add(object);\n await object.init(part.material);\n object.iterateAllMeshes(mesh => {\n const source = mesh.material as MeshBasicMaterial;\n let material = this.specialMaterials.get(source);\n if (!material) {\n const front = this.options.displayPosition === DisplayPosition.GUI &&\n (this.originalModel as ItemModel).gui_light === GuiLight.FRONT;\n material = SpecialItems.createMaterial(source, !front);\n // Entity geometry already contains the inward faces used by vanilla's translucent draw.\n if (part.material) material.side = FrontSide;\n this.specialMaterials.set(source, material);\n }\n mesh.material = material;\n });\n for (const [name, rotation] of Object.entries(part.rotations)) {\n object.getGroupByName(name)?.rotation.set(...rotation, \"ZYX\");\n }\n for (const [name, position] of Object.entries(part.positions ?? {})) {\n object.getGroupByName(name)?.position.set(...position);\n }\n if (this.hasGlint) {\n if (special.type === \"shield\" || special.type === \"minecraft:shield\") {\n const mesh = object.getMeshByName(\"plate\", \"main\")!;\n const layers = Object.keys(part.model.layers!);\n if (part.model.layers!.pattern_base) targets.push({ mesh: object.getMeshByName(\"handle\", \"main\")! });\n // Follow the final plate draw so GUI and composite ordering keeps glint above the patterns.\n targets.push({ mesh, parent: object.getMeshByName(\"plate\", layers[layers.length - 1])! });\n } else {\n object.iterateAllMeshes(mesh => targets.push({ mesh }));\n }\n }\n }\n if (targets.length) {\n this.glint = await ItemGlint.create(this, undefined, this.originalModel.key?.root, targets);\n this.updateAnimationSubscription();\n }\n } catch (error) {\n this.disposeAndRemoveAllChildren();\n throw error;\n }\n this.notifyDirty();\n return;\n }\n try {\n // Load the atlas before creating geometry so every pass uses the mapped UVs.\n await this.loadTextures();\n this.createMeshes();\n this.applyTextures();\n if (this.hasGlint && this.atlasTexture) {\n this.glint = await ItemGlint.create(this, this.atlasTexture, this.originalModel.key?.root);\n this.updateAnimationSubscription();\n }\n } catch (error) {\n this.disposeAndRemoveAllChildren();\n throw error;\n }\n }\n\n public get textureAtlas(): Maybe<TextureAtlas> {\n return this.atlas;\n }\n\n public get isOpaqueFullCube(): boolean {\n return !this.options.displayPosition && ModelCulling.isOpaqueFullCube(this.atlas);\n }\n\n //TODO: support for replacing textures\n\n protected async loadTextures(): Promise<void> {\n this.atlas = await UVMapper.getAtlas(this.originalModel);\n }\n\n\n protected createMeshes(force: boolean = false) {\n if (this.meshesCreated && !force) return;\n\n const mat = Materials.MISSING_TEXTURE;\n const displayTransform = this.options.displayPosition\n ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : undefined;\n\n let allGeos: BufferGeometry[] = [];\n\n if (this.atlas) {\n if (this.atlas.model.elements) {\n this.atlas.model.elements?.forEach(el => {\n const elGeo = this._getBoxGeometryFromElement(el).clone();\n this.geometries.add(elGeo);\n elGeo.setAttribute(\"shade\", new BufferAttribute(\n new Float32Array(elGeo.getAttribute(\"position\").count).fill(!(this.originalModel as ItemModel).itemId && el.shade === false ? 0 : 1), 1));\n if (this.options.cullMask) {\n const indices = Array.from(elGeo.getIndex()!.array);\n elGeo.setIndex(indices.filter((_, index) => {\n const face = CUBE_FACES[Math.floor(index / 6)];\n const direction = CUBE_FACES.findIndex(name => name === el.faces[face]?.cullface);\n return direction < 0 || !(this.options.cullMask! & (1 << direction));\n }));\n elGeo.clearGroups();\n }\n if (this.options.uvLockRotation) {\n UVMapper.lockUvs(elGeo, el.faces, this.atlas!, new Euler(...this.options.uvLockRotation));\n }\n UVMapper.setAtlasUvBounds(elGeo, el.faces, this.atlas!);\n if (this.options.tints) {\n const colors = new Float32Array(elGeo.getAttribute(\"position\").count * 3).fill(1);\n for (const [faceIndex, faceName] of CUBE_FACES.entries()) {\n const tintIndex = el.faces[faceName]?.tintindex;\n if (tintIndex === undefined || tintIndex < 0) continue;\n const tint = this.options.tints[tintIndex];\n if (tint === undefined) continue;\n const color = new Color(tint);\n for (let vertex = 0; vertex < 4; vertex++) {\n color.toArray(colors, (faceIndex * 4 + vertex) * 3);\n }\n }\n elGeo.setAttribute(\"color\", new BufferAttribute(colors, 3));\n }\n\n // elGeo.applyMatrix4(new THREE.Matrix4().makeTranslation(-8,-8,-8));\n\n\n elGeo.applyMatrix4(new Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));\n elGeo.applyMatrix4(new Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));\n\n if (el.rotation) {\n applyElementRotation(el.rotation, elGeo);\n }\n if (this.hasGlint) ItemGlint.mapUvs(elGeo, el.faces, this.atlas!, (this.originalModel as ItemModel).itemId, this.options.displayPosition);\n\n elGeo.applyMatrix4(new Matrix4().makeTranslation(-8, -8, -8));\n if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);\n\n if (this.options.mergeMeshes) {\n allGeos.push(elGeo);\n } else {\n const mesh = this.createAndAddMesh(undefined, undefined, elGeo, mat);\n if (this.options.wireframe) {\n addWireframeToMesh(elGeo, mesh);\n }\n }\n });\n } else {\n console.debug(p, this.atlas.model, \"has no elements\")\n }\n } else {\n console.debug(p, \"Missing atlas for\", this);\n }\n\n if (this.options.mergeMeshes) {\n let combinedGeo: BufferGeometry;\n if (allGeos.length > 0) {\n // if (this.options.wireframe) {\n // allGeos.push(new BoxGeometry(16, 16, 16, 1, 1, 1))\n // }\n\n combinedGeo = mergeBufferGeometries(allGeos);\n for (const geometry of allGeos) {\n this.geometries.delete(geometry);\n }\n } else {\n combinedGeo = new BoxGeometry(16, 16, 16);\n if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);\n }\n this.geometries.add(combinedGeo);\n combinedGeo.computeBoundingBox();\n // combinedGeo.translate(-8, -8, -8);\n // TODO: cache the combined geometry\n let mesh: Mesh;\n if (this.options.instanceMeshes) {\n mesh = this.createInstancedMesh(undefined, combinedGeo, mat, this.options.maxInstanceCount || 50);\n this.add(mesh);\n this._isInstanced = true;\n //TODO\n } else {\n mesh = this.createAndAddMesh(undefined, undefined, combinedGeo, mat)\n }\n if (this.options.wireframe) {\n addWireframeToMesh(combinedGeo, mesh, 0x0000ff, 4);\n addBox3WireframeToObject(combinedGeo.boundingBox!, mesh, 0x00ffff, 3);\n }\n }\n\n if (this.options.wireframe) {\n addWireframeToObject(this, 0x00ff00, 3)\n }\n\n this.meshesCreated = true;\n }\n\n\n protected applyTextures() {\n if (this.atlas) {\n const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas as HTMLCanvasElement, this.atlas.hasTranslucency, false, true);\n mat.side = this.atlas.hasTransparency ? DoubleSide : FrontSide;\n this.atlasMaterial = mat;\n this.atlasTexture = (mat as ShaderMaterial).uniforms?.map?.value ?? (mat as MeshBasicMaterial).map;\n if (this.options.displayPosition === DisplayPosition.GUI &&\n (this.originalModel as ItemModel).gui_light === GuiLight.FRONT && (mat as ShaderMaterial).uniforms?.SHADE) {\n (mat as ShaderMaterial).uniforms.SHADE.value = false;\n }\n this.iterateAllMeshes(mesh => {\n if (mesh.geometry.hasAttribute(\"color\")) mat.vertexColors = true;\n mesh.material = mat;\n });\n this.updateAnimationSubscription();\n }\n }\n\n private updateAnimationSubscription(): void {\n let root: ModelObject = this;\n while (root.parent && isModelObject(root.parent)) root = root.parent;\n const active = !!root.parent && (!this.isInstanced || this.instanceCounter > 0);\n this.glint?.updateSubscription(active);\n if (active && this.atlas?.hasAnimation && this.atlasTexture) {\n if (!this.unsubscribeAtlas) {\n this.atlasTexture.needsUpdate = true;\n this.unsubscribeAtlas = this.atlas.subscribe(() => {\n this.atlasTexture!.needsUpdate = true;\n this.traverseAncestors(parent => {\n if ((parent as MineRenderScene).isMineRenderScene) (parent as MineRenderScene).dirty = true;\n });\n this.notifyDirty();\n });\n }\n } else {\n this.unsubscribeAtlas?.();\n this.unsubscribeAtlas = undefined;\n }\n for (const child of this.children) {\n if (isModelObject(child)) child.updateAnimationSubscription();\n }\n }\n\n nextInstance() {\n const reference = super.nextInstance();\n this.updateAnimationSubscription();\n return reference;\n }\n\n removeInstanceAt(index: number): void {\n super.removeInstanceAt(index);\n this.updateAnimationSubscription();\n }\n\n public disposeAndRemoveAllChildren(): void {\n this.glint?.dispose();\n this.glint = undefined;\n this.unsubscribeAtlas?.();\n this.unsubscribeAtlas = undefined;\n this.atlasTexture?.dispose();\n this.atlasMaterial?.dispose();\n this.atlasTexture = undefined;\n this.atlasMaterial = undefined;\n for (const material of this.specialMaterials.values()) material.dispose();\n this.specialMaterials.clear();\n for (const geometry of this.geometries) geometry.dispose();\n this.geometries.clear();\n super.disposeAndRemoveAllChildren();\n }\n\n}\n\n/** Model settings passed to `scene.addModel(model, options)` or the ModelObject constructor. */\nexport interface ModelObjectOptions extends SceneObjectOptions {\n /** Minecraft display pose applied around the model center, before scene transforms. */\n displayPosition?: DisplayPosition;\n /** Quarter-turn block rotation in radians to compensate when locking UVs. */\n uvLockRotation?: TripleArray;\n /** sRGB 0xRRGGBB colors by face tint index, overriding automatic item or block preview colors. */\n tints?: Record<number, number>;\n /** Hidden neighbor directions in CUBE_FACES order, before the model's block rotation. */\n cullMask?: number;\n}\n\nexport function isModelObject(obj: any): obj is ModelObject {\n return (<ModelObject>obj).isModelObject;\n}\n"],"mappings":"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","names":["parts"]}
|
|
@@ -21,7 +21,7 @@ function buildSectionGeometry(input) {
|
|
|
21
21
|
const cornerBrightness = ambientOcclusion ? new Float32Array(4) : void 0;
|
|
22
22
|
for (const template of templateData) {
|
|
23
23
|
const { quads } = template;
|
|
24
|
-
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) {
|
|
24
|
+
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.shade && template.shade.length !== quads * 4 || template.biomeTint && template.biomeTint.length !== quads) {
|
|
25
25
|
throw new RangeError("Section template arrays do not match its quad count");
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -112,6 +112,7 @@ function buildSectionGeometry(input) {
|
|
|
112
112
|
}
|
|
113
113
|
const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
|
|
114
114
|
const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
|
|
115
|
+
const shade = new Float32Array(faces * 4).fill(1);
|
|
115
116
|
const outputIndices = new Uint32Array(faces * 6);
|
|
116
117
|
const blockIndices = new Uint16Array(faces);
|
|
117
118
|
let vertex = 0, indexOffset = 0;
|
|
@@ -141,6 +142,7 @@ function buildSectionGeometry(input) {
|
|
|
141
142
|
normals[vertex * 3] = template.normals[source * 3];
|
|
142
143
|
normals[vertex * 3 + 1] = template.normals[source * 3 + 1];
|
|
143
144
|
normals[vertex * 3 + 2] = template.normals[source * 3 + 2];
|
|
145
|
+
shade[vertex] = template.shade?.[source] ?? 1;
|
|
144
146
|
uvs[vertex * 2] = mapU(template.uvs[source * 2]);
|
|
145
147
|
uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);
|
|
146
148
|
uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);
|
|
@@ -193,11 +195,11 @@ function buildSectionGeometry(input) {
|
|
|
193
195
|
indexOffset += 6;
|
|
194
196
|
}
|
|
195
197
|
}
|
|
196
|
-
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
|
|
198
|
+
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };
|
|
197
199
|
});
|
|
198
200
|
}
|
|
199
201
|
function sectionGeometryTransferables(pages) {
|
|
200
|
-
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]);
|
|
202
|
+
return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.shade.buffer, page.indices.buffer, page.blockIndices.buffer]);
|
|
201
203
|
}
|
|
202
204
|
export {
|
|
203
205
|
buildSectionGeometry,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/world/SectionGeometry.ts"],"sourcesContent":["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"],"mappings":"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","names":["page"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/world/SectionGeometry.ts"],"sourcesContent":["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 shade?: 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 shade: 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.shade && template.shade.length !== quads * 4) ||\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 shade = new Float32Array(faces * 4).fill(1);\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 shade[vertex] = template.shade?.[source] ?? 1;\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, shade, 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.shade.buffer, page.indices.buffer, page.blockIndices.buffer]);\n}\n"],"mappings":"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","names":["page"]}
|
|
@@ -51,6 +51,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
51
51
|
uvs: new Float32Array(quads * 8),
|
|
52
52
|
uvBounds: new Float32Array(quads * 16),
|
|
53
53
|
colors: new Float32Array(quads * 12),
|
|
54
|
+
shade: new Float32Array(quads * 4),
|
|
54
55
|
indices: new Uint16Array(quads * 6),
|
|
55
56
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
56
57
|
biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
|
|
@@ -62,6 +63,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
62
63
|
const uv = template.geometry.getAttribute("uv");
|
|
63
64
|
const bounds = template.geometry.getAttribute("uvBounds");
|
|
64
65
|
const color = template.geometry.getAttribute("color");
|
|
66
|
+
const shade = template.geometry.getAttribute("shade");
|
|
65
67
|
for (let vertex = 0; vertex < quads * 4; vertex++) {
|
|
66
68
|
data.positions.set([position.getX(vertex), position.getY(vertex), position.getZ(vertex)], vertex * 3);
|
|
67
69
|
data.normals.set([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)], vertex * 3);
|
|
@@ -73,6 +75,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
73
75
|
bounds?.getW(vertex) ?? 1
|
|
74
76
|
], vertex * 4);
|
|
75
77
|
data.colors.set([color?.getX(vertex) ?? 1, color?.getY(vertex) ?? 1, color?.getZ(vertex) ?? 1], vertex * 3);
|
|
78
|
+
data.shade[vertex] = shade?.getX(vertex) ?? 1;
|
|
76
79
|
}
|
|
77
80
|
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) - 4 * Math.floor(i2 / 6);
|
|
78
81
|
templateCache.set(template, data);
|
|
@@ -144,6 +147,7 @@ var SectionMesh = class _SectionMesh extends Group {
|
|
|
144
147
|
geometry.setAttribute("uv", new Float32BufferAttribute(page.uvs.buffer, 2));
|
|
145
148
|
geometry.setAttribute("uvBounds", new Float32BufferAttribute(page.uvBounds.buffer, 4));
|
|
146
149
|
geometry.setAttribute("color", new Float32BufferAttribute(page.colors.buffer, 3));
|
|
150
|
+
geometry.setAttribute("shade", new Float32BufferAttribute(page.shade.buffer, 1));
|
|
147
151
|
geometry.setIndex(new Uint32BufferAttribute(page.indices.buffer, 1));
|
|
148
152
|
geometry.computeBoundingBox();
|
|
149
153
|
geometry.computeBoundingSphere();
|