private void initChunkRaw(Point p) {
    int x = p.getChunkX();
    int y = p.getChunkY(); // + SEALEVEL_CHUNK;
    int z = p.getChunkZ();

    RepositionManager rm = getRepositionManager();

    int cY = rm.convertChunkY(y);

    if (cY < 0 || cY >= p.getWorld().getHeight() >> Chunk.BLOCKS.BITS) {
      return;
    }

    TSyncIntHashSet column = initializedChunks.get(x, z);
    if (column == null) {
      column = new TSyncIntHashSet();
      synchronized (initChunkLock) {
        TSyncIntHashSet oldColumn = initializedChunks.putIfAbsent(x, z, column);
        if (oldColumn != null) {
          column = oldColumn;
        }
      }
    }
    column.add(y);
  }
    private static byte[] getChunkHeightMap(int[][] heights, BlockMaterial[][] materials, Point p) {
      int chunkY = p.getChunkY();
      byte[] packetChunkData = new byte[Chunk.BLOCKS.HALF_VOLUME * 5];
      int baseY = chunkY << Chunk.BLOCKS.BITS;

      for (int xx = 0; xx < Chunk.BLOCKS.SIZE; xx++) {
        for (int zz = 0; zz < Chunk.BLOCKS.SIZE; zz++) {
          int dataOffset = xx | (zz << Chunk.BLOCKS.BITS);
          int threshold = heights[xx][zz] - baseY;
          if (chunkY == 0 && threshold < 0) {
            threshold = 0;
          }
          int yy;
          // Set blocks below height to the solid block
          for (yy = 0; yy < Chunk.BLOCKS.SIZE && yy <= threshold; yy++) {
            if (yy == threshold) {
              BlockMaterial bm = materials[xx][zz];
              if (bm == null) {
                bm = VanillaMaterials.STONE;
              }
              int converted = getMinecraftId(bm.getId());
              packetChunkData[dataOffset] = (byte) converted;
            } else {
              packetChunkData[dataOffset] = SOLID_BLOCK_ID;
            }
            dataOffset += Chunk.BLOCKS.AREA;
          }
          // Set sky light of blocks above height to 15
          // Use half of start offset and add the block id and data length (2 volumes)
          byte mask = (xx & 0x1) == 0 ? (byte) 0x0F : (byte) 0xF0;
          dataOffset = Chunk.BLOCKS.DOUBLE_VOLUME + (dataOffset >> 1);
          for (; yy < Chunk.BLOCKS.SIZE; yy++) {
            packetChunkData[dataOffset] |= mask;
            dataOffset += Chunk.BLOCKS.HALF_AREA;
          }
        }
      }
      return packetChunkData;
    }
  @Override
  protected void initChunk(Point p) {

    int x = p.getChunkX();
    int y = p.getChunkY(); // + SEALEVEL_CHUNK;
    int z = p.getChunkZ();

    if (y < 0 || y >= p.getWorld().getHeight() >> Chunk.BLOCKS.BITS) {
      return;
    }

    TSyncIntHashSet column = initializedChunks.get(x, z);
    if (column == null) {
      column = new TSyncIntHashSet();
      synchronized (initChunkLock) {
        TSyncIntHashSet oldColumn = initializedChunks.putIfAbsent(x, z, column);
        if (oldColumn != null) {
          column = oldColumn;
        }
      }
    }
    column.add(y);
  }
Example #4
0
  /**
   * Updates the list of chunks around the player.
   *
   * @param force Forces the update
   * @return True if the list was changed
   */
  public boolean updateNearbyChunkMeshes(boolean force) {
    if (world == null) {
      world = client.getDefaultWorld();
      if (world != null)
        System.out.println("World updated to " + world.getName() + "-" + world.getUID());
    }

    if (world == null) {
      try {
        Thread.sleep(5);
      } catch (InterruptedException e) {
      }
      return false;
    }

    int chunkViewDistance = client.getActivePlayer().getViewDistance() / 16;

    Point currentPos = client.getActivePlayer().getTransform().getPosition();

    int currentChunkX = currentPos.getChunkX();
    int currentChunkY = currentPos.getChunkY();
    int currentChunkZ = currentPos.getChunkZ();

    if (currentChunkX == lastChunkX
        && currentChunkY == lastChunkY
        && currentChunkZ == lastChunkZ
        && !force
        && !firstUpdate) {
      return false;
    }
    // just add all visible chunks

    if (chunkRenderers.size() == 0 || force) {
      chunkRenderers.clear();

      int cubeMinX = currentChunkX - chunkViewDistance;
      int cubeMinY = currentChunkY - chunkViewDistance;
      int cubeMinZ = currentChunkZ - chunkViewDistance;

      int cubeMaxX = currentChunkX + chunkViewDistance;
      int cubeMaxY = currentChunkY + chunkViewDistance;
      int cubeMaxZ = currentChunkZ + chunkViewDistance;

      Vector3 batchMin =
          ChunkMeshBatch.getBatchCoordinates(new Vector3(cubeMinX, cubeMinY, cubeMinZ));
      Vector3 batchMax =
          ChunkMeshBatch.getBatchCoordinates(new Vector3(cubeMaxX, cubeMaxY, cubeMaxZ));

      for (int x = batchMin.getFloorX(); x <= batchMax.getFloorX(); x++) {
        for (int y = batchMin.getFloorY(); y <= batchMax.getFloorY(); y++) {
          for (int z = batchMin.getFloorZ(); z <= batchMax.getFloorZ(); z++) {
            Vector3 chunkCoords = ChunkMeshBatch.getChunkCoordinates(new Vector3(x, y, z));
            ChunkMeshBatch batch =
                new ChunkMeshBatch(
                    material,
                    world,
                    chunkCoords.getFloorX(),
                    chunkCoords.getFloorY(),
                    chunkCoords.getFloorZ());
            addChunkMeshBatch(batch);
            batch.update();

            System.out.println(batch);
          }
        }
      }
    } else {
      Cube oldView =
          new Cube(
              new Point(
                  world,
                  lastChunkX - chunkViewDistance,
                  lastChunkY - chunkViewDistance,
                  lastChunkZ - chunkViewDistance),
              chunkViewDistance * 2);
      Cube newView =
          new Cube(
              new Point(
                  world,
                  currentChunkX - chunkViewDistance,
                  currentChunkY - chunkViewDistance,
                  currentChunkZ - chunkViewDistance),
              chunkViewDistance * 2);

      Vector3 min = oldView.getBase().min(newView.getBase());
      Vector3 max =
          oldView.getBase().add(oldView.getSize()).max(newView.getBase().add(newView.getSize()));

      // Shared area
      Vector3 ignoreMin = oldView.getBase().max(newView.getBase());
      Vector3 ignoreMax =
          oldView.getBase().add(oldView.getSize()).min(newView.getBase().add(newView.getSize()));
      Cuboid ignore = new Cuboid(new Point(ignoreMin, world), ignoreMax.subtract(ignoreMin));

      for (int x = min.getFloorX(); x < max.getFloorX(); x++) {
        for (int y = min.getFloorY(); y < max.getFloorY(); y++) {
          for (int z = min.getFloorZ(); z < max.getFloorZ(); z++) {
            Vector3 vec = new Vector3(x, y, z);
            if (ignore.contains(vec)) {
              continue;
            }

            Vector3 pos = ChunkMeshBatch.getChunkCoordinates(vec);

            if (oldView.contains(vec)) {
              ChunkMeshBatch c =
                  chunkRenderersByPosition.get(pos.getFloorX(), pos.getFloorY(), pos.getFloorZ());
              removeChunkMeshBatch(c);
              continue;
            }

            if (newView.contains(vec)) {
              ChunkMeshBatch c =
                  new ChunkMeshBatch(
                      material, world, pos.getFloorX(), pos.getFloorY(), pos.getFloorZ());
              addChunkMeshBatch(c);
              c.update();
            }
          }
        }
      }
    }

    firstUpdate = false;
    lastChunkX = currentChunkX;
    lastChunkY = currentChunkY;
    lastChunkZ = currentChunkZ;

    return true;
  }
 private static byte[] getEmptyChunk(int[][] heights, BlockMaterial[][] materials, Point p) {
   int chunkY = p.getChunkY();
   return chunkY <= 4 ? emptyGroundChunkData : emptySkyChunkData;
 }