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); }
/** * 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; }