use of org.joml.Vector2ic in project Terasology by MovingBlocks.
the class LayeredZoneRegionFunctionTest method setup.
@BeforeEach
public void setup() {
parent.addZone(new Zone("Medium sky", new LayeredZoneRegionFunction(new MinMaxLayerThickness(100, 100), MEDIUM_SKY))).addZone(new Zone("Low sky", new LayeredZoneRegionFunction(new MinMaxLayerThickness(100, 100), LOW_SKY))).addZone(new Zone("Above ground", new LayeredZoneRegionFunction(new MinMaxLayerThickness(100, 100), ABOVE_GROUND))).addZone(new Zone("Ground", new LayeredZoneRegionFunction(new MinMaxLayerThickness(100, 100), GROUND))).addZone(new Zone("Shallow underground", new LayeredZoneRegionFunction(new MinMaxLayerThickness(100, 100), SHALLOW_UNDERGROUND))).addZone(new Zone("Medium underground", new LayeredZoneRegionFunction(new MinMaxLayerThickness(100, 100), MEDIUM_UNDERGROUND)));
parent.setSeed(12345);
parent.initialize();
ListMultimap<Class<? extends WorldFacet>, FacetProvider> facetProviderChains = ArrayListMultimap.create();
facetProviderChains.put(ElevationFacet.class, (generatingRegion) -> {
ElevationFacet facet = new ElevationFacet(generatingRegion.getRegion(), generatingRegion.getBorderForFacet(ElevationFacet.class));
for (Vector2ic pos : facet.getRelativeArea()) {
facet.set(pos, 100);
}
generatingRegion.setRegionFacet(ElevationFacet.class, facet);
});
Map<Class<? extends WorldFacet>, Border3D> borders = new HashMap<>();
borders.put(ElevationFacet.class, new Border3D(0, 0, 0));
region = new RegionImpl(new BlockRegion(0, 0, 0).expand(4, 4, 4), facetProviderChains, borders, 1);
}
use of org.joml.Vector2ic in project Terasology by MovingBlocks.
the class PlayerFactory method findSpawnPos.
private Optional<Vector3f> findSpawnPos(Vector3fc targetPos, float entityHeight) {
int targetBlockX = TeraMath.floorToInt(targetPos.x());
int targetBlockY = TeraMath.floorToInt(targetPos.y());
int targetBlockZ = TeraMath.floorToInt(targetPos.z());
Vector2i center = new Vector2i(targetBlockX, targetBlockZ);
for (Vector2ic pos : SpiralIterable.clockwise(center).maxRadius(32).scale(2).build()) {
Vector3i testPos = new Vector3i(pos.x(), targetBlockY, pos.y());
Vector3i spawnPos = findOpenVerticalPosition(testPos, entityHeight);
if (spawnPos != null) {
return Optional.of(new Vector3f(spawnPos.x(), spawnPos.y() + entityHeight, spawnPos.z()));
}
}
return Optional.empty();
}
use of org.joml.Vector2ic 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");
}
use of org.joml.Vector2ic in project Terasology by MovingBlocks.
the class BlockAreaTest method testIterator.
@Test
public void testIterator() {
BlockArea a = new BlockArea(0, 0, 2, 2);
// Make sure the iterator visits positions in the correct order, and that it works without calling hasNext() in between
Iterator<Vector2ic> i = a.iterator();
assertEquals(i.next(), new Vector2i(0, 0));
assertEquals(i.next(), new Vector2i(1, 0));
assertEquals(i.next(), new Vector2i(2, 0));
assertEquals(i.next(), new Vector2i(0, 1));
assertEquals(i.next(), new Vector2i(1, 1));
assertEquals(i.next(), new Vector2i(2, 1));
assertEquals(i.next(), new Vector2i(0, 2));
assertEquals(i.next(), new Vector2i(1, 2));
assertEquals(i.next(), new Vector2i(2, 2));
assertFalse(i.hasNext());
}
use of org.joml.Vector2ic 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;
}
Aggregations