minecraft-renderer 0.1.99 → 0.1.100

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.99",
3
+ "version": "0.1.100",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,17 @@
1
+ //@ts-nocheck
2
+ export function createGeometryIndexArray(indices: readonly number[]): Uint16Array | Uint32Array {
3
+ let using32Array = false
4
+ for (let index = 0; index < indices.length; index++) {
5
+ if (indices[index] > 65535) {
6
+ using32Array = true
7
+ break
8
+ }
9
+ }
10
+ return using32Array ? new Uint32Array(indices) : new Uint16Array(indices)
11
+ }
12
+
13
+ export function appendGeometryIndices(target: number[], source: readonly number[], vertexOffset: number): void {
14
+ for (let index = 0; index < source.length; index++) {
15
+ target.push(source[index] + vertexOffset)
16
+ }
17
+ }
@@ -19,6 +19,7 @@ import { resolveBlockPropertiesForMeshing } from '../../mesher-shared/blockPrope
19
19
  import { isSemiTransparentBlockName } from '../../mesher-shared/models'
20
20
  import { faceIsCulled } from '../../mesher-shared/faceOcclusion'
21
21
  import { buildShaderCubesFromWords, getShaderCubeResources, tryBuildShaderCubeInstances } from './shaderCubeBridge'
22
+ import { appendGeometryIndices } from './geometryIndices'
22
23
  import { getSideShading, vertexLightFromAo } from '../../mesher-shared/vertexShading'
23
24
  import tintsJson from 'minecraft-data/minecraft-data/data/pc/1.16.2/tints.json'
24
25
 
@@ -986,10 +987,8 @@ export function renderWasmOutputToGeometry(
986
987
  blendSkyLights = liquidSkyLights.concat(blockBlendSkyLights)
987
988
  blendBlockLights = liquidBlockLights.concat(blockBlendBlockLights)
988
989
  blendUvs = liquidUvs.concat(blockBlendUvs)
989
- blendIndices.push(...liquidIndices)
990
- for (const idx of blockBlendIndices) {
991
- blendIndices.push(idx + liquidVertexCount)
992
- }
990
+ appendGeometryIndices(blendIndices, liquidIndices, 0)
991
+ appendGeometryIndices(blendIndices, blockBlendIndices, liquidVertexCount)
993
992
  }
994
993
 
995
994
  const shaderCubes = buildShaderCubesFromWords(shaderWordBuffer)
@@ -0,0 +1,71 @@
1
+ //@ts-nocheck
2
+ import { expect, test } from 'vitest'
3
+ import { appendGeometryIndices, createGeometryIndexArray } from '../bridge/geometryIndices'
4
+
5
+ function expectSameValues(actual: ArrayLike<number>, expected: ArrayLike<number>): void {
6
+ expect(actual.length).toBe(expected.length)
7
+ let firstMismatch = -1
8
+ for (let index = 0; index < expected.length; index++) {
9
+ if (actual[index] !== expected[index]) {
10
+ firstMismatch = index
11
+ break
12
+ }
13
+ }
14
+ expect(firstMismatch, 'First differing index; -1 means all values match').toBe(-1)
15
+ }
16
+
17
+ test('creates lossless index buffers without depending on argument count', () => {
18
+ const cases: Array<{ input: number[]; using32Array: boolean }> = [
19
+ { input: [], using32Array: false },
20
+ { input: [0, 65535, 7], using32Array: false },
21
+ { input: [0, 65536, 7], using32Array: true }
22
+ ]
23
+
24
+ for (const { input, using32Array } of cases) {
25
+ const inputBefore = input.slice()
26
+ const result = createGeometryIndexArray(input)
27
+ expect(result).toBeInstanceOf(using32Array ? Uint32Array : Uint16Array)
28
+ expect(Array.from(result)).toEqual(inputBefore)
29
+ expect(input).toEqual(inputBefore)
30
+ }
31
+
32
+ const source = new Array<number>(1_000_000).fill(65535)
33
+ source[0] = 0
34
+ source[500_000] = 123
35
+ const sourceBeforeSmall = source.slice()
36
+ const smallValues = createGeometryIndexArray(source)
37
+ expect(smallValues).toBeInstanceOf(Uint16Array)
38
+ expectSameValues(smallValues, sourceBeforeSmall)
39
+ expectSameValues(source, sourceBeforeSmall)
40
+
41
+ source[source.length - 1] = 65536
42
+ const sourceBeforeLarge = source.slice()
43
+ const largeValue = createGeometryIndexArray(source)
44
+ expect(largeValue).toBeInstanceOf(Uint32Array)
45
+ expectSameValues(largeValue, sourceBeforeLarge)
46
+ expectSameValues(source, sourceBeforeLarge)
47
+ })
48
+
49
+ test('appends large liquid indices before rebased block indices', () => {
50
+ const liquidIndices = new Array<number>(1_000_000).fill(0)
51
+ liquidIndices[0] = 2
52
+ liquidIndices[liquidIndices.length - 1] = 1
53
+ const blockBlendIndices = [0, 2, 1]
54
+ const liquidVertexCount = 3
55
+ const blendIndices: number[] = []
56
+ const liquidIndicesBefore = liquidIndices.slice()
57
+ const blockBlendIndicesBefore = blockBlendIndices.slice()
58
+
59
+ appendGeometryIndices(blendIndices, liquidIndices, 0)
60
+ appendGeometryIndices(blendIndices, blockBlendIndices, liquidVertexCount)
61
+
62
+ expect(blendIndices.length).toBe(liquidIndicesBefore.length + blockBlendIndicesBefore.length)
63
+ expectSameValues(blendIndices.slice(0, liquidIndicesBefore.length), liquidIndicesBefore)
64
+ expect(blendIndices.slice(liquidIndicesBefore.length)).toEqual([3, 5, 4])
65
+ expect(blockBlendIndices).toEqual(blockBlendIndicesBefore)
66
+ expectSameValues(liquidIndices, liquidIndicesBefore)
67
+
68
+ const snapshot = blendIndices.slice()
69
+ appendGeometryIndices(blendIndices, [], liquidVertexCount)
70
+ expectSameValues(blendIndices, snapshot)
71
+ })
@@ -2,6 +2,7 @@
2
2
  import { Vec3 } from 'vec3'
3
3
  import { convertChunkToWasm, getBlockMeta, type ChunkConversionResult } from '../bridge/convertChunk'
4
4
  import { extractColumnHeightmap, splitColumnWasmOutputToSections } from '../bridge/render-from-wasm'
5
+ import { createGeometryIndexArray } from '../bridge/geometryIndices'
5
6
  import { setBlockStatesData as setMesherData } from '../../mesher-shared/models'
6
7
  import { defaultMesherConfig, type MesherGeometryOutput, SECTION_HEIGHT } from '../../mesher-shared/shared'
7
8
  import { SHADER_CUBES_FORMAT_VERSION } from '../../mesher-shared/shaderCubeFormat'
@@ -1493,8 +1494,8 @@ function processColumnTick() {
1493
1494
  const hasLegacyMesh = hasOpaqueMesh || hasBlendMesh
1494
1495
  const hasShaderCubes = (exported?.shaderCubes?.count ?? 0) > 0
1495
1496
  if (exported && (hasLegacyMesh || hasShaderCubes)) {
1496
- const maxIndex = exported.geometry.indices.length > 0 ? Math.max(...exported.geometry.indices) : 0
1497
- const using32Array = maxIndex > 65535
1497
+ const indices = createGeometryIndexArray(exported.geometry.indices)
1498
+ const using32Array = indices instanceof Uint32Array
1498
1499
  geometry = {
1499
1500
  sectionYNumber: (sy - (config?.worldMinY || 0)) >> 4,
1500
1501
  chunkKey: worldColumnKey(sx, sz),
@@ -1513,7 +1514,7 @@ function processColumnTick() {
1513
1514
  skyLights: new Float32Array(exported.geometry.skyLights),
1514
1515
  blockLights: new Float32Array(exported.geometry.blockLights),
1515
1516
  uvs: new Float32Array(exported.geometry.uvs),
1516
- indices: using32Array ? new Uint32Array(exported.geometry.indices) : new Uint16Array(exported.geometry.indices),
1517
+ indices,
1517
1518
  indicesCount: exported.geometry.indices.length,
1518
1519
  using32Array,
1519
1520
  tiles: {},
@@ -1537,7 +1538,6 @@ function processColumnTick() {
1537
1538
  }
1538
1539
  }
1539
1540
  if (exported.blendGeometry && hasBlendMesh) {
1540
- const blendMax = Math.max(...exported.blendGeometry.indices)
1541
1541
  geometry.blend = {
1542
1542
  positions: new Float32Array(exported.blendGeometry.positions),
1543
1543
  normals: new Float32Array(exported.blendGeometry.normals),
@@ -1545,7 +1545,7 @@ function processColumnTick() {
1545
1545
  skyLights: new Float32Array(exported.blendGeometry.skyLights),
1546
1546
  blockLights: new Float32Array(exported.blendGeometry.blockLights),
1547
1547
  uvs: new Float32Array(exported.blendGeometry.uvs),
1548
- indices: blendMax > 65535 ? new Uint32Array(exported.blendGeometry.indices) : new Uint16Array(exported.blendGeometry.indices)
1548
+ indices: createGeometryIndexArray(exported.blendGeometry.indices)
1549
1549
  }
1550
1550
  }
1551
1551
  transferable = [