Search in sources :

Example 1 with Region

use of org.terasology.world.generation.Region in project Terasology by MovingBlocks.

the class FacetLayerPreview method render.

@Override
public ByteBuffer render(TextureData texData, int scale, ProgressListener progressListener) throws InterruptedException {
    int width = texData.getWidth();
    int height = texData.getWidth();
    final int offX = -width * scale / 2;
    final int offY = -height * scale / 2;
    // trigger building the World now
    worldGenerator.getWorld();
    Rect2i worldArea = Rect2i.createFromMinAndSize(offX, offY, width * scale, height * scale);
    Rect2i tileArea = worldToTileArea(worldArea);
    AtomicInteger tilesComplete = new AtomicInteger(0);
    int tileCount = tileArea.area();
    int[] masks = colorModel.getMasks();
    DataBufferInt imageBuffer = new DataBufferInt(width * height);
    WritableRaster raster = Raster.createPackedRaster(imageBuffer, width, height, width, masks, null);
    BufferedImage view = new BufferedImage(colorModel, raster, false, null);
    Graphics2D g = view.createGraphics();
    g.scale(1f / scale, 1f / scale);
    g.translate(-offX, -offY);
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    Map<ImmutableVector2i, Future<BufferedImage>> imageFutures = new HashMap<>(tileCount);
    for (int z = tileArea.minY(); z < tileArea.maxY(); z++) {
        for (int x = tileArea.minX(); x < tileArea.maxX(); x++) {
            ImmutableVector2i pos = new ImmutableVector2i(x, z);
            imageFutures.put(pos, threadPool.submit(() -> {
                Region createRegion = createRegion(pos);
                BufferedImage image = rasterize(createRegion);
                if (progressListener != null) {
                    progressListener.onProgress(tilesComplete.incrementAndGet() / (float) tileCount);
                }
                return image;
            }));
        }
    }
    for (int z = tileArea.minY(); z < tileArea.maxY(); z++) {
        for (int x = tileArea.minX(); x < tileArea.maxX(); x++) {
            ImmutableVector2i pos = new ImmutableVector2i(x, z);
            try {
                BufferedImage tileImage = imageFutures.get(pos).get();
                g.drawImage(tileImage, x * TILE_SIZE_X, z * TILE_SIZE_Y, null);
            } catch (ExecutionException e) {
                logger.warn("Could not rasterize tile {}", pos, e);
            }
            if (Thread.currentThread().isInterrupted()) {
                throw new InterruptedException();
            }
        }
    }
    // draw coordinate lines through 0 / 0
    g.setColor(Color.GRAY);
    g.drawLine(worldArea.minX(), 0, worldArea.maxX(), 0);
    g.drawLine(0, worldArea.minY(), 0, worldArea.maxY());
    g.dispose();
    int[] data = imageBuffer.getData();
    ByteBuffer byteBuffer = texData.getBuffers()[0];
    byteBuffer.asIntBuffer().put(data);
    return byteBuffer;
}
Also used : HashMap(java.util.HashMap) DataBufferInt(java.awt.image.DataBufferInt) ByteBuffer(java.nio.ByteBuffer) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D) Rect2i(org.terasology.math.geom.Rect2i) ImmutableVector2i(org.terasology.math.geom.ImmutableVector2i) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WritableRaster(java.awt.image.WritableRaster) Future(java.util.concurrent.Future) Region(org.terasology.world.generation.Region) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with Region

use of org.terasology.world.generation.Region in project Terasology by MovingBlocks.

the class FacetLayerPreview method createRegion.

private Region createRegion(ImmutableVector2i chunkPos) {
    // 4 chunks high (relevant for trees, etc)
    int vertChunks = 4;
    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;
}
Also used : Vector3i(org.terasology.math.geom.Vector3i) Region(org.terasology.world.generation.Region) World(org.terasology.world.generation.World) Region3i(org.terasology.math.Region3i)

Example 3 with Region

use of org.terasology.world.generation.Region in project Terasology by MovingBlocks.

the class AbstractSpawner method findSpawnPosition.

/**
 * Tries to find a suitable spawning point based on {@link SurfaceHeightFacet} and {@link SeaLevelFacet}.
 * @param searchRadius the radius within a suitable spawning point will be searched
 * @param world the facet-based world
 * @param pos the desired 2D position in that world
 * @return a 3D position above the surface and sea level or <code>null</code> if none was found
 * @throws IllegalStateException if no SurfaceHeightFacet can be created.
 */
protected Vector3f findSpawnPosition(World world, Vector2i pos, int searchRadius) {
    Vector3i ext = new Vector3i(searchRadius, 1, searchRadius);
    Vector3i desiredPos = new Vector3i(pos.getX(), 1, pos.getY());
    // try and find somewhere in this region a spot to land
    Region3i spawnArea = Region3i.createFromCenterExtents(desiredPos, ext);
    Region worldRegion = world.getWorldData(spawnArea);
    // check if generation uses sea level and surface height facets
    SurfaceHeightFacet surfaceHeightFacet = worldRegion.getFacet(SurfaceHeightFacet.class);
    if (surfaceHeightFacet == null) {
        throw new IllegalStateException("surface height facet not found");
    }
    SeaLevelFacet seaLevelFacet = worldRegion.getFacet(SeaLevelFacet.class);
    int seaLevel = (seaLevelFacet != null) ? seaLevelFacet.getSeaLevel() : 0;
    int spiralRad = searchRadius / 2 - 1;
    SpiralIterable spiral = SpiralIterable.clockwise(pos).maxRadius(spiralRad).scale(2).build();
    for (BaseVector2i test : spiral) {
        float val = surfaceHeightFacet.getWorld(test.getX(), test.getY());
        int height = TeraMath.floorToInt(val);
        if (height >= seaLevel) {
            return new Vector3f(test.getX(), height, test.getY());
        }
    }
    // nothing above sea level found
    float y = surfaceHeightFacet.getWorld(pos.getX(), pos.getY());
    return new Vector3f(pos.getX(), y, pos.getY());
}
Also used : SurfaceHeightFacet(org.terasology.world.generation.facets.SurfaceHeightFacet) Vector3f(org.terasology.math.geom.Vector3f) Vector3i(org.terasology.math.geom.Vector3i) BaseVector2i(org.terasology.math.geom.BaseVector2i) Region(org.terasology.world.generation.Region) SeaLevelFacet(org.terasology.world.generation.facets.SeaLevelFacet) SpiralIterable(org.terasology.math.geom.SpiralIterable) Region3i(org.terasology.math.Region3i)

Example 4 with Region

use of org.terasology.world.generation.Region in project Terasology by MovingBlocks.

the class FloraRasterizer method generateChunk.

@Override
public void generateChunk(CoreChunk chunk, Region chunkRegion) {
    FloraFacet facet = chunkRegion.getFacet(FloraFacet.class);
    WhiteNoise noise = new WhiteNoise(chunk.getPosition().hashCode());
    Map<BaseVector3i, FloraType> entries = facet.getRelativeEntries();
    // check if some other rasterizer has already placed something here
    entries.keySet().stream().filter(pos -> chunk.getBlock(pos).equals(air)).forEach(pos -> {
        FloraType type = entries.get(pos);
        List<Block> list = flora.get(type);
        int blockIdx = Math.abs(noise.intNoise(pos.x(), pos.y(), pos.z())) % list.size();
        Block block = list.get(blockIdx);
        chunk.setBlock(pos, block);
    });
}
Also used : BlockManager(org.terasology.world.block.BlockManager) Region(org.terasology.world.generation.Region) WorldRasterizer(org.terasology.world.generation.WorldRasterizer) Maps(com.google.common.collect.Maps) FloraFacet(org.terasology.core.world.generator.facets.FloraFacet) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) BaseVector3i(org.terasology.math.geom.BaseVector3i) Block(org.terasology.world.block.Block) CoreChunk(org.terasology.world.chunks.CoreChunk) Map(java.util.Map) CoreRegistry(org.terasology.registry.CoreRegistry) WhiteNoise(org.terasology.utilities.procedural.WhiteNoise) FloraFacet(org.terasology.core.world.generator.facets.FloraFacet) WhiteNoise(org.terasology.utilities.procedural.WhiteNoise) BaseVector3i(org.terasology.math.geom.BaseVector3i) Block(org.terasology.world.block.Block)

Example 5 with Region

use of org.terasology.world.generation.Region in project Terasology by MovingBlocks.

the class TreeFacetLayer method getWorldText.

@Override
public String getWorldText(Region region, int wx, int wy) {
    TreeFacet treeFacet = region.getFacet(TreeFacet.class);
    Region3i worldRegion = treeFacet.getWorldRegion();
    Region3i relativeRegion = treeFacet.getRelativeRegion();
    int rx = wx - worldRegion.minX() + relativeRegion.minX();
    int rz = wy - worldRegion.minZ() + relativeRegion.minZ();
    Vector2f relCursor = new Vector2f(rx, rz);
    CirclePicker<TreeGenerator> picker = new CirclePickerAll<>(relCursor, radiusFunc);
    for (Entry<BaseVector3i, TreeGenerator> entry : treeFacet.getRelativeEntries().entrySet()) {
        TreeGenerator treeGen = entry.getValue();
        BaseVector3i treePos = entry.getKey();
        picker.offer(treePos.getX(), treePos.getZ(), treeGen);
    }
    Set<TreeGenerator> picked = picker.getAll();
    // try to exit early first
    if (picked.isEmpty()) {
        return null;
    }
    if (picked.size() == 1) {
        TreeGenerator first = picked.iterator().next();
        return labelFunc.apply(first);
    }
    // convert to a stream of labels
    Stream<String> labels = picked.stream().map(labelFunc);
    // collect identical String elements and collect the count in a map
    Map<String, Long> counters = labels.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    // define a mapping from a map entry to a String representation
    // TODO: treat 1x occurrences like above (e.g. Tree instead of 1x Tree)
    Function<Entry<String, Long>, String> toStringFunc = e -> String.format("%dx %s", e.getValue(), e.getKey());
    // apply that mapping and join the Strings with a comma
    return counters.entrySet().stream().map(toStringFunc).collect(Collectors.joining(", "));
}
Also used : Color(java.awt.Color) Region(org.terasology.world.generation.Region) Region3i(org.terasology.math.Region3i) BufferedImage(java.awt.image.BufferedImage) TreeGenerator(org.terasology.core.world.generator.trees.TreeGenerator) Set(java.util.Set) RenderingHints(java.awt.RenderingHints) Vector2f(org.terasology.math.geom.Vector2f) CirclePickerAll(org.terasology.world.viewer.picker.CirclePickerAll) Renders(org.terasology.world.viewer.layers.Renders) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) AbstractFacetLayer(org.terasology.world.viewer.layers.AbstractFacetLayer) Stream(java.util.stream.Stream) TreeFacet(org.terasology.core.world.generator.facets.TreeFacet) BaseVector3i(org.terasology.math.geom.BaseVector3i) Graphics2D(java.awt.Graphics2D) Map(java.util.Map) Entry(java.util.Map.Entry) CirclePicker(org.terasology.world.viewer.picker.CirclePicker) ZOrder(org.terasology.world.viewer.layers.ZOrder) CirclePickerAll(org.terasology.world.viewer.picker.CirclePickerAll) TreeFacet(org.terasology.core.world.generator.facets.TreeFacet) TreeGenerator(org.terasology.core.world.generator.trees.TreeGenerator) Entry(java.util.Map.Entry) Vector2f(org.terasology.math.geom.Vector2f) BaseVector3i(org.terasology.math.geom.BaseVector3i) Region3i(org.terasology.math.Region3i)

Aggregations

Region (org.terasology.world.generation.Region)5 Region3i (org.terasology.math.Region3i)3 Graphics2D (java.awt.Graphics2D)2 BufferedImage (java.awt.image.BufferedImage)2 Map (java.util.Map)2 BaseVector3i (org.terasology.math.geom.BaseVector3i)2 Vector3i (org.terasology.math.geom.Vector3i)2 ImmutableList (com.google.common.collect.ImmutableList)1 Maps (com.google.common.collect.Maps)1 Color (java.awt.Color)1 RenderingHints (java.awt.RenderingHints)1 DataBufferInt (java.awt.image.DataBufferInt)1 WritableRaster (java.awt.image.WritableRaster)1 ByteBuffer (java.nio.ByteBuffer)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Entry (java.util.Map.Entry)1 Set (java.util.Set)1 ExecutionException (java.util.concurrent.ExecutionException)1 Future (java.util.concurrent.Future)1