minerender 2.1.0-alpha.121 → 2.1.0-alpha.122

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/bundle.js CHANGED
@@ -100712,6 +100712,10 @@ property list uchar int vertex_index
100712
100712
  get blockEntities() {
100713
100713
  return this._entities;
100714
100714
  }
100715
+ /** Model placements drawn for this block, including its fluid surface. */
100716
+ get models() {
100717
+ return this._models;
100718
+ }
100715
100719
  /** Sets visibility for this block's model instances and block entities. */
100716
100720
  setVisible(visible) {
100717
100721
  this.visible = visible;
@@ -107967,6 +107971,13 @@ gl_FragDepth=readDepth(vUv);
107967
107971
  if (options.sectionMeshing) this.sectionModels = new SectionModels(options.maxAtlasSize);
107968
107972
  if (options.renderEntities) this.entities = new WorldEntities(scene);
107969
107973
  }
107974
+ /**
107975
+ * Returns the nearest visible block geometry hit, respecting the raycaster's layers and near/far range.
107976
+ * Includes fluids and block entities; texture alpha does not change triangle intersections.
107977
+ */
107978
+ raycast(raycaster) {
107979
+ return Chunk.raycast(this._chunks.values(), raycaster);
107980
+ }
107970
107981
  /** Whether neighboring opaque cubes shade block-face corners. Defaults to false. */
107971
107982
  get ambientOcclusion() {
107972
107983
  return this._ambientOcclusion;
@@ -108653,6 +108664,7 @@ gl_FragDepth=readDepth(vUv);
108653
108664
  const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
108654
108665
  const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
108655
108666
  const outputIndices = new Uint32Array(faces * 6);
108667
+ const blockIndices = new Uint16Array(faces);
108656
108668
  let vertex2 = 0, indexOffset = 0;
108657
108669
  for (const entry of page.entries) {
108658
108670
  const template = templateData[templates[entry]];
@@ -108667,6 +108679,7 @@ gl_FragDepth=readDepth(vUv);
108667
108679
  const ambientMask = ambientOcclusion && template.ambientOcclusion !== false ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;
108668
108680
  for (let quad = 0; quad < template.quads; quad++) {
108669
108681
  if (cullMasks[entry] & template.cullFaces[quad]) continue;
108682
+ blockIndices[indexOffset / 6] = indices[entry];
108670
108683
  if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness2);
108671
108684
  const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;
108672
108685
  const start = vertex2;
@@ -108699,6 +108712,7 @@ gl_FragDepth=readDepth(vUv);
108699
108712
  const mapV = (v5) => 1 - (placement.y + (1 - v5) * atlas.height) / page.height;
108700
108713
  const lightIndex = (y5 + 1) * 324 + (z4 + 1) * 18 + x4 + 1;
108701
108714
  for (let quad = 0; quad < quads.sprites.length; quad++) {
108715
+ blockIndices[indexOffset / 6] = x4 + z4 * 16 + y5 * 256;
108702
108716
  const rect = quads.sprites[quad] === 0 ? data.still : data.flow;
108703
108717
  const brightness = light ? lightBrightness(fluidLightLevel(
108704
108718
  light[lightIndex],
@@ -108729,11 +108743,11 @@ gl_FragDepth=readDepth(vUv);
108729
108743
  indexOffset += 6;
108730
108744
  }
108731
108745
  }
108732
- return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices };
108746
+ return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
108733
108747
  });
108734
108748
  }
108735
108749
  function sectionGeometryTransferables(pages) {
108736
- return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer]);
108750
+ 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]);
108737
108751
  }
108738
108752
 
108739
108753
  // src/world/SectionWorker.ts
@@ -108894,6 +108908,12 @@ gl_FragDepth=readDepth(vUv);
108894
108908
  constructor() {
108895
108909
  super(...arguments);
108896
108910
  this.ownedMeshes = [];
108911
+ this.blockIndices = /* @__PURE__ */ new Map();
108912
+ }
108913
+ /** Returns the owning section cell for a triangle hit on this mesh's merged geometry. */
108914
+ getBlockIndex(hit) {
108915
+ if (hit.faceIndex === void 0 || hit.faceIndex === null) return void 0;
108916
+ return this.blockIndices.get(hit.object)?.[Math.floor(hit.faceIndex / 2)];
108897
108917
  }
108898
108918
  /** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
108899
108919
  static build(entries, maxAtlasSize = 2048, fluids, lighting) {
@@ -108936,6 +108956,7 @@ gl_FragDepth=readDepth(vUv);
108936
108956
  const texture = material.uniforms?.map?.value ?? material.map;
108937
108957
  const mesh = new Mesh(geometry, material);
108938
108958
  section.add(mesh);
108959
+ section.blockIndices.set(mesh, page.blockIndices);
108939
108960
  const unsubscribe = [];
108940
108961
  for (const { atlas: id, x: x4, y: y5 } of page.placements) {
108941
108962
  const atlas = atlases[id];
@@ -108961,6 +108982,7 @@ gl_FragDepth=readDepth(vUv);
108961
108982
  mesh.material.dispose();
108962
108983
  texture?.dispose();
108963
108984
  }
108985
+ this.blockIndices.clear();
108964
108986
  this.removeFromParent();
108965
108987
  super.dispose();
108966
108988
  }
@@ -108970,6 +108992,8 @@ gl_FragDepth=readDepth(vUv);
108970
108992
  init_FluidGeometry();
108971
108993
  init_FluidQuads();
108972
108994
  init_CubeFace();
108995
+ init_InstanceReference();
108996
+ init_three();
108973
108997
  var WATER_TINT2 = new Color(4159204).toArray();
108974
108998
  var Chunk = class _Chunk {
108975
108999
  constructor(scene, x4, y5, z4, onBlocksChanged, sectionModels, neighborCell, biomeAt, onBiomesChanged, lightAt, onLightCleared, ambientLight = 0) {
@@ -108983,6 +109007,7 @@ gl_FragDepth=readDepth(vUv);
108983
109007
  this.ambientLight = ambientLight;
108984
109008
  this.data = new ChunkData();
108985
109009
  this.renderedBlocks = /* @__PURE__ */ new Map();
109010
+ this.objectBlocks = /* @__PURE__ */ new Set();
108986
109011
  this.sectionBlocks = /* @__PURE__ */ new Map();
108987
109012
  this.hiddenBlocks = /* @__PURE__ */ new Set();
108988
109013
  this.fluidCells = new Uint8Array(4096);
@@ -108994,6 +109019,89 @@ gl_FragDepth=readDepth(vUv);
108994
109019
  this.y = y5;
108995
109020
  this.z = z4;
108996
109021
  }
109022
+ /** Finds the nearest owned block hit across sections, testing each shared mesh once. */
109023
+ static raycast(chunks, raycaster) {
109024
+ const roots = /* @__PURE__ */ new Map();
109025
+ const targets = /* @__PURE__ */ new Map();
109026
+ const meshes = (root, scene) => {
109027
+ const cached2 = roots.get(root);
109028
+ if (cached2) return cached2;
109029
+ const result = [];
109030
+ roots.set(root, result);
109031
+ let attached = false;
109032
+ for (let parent = root; parent; parent = parent.parent) {
109033
+ if (!parent.visible) return result;
109034
+ if (parent === scene) attached = true;
109035
+ }
109036
+ if (!attached) return result;
109037
+ root.updateWorldMatrix(true, true);
109038
+ root.traverseVisible((object4) => {
109039
+ if (isMesh(object4) && raycaster.layers.test(object4.layers)) result.push(object4);
109040
+ });
109041
+ return result;
109042
+ };
109043
+ const add = (root, owner, reference) => {
109044
+ for (const mesh of meshes(root, owner.chunk.scene)) {
109045
+ if (reference && reference.instanceable.getInstanceReference(mesh, reference.index) !== reference) continue;
109046
+ let entry = targets.get(mesh);
109047
+ if (!entry) targets.set(mesh, entry = { owners: /* @__PURE__ */ new Map() });
109048
+ entry.owners.set(reference?.index, owner);
109049
+ }
109050
+ };
109051
+ for (const chunk of chunks) {
109052
+ for (const index of chunk.objectBlocks) {
109053
+ const block = chunk.renderedBlocks.get(index).object;
109054
+ if (!block || !block.visible || chunk.hiddenBlocks.has(index)) continue;
109055
+ const owner = { chunk, index };
109056
+ for (const model of block.models) {
109057
+ if (isInstanceReference(model)) {
109058
+ if (model.instanceable.isInstanceActive(model.index, model)) add(model.instanceable, owner, model);
109059
+ } else {
109060
+ add(model, owner);
109061
+ }
109062
+ }
109063
+ for (const entity of block.blockEntities) add(entity, owner);
109064
+ }
109065
+ if (chunk.sectionMesh) {
109066
+ for (const mesh of meshes(chunk.sectionMesh, chunk.scene)) {
109067
+ targets.set(mesh, { owners: /* @__PURE__ */ new Map(), section: { chunk, mesh: chunk.sectionMesh } });
109068
+ }
109069
+ }
109070
+ }
109071
+ for (const hit of raycaster.intersectObjects([...targets.keys()], false)) {
109072
+ if (!hit.face) continue;
109073
+ const mesh = hit.object;
109074
+ const material = Array.isArray(mesh.material) ? mesh.material[hit.face.materialIndex] : mesh.material;
109075
+ if (!material?.visible) continue;
109076
+ const entry = targets.get(mesh);
109077
+ let owner = entry.owners.get(hit.instanceId) ?? entry.owners.get(void 0);
109078
+ if (entry.section) {
109079
+ const index = entry.section.mesh.getBlockIndex(hit);
109080
+ if (index !== void 0) owner = { chunk: entry.section.chunk, index };
109081
+ }
109082
+ if (!owner || owner.chunk.hiddenBlocks.has(owner.index)) continue;
109083
+ const info = owner.chunk.renderedBlocks.get(owner.index);
109084
+ if (!info) continue;
109085
+ const matrix = mesh.matrixWorld.clone();
109086
+ if (isInstancedMesh(mesh) && hit.instanceId !== void 0) {
109087
+ const instance = new Matrix4();
109088
+ mesh.getMatrixAt(hit.instanceId, instance);
109089
+ matrix.multiply(instance);
109090
+ }
109091
+ return {
109092
+ position: new Vector3(
109093
+ owner.chunk.x * 16 + owner.index % 16,
109094
+ owner.chunk.y * 16 + Math.floor(owner.index / 256),
109095
+ owner.chunk.z * 16 + Math.floor(owner.index / 16) % 16
109096
+ ),
109097
+ block: info.block,
109098
+ point: hit.point.clone(),
109099
+ normal: hit.face.normal.clone().applyNormalMatrix(new Matrix3().getNormalMatrix(matrix)),
109100
+ distance: hit.distance
109101
+ };
109102
+ }
109103
+ return void 0;
109104
+ }
108997
109105
  getBlockAt(posOrX, y5, z4) {
108998
109106
  if (typeof posOrX == "number") {
108999
109107
  return this.getBlockAt(new Vector3(posOrX, y5, z4));
@@ -109114,6 +109222,7 @@ gl_FragDepth=readDepth(vUv);
109114
109222
  if (this.fluidCells[index]) this.meshDirty = true;
109115
109223
  this.fluidCells[index] = 0;
109116
109224
  this.renderedBlocks.delete(index);
109225
+ this.objectBlocks.delete(index);
109117
109226
  const worldPos = new Vector3(
109118
109227
  this.x * 16 + index % 16,
109119
109228
  this.y * 16 + Math.floor(index / 256),
@@ -109156,6 +109265,7 @@ gl_FragDepth=readDepth(vUv);
109156
109265
  this.renderedBlocks.set(index, { get block() {
109157
109266
  return readBlock();
109158
109267
  }, object: object4 });
109268
+ if (object4) this.objectBlocks.add(index);
109159
109269
  } catch (error2) {
109160
109270
  this.data.assign(index, 0);
109161
109271
  this.fluidCells[index] = 0;
@@ -109174,6 +109284,7 @@ gl_FragDepth=readDepth(vUv);
109174
109284
  this.fluidCells.fill(0);
109175
109285
  this.waterTints = void 0;
109176
109286
  this.renderedBlocks.clear();
109287
+ this.objectBlocks.clear();
109177
109288
  this.hiddenBlocks.clear();
109178
109289
  this.meshDirty = true;
109179
109290
  this.data.copyFrom(data);
@@ -109223,6 +109334,7 @@ gl_FragDepth=readDepth(vUv);
109223
109334
  this.renderedBlocks.set(index, { get block() {
109224
109335
  return readBlock();
109225
109336
  }, object: void 0 });
109337
+ this.objectBlocks.delete(index);
109226
109338
  } catch (error2) {
109227
109339
  this.data.assign(index, 0);
109228
109340
  this.fluidCells[index] = 0;
@@ -109248,10 +109360,12 @@ gl_FragDepth=readDepth(vUv);
109248
109360
  this.z * 256 + Math.floor(index / 16) % 16 * 16
109249
109361
  ));
109250
109362
  this.renderedBlocks.get(index).object = object4;
109363
+ this.objectBlocks.add(index);
109251
109364
  } catch (error2) {
109252
109365
  this.data.assign(index, 0);
109253
109366
  this.fluidCells[index] = 0;
109254
109367
  this.renderedBlocks.delete(index);
109368
+ this.objectBlocks.delete(index);
109255
109369
  object4?.removeFromScene();
109256
109370
  if (!failed) failure = error2;
109257
109371
  failed = true;
@@ -109512,6 +109626,7 @@ gl_FragDepth=readDepth(vUv);
109512
109626
  this.sectionMesh = void 0;
109513
109627
  this.meshDirty = false;
109514
109628
  this.renderedBlocks.clear();
109629
+ this.objectBlocks.clear();
109515
109630
  this.hiddenBlocks.clear();
109516
109631
  this.fluidCells.fill(0);
109517
109632
  this.waterTints = void 0;
@@ -109553,6 +109668,11 @@ gl_FragDepth=readDepth(vUv);
109553
109668
  }
109554
109669
  };
109555
109670
 
109671
+ // src/world/WorldBlockIntersection.ts
109672
+ init_dirname();
109673
+ init_buffer2();
109674
+ init_process2();
109675
+
109556
109676
  // src/world/WorldChunkSource.ts
109557
109677
  init_dirname();
109558
109678
  init_buffer2();