Search in sources :

Example 1 with Region

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

the class AbstractSpawner method getStartHeight.

/**
 * Get the elevation at a single point, to use as the base point for searching.
 */
private int getStartHeight(World world, Vector2i pos) {
    BlockRegion spawnArea = new BlockRegion(pos.x(), 0, pos.y());
    Region worldRegion = world.getWorldData(spawnArea);
    ElevationFacet elevationFacet = worldRegion.getFacet(ElevationFacet.class);
    if (elevationFacet != null) {
        return (int) elevationFacet.getWorld(pos);
    } else {
        // We'll have to rely on the SurfaceHeightFacet or SpawnHeightFacet anyway, and those are purely 2D so the height doesn't matter.
        return 0;
    }
}
Also used : BlockRegion(org.terasology.engine.world.block.BlockRegion) Region(org.terasology.engine.world.generation.Region) BlockRegion(org.terasology.engine.world.block.BlockRegion) ElevationFacet(org.terasology.engine.world.generation.facets.ElevationFacet)

Example 2 with Region

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

the class AbstractSpawner method findSpawnPosition.

/**
 * Tries to find a suitable spawning point based on {@link SurfacesFacet} and {@link ElevationFacet}.
 * @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 required facets can be created.
 */
protected Vector3f findSpawnPosition(World world, Vector2i pos, int searchRadius) {
    Vector3i ext = new Vector3i(searchRadius, searchRadius, searchRadius);
    Vector3i desiredPos = new Vector3i(pos.x(), getStartHeight(world, pos), pos.y());
    // try and find somewhere in this region a spot to land
    BlockRegion spawnArea = new BlockRegion(desiredPos).expand(ext);
    Region worldRegion = world.getWorldData(spawnArea);
    Function<Vector2ic, Optional<Float>> getWorld;
    // check if generation uses sea level and surface height facets
    SurfacesFacet surfacesFacet = worldRegion.getFacet(SurfacesFacet.class);
    ElevationFacet elevationFacet = worldRegion.getFacet(ElevationFacet.class);
    SpawnHeightFacet spawnHeightFacet = worldRegion.getFacet(SpawnHeightFacet.class);
    if (spawnHeightFacet != null) {
        getWorld = v -> spawnHeightFacet.getWorld(v.x(), v.y());
    } else if (elevationFacet != null) {
        if (surfacesFacet != null) {
            getWorld = v -> surfacesFacet.getPrimarySurface(elevationFacet, v.x(), v.y());
        } else {
            getWorld = v -> Optional.of(elevationFacet.getWorld(v.x(), v.y()));
        }
    } else {
        throw new IllegalStateException("No spawn height facet or elevation facet facet found. Can't place spawn point.");
    }
    Function<Vector2ic, Optional<Integer>> getSeaLevel;
    SeaLevelFacet seaLevelFacet = worldRegion.getFacet(SeaLevelFacet.class);
    StrictlySparseSeaLevelFacet sparseSeaLevelFacet = worldRegion.getFacet(StrictlySparseSeaLevelFacet.class);
    if (sparseSeaLevelFacet != null) {
        getSeaLevel = v -> sparseSeaLevelFacet.getSeaLevel(v.x(), v.y());
    } else if (seaLevelFacet != null) {
        getSeaLevel = v -> Optional.of(seaLevelFacet.getSeaLevel());
    } else {
        getSeaLevel = v -> Optional.of(0);
    }
    int spiralRad = searchRadius / 2 - 1;
    SpiralIterable spiral = SpiralIterable.clockwise(pos).maxRadius(spiralRad).scale(2).build();
    for (Vector2ic test : spiral) {
        Optional<Float> val = getWorld.apply(test);
        if (!val.isPresent()) {
            continue;
        }
        int height = TeraMath.floorToInt(val.get());
        if (!getSeaLevel.apply(test).isPresent() || height >= getSeaLevel.apply(test).get()) {
            return new Vector3f(test.x(), height, test.y());
        }
    }
    // nothing above sea level found
    for (Vector2ic test : spiral) {
        Optional<Float> val = getWorld.apply(test);
        if (!val.isPresent()) {
            continue;
        }
        return new Vector3f(test.x(), TeraMath.floorToInt(val.get()), test.y());
    }
    throw new IllegalStateException("No spawn location found");
}
Also used : SpawnHeightFacet(org.terasology.engine.world.generation.facets.SpawnHeightFacet) BlockRegion(org.terasology.engine.world.block.BlockRegion) Region(org.terasology.engine.world.generation.Region) StrictlySparseSeaLevelFacet(org.terasology.engine.world.generation.facets.StrictlySparseSeaLevelFacet) ElevationFacet(org.terasology.engine.world.generation.facets.ElevationFacet) World(org.terasology.engine.world.generation.World) Function(java.util.function.Function) SurfacesFacet(org.terasology.engine.world.generation.facets.SurfacesFacet) Vector2ic(org.joml.Vector2ic) Vector2i(org.joml.Vector2i) Vector3i(org.joml.Vector3i) SpiralIterable(org.terasology.engine.math.SpiralIterable) SeaLevelFacet(org.terasology.engine.world.generation.facets.SeaLevelFacet) Vector3f(org.joml.Vector3f) Optional(java.util.Optional) TeraMath(org.terasology.math.TeraMath) Optional(java.util.Optional) ElevationFacet(org.terasology.engine.world.generation.facets.ElevationFacet) StrictlySparseSeaLevelFacet(org.terasology.engine.world.generation.facets.StrictlySparseSeaLevelFacet) SurfacesFacet(org.terasology.engine.world.generation.facets.SurfacesFacet) Vector2ic(org.joml.Vector2ic) Vector3f(org.joml.Vector3f) Vector3i(org.joml.Vector3i) BlockRegion(org.terasology.engine.world.block.BlockRegion) Region(org.terasology.engine.world.generation.Region) BlockRegion(org.terasology.engine.world.block.BlockRegion) StrictlySparseSeaLevelFacet(org.terasology.engine.world.generation.facets.StrictlySparseSeaLevelFacet) SeaLevelFacet(org.terasology.engine.world.generation.facets.SeaLevelFacet) SpiralIterable(org.terasology.engine.math.SpiralIterable) SpawnHeightFacet(org.terasology.engine.world.generation.facets.SpawnHeightFacet)

Example 3 with Region

use of org.terasology.engine.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();
    Rectanglei worldArea = new Rectanglei(offX, offY).setSize(width * scale, height * scale);
    Rectanglei 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<Vector2ic, Future<BufferedImage>> imageFutures = new HashMap<>(tileCount);
    for (int z = tileArea.minY(); z < tileArea.maxY(); z++) {
        for (int x = tileArea.minX(); x < tileArea.maxX(); x++) {
            Vector2i pos = new Vector2i(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++) {
            Vector2i pos = new Vector2i(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) Rectanglei(org.terasology.joml.geom.Rectanglei) DataBufferInt(java.awt.image.DataBufferInt) ByteBuffer(java.nio.ByteBuffer) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WritableRaster(java.awt.image.WritableRaster) Vector2ic(org.joml.Vector2ic) Future(java.util.concurrent.Future) BlockRegion(org.terasology.engine.world.block.BlockRegion) Region(org.terasology.engine.world.generation.Region) Vector2i(org.joml.Vector2i) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

BlockRegion (org.terasology.engine.world.block.BlockRegion)3 Region (org.terasology.engine.world.generation.Region)3 Vector2i (org.joml.Vector2i)2 Vector2ic (org.joml.Vector2ic)2 ElevationFacet (org.terasology.engine.world.generation.facets.ElevationFacet)2 Graphics2D (java.awt.Graphics2D)1 BufferedImage (java.awt.image.BufferedImage)1 DataBufferInt (java.awt.image.DataBufferInt)1 WritableRaster (java.awt.image.WritableRaster)1 ByteBuffer (java.nio.ByteBuffer)1 HashMap (java.util.HashMap)1 Optional (java.util.Optional)1 ExecutionException (java.util.concurrent.ExecutionException)1 Future (java.util.concurrent.Future)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Function (java.util.function.Function)1 Vector3f (org.joml.Vector3f)1 Vector3i (org.joml.Vector3i)1 SpiralIterable (org.terasology.engine.math.SpiralIterable)1 World (org.terasology.engine.world.generation.World)1