minerender 2.1.0-beta.5 → 2.1.0-beta.6
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/Fonts.mjs +31 -4
- package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs +166 -0
- package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs +12 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
- package/dist/browser/esm/cache/Caching.mjs +2 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs +62 -11
- package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityObject.mjs +53 -20
- package/dist/browser/esm/entity/scene/EntityObject.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/gui/GuiText.mjs +4 -3
- package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +52 -10
- 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/util/model.mjs +7 -7
- package/dist/browser/esm/util/model.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/index.d.ts +52 -10
- package/dist/browser/index.js +382 -73
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +425 -73
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +52 -10
- package/dist/node/index.d.ts +52 -10
- package/dist/node/index.js +387 -73
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +386 -73
- 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"]}
|
|
@@ -8,6 +8,7 @@ async function layoutGuiText(text, options = {}) {
|
|
|
8
8
|
}
|
|
9
9
|
const font = await Fonts.get(options.font);
|
|
10
10
|
const runs = typeof text === "string" ? [{ text }] : text;
|
|
11
|
+
await font.resolve?.(runs.map((run) => run.text).join(""));
|
|
11
12
|
const glyphs = [], lineWidths = [];
|
|
12
13
|
let line = [], width = 0;
|
|
13
14
|
let trailingNewline = false;
|
|
@@ -34,7 +35,7 @@ async function layoutGuiText(text, options = {}) {
|
|
|
34
35
|
continue;
|
|
35
36
|
}
|
|
36
37
|
const glyph = font.glyphs.get(character);
|
|
37
|
-
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
38
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
|
|
38
39
|
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
39
40
|
width += advance;
|
|
40
41
|
while (width > maxWidth && line.length > 1) {
|
|
@@ -62,7 +63,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
62
63
|
batches.push(batch);
|
|
63
64
|
}
|
|
64
65
|
const color = new Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
65
|
-
const offset = isShadow ? 1 : 0;
|
|
66
|
+
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
66
67
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
67
68
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
68
69
|
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
@@ -92,7 +93,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
92
93
|
for (let i = 0; i < 4; i++) batch.colors.push(color.r, color.g, color.b);
|
|
93
94
|
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
94
95
|
};
|
|
95
|
-
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
96
|
+
for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
|
|
96
97
|
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
97
98
|
else {
|
|
98
99
|
quad(0, 0, 5, 1, boldOffset);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/gui/GuiText.ts"],"sourcesContent":["import { BufferGeometry, Color, Float32BufferAttribute } from \"three\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport { Fonts, type BitmapGlyph } from \"../assets/Fonts\";\nimport type { CompatCanvas } from \"../canvas/CanvasCompat\";\n\n/** Text appearance set on a GUI text layer or overridden by an individual text run. */\nexport interface GuiTextStyle {\n /** sRGB 0xRRGGBB; defaults to white. */\n color?: number;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A text segment with optional style overrides within {@link GuiText}. */\nexport interface GuiTextRun extends GuiTextStyle {\n text: string;\n}\n\n/** Literal text, or styled runs. Newlines are preserved. */\nexport type GuiText = string | readonly GuiTextRun[];\n\n/** Text layout settings set on a GUI text layer or passed to {@link layoutGuiText}. */\nexport interface GuiTextOptions extends GuiTextStyle {\n /** Font resource ID; defaults to minecraft:default. */\n font?: AssetKey | string;\n /** Draws a one-pixel shadow; defaults to true. */\n shadow?: boolean;\n /** Wrap width in GUI pixels. Long words break at glyph boundaries. */\n maxWidth?: number;\n /** Distance between line origins; defaults to 9 GUI pixels. */\n lineHeight?: number;\n}\n\n/** One measured glyph and its position in GUI pixels, produced by {@link layoutGuiText}. */\nexport interface PositionedGuiGlyph {\n character: string;\n glyph?: BitmapGlyph;\n x: number;\n y: number;\n advance: number;\n style: Required<GuiTextStyle>;\n}\n\n/** Measured glyphs, line widths, and overall dimensions in GUI pixels. */\nexport interface GuiTextLayout {\n glyphs: PositionedGuiGlyph[];\n lineWidths: number[];\n width: number;\n height: number;\n}\n\n/** Measures and wraps text using the same glyph advances used for rendering. */\nexport async function layoutGuiText(text: GuiText, options: GuiTextOptions = {}): Promise<GuiTextLayout> {\n const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;\n if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {\n throw new Error(\"Text wrap width and line height must be positive\");\n }\n const font = await Fonts.get(options.font);\n const runs = typeof text === \"string\" ? [{ text }] : text;\n const glyphs: PositionedGuiGlyph[] = [], lineWidths: number[] = [];\n let line: PositionedGuiGlyph[] = [], width = 0;\n let trailingNewline = false;\n const finishLine = (entries: PositionedGuiGlyph[]) => {\n let x = 0;\n for (const entry of entries) {\n glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });\n x += entry.advance;\n }\n lineWidths.push(x);\n };\n for (const run of runs) {\n const style = { color: run.color ?? options.color ?? 0xffffff,\n bold: run.bold ?? options.bold ?? false, italic: run.italic ?? options.italic ?? false };\n for (const character of run.text.replace(/\\r\\n?/g, \"\\n\")) {\n trailingNewline = character === \"\\n\";\n if (character === \"\\n\") {\n finishLine(line); line = []; width = 0;\n continue;\n }\n const glyph = font.glyphs.get(character);\n const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);\n line.push({ character, glyph, advance, style, x: 0, y: 0 });\n width += advance;\n while (width > maxWidth && line.length > 1) {\n let space = -1;\n for (let i = 0; i < line.length; i++) if (line[i].character === \" \") space = i;\n const split = space >= 0 ? space : line.length - 1;\n if (split > 0) finishLine(line.slice(0, split));\n line = line.slice(split + (space >= 0 ? 1 : 0));\n width = line.reduce((sum, entry) => sum + entry.advance, 0);\n }\n }\n }\n if (line.length || !lineWidths.length || trailingNewline) finishLine(line);\n return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };\n}\n\n/** Creates glyph batches in painter order. Unsupported characters use an outlined missing glyph. */\nexport function createGuiTextGeometry(layout: GuiTextLayout, shadow = true): { image?: CompatCanvas; geometry: BufferGeometry }[] {\n interface Batch { image?: CompatCanvas; positions: number[]; uvs: number[]; colors: number[]; indices: number[]; }\n const batches: Batch[] = [];\n for (const isShadow of shadow ? [true, false] : [false]) {\n let batch: Batch | undefined;\n for (const entry of layout.glyphs) {\n const { glyph, style } = entry;\n if (glyph && !glyph.image) continue;\n if (!batch || batch.image !== glyph?.image) {\n batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };\n batches.push(batch);\n }\n const color = new Color(isShadow ? (style.color & 0xfcfcfc) >> 2 : style.color);\n const offset = isShadow ? 1 : 0;\n const top = glyph ? 7 - glyph.ascent : 0;\n const height = glyph ? glyph.height * glyph.scale : 8;\n const width = glyph ? glyph.width * glyph.scale : 5;\n const shear = (y: number) => style.italic ? 1 - 0.25 * y : 0;\n const quad = (left: number, upper: number, right: number, lower: number, boldOffset: number) => {\n const base = batch!.positions.length / 3;\n const x = entry.x + offset + boldOffset, y = entry.y + offset;\n batch!.positions.push(x + left + shear(upper), -y - upper, 0, x + right + shear(upper), -y - upper, 0,\n x + left + shear(lower), -y - lower, 0, x + right + shear(lower), -y - lower, 0);\n const u0 = glyph ? glyph.x / glyph.image!.width : 0;\n const u1 = glyph ? (glyph.x + glyph.width) / glyph.image!.width : 1;\n const v0 = glyph ? 1 - glyph.y / glyph.image!.height : 1;\n const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image!.height : 0;\n batch!.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);\n for (let i = 0; i < 4; i++) batch!.colors.push(color.r, color.g, color.b);\n batch!.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);\n };\n for (const boldOffset of style.bold ? [0, 1] : [0]) {\n if (glyph) quad(0, top, width, top + height, boldOffset);\n else {\n quad(0, 0, 5, 1, boldOffset); quad(0, 7, 5, 8, boldOffset);\n quad(0, 1, 1, 7, boldOffset); quad(4, 1, 5, 7, boldOffset);\n }\n }\n }\n }\n return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setAttribute(\"uv\", new Float32BufferAttribute(uvs, 2))\n .setAttribute(\"color\", new Float32BufferAttribute(colors, 3))\n .setIndex(indices) }));\n}\n"],"mappings":";AAAA,SAAS,gBAAgB,OAAO,8BAA8B;AAE9D,SAAS,aAA+B;AAkDxC,eAAsB,cAAc,MAAe,UAA0B,CAAC,GAA2B;AACrG,QAAM,WAAW,QAAQ,YAAY,UAAU,aAAa,QAAQ,cAAc;AAClF,MAAI,EAAE,WAAW,MAAM,CAAC,OAAO,SAAS,UAAU,KAAK,cAAc,GAAG;AACpE,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACtE;AACA,QAAM,OAAO,MAAM,MAAM,IAAI,QAAQ,IAAI;AACzC,QAAM,OAAO,OAAO,SAAS,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI;AACrD,QAAM,SAA+B,CAAC,GAAG,aAAuB,CAAC;AACjE,MAAI,OAA6B,CAAC,GAAG,QAAQ;AAC7C,MAAI,kBAAkB;AACtB,QAAM,aAAa,CAAC,YAAkC;AAClD,QAAI,IAAI;AACR,eAAW,SAAS,SAAS;AACzB,aAAO,KAAK,EAAE,GAAG,OAAO,GAAG,GAAG,WAAW,SAAS,WAAW,CAAC;AAC9D,WAAK,MAAM;AAAA,IACf;AACA,eAAW,KAAK,CAAC;AAAA,EACrB;AACA,aAAW,OAAO,MAAM;AACpB,UAAM,QAAQ;AAAA,MAAE,OAAO,IAAI,SAAS,QAAQ,SAAS;AAAA,MACjD,MAAM,IAAI,QAAQ,QAAQ,QAAQ;AAAA,MAAO,QAAQ,IAAI,UAAU,QAAQ,UAAU;AAAA,IAAM;AAC3F,eAAW,aAAa,IAAI,KAAK,QAAQ,UAAU,IAAI,GAAG;AACtD,wBAAkB,cAAc;AAChC,UAAI,cAAc,MAAM;AACpB,mBAAW,IAAI;AAAG,eAAO,CAAC;AAAG,gBAAQ;AACrC;AAAA,MACJ;AACA,YAAM,QAAQ,KAAK,OAAO,IAAI,SAAS;AACvC,YAAM,WAAW,OAAO,WAAW,MAAM,MAAM,OAAO,IAAI;AAC1D,WAAK,KAAK,EAAE,WAAW,OAAO,SAAS,OAAO,GAAG,GAAG,GAAG,EAAE,CAAC;AAC1D,eAAS;AACT,aAAO,QAAQ,YAAY,KAAK,SAAS,GAAG;AACxC,YAAI,QAAQ;AACZ,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,KAAI,KAAK,CAAC,EAAE,cAAc,IAAK,SAAQ;AAC7E,cAAM,QAAQ,SAAS,IAAI,QAAQ,KAAK,SAAS;AACjD,YAAI,QAAQ,EAAG,YAAW,KAAK,MAAM,GAAG,KAAK,CAAC;AAC9C,eAAO,KAAK,MAAM,SAAS,SAAS,IAAI,IAAI,EAAE;AAC9C,gBAAQ,KAAK,OAAO,CAAC,KAAK,UAAU,MAAM,MAAM,SAAS,CAAC;AAAA,MAC9D;AAAA,IACJ;AAAA,EACJ;AACA,MAAI,KAAK,UAAU,CAAC,WAAW,UAAU,gBAAiB,YAAW,IAAI;AACzE,SAAO,EAAE,QAAQ,YAAY,OAAO,KAAK,IAAI,GAAG,GAAG,UAAU,GAAG,QAAQ,WAAW,SAAS,WAAW;AAC3G;AAGO,SAAS,sBAAsB,QAAuB,SAAS,MAA4D;AAE9H,QAAM,UAAmB,CAAC;AAC1B,aAAW,YAAY,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG;AACrD,QAAI;AACJ,eAAW,SAAS,OAAO,QAAQ;AAC/B,YAAM,EAAE,OAAO,MAAM,IAAI;AACzB,UAAI,SAAS,CAAC,MAAM,MAAO;AAC3B,UAAI,CAAC,SAAS,MAAM,UAAU,OAAO,OAAO;AACxC,gBAAQ,EAAE,OAAO,OAAO,OAAO,WAAW,CAAC,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,SAAS,CAAC,EAAE;AAC/E,gBAAQ,KAAK,KAAK;AAAA,MACtB;AACA,YAAM,QAAQ,IAAI,MAAM,YAAY,MAAM,QAAQ,aAAa,IAAI,MAAM,KAAK;AAC9E,YAAM,SAAS,WAAW,IAAI;AAC9B,YAAM,MAAM,QAAQ,IAAI,MAAM,SAAS;AACvC,YAAM,SAAS,QAAQ,MAAM,SAAS,MAAM,QAAQ;AACpD,YAAM,QAAQ,QAAQ,MAAM,QAAQ,MAAM,QAAQ;AAClD,YAAM,QAAQ,CAAC,MAAc,MAAM,SAAS,IAAI,OAAO,IAAI;AAC3D,YAAM,OAAO,CAAC,MAAc,OAAe,OAAe,OAAe,eAAuB;AAC5F,cAAM,OAAO,MAAO,UAAU,SAAS;AACvC,cAAM,IAAI,MAAM,IAAI,SAAS,YAAY,IAAI,MAAM,IAAI;AACvD,cAAO,UAAU;AAAA,UAAK,IAAI,OAAO,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,UAAG,IAAI,QAAQ,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,UAChG,IAAI,OAAO,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,UAAG,IAAI,QAAQ,MAAM,KAAK;AAAA,UAAG,CAAC,IAAI;AAAA,UAAO;AAAA,QAAC;AACnF,cAAM,KAAK,QAAQ,MAAM,IAAI,MAAM,MAAO,QAAQ;AAClD,cAAM,KAAK,SAAS,MAAM,IAAI,MAAM,SAAS,MAAM,MAAO,QAAQ;AAClE,cAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,MAAO,SAAS;AACvD,cAAM,KAAK,QAAQ,KAAK,MAAM,IAAI,MAAM,UAAU,MAAM,MAAO,SAAS;AACxE,cAAO,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC9C,iBAAS,IAAI,GAAG,IAAI,GAAG,IAAK,OAAO,OAAO,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AACxE,cAAO,QAAQ,KAAK,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAAA,MAC9E;AACA,iBAAW,cAAc,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG;AAChD,YAAI,MAAO,MAAK,GAAG,KAAK,OAAO,MAAM,QAAQ,UAAU;AAAA,aAClD;AACD,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AAAG,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AACzD,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AAAG,eAAK,GAAG,GAAG,GAAG,GAAG,UAAU;AAAA,QAC7D;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACA,SAAO,QAAQ,IAAI,CAAC,EAAE,OAAO,WAAW,KAAK,QAAQ,QAAQ,OAAO,EAAE,OAAO,UAAU,IAAI,eAAe,EACrG,aAAa,YAAY,IAAI,uBAAuB,WAAW,CAAC,CAAC,EACjE,aAAa,MAAM,IAAI,uBAAuB,KAAK,CAAC,CAAC,EACrD,aAAa,SAAS,IAAI,uBAAuB,QAAQ,CAAC,CAAC,EAC3D,SAAS,OAAO,EAAE,EAAE;AAC7B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/gui/GuiText.ts"],"sourcesContent":["import { BufferGeometry, Color, Float32BufferAttribute } from \"three\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport { Fonts, type BitmapGlyph } from \"../assets/Fonts\";\nimport type { CompatCanvas } from \"../canvas/CanvasCompat\";\n\n/** Text appearance set on a GUI text layer or overridden by an individual text run. */\nexport interface GuiTextStyle {\n /** sRGB 0xRRGGBB; defaults to white. */\n color?: number;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A text segment with optional style overrides within {@link GuiText}. */\nexport interface GuiTextRun extends GuiTextStyle {\n text: string;\n}\n\n/** Literal text, or styled runs. Newlines are preserved. */\nexport type GuiText = string | readonly GuiTextRun[];\n\n/** Text layout settings set on a GUI text layer or passed to {@link layoutGuiText}. */\nexport interface GuiTextOptions extends GuiTextStyle {\n /** Font resource ID; defaults to minecraft:default. */\n font?: AssetKey | string;\n /** Draws a one-pixel shadow; defaults to true. */\n shadow?: boolean;\n /** Wrap width in GUI pixels. Long words break at glyph boundaries. */\n maxWidth?: number;\n /** Distance between line origins; defaults to 9 GUI pixels. */\n lineHeight?: number;\n}\n\n/** One measured glyph and its position in GUI pixels, produced by {@link layoutGuiText}. */\nexport interface PositionedGuiGlyph {\n character: string;\n glyph?: BitmapGlyph;\n x: number;\n y: number;\n advance: number;\n style: Required<GuiTextStyle>;\n}\n\n/** Measured glyphs, line widths, and overall dimensions in GUI pixels. */\nexport interface GuiTextLayout {\n glyphs: PositionedGuiGlyph[];\n lineWidths: number[];\n width: number;\n height: number;\n}\n\n/** Measures and wraps text using the same glyph advances used for rendering. */\nexport async function layoutGuiText(text: GuiText, options: GuiTextOptions = {}): Promise<GuiTextLayout> {\n const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;\n if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {\n throw new Error(\"Text wrap width and line height must be positive\");\n }\n const font = await Fonts.get(options.font);\n const runs = typeof text === \"string\" ? [{ text }] : text;\n await font.resolve?.(runs.map(run => run.text).join(\"\"));\n const glyphs: PositionedGuiGlyph[] = [], lineWidths: number[] = [];\n let line: PositionedGuiGlyph[] = [], width = 0;\n let trailingNewline = false;\n const finishLine = (entries: PositionedGuiGlyph[]) => {\n let x = 0;\n for (const entry of entries) {\n glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });\n x += entry.advance;\n }\n lineWidths.push(x);\n };\n for (const run of runs) {\n const style = { color: run.color ?? options.color ?? 0xffffff,\n bold: run.bold ?? options.bold ?? false, italic: run.italic ?? options.italic ?? false };\n for (const character of run.text.replace(/\\r\\n?/g, \"\\n\")) {\n trailingNewline = character === \"\\n\";\n if (character === \"\\n\") {\n finishLine(line); line = []; width = 0;\n continue;\n }\n const glyph = font.glyphs.get(character);\n const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);\n line.push({ character, glyph, advance, style, x: 0, y: 0 });\n width += advance;\n while (width > maxWidth && line.length > 1) {\n let space = -1;\n for (let i = 0; i < line.length; i++) if (line[i].character === \" \") space = i;\n const split = space >= 0 ? space : line.length - 1;\n if (split > 0) finishLine(line.slice(0, split));\n line = line.slice(split + (space >= 0 ? 1 : 0));\n width = line.reduce((sum, entry) => sum + entry.advance, 0);\n }\n }\n }\n if (line.length || !lineWidths.length || trailingNewline) finishLine(line);\n return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };\n}\n\n/** Creates glyph batches in painter order. Unsupported characters use an outlined missing glyph. */\nexport function createGuiTextGeometry(layout: GuiTextLayout, shadow = true): { image?: CompatCanvas; geometry: BufferGeometry }[] {\n interface Batch { image?: CompatCanvas; positions: number[]; uvs: number[]; colors: number[]; indices: number[]; }\n const batches: Batch[] = [];\n for (const isShadow of shadow ? [true, false] : [false]) {\n let batch: Batch | undefined;\n for (const entry of layout.glyphs) {\n const { glyph, style } = entry;\n if (glyph && !glyph.image) continue;\n if (!batch || batch.image !== glyph?.image) {\n batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };\n batches.push(batch);\n }\n const color = new Color(isShadow ? (style.color & 0xfcfcfc) >> 2 : style.color);\n const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;\n const top = glyph ? 7 - glyph.ascent : 0;\n const height = glyph ? glyph.height * glyph.scale : 8;\n const width = glyph ? glyph.width * glyph.scale : 5;\n const shear = (y: number) => style.italic ? 1 - 0.25 * y : 0;\n const quad = (left: number, upper: number, right: number, lower: number, boldOffset: number) => {\n const base = batch!.positions.length / 3;\n const x = entry.x + offset + boldOffset, y = entry.y + offset;\n batch!.positions.push(x + left + shear(upper), -y - upper, 0, x + right + shear(upper), -y - upper, 0,\n x + left + shear(lower), -y - lower, 0, x + right + shear(lower), -y - lower, 0);\n const u0 = glyph ? glyph.x / glyph.image!.width : 0;\n const u1 = glyph ? (glyph.x + glyph.width) / glyph.image!.width : 1;\n const v0 = glyph ? 1 - glyph.y / glyph.image!.height : 1;\n const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image!.height : 0;\n batch!.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);\n for (let i = 0; i < 4; i++) batch!.colors.push(color.r, color.g, color.b);\n batch!.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);\n };\n for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {\n if (glyph) quad(0, top, width, top + height, boldOffset);\n else {\n quad(0, 0, 5, 1, boldOffset); quad(0, 7, 5, 8, boldOffset);\n quad(0, 1, 1, 7, boldOffset); quad(4, 1, 5, 7, boldOffset);\n }\n }\n }\n }\n return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setAttribute(\"uv\", new Float32BufferAttribute(uvs, 2))\n .setAttribute(\"color\", new Float32BufferAttribute(colors, 3))\n .setIndex(indices) }));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -962,7 +962,8 @@ declare enum AssetParser {
|
|
|
962
962
|
NBT = "nbt",
|
|
963
963
|
IMAGE = "image",
|
|
964
964
|
LIST = "list",
|
|
965
|
-
JSON = "json"
|
|
965
|
+
JSON = "json",
|
|
966
|
+
BINARY = "binary"
|
|
966
967
|
}
|
|
967
968
|
|
|
968
969
|
/** An asset provider registered with {@link AssetLoader.addSource}. */
|
|
@@ -1280,14 +1281,20 @@ interface BitmapGlyph {
|
|
|
1280
1281
|
scale: number;
|
|
1281
1282
|
ascent: number;
|
|
1282
1283
|
advance: number;
|
|
1284
|
+
/** Extra advance and drawing offset for bold text, in GUI pixels. Defaults to 1. */
|
|
1285
|
+
boldOffset?: number;
|
|
1286
|
+
/** Shadow displacement in GUI pixels. Defaults to 1. */
|
|
1287
|
+
shadowOffset?: number;
|
|
1283
1288
|
}
|
|
1284
1289
|
/** Character-to-glyph lookup assembled from the active resource-pack fonts. */
|
|
1285
1290
|
interface BitmapFont {
|
|
1286
1291
|
glyphs: Map<string, BitmapGlyph>;
|
|
1292
|
+
/** Resolves characters through the font providers before measuring or drawing them. */
|
|
1293
|
+
resolve?(characters: string): Promise<void>;
|
|
1287
1294
|
}
|
|
1288
|
-
/** Loads Minecraft bitmap, space, and reference font providers for GUI text. */
|
|
1295
|
+
/** Loads Minecraft bitmap, Unihex, space, and reference font providers for GUI text. */
|
|
1289
1296
|
declare class Fonts {
|
|
1290
|
-
/** Combines font definitions in source-priority order.
|
|
1297
|
+
/** Combines font definitions in source-priority order. TrueType providers are skipped. */
|
|
1291
1298
|
static get(key?: AssetKey | string): Promise<BitmapFont>;
|
|
1292
1299
|
private static relatedKey;
|
|
1293
1300
|
private static load;
|
|
@@ -1576,25 +1583,35 @@ interface EntityAnimationOptions {
|
|
|
1576
1583
|
speed?: number;
|
|
1577
1584
|
/** Start time in seconds; defaults to 0. */
|
|
1578
1585
|
time?: number;
|
|
1586
|
+
/** Nonnegative finite weights in clip order; defaults to 1 per clip. Offsets add without normalizing weights. */
|
|
1587
|
+
weights?: readonly number[];
|
|
1579
1588
|
}
|
|
1580
1589
|
/**
|
|
1581
|
-
* Poses part groups from
|
|
1582
|
-
*
|
|
1590
|
+
* Poses part groups from keyframe animations: every update restores the default pose of each
|
|
1591
|
+
* animated part, then adds weighted sampled offsets to its position, Euler angles and scale.
|
|
1583
1592
|
* It owns no timer; the owner advances it.
|
|
1584
1593
|
*/
|
|
1585
1594
|
declare class EntityAnimationPlayer {
|
|
1586
1595
|
private parts;
|
|
1587
|
-
private
|
|
1596
|
+
private _animations;
|
|
1597
|
+
private _weights;
|
|
1598
|
+
private loops;
|
|
1588
1599
|
private _time;
|
|
1589
|
-
private loop;
|
|
1590
1600
|
private speed;
|
|
1591
1601
|
get animation(): EntityAnimation | undefined;
|
|
1602
|
+
get animations(): readonly EntityAnimation[];
|
|
1603
|
+
get weights(): readonly number[];
|
|
1592
1604
|
get time(): number;
|
|
1593
1605
|
/**
|
|
1594
1606
|
* Starts an animation on matching named parts. Supplied baked poses are the baseline for offsets;
|
|
1595
1607
|
* without them, the current pose is used. Stopping restores the pose from before playback.
|
|
1596
1608
|
*/
|
|
1597
1609
|
play(layers: Object3D[], animation: EntityAnimation, options?: EntityAnimationOptions, poses?: ReadonlyMap<Object3D, EntityModelPart["pose"]>): void;
|
|
1610
|
+
/**
|
|
1611
|
+
* Starts clips on matching parts with a shared clock. Weighted offsets add to the supplied baked poses
|
|
1612
|
+
* or, without poses, to each animated part's pose when playback starts.
|
|
1613
|
+
*/
|
|
1614
|
+
playAnimations(layers: Object3D[], animations: readonly EntityAnimation[], options?: EntityAnimationOptions, poses?: ReadonlyMap<Object3D, EntityModelPart["pose"]>): void;
|
|
1598
1615
|
/** Restores the poses from before playback. Returns whether an animation was active. */
|
|
1599
1616
|
stop(): boolean;
|
|
1600
1617
|
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
@@ -1603,8 +1620,12 @@ declare class EntityAnimationPlayer {
|
|
|
1603
1620
|
setTime(seconds: number): boolean;
|
|
1604
1621
|
/** Advances playback by elapsed seconds multiplied by the speed passed to {@link play}. */
|
|
1605
1622
|
advance(deltaSeconds: number): boolean;
|
|
1623
|
+
/** Changes weights in clip order and reapplies the current time without restarting playback. */
|
|
1624
|
+
setWeights(weights: readonly number[]): boolean;
|
|
1606
1625
|
private apply;
|
|
1607
1626
|
}
|
|
1627
|
+
/** @internal */
|
|
1628
|
+
declare function validateAnimationWeights(weights: readonly number[], count: number): number[];
|
|
1608
1629
|
|
|
1609
1630
|
/** Renders selected entity layers as named part groups. Create it through {@link MineRenderScene.addEntity}. */
|
|
1610
1631
|
declare class EntityObject extends SceneObject {
|
|
@@ -1633,8 +1654,10 @@ declare class EntityObject extends SceneObject {
|
|
|
1633
1654
|
private updateScroll;
|
|
1634
1655
|
/** The first active clip, until playback is stopped or the object is disposed. */
|
|
1635
1656
|
get animation(): Maybe<EntityAnimation>;
|
|
1636
|
-
/** Clips playing together,
|
|
1657
|
+
/** Clips playing together, in the order passed to {@link playAnimations}. */
|
|
1637
1658
|
get activeAnimations(): readonly EntityAnimation[];
|
|
1659
|
+
/** Weights of the active clips, in the same order as {@link activeAnimations}. */
|
|
1660
|
+
get animationWeights(): readonly number[];
|
|
1638
1661
|
/** Seconds since the animation started, before looping. */
|
|
1639
1662
|
get animationTime(): number;
|
|
1640
1663
|
/**
|
|
@@ -1644,8 +1667,13 @@ declare class EntityObject extends SceneObject {
|
|
|
1644
1667
|
* The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
|
|
1645
1668
|
*/
|
|
1646
1669
|
playAnimation(animation: EntityAnimation, options?: EntityAnimationOptions): void;
|
|
1647
|
-
/**
|
|
1670
|
+
/**
|
|
1671
|
+
* Plays clips with a shared clock, adding their weighted offsets within each geometry layer.
|
|
1672
|
+
* Weights default to 1 and are not normalized. Selected layers without their own clip follow `main`.
|
|
1673
|
+
*/
|
|
1648
1674
|
playAnimations(animations: readonly EntityAnimation[], options?: EntityAnimationOptions): void;
|
|
1675
|
+
/** Changes weights in active clip order, notifying the scene without restarting the shared clock. Has no effect without an animation. */
|
|
1676
|
+
setAnimationWeights(weights: readonly number[]): void;
|
|
1649
1677
|
/** Stops all clips and restores the poses from before playback. */
|
|
1650
1678
|
stopAnimation(): void;
|
|
1651
1679
|
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
@@ -2493,6 +2521,7 @@ declare class HostedAssetSource extends AssetSource {
|
|
|
2493
2521
|
static readonly IMAGE: ResponseParser<TextureAsset>;
|
|
2494
2522
|
static readonly LIST: ResponseParser<ListAsset>;
|
|
2495
2523
|
static readonly JSON: ResponseParser<any>;
|
|
2524
|
+
static readonly BINARY: ResponseParser<BinaryAsset>;
|
|
2496
2525
|
static readonly PARSER_MAP: Map<AssetParser, ResponseParser<any>>;
|
|
2497
2526
|
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
2498
2527
|
loadOrRetryWithDefaults<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>>;
|
|
@@ -2513,6 +2542,10 @@ declare class HostedAssetSource extends AssetSource {
|
|
|
2513
2542
|
interface HostedAssetSourceOptions {
|
|
2514
2543
|
retryDefaults: boolean;
|
|
2515
2544
|
}
|
|
2545
|
+
/** Encoded asset bytes loaded without JSON or image decoding. */
|
|
2546
|
+
interface BinaryAsset extends MinecraftAsset {
|
|
2547
|
+
data: Uint8Array;
|
|
2548
|
+
}
|
|
2516
2549
|
|
|
2517
2550
|
/** A resource-pack ZIP entry, with its archive-relative path and lazily extracted bytes. */
|
|
2518
2551
|
interface ArchiveEntry {
|
|
@@ -2650,6 +2683,12 @@ interface BedrockGeometryFile {
|
|
|
2650
2683
|
[key: string]: BedrockGeometry | any;
|
|
2651
2684
|
}
|
|
2652
2685
|
|
|
2686
|
+
interface UnihexFile {
|
|
2687
|
+
indices: Int32Array;
|
|
2688
|
+
rows: Uint32Array;
|
|
2689
|
+
metrics: Uint8Array;
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2653
2692
|
/** Shared in-memory caches for loaded assets and render resources. Persistent stores are managed separately. */
|
|
2654
2693
|
declare class Caching {
|
|
2655
2694
|
private static _generation;
|
|
@@ -2675,6 +2714,7 @@ declare class Caching {
|
|
|
2675
2714
|
static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey>;
|
|
2676
2715
|
static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile>;
|
|
2677
2716
|
static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex>;
|
|
2717
|
+
static readonly unihexCache: AsyncLoadingCache<CacheKey, UnihexFile>;
|
|
2678
2718
|
static readonly fontCache: AsyncLoadingCache<CacheKey, BitmapFont>;
|
|
2679
2719
|
static readonly bannerPatternCache: AsyncLoadingCache<CacheKey, BannerPattern>;
|
|
2680
2720
|
static readonly mineRenderDataCache: AsyncLoadingCache<CacheKey, unknown>;
|
|
@@ -3790,6 +3830,7 @@ interface SectionTemplateData {
|
|
|
3790
3830
|
uvs: Float32Array;
|
|
3791
3831
|
uvBounds: Float32Array;
|
|
3792
3832
|
colors: Float32Array;
|
|
3833
|
+
shade?: Float32Array;
|
|
3793
3834
|
indices: Uint16Array;
|
|
3794
3835
|
cullFaces: Uint8Array;
|
|
3795
3836
|
biomeTint?: Uint8Array;
|
|
@@ -3853,6 +3894,7 @@ interface SectionGeometryPage {
|
|
|
3853
3894
|
uvs: Float32Array;
|
|
3854
3895
|
uvBounds: Float32Array;
|
|
3855
3896
|
colors: Float32Array;
|
|
3897
|
+
shade: Float32Array;
|
|
3856
3898
|
indices: Uint32Array;
|
|
3857
3899
|
/** Owning section cell for each quad; each quad contributes two consecutive triangles. */
|
|
3858
3900
|
blockIndices: Uint16Array;
|
|
@@ -4344,4 +4386,4 @@ declare class BrowserCache extends PersistentCache<LocalForage> {
|
|
|
4344
4386
|
*/
|
|
4345
4387
|
declare function probeImageSize(data: Uint8Array): ImageSizeInfo;
|
|
4346
4388
|
|
|
4347
|
-
export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, yieldToEventLoop };
|
|
4389
|
+
export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type BinaryAsset, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, validateAnimationWeights, yieldToEventLoop };
|
|
@@ -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) => {
|