/** * @param offset * @return A copy of the region offset by the given value */ public Region3i move(BaseVector3i offset) { Vector3i newMin = min(); newMin.add(offset); return Region3i.createFromMinAndSize(newMin, size); }
private Region createRegion(ImmutableVector2i chunkPos) { int vertChunks = 4; // 4 chunks high (relevant for trees, etc) int minX = chunkPos.getX() * TILE_SIZE_X; int minZ = chunkPos.getY() * TILE_SIZE_Y; int height = vertChunks * ChunkConstants.SIZE_Y; Region3i area3d = Region3i.createFromMinAndSize(new Vector3i(minX, 0, minZ), new Vector3i(TILE_SIZE_X, height, TILE_SIZE_Y)); World world = worldGenerator.getWorld(); Region region = world.getWorldData(area3d); return region; }
@Override public Region3i deserialize(PersistedData data, DeserializationContext context) { if (!data.isNull() && data.isValueMap()) { PersistedDataMap map = data.getAsValueMap(); Vector3i min = context.deserializeAs(map.get(MIN_FIELD), Vector3i.class); Vector3i size = context.deserializeAs(map.get(SIZE_FIELD), Vector3i.class); return Region3i.createFromMinAndSize(min, size); } return null; }
public ChunkImpl(Vector3i chunkPos, TeraArray blocks, TeraArray biome, TeraArray[] extra, BlockManager blockManager, BiomeManager biomeManager) { this.chunkPos.set(Preconditions.checkNotNull(chunkPos)); this.blockData = Preconditions.checkNotNull(blocks); this.biomeData = Preconditions.checkNotNull(biome); this.extraData = Preconditions.checkNotNull(extra); sunlightData = new TeraDenseArray8Bit(getChunkSizeX(), getChunkSizeY(), getChunkSizeZ()); sunlightRegenData = new TeraDenseArray8Bit(getChunkSizeX(), getChunkSizeY(), getChunkSizeZ()); lightData = new TeraDenseArray8Bit(getChunkSizeX(), getChunkSizeY(), getChunkSizeZ()); dirty = true; this.blockManager = blockManager; this.biomeManager = biomeManager; region = Region3i.createFromMinAndSize(new Vector3i(chunkPos.x * ChunkConstants.SIZE_X, chunkPos.y * ChunkConstants.SIZE_Y, chunkPos.z * ChunkConstants.SIZE_Z), ChunkConstants.CHUNK_SIZE); ChunkMonitor.fireChunkCreated(this); }
@Override public void propagateBetween(LitChunk chunk, LitChunk adjChunk, Side side, boolean propagateExternal) { IndexProvider indexProvider = createIndexProvider(side); Region3i edgeRegion = ChunkMath.getEdgeRegion(Region3i.createFromMinAndSize(Vector3i.zero(), ChunkConstants.CHUNK_SIZE), side); int edgeSize = edgeRegion.size().x * edgeRegion.size().y * edgeRegion.size().z; int[] depth = new int[edgeSize]; propagateSide(chunk, adjChunk, side, indexProvider, edgeRegion, depth); propagateDepth(adjChunk, side, propagateExternal, indexProvider, edgeRegion, depth); }
@Test public void testCreateRegionWithMinAndSize() { List<Vector3i> mins = Arrays.asList(new Vector3i(), new Vector3i(1, 1, 1), new Vector3i(3, 4, 5)); List<Vector3i> size = Arrays.asList(new Vector3i(1, 1, 1), new Vector3i(3, 3, 3), new Vector3i(8, 5, 2)); List<Vector3i> expectedMax = Arrays.asList(new Vector3i(), new Vector3i(3, 3, 3), new Vector3i(10, 8, 6)); for (int i = 0; i < mins.size(); ++i) { Region3i region = Region3i.createFromMinAndSize(mins.get(i), size.get(i)); assertEquals(mins.get(i), region.min()); assertEquals(size.get(i), region.size()); assertEquals(expectedMax.get(i), region.max()); assertFalse(region.isEmpty()); } }
@Test public void testBlockedAtTopSunlightRegenPropagationResets() { Chunk chunk = new ChunkImpl(0, 0, 0, blockManager, biomeManager, extraDataManager); for (Vector3i pos : Region3i.createFromMinAndSize(new Vector3i(0, 63, 0), new Vector3i(ChunkConstants.SIZE_X, 1, ChunkConstants.SIZE_Z))) { chunk.setBlock(pos, solidBlock); } InternalLightProcessor.generateInternalLighting(chunk); for (Vector3i pos : Region3i.createFromMinAndSize(Vector3i.zero(), new Vector3i(ChunkConstants.SIZE_X, ChunkConstants.SIZE_Y - 1, ChunkConstants.SIZE_Z))) { byte expectedRegen = (byte) Math.min(ChunkConstants.SIZE_Y - pos.y - 2, ChunkConstants.MAX_SUNLIGHT_REGEN); assertEquals(expectedRegen, chunk.getSunlightRegen(pos)); } }
@Test public void testRegionEmptyIfSizeZeroOrLess() { Region3i region = Region3i.createFromMinAndSize(new Vector3i(1, 1, 1), new Vector3i(0, 1, 1)); assertTrue(region.isEmpty()); region = Region3i.createFromMinAndSize(new Vector3i(1, 1, 1), new Vector3i(1, -1, 1)); assertTrue(region.isEmpty()); }
@Test public void testUnblockedSunlightRegenPropagation() { Chunk chunk = new ChunkImpl(0, 0, 0, blockManager, biomeManager, extraDataManager); InternalLightProcessor.generateInternalLighting(chunk); for (Vector3i pos : Region3i.createFromMinAndSize(Vector3i.zero(), new Vector3i(ChunkConstants.SIZE_X, ChunkConstants.SIZE_Y, ChunkConstants.SIZE_Z))) { byte expectedRegen = (byte) Math.min(ChunkConstants.SIZE_Y - pos.y - 1, ChunkConstants.MAX_SUNLIGHT_REGEN); assertEquals(expectedRegen, chunk.getSunlightRegen(pos)); } }
@Test public void testBlockedSunlightPropagation() { Chunk chunk = new ChunkImpl(0, 0, 0, blockManager, biomeManager, extraDataManager); for (Vector3i pos : Region3i.createFromMinAndSize(new Vector3i(0, 4, 0), new Vector3i(ChunkConstants.SIZE_X, 1, ChunkConstants.SIZE_Z))) { chunk.setBlock(pos, solidBlock); } InternalLightProcessor.generateInternalLighting(chunk); for (Vector3i pos : Region3i.createFromMinAndSize(new Vector3i(0, 0, 0), new Vector3i(ChunkConstants.SIZE_X, 5, ChunkConstants.SIZE_Z))) { assertEquals("Incorrect lighting at " + pos, 0, chunk.getSunlight(pos)); } }
@Test public void testUnblockedSunlightPropagationAfterHittingMaxRegen() { Chunk chunk = new ChunkImpl(0, 0, 0, blockManager, biomeManager, extraDataManager); InternalLightProcessor.generateInternalLighting(chunk); for (Vector3i pos : Region3i.createFromMinAndSize(new Vector3i(0, 15, 0), new Vector3i(ChunkConstants.SIZE_X, ChunkConstants.SIZE_Y - 15, ChunkConstants.SIZE_Z))) { assertEquals(0, chunk.getSunlight(pos)); } for (Vector3i pos : Region3i.createFromMinAndSize(Vector3i.zero(), new Vector3i(ChunkConstants.SIZE_X, ChunkConstants.SIZE_Y - ChunkConstants.MAX_SUNLIGHT_REGEN, ChunkConstants.SIZE_Z))) { byte expectedSunlight = (byte) Math.min(ChunkConstants.SIZE_Y - ChunkConstants.SUNLIGHT_REGEN_THRESHOLD - pos.y - 1, ChunkConstants.MAX_SUNLIGHT); assertEquals("Incorrect lighting at " + pos, expectedSunlight, chunk.getSunlight(pos)); } }
@Before public void setup() { Border3D border = new Border3D(0, 0, 0).extendBy(0, 15, 10); Vector3i min = new Vector3i(10, 20, 30); Vector3i size = new Vector3i(40, 50, 60); Region3i region = Region3i.createFromMinAndSize(min, size); facet = createFacet(region, border); // facet = [worldMin=(0, 5, 20), relativeMin=(-10, -15, -10), size=(60, 65, 80)] }
public void setChunkSize(Vector3i chunkSize) { this.chunkFilterSize = new Vector3i(TeraMath.ceilPowerOfTwo(chunkSize.x) - 1, TeraMath.ceilPowerOfTwo(chunkSize.y) - 1, TeraMath.ceilPowerOfTwo(chunkSize.z) - 1); this.chunkPower = new Vector3i(TeraMath.sizeOfPower(chunkSize.x), TeraMath.sizeOfPower(chunkSize.y), TeraMath.sizeOfPower(chunkSize.z)); Vector3i blockMin = new Vector3i(); blockMin.sub(offset); blockMin.mul(chunkSize.x, chunkSize.y, chunkSize.z); Vector3i blockSize = chunkRegion.size(); blockSize.mul(chunkSize.x, chunkSize.y, chunkSize.z); this.blockRegion = Region3i.createFromMinAndSize(blockMin, blockSize); }
@Before public void setup() { Border3D border = new Border3D(0, 0, 0).extendBy(0, 15, 10); Vector3i min = new Vector3i(10, 20, 30); Vector3i size = new Vector3i(40, 50, 60); Region3i region = Region3i.createFromMinAndSize(min, size); facet = createFacet(region, border); // facet = [worldMin=(0, 5, 20), relativeMin=(-10, -15, -10), size=(60, 65, 80)] }
@Before public void setup() { Border3D border = new Border3D(0, 0, 0).extendBy(0, 15, 10); Vector3i min = new Vector3i(10, 20, 30); Vector3i size = new Vector3i(40, 50, 60); Region3i region = Region3i.createFromMinAndSize(min, size); facet = createFacet(region, border); // facet = [worldMin=(0, 5, 20), relativeMin=(-10, -15, -10), size=(60, 65, 80)] }
@Test public void testUnblockedSunlightPropagation() { Chunk chunk = new ChunkImpl(0, 0, 0, blockManager, biomeManager, extraDataManager); InternalLightProcessor.generateInternalLighting(chunk); for (Vector3i pos : Region3i.createFromMinAndSize(new Vector3i(0, 0, 0), new Vector3i(ChunkConstants.SIZE_X, 15, ChunkConstants.SIZE_Z))) { assertEquals("Incorrect lighting at " + pos, 15 - pos.y, chunk.getSunlight(pos)); } }
@Test public void testGetEdgeRegion() { Region3i region = Region3i.createFromMinAndSize(new Vector3i(16, 0, 16), new Vector3i(16, 128, 16)); assertEquals(Region3i.createFromMinMax(new Vector3i(16, 0, 16), new Vector3i(16, 127, 31)), ChunkMath.getEdgeRegion(region, Side.LEFT)); }
@Test public void testCumulativeBorderCalculation() { WorldBuilder worldBuilder = new WorldBuilder(context.get(WorldGeneratorPluginLibrary.class)); worldBuilder.setSeed(12); worldBuilder.addProvider(new Facet1Provider()); worldBuilder.addProvider(new Facet2Provider()); worldBuilder.addProvider(new Facet3Provider()); World world = worldBuilder.build(); Region3i regionToGenerate = Region3i.createFromCenterExtents(new Vector3i(), 1); Region regionData = world.getWorldData(regionToGenerate); Facet3 facet3 = regionData.getFacet(Facet3.class); assertEquals(regionToGenerate, facet3.getWorldRegion()); Facet1 facet1 = regionData.getFacet(Facet1.class); assertEquals(Region3i.createFromMinAndSize(new Vector3i(-2, -1, -2), new Vector3i(5, 3, 5)), facet1.getWorldRegion()); Facet2 facet2 = regionData.getFacet(Facet2.class); assertEquals(Region3i.createFromMinAndSize(new Vector3i(-4, -1, -4), new Vector3i(9, 3, 9)), facet2.getWorldRegion()); }
@Test public void testBorderCalculation() { WorldBuilder worldBuilder = new WorldBuilder(context.get(WorldGeneratorPluginLibrary.class)); worldBuilder.setSeed(12); worldBuilder.addProvider(new Facet1Provider()); worldBuilder.addProvider(new Facet2Provider()); World world = worldBuilder.build(); Region3i regionToGenerate = Region3i.createFromCenterExtents(new Vector3i(), 1); Region regionData = world.getWorldData(regionToGenerate); Facet1 facet1 = regionData.getFacet(Facet1.class); assertEquals(regionToGenerate, facet1.getWorldRegion()); Facet2 facet2 = regionData.getFacet(Facet2.class); assertEquals(Region3i.createFromMinAndSize(new Vector3i(-3, -1, -3), new Vector3i(7, 3, 7)), facet2.getWorldRegion()); }
@Test public void testHorizontalSunlightPropagation() { Chunk chunk = new ChunkImpl(0, 0, 0, blockManager, biomeManager, extraDataManager); for (Vector3i pos : Region3i.createFromMinAndSize(new Vector3i(0, 4, 0), new Vector3i(ChunkConstants.SIZE_X, 1, ChunkConstants.SIZE_Z))) { chunk.setBlock(pos, solidBlock); } chunk.setBlock(new Vector3i(16, 4, 16), airBlock); InternalLightProcessor.generateInternalLighting(chunk); assertEquals(12, chunk.getSunlight(16, 3, 16)); assertEquals(11, chunk.getSunlight(15, 3, 16)); assertEquals(11, chunk.getSunlight(17, 3, 16)); assertEquals(11, chunk.getSunlight(16, 3, 15)); assertEquals(11, chunk.getSunlight(16, 3, 17)); assertEquals(12, chunk.getSunlight(15, 2, 16)); assertEquals(12, chunk.getSunlight(17, 2, 16)); assertEquals(12, chunk.getSunlight(16, 2, 15)); assertEquals(12, chunk.getSunlight(16, 2, 17)); }