Search in sources :

Example 16 with Point3i

use of javax.vecmath.Point3i in project WorldPainter by Captain-Chaos.

the class WPObjectExporter method getBounds.

private static Box getBounds(WPObject object, int x, int y, int z) {
    Point3i dimensions = object.getDimensions();
    Point3i offset = object.getOffset();
    return new Box(x + offset.x, x + offset.x + dimensions.x - 1, y + offset.y, y + offset.y + dimensions.y - 1, z + offset.z, z + offset.z + dimensions.z - 1);
}
Also used : Point3i(javax.vecmath.Point3i) Box(org.pepsoft.util.Box)

Example 17 with Point3i

use of javax.vecmath.Point3i in project WorldPainter by Captain-Chaos.

the class CavesExporter method render.

@Override
public List<Fixup> render(Dimension dimension, Rectangle area, Rectangle exportedArea, MinecraftWorld minecraftWorld) {
    CavesSettings settings = (CavesSettings) getSettings();
    int minZ = Math.max(settings.getMinimumLevel(), dimension.isBottomless() ? 0 : 1), maxZForWorld = Math.min(settings.getMaximumLevel(), minecraftWorld.getMaxHeight() - 1);
    boolean surfaceBreaking = settings.isSurfaceBreaking();
    Random random = new Random();
    CaveSettings caveSettings = new CaveSettings();
    caveSettings.minZ = minZ;
    // Grow the area we will check for spawning caves, such that parts of
    // caves which start outside the exported area are still rendered inside
    // the exported area
    Rectangle spawnArea = (Rectangle) exportedArea.clone();
    spawnArea.grow(MAX_CAVE_LENGTH, MAX_CAVE_LENGTH);
    // Go tile by tile, so we can quickly check whether the tile even
    // exists and contains the layer and if not skip it entirely
    int tileX1 = spawnArea.x >> TILE_SIZE_BITS, tileX2 = (spawnArea.x + spawnArea.width - 1) >> TILE_SIZE_BITS;
    int tileY1 = spawnArea.y >> TILE_SIZE_BITS, tileY2 = (spawnArea.y + spawnArea.height - 1) >> TILE_SIZE_BITS;
    for (int tileX = tileX1; tileX <= tileX2; tileX++) {
        for (int tileY = tileY1; tileY <= tileY2; tileY++) {
            Tile tile = dimension.getTile(tileX, tileY);
            if ((tile == null) || (!tile.hasLayer(Caves.INSTANCE))) {
                continue;
            }
            for (int xInTile = 0; xInTile < TILE_SIZE; xInTile++) {
                for (int yInTile = 0; yInTile < TILE_SIZE; yInTile++) {
                    int x = (tileX << TILE_SIZE_BITS) | xInTile, y = (tileY << TILE_SIZE_BITS) | yInTile;
                    int value = tile.getLayerValue(Caves.INSTANCE, xInTile, yInTile);
                    if (value > 0) {
                        int height = tile.getIntHeight(xInTile, yInTile);
                        int maxZ = Math.min(maxZForWorld, height - (surfaceBreaking ? 0 : dimension.getTopLayerDepth(x, y, height)));
                        random.setSeed(dimension.getSeed() + x * 65537 + y);
                        for (int z = minZ; z <= maxZ; z++) {
                            if (value > random.nextInt(CAVE_CHANCE)) {
                                caveSettings.start = new Point3i(x, y, z);
                                caveSettings.length = MathUtils.clamp(0, (int) ((random.nextGaussian() + 2.0) * (MAX_CAVE_LENGTH / 3.0) + 0.5), MAX_CAVE_LENGTH);
                                createTunnel(minecraftWorld, dimension, new Random(random.nextLong()), caveSettings);
                            }
                        }
                    }
                }
            }
        }
    }
    return null;
}
Also used : Point3i(javax.vecmath.Point3i) Random(java.util.Random) Tile(org.pepsoft.worldpainter.Tile)

Example 18 with Point3i

use of javax.vecmath.Point3i in project WorldPainter by Captain-Chaos.

the class TunnelLayerExporter method render.

@Override
public List<Fixup> render(Dimension dimension, Rectangle area, Rectangle exportedArea, MinecraftWorld world) {
    final TunnelLayer.Mode floorMode = layer.getFloorMode(), roofMode = layer.getRoofMode();
    final int floorWallDepth = layer.getFloorWallDepth(), roofWallDepth = layer.getRoofWallDepth(), floorLevel = layer.getFloorLevel(), roofLevel = layer.getRoofLevel(), maxWallDepth = Math.max(floorWallDepth, roofWallDepth) + 1, floorMin = layer.getFloorMin(), floorMax = layer.getFloorMax(), roofMin = layer.getRoofMin(), roofMax = layer.getRoofMax(), floodLevel = layer.getFloodLevel();
    final int minZ = dimension.isBottomless() ? 0 : 1, maxZ = dimension.getMaxHeight() - 1;
    final boolean removeWater = layer.isRemoveWater(), floodWithLava = layer.isFloodWithLava();
    final MixedMaterial floorMaterial = layer.getFloorMaterial(), wallMaterial = layer.getWallMaterial(), roofMaterial = layer.getRoofMaterial();
    if (floorNoise != null) {
        floorNoise.setSeed(dimension.getSeed());
    }
    if (roofNoise != null) {
        roofNoise.setSeed(dimension.getSeed());
    }
    if ((floorMaterial == null) && (wallMaterial == null) && (roofMaterial == null)) {
        // One pass: just remove blocks
        for (int x = area.x; x < area.x + area.width; x++) {
            for (int y = area.y; y < area.y + area.height; y++) {
                if (dimension.getBitLayerValueAt(layer, x, y)) {
                    final int terrainHeight = dimension.getIntHeightAt(x, y);
                    int actualFloorLevel = calculateLevel(floorMode, floorLevel, terrainHeight, floorMin, floorMax, minZ, maxZ, (floorNoise != null) ? ((int) floorNoise.getHeight(x, y) - floorNoiseOffset) : 0);
                    int actualRoofLevel = calculateLevel(roofMode, roofLevel, terrainHeight, roofMin, roofMax, minZ, maxZ, (roofNoise != null) ? ((int) roofNoise.getHeight(x, y) - roofNoiseOffset) : 0);
                    if (actualRoofLevel <= actualFloorLevel) {
                        continue;
                    }
                    final float distanceToWall = dimension.getDistanceToEdge(layer, x, y, maxWallDepth) - 1;
                    final int floorLedgeHeight = calculateLedgeHeight(floorWallDepth, distanceToWall);
                    final int roofLedgeHeight = calculateLedgeHeight(roofWallDepth, distanceToWall);
                    actualFloorLevel += floorLedgeHeight;
                    actualRoofLevel -= roofLedgeHeight;
                    if (actualRoofLevel <= actualFloorLevel) {
                        continue;
                    }
                    final int waterLevel = dimension.getWaterLevelAt(x, y);
                    for (int z = Math.min(removeWater ? Math.max(terrainHeight, waterLevel) : terrainHeight, actualRoofLevel); z > actualFloorLevel; z--) {
                        if (removeWater || (z <= terrainHeight) || (z > waterLevel)) {
                            if (z <= floodLevel) {
                                world.setMaterialAt(x, y, z, floodWithLava ? Material.LAVA : Material.WATER);
                            } else {
                                world.setMaterialAt(x, y, z, Material.AIR);
                            }
                        }
                    }
                    if (actualFloorLevel == 0) {
                        // probably what the user wants
                        if ((floodLevel > 0) && (0 <= floodLevel)) {
                            world.setMaterialAt(x, y, 0, floodWithLava ? Material.STATIONARY_LAVA : Material.STATIONARY_WATER);
                        } else {
                            world.setMaterialAt(x, y, 0, Material.AIR);
                        }
                    }
                }
            }
        }
    } else {
        // excavate the interior
        for (int x = area.x; x < area.x + area.width; x++) {
            for (int y = area.y; y < area.y + area.height; y++) {
                if (dimension.getBitLayerValueAt(layer, x, y)) {
                    int terrainHeight = dimension.getIntHeightAt(x, y);
                    int actualFloorLevel = calculateLevel(floorMode, floorLevel, terrainHeight, floorMin, floorMax, minZ, maxZ, (floorNoise != null) ? ((int) floorNoise.getHeight(x, y) - floorNoiseOffset) : 0);
                    int actualRoofLevel = calculateLevel(roofMode, roofLevel, terrainHeight, roofMin, roofMax, minZ, maxZ, (roofNoise != null) ? ((int) roofNoise.getHeight(x, y) - roofNoiseOffset) : 0);
                    if (actualRoofLevel <= actualFloorLevel) {
                        continue;
                    }
                    final float distanceToWall = dimension.getDistanceToEdge(layer, x, y, maxWallDepth) - 1;
                    final int floorLedgeHeight = calculateLedgeHeight(floorWallDepth, distanceToWall);
                    final int roofLedgeHeight = calculateLedgeHeight(roofWallDepth, distanceToWall);
                    actualFloorLevel += floorLedgeHeight;
                    actualRoofLevel -= roofLedgeHeight;
                    if (actualRoofLevel <= actualFloorLevel) {
                        continue;
                    }
                    int waterLevel = dimension.getWaterLevelAt(x, y);
                    boolean flooded = waterLevel > terrainHeight;
                    final int startZ = Math.min(removeWater ? Math.max(terrainHeight, waterLevel) : terrainHeight, actualRoofLevel);
                    for (int z = startZ; z > actualFloorLevel; z--) {
                        if ((floorLedgeHeight == 0) && (floorMaterial != null)) {
                            setIfSolid(world, x, y, z - 1, minZ, maxZ, floorMaterial, flooded, terrainHeight, waterLevel, removeWater);
                        }
                        if (wallMaterial != null) {
                            if (floorLedgeHeight > 0) {
                                setIfSolid(world, x, y, z - 1, minZ, maxZ, wallMaterial, flooded, terrainHeight, waterLevel, removeWater);
                            }
                            if (roofLedgeHeight > 0) {
                                setIfSolid(world, x, y, z + 1, minZ, maxZ, wallMaterial, flooded, terrainHeight, waterLevel, removeWater);
                            }
                        }
                        if ((roofLedgeHeight == 0) && (roofMaterial != null)) {
                            setIfSolid(world, x, y, z + 1, minZ, maxZ, roofMaterial, flooded, terrainHeight, waterLevel, removeWater);
                        }
                    }
                    if (wallMaterial != null) {
                        terrainHeight = dimension.getIntHeightAt(x - 1, y);
                        waterLevel = dimension.getWaterLevelAt(x - 1, y);
                        flooded = waterLevel > terrainHeight;
                        for (int z = startZ; z > actualFloorLevel; z--) {
                            setIfSolid(world, x - 1, y, z, minZ, maxZ, wallMaterial, flooded, terrainHeight, waterLevel, removeWater);
                        }
                        terrainHeight = dimension.getIntHeightAt(x, y - 1);
                        waterLevel = dimension.getWaterLevelAt(x, y - 1);
                        flooded = waterLevel > terrainHeight;
                        for (int z = startZ; z > actualFloorLevel; z--) {
                            setIfSolid(world, x, y - 1, z, minZ, maxZ, wallMaterial, flooded, terrainHeight, waterLevel, removeWater);
                        }
                        terrainHeight = dimension.getIntHeightAt(x + 1, y);
                        waterLevel = dimension.getWaterLevelAt(x + 1, y);
                        flooded = waterLevel > terrainHeight;
                        for (int z = startZ; z > actualFloorLevel; z--) {
                            setIfSolid(world, x + 1, y, z, minZ, maxZ, wallMaterial, flooded, terrainHeight, waterLevel, removeWater);
                        }
                        terrainHeight = dimension.getIntHeightAt(x, y + 1);
                        waterLevel = dimension.getWaterLevelAt(x, y + 1);
                        flooded = waterLevel > terrainHeight;
                        for (int z = startZ; z > actualFloorLevel; z--) {
                            setIfSolid(world, x, y + 1, z, minZ, maxZ, wallMaterial, flooded, terrainHeight, waterLevel, removeWater);
                        }
                    }
                }
            }
        }
        // Second pass: excavate interior
        for (int x = area.x; x < area.x + area.width; x++) {
            for (int y = area.y; y < area.y + area.height; y++) {
                if (dimension.getBitLayerValueAt(layer, x, y)) {
                    final int terrainHeight = dimension.getIntHeightAt(x, y);
                    int actualFloorLevel = calculateLevel(floorMode, floorLevel, terrainHeight, floorMin, floorMax, minZ, maxZ, (floorNoise != null) ? ((int) floorNoise.getHeight(x, y) - floorNoiseOffset) : 0);
                    int actualRoofLevel = calculateLevel(roofMode, roofLevel, terrainHeight, roofMin, roofMax, minZ, maxZ, (roofNoise != null) ? ((int) roofNoise.getHeight(x, y) - roofNoiseOffset) : 0);
                    if (actualRoofLevel <= actualFloorLevel) {
                        continue;
                    }
                    final float distanceToWall = dimension.getDistanceToEdge(layer, x, y, maxWallDepth) - 1;
                    final int floorLedgeHeight = calculateLedgeHeight(floorWallDepth, distanceToWall);
                    final int roofLedgeHeight = calculateLedgeHeight(roofWallDepth, distanceToWall);
                    actualFloorLevel += floorLedgeHeight;
                    actualRoofLevel -= roofLedgeHeight;
                    if (actualRoofLevel <= actualFloorLevel) {
                        continue;
                    }
                    final int waterLevel = dimension.getWaterLevelAt(x, y);
                    for (int z = actualRoofLevel; z > actualFloorLevel; z--) {
                        if (removeWater || (z <= terrainHeight) || (z > waterLevel)) {
                            if (z <= floodLevel) {
                                world.setMaterialAt(x, y, z, floodWithLava ? Material.LAVA : Material.WATER);
                            } else {
                                world.setMaterialAt(x, y, z, Material.AIR);
                            }
                        }
                    }
                    if (actualFloorLevel == 0) {
                        // probably what the user wants
                        if ((floodLevel > 0) && (0 <= floodLevel)) {
                            world.setMaterialAt(x, y, 0, floodWithLava ? Material.LAVA : Material.WATER);
                        } else {
                            world.setMaterialAt(x, y, 0, Material.AIR);
                        }
                    }
                }
            }
        }
    }
    // Second/third pass: render floor layers
    List<Fixup> fixups = new ArrayList<>();
    final Map<Layer, TunnelLayer.LayerSettings> floorLayers = layer.getFloorLayers();
    if ((floorLayers != null) && (!floorLayers.isEmpty())) {
        final IncidentalLayerExporter[] floorExporters = new IncidentalLayerExporter[floorLayers.size()];
        final TunnelLayer.LayerSettings[] floorLayerSettings = new TunnelLayer.LayerSettings[floorLayers.size()];
        final NoiseHeightMap[] floorLayerNoise = new NoiseHeightMap[floorLayers.size()];
        int index = 0;
        for (Layer floorLayer : floorLayers.keySet()) {
            floorExporters[index] = (IncidentalLayerExporter) floorLayer.getExporter();
            TunnelLayer.LayerSettings layerSettings = floorLayers.get(floorLayer);
            floorLayerSettings[index] = layerSettings;
            if (layerSettings.getVariation() != null) {
                floorLayerNoise[index] = new NoiseHeightMap(layerSettings.getVariation(), index);
                floorLayerNoise[index].setSeed(dimension.getSeed());
            }
            index++;
        }
        final TunnelFloorDimension floorDimension = new TunnelFloorDimension(dimension, layer);
        for (int x = area.x; x < area.x + area.width; x++) {
            for (int y = area.y; y < area.y + area.height; y++) {
                if (dimension.getBitLayerValueAt(layer, x, y)) {
                    final int terrainHeight = dimension.getIntHeightAt(x, y);
                    int actualFloorLevel = calculateLevel(floorMode, floorLevel, terrainHeight, floorMin, floorMax, minZ, maxZ, (floorNoise != null) ? ((int) floorNoise.getHeight(x, y) - floorNoiseOffset) : 0);
                    int actualRoofLevel = calculateLevel(roofMode, roofLevel, terrainHeight, roofMin, roofMax, minZ, maxZ, (roofNoise != null) ? ((int) roofNoise.getHeight(x, y) - roofNoiseOffset) : 0);
                    if (actualRoofLevel <= actualFloorLevel) {
                        continue;
                    }
                    final float distanceToWall = dimension.getDistanceToEdge(layer, x, y, maxWallDepth) - 1;
                    final int floorLedgeHeight = calculateLedgeHeight(floorWallDepth, distanceToWall);
                    final int roofLedgeHeight = calculateLedgeHeight(roofWallDepth, distanceToWall);
                    actualFloorLevel += floorLedgeHeight;
                    actualRoofLevel -= roofLedgeHeight;
                    if ((actualRoofLevel <= actualFloorLevel) || (actualFloorLevel == 0)) {
                        continue;
                    }
                    final int z = actualFloorLevel + 1;
                    final Point3i location = new Point3i(x, y, z);
                    for (int i = 0; i < floorExporters.length; i++) {
                        if ((z >= floorLayerSettings[i].getMinLevel()) && (z <= floorLayerSettings[i].getMaxLevel())) {
                            final int intensity = floorLayerNoise[i] != null ? MathUtils.clamp(0, (int) (floorLayerSettings[i].getIntensity() + floorLayerNoise[i].getValue(x, y, z) + 0.5f), 100) : floorLayerSettings[i].getIntensity();
                            if (intensity > 0) {
                                Fixup fixup = floorExporters[i].apply(floorDimension, location, intensity, exportedArea, world);
                                if (fixup != null) {
                                    fixups.add(fixup);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return fixups.isEmpty() ? null : fixups;
}
Also used : ArrayList(java.util.ArrayList) Layer(org.pepsoft.worldpainter.layers.Layer) Point3i(javax.vecmath.Point3i) NoiseHeightMap(org.pepsoft.worldpainter.heightMaps.NoiseHeightMap) MixedMaterial(org.pepsoft.worldpainter.MixedMaterial)

Example 19 with Point3i

use of javax.vecmath.Point3i in project WorldPainter by Captain-Chaos.

the class JavaChunkStore method saveChunk.

@Override
public void saveChunk(Chunk chunk) {
    // actually there
    for (Iterator<TileEntity> i = chunk.getTileEntities().iterator(); i.hasNext(); ) {
        final TileEntity tileEntity = i.next();
        final Set<Integer> blockIds = Constants.TILE_ENTITY_MAP.get(tileEntity.getId());
        if (blockIds == null) {
            logger.warn("Unknown tile entity ID \"" + tileEntity.getId() + "\" encountered @ " + tileEntity.getX() + "," + tileEntity.getZ() + "," + tileEntity.getY() + "; can't check whether the corresponding block is there!");
        } else {
            final int existingBlockId = chunk.getBlockType(tileEntity.getX() & 0xf, tileEntity.getY(), tileEntity.getZ() & 0xf);
            if (!blockIds.contains(existingBlockId)) {
                // The block at the specified location
                // is not a tile entity, or a different
                // tile entity. Remove the data
                i.remove();
                if (logger.isDebugEnabled()) {
                    logger.debug("Removing tile entity " + tileEntity.getId() + " @ " + tileEntity.getX() + "," + tileEntity.getZ() + "," + tileEntity.getY() + " because the block at that location is a " + BLOCK_TYPE_NAMES[existingBlockId]);
                }
            }
        }
    }
    // Check that there aren't multiple tile entities (of the same type,
    // otherwise they would have been removed above) in the same location
    Set<Point3i> occupiedCoords = new HashSet<>();
    for (Iterator<TileEntity> i = chunk.getTileEntities().iterator(); i.hasNext(); ) {
        TileEntity tileEntity = i.next();
        Point3i coords = new Point3i(tileEntity.getX(), tileEntity.getZ(), tileEntity.getY());
        if (occupiedCoords.contains(coords)) {
            // There is already tile data for that location in the chunk;
            // remove this copy
            i.remove();
            logger.warn("Removing tile entity " + tileEntity.getId() + " @ " + tileEntity.getX() + "," + tileEntity.getZ() + "," + tileEntity.getY() + " because there is already a tile entity of the same type at that location");
        } else {
            occupiedCoords.add(coords);
        }
    }
    try {
        int x = chunk.getxPos(), z = chunk.getzPos();
        RegionFile regionFile = getOrCreateRegionFile(new Point(x >> 5, z >> 5));
        try (NBTOutputStream out = new NBTOutputStream(regionFile.getChunkDataOutputStream(x & 31, z & 31))) {
            out.writeTag(((NBTItem) chunk).toNBT());
        }
    } catch (IOException e) {
        throw new RuntimeException("I/O error saving chunk", e);
    }
// timeSpentSaving += System.currentTimeMillis() - start;
}
Also used : IOException(java.io.IOException) NBTOutputStream(org.jnbt.NBTOutputStream) Point3i(javax.vecmath.Point3i)

Example 20 with Point3i

use of javax.vecmath.Point3i in project WorldPainter by Captain-Chaos.

the class WPDynmapWorld method forMinecraftMap.

public static WPDynmapWorld forMinecraftMap(File worldDir, int dim) throws IOException {
    File levelDatFile = new File(worldDir, "level.dat");
    Level level = Level.load(levelDatFile);
    return forMinecraftWorld(new JavaMinecraftWorld(worldDir, dim, level.getMaxHeight(), level.getVersion() == org.pepsoft.minecraft.Constants.SUPPORTED_VERSION_1 ? DefaultPlugin.JAVA_MCREGION : DefaultPlugin.JAVA_ANVIL, true, 256), level.getName(), dim, 62, new Point3i(level.getSpawnX(), level.getSpawnZ(), level.getSpawnY()));
}
Also used : Point3i(javax.vecmath.Point3i) File(java.io.File) JavaMinecraftWorld(org.pepsoft.worldpainter.exporting.JavaMinecraftWorld)

Aggregations

Point3i (javax.vecmath.Point3i)22 Material (org.pepsoft.minecraft.Material)3 Box (org.pepsoft.util.Box)3 WPObject (org.pepsoft.worldpainter.objects.WPObject)3 HashMap (java.util.HashMap)2 TileEntity (org.pepsoft.minecraft.TileEntity)2 DefaultMaterial (com.khorn.terraincontrol.util.minecraftTypes.DefaultMaterial)1 Graphics2D (java.awt.Graphics2D)1 BufferedImage (java.awt.image.BufferedImage)1 File (java.io.File)1 IOException (java.io.IOException)1 Serializable (java.io.Serializable)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Random (java.util.Random)1 GZIPInputStream (java.util.zip.GZIPInputStream)1 NBTOutputStream (org.jnbt.NBTOutputStream)1 Block (org.pepsoft.minecraft.Block)1 Chunk (org.pepsoft.minecraft.Chunk)1 Entity (org.pepsoft.minecraft.Entity)1