PrismarineJS / prismarine-viewer

Web based viewer for servers and bots
https://prismarinejs.github.io/prismarine-viewer/
MIT License
268 stars 72 forks source link

BUG 1.20.1 flat world doens't work (normal does) #435

Open SinanAkkoyun opened 2 months ago

SinanAkkoyun commented 2 months ago

On servers, flat worlds do not get rendered (also every user placed block too)

Bot click walk works flawlessly, despite noting being rendered

SinanAkkoyun commented 2 months ago

https://github.com/PrismarineJS/prismarine-world/issues/144

Please help here, this might resolve this issue

SinanAkkoyun commented 2 months ago

image

Everything below y=0 doesn't render. I already updated the lib/models.js file:


function renderLiquid (world, cursor, texture, type, biome, water, attr) {
  const heights = []
  for (let z = -1; z <= 1; z++) {
    for (let x = -1; x <= 1; x++) {
      heights.push(getLiquidRenderHeight(world, world.getBlock(cursor.offset(x, -64, z)), type))
    }
  }
  const cornerHeights = [
    Math.max(Math.max(heights[0], heights[1]), Math.max(heights[3], heights[4])),
    Math.max(Math.max(heights[1], heights[2]), Math.max(heights[4], heights[5])),
    Math.max(Math.max(heights[3], heights[4]), Math.max(heights[6], heights[7])),
    Math.max(Math.max(heights[4], heights[5]), Math.max(heights[7], heights[8]))
  ]

  for (const face in elemFaces) {
    const { dir, corners } = elemFaces[face]
    const isUp = dir[1] === 1

    const neighbor = world.getBlock(cursor.offset(...dir))
    if (!neighbor) continue
    if (neighbor.type === type) continue
    if ((neighbor.isCube && !isUp) || neighbor.material === 'plant' || neighbor.getProperties().waterlogged) continue
    if (neighbor.position.y < -64) continue

    let tint = [1, 1, 1]
    if (water) {
      let m = 1 // Fake lighting to improve lisibility
      if (Math.abs(dir[0]) > 0) m = 0.6
      else if (Math.abs(dir[2]) > 0) m = 0.8
      tint = tints.water[biome]
      tint = [tint[0] * m, tint[1] * m, tint[2] * m]
    }

    const u = texture.u
    const v = texture.v
    const su = texture.su
    const sv = texture.sv

    for (const pos of corners) {
      const height = cornerHeights[pos[2] * 2 + pos[0]]
      attr.t_positions.push(
        (pos[0] ? 1 : 0) + (cursor.x & 15) - 8,
        (pos[1] ? height : 0) + (cursor.y & 15) - 8,
        (pos[2] ? 1 : 0) + (cursor.z & 15) - 8)
      attr.t_normals.push(...dir)
      attr.t_uvs.push(pos[3] * su + u, pos[4] * sv * (pos[1] ? 1 : height) + v)
      attr.t_colors.push(tint[0], tint[1], tint[2])
    }
  }
}

(notice cursor start and neighor y check, did the same for renderElement and changed cursor start in getSectionGeometry to -64)

But still no luck!

SinanAkkoyun commented 2 months ago

It must have something to do with the dirty sections not being able to load below 0 blocks

SinanAkkoyun commented 2 months ago

@rom1504 Given you have most contributions I wanted to ask if you know what's happening, as the bot seems to work just fine in the world (and mesh generation clearly accounts for blocks lower than y 0 as seen in the screenshot)

SinanAkkoyun commented 2 months ago
function getSectionGeometry (sx, sy, sz, world, blocksStates) {
  const attr = {
    sx: sx + 8,
    sy: sy + 8,
    sz: sz + 8,
    positions: [],
    normals: [],
    colors: [],
    uvs: [],
    t_positions: [],
    t_normals: [],
    t_colors: [],
    t_uvs: [],
    indices: []
  }

  const cursor = new Vec3(0, -64, 0)
  for (cursor.y = sy; cursor.y < sy + 16; cursor.y++) {
    for (cursor.z = sz; cursor.z < sz + 16; cursor.z++) {
      for (cursor.x = sx; cursor.x < sx + 16; cursor.x++) {
        const block = world.getBlock(cursor)
        // console.log('lel')
        if(block.type !== 0) console.log("Block " + block.type)

However, here, world.getBlock only returns the blocks above y 0

World takes it's blocks by addColumn <- addColumn in worldrenderer (my mod):

addColumn (x, z, chunk) {
    this.loadedChunks[`${x},${z}`] = true
    for (const worker of this.workers) {
      worker.postMessage({ type: 'chunk', x, z, chunk })
    }
    for (let y = -64; y < 256; y += 16) {
      const loc = new Vec3(x, y, z)
      this.setSectionDirty(loc)
      this.setSectionDirty(loc.offset(-16, 0, 0))
      this.setSectionDirty(loc.offset(16, 0, 0))
      this.setSectionDirty(loc.offset(0, 0, -16))
      this.setSectionDirty(loc.offset(0, 0, 16))
    }
  }

Still nothing