use of org.pepsoft.worldpainter.Tile in project WorldPainter by Captain-Chaos.
the class Background3DTileRenderer method run.
@Override
public void run() {
if (logger.isDebugEnabled()) {
logger.debug("Background 3D rendering thread started");
}
try {
while (running) {
synchronized (this) {
Tile3DRenderJob job = jobQueue.takeJob();
Tile tile = job.getTile();
renderTile(tile);
}
}
} catch (InterruptedException e) {
if (running) {
throw new RuntimeException("Thread interrupted while waiting for render job", e);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Background 3D rendering thread halted");
}
}
use of org.pepsoft.worldpainter.Tile in project WorldPainter by Captain-Chaos.
the class ThreeDeeView method actionPerformed.
// ActionListener
@Override
public void actionPerformed(ActionEvent e) {
// Send tiles to be rendered
if ((!tilesWaitingToBeRendered.isEmpty()) && ((System.currentTimeMillis() - lastTileChange) > 250)) {
tilesWaitingToBeRendered.forEach(threeDeeRenderManager::renderTile);
tilesWaitingToBeRendered.clear();
}
// Collect rendered tiles
Set<RenderResult> renderResults = threeDeeRenderManager.getRenderedTiles();
Rectangle repaintArea = null;
for (RenderResult renderResult : renderResults) {
Tile tile = renderResult.getTile();
int x = tile.getX(), y = tile.getY();
renderedTiles.put(tile, renderResult.getImage());
Rectangle tileBounds = zoom(getTileBounds(x, y));
if (repaintArea == null) {
repaintArea = tileBounds;
} else {
repaintArea = repaintArea.union(tileBounds);
}
}
if (repaintArea != null) {
// System.out.println("Repainting " + repaintArea);
repaint(repaintArea);
}
}
use of org.pepsoft.worldpainter.Tile in project WorldPainter by Captain-Chaos.
the class ThreeDeeView method paintComponent.
@Override
protected void paintComponent(Graphics g) {
// System.out.println("Drawing");
Graphics2D g2 = (Graphics2D) g;
if (zoom != 1) {
double scaleFactor = Math.pow(2.0, zoom - 1);
// System.out.println("Scaling with factor " + scaleFactor);
g2.scale(scaleFactor, scaleFactor);
if (zoom > 1) {
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
} else {
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
}
}
if (upsideDown) {
g2.scale(1.0, -1.0);
g2.translate(0, -getHeight());
}
Rectangle visibleRect = unzoom(getVisibleRect());
// System.out.println("Unzoomed visible rectangle: " + visibleRect);
int centerX = visibleRect.x + visibleRect.width / 2;
int centerY = visibleRect.y + visibleRect.height / 2 + waterLevel;
Tile mostCentredTile = null;
int smallestDistance = Integer.MAX_VALUE;
Rectangle clipBounds = g.getClipBounds();
for (Tile tile : zSortedTiles) {
Rectangle tileBounds = getTileBounds(tile.getX(), tile.getY());
// System.out.print("Tile bounds: " + tileBounds);
if (tileBounds.intersects(clipBounds)) {
// System.out.println(" intersects");
int dx = tileBounds.x + tileBounds.width / 2 - centerX;
int dy = tileBounds.y + tileBounds.height - TILE_SIZE / 2 - centerY;
int dist = (int) Math.sqrt((dx * dx) + (dy * dy));
if (dist < smallestDistance) {
smallestDistance = dist;
mostCentredTile = tile;
}
BufferedImage tileImg = renderedTiles.get(tile);
if (tileImg != null) {
g.drawImage(tileImg, tileBounds.x, tileBounds.y, null);
} else {
tilesWaitingToBeRendered.add(0, tile);
}
// } else {
// System.out.println(" does NOT intersect");
}
}
if (mostCentredTile != null) {
centreTile = new Point(mostCentredTile.getX(), mostCentredTile.getY());
}
if (highlightTile != null) {
g.setColor(Color.RED);
Rectangle rect = getTileBounds(highlightTile.x, highlightTile.y);
g.drawRect(rect.x, rect.y, rect.width, rect.height);
}
if (highlightPoint != null) {
g.setColor(Color.RED);
g.drawLine(highlightPoint.x - 2, highlightPoint.y, highlightPoint.x + 2, highlightPoint.y);
g.drawLine(highlightPoint.x, highlightPoint.y - 2, highlightPoint.x, highlightPoint.y + 2);
}
// for (Map.Entry<Point, BufferedImage> entry: renderedTiles.entrySet()) {
// Point tileCoords = entry.getKey();
// BufferedImage tileImg = entry.getValue();
// Rectangle tileBounds = getTileBounds(tileCoords.x, tileCoords.y);
// if (tileBounds.intersects(clipBounds)) {
// g.drawImage(tileImg, tileBounds.x, tileBounds.y, null);
// // g.setColor(Color.RED);
// // g.drawRect(tileBounds.x, tileBounds.y, tileBounds.width, tileBounds.height);
// }
// }
}
use of org.pepsoft.worldpainter.Tile in project WorldPainter by Captain-Chaos.
the class SelectionHelper method copySelection.
public void copySelection(int targetX, int targetY, ProgressReceiver progressReceiver) throws ProgressReceiver.OperationCancelled {
Rectangle bounds = getSelectionBounds();
if (bounds == null) {
// No selection
return;
}
final int dx = targetX - bounds.x;
final int dy = targetY - bounds.y;
if ((dx == 0) && (dy == 0)) {
// Target is at the same location as the selection
return;
}
final int tileX1 = bounds.x >> TILE_SIZE_BITS;
final int tileX2 = (bounds.x + bounds.width - 1) >> TILE_SIZE_BITS;
final int tileY1 = bounds.y >> TILE_SIZE_BITS;
final int tileY2 = (bounds.y + bounds.height - 1) >> TILE_SIZE_BITS;
// Make sure to copy in the right direction to avoid problems if the
// destination overlaps the selection
clearUndoOnNewTileCreation = options.createNewTiles;
if (dx > 0) {
// Shifting right
if (dy > 0) {
// Shifting right and down
for (int tileX = tileX2; tileX >= tileX1; tileX--) {
for (int tileY = tileY2; tileY >= tileY1; tileY--) {
Tile tile = dimension.getTile(tileX, tileY);
if (tile != null) {
for (int xInTile = TILE_SIZE - 1; xInTile >= 0; xInTile--) {
for (int yInTile = TILE_SIZE - 1; yInTile >= 0; yInTile--) {
processColumn(tile, xInTile, yInTile, dx, dy);
}
}
}
}
if (progressReceiver != null) {
progressReceiver.setProgress((float) (tileX2 - tileX + 1) / (tileX2 - tileX1 + 1));
}
}
} else {
// Shifting right or right and up
for (int tileX = tileX2; tileX >= tileX1; tileX--) {
for (int tileY = tileY1; tileY <= tileY2; tileY++) {
Tile tile = dimension.getTile(tileX, tileY);
if (tile != null) {
for (int xInTile = TILE_SIZE - 1; xInTile >= 0; xInTile--) {
for (int yInTile = 0; yInTile < TILE_SIZE; yInTile++) {
processColumn(tile, xInTile, yInTile, dx, dy);
}
}
}
}
if (progressReceiver != null) {
progressReceiver.setProgress((float) (tileX2 - tileX + 1) / (tileX2 - tileX1 + 1));
}
}
}
} else {
// Shifting left or not horizontally
if (dy > 0) {
// Shifting down or left and down
for (int tileX = tileX1; tileX <= tileX2; tileX++) {
for (int tileY = tileY2; tileY >= tileY1; tileY--) {
Tile tile = dimension.getTile(tileX, tileY);
if (tile != null) {
for (int xInTile = 0; xInTile < TILE_SIZE; xInTile++) {
for (int yInTile = TILE_SIZE - 1; yInTile >= 0; yInTile--) {
processColumn(tile, xInTile, yInTile, dx, dy);
}
}
}
}
if (progressReceiver != null) {
progressReceiver.setProgress((float) (tileX - tileX1 + 1) / (tileX2 - tileX1 + 1));
}
}
} else {
// Shifting up or left and up
for (int tileX = tileX1; tileX <= tileX2; tileX++) {
for (int tileY = tileY1; tileY <= tileY2; tileY++) {
Tile tile = dimension.getTile(tileX, tileY);
if (tile != null) {
for (int xInTile = 0; xInTile < TILE_SIZE; xInTile++) {
for (int yInTile = 0; yInTile < TILE_SIZE; yInTile++) {
processColumn(tile, xInTile, yInTile, dx, dy);
}
}
}
}
if (progressReceiver != null) {
progressReceiver.setProgress((float) (tileX - tileX1 + 1) / (tileX2 - tileX1 + 1));
}
}
}
}
}
use of org.pepsoft.worldpainter.Tile in project WorldPainter by Captain-Chaos.
the class SelectionHelper method editSelection.
private void editSelection(Shape shape, boolean add) {
// Determine the bounding box of the selection in tile coordinates
final Rectangle shapeBounds = shape.getBounds();
final int tileX1 = shapeBounds.x >> TILE_SIZE_BITS;
final int tileX2 = (shapeBounds.x + shapeBounds.width - 1) >> TILE_SIZE_BITS;
final int tileY1 = shapeBounds.y >> TILE_SIZE_BITS;
final int tileY2 = (shapeBounds.y + shapeBounds.height - 1) >> TILE_SIZE_BITS;
// Iterate over all the tiles in the bounding box
for (int tileX = tileX1; tileX <= tileX2; tileX++) {
for (int tileY = tileY1; tileY <= tileY2; tileY++) {
Tile tile = dimension.getTileForEditing(tileX, tileY);
if (tile != null) {
Rectangle tileBounds = new Rectangle(tileX << TILE_SIZE_BITS, tileY << TILE_SIZE_BITS, TILE_SIZE, TILE_SIZE);
if (shape.contains(tileBounds)) {
// The tile lies entirely inside the selection
if (add) {
tile.clearLayerData(SelectionBlock.INSTANCE);
fillTile(tile, SelectionChunk.INSTANCE);
} else {
tile.clearLayerData(SelectionBlock.INSTANCE);
tile.clearLayerData(SelectionChunk.INSTANCE);
}
} else if (shape.intersects(tileBounds)) {
// lie entirely inside it; go chunk by chunk
for (int chunkX = 0; chunkX < TILE_SIZE; chunkX += 16) {
for (int chunkY = 0; chunkY < TILE_SIZE; chunkY += 16) {
Rectangle chunkBounds = new Rectangle(tileBounds.x + chunkX, tileBounds.y + chunkY, 16, 16);
if (shape.contains(chunkBounds)) {
// selection
if (add) {
clearTile(tile, SelectionBlock.INSTANCE, chunkX, chunkY, 16, 16);
tile.setBitLayerValue(SelectionChunk.INSTANCE, chunkX, chunkY, true);
} else {
clearTile(tile, SelectionBlock.INSTANCE, chunkX, chunkY, 16, 16);
tile.setBitLayerValue(SelectionChunk.INSTANCE, chunkX, chunkY, false);
}
} else if (shape.intersects(chunkBounds)) {
// go block by block
if (add && (!tile.getBitLayerValue(SelectionChunk.INSTANCE, chunkX, chunkY))) {
// The chunk is not yet entirely selected
for (int dx = 0; dx < 16; dx++) {
for (int dy = 0; dy < 16; dy++) {
int blockX = chunkBounds.x + dx;
int blockY = chunkBounds.y + dy;
if (shape.contains(blockX, blockY)) {
tile.setBitLayerValue(SelectionBlock.INSTANCE, chunkX + dx, chunkY + dy, true);
}
}
}
} else if (!add) {
if (tile.getBitLayerValue(SelectionChunk.INSTANCE, chunkX, chunkY)) {
// The chunk is entirely selected
tile.setBitLayerValue(SelectionChunk.INSTANCE, chunkX, chunkY, false);
for (int dx = 0; dx < 16; dx++) {
for (int dy = 0; dy < 16; dy++) {
int blockX = chunkBounds.x + dx;
int blockY = chunkBounds.y + dy;
tile.setBitLayerValue(SelectionBlock.INSTANCE, chunkX + dx, chunkY + dy, !shape.contains(blockX, blockY));
}
}
} else {
for (int dx = 0; dx < 16; dx++) {
for (int dy = 0; dy < 16; dy++) {
int blockX = chunkBounds.x + dx;
int blockY = chunkBounds.y + dy;
if (shape.contains(blockX, blockY)) {
tile.setBitLayerValue(SelectionBlock.INSTANCE, chunkX + dx, chunkY + dy, false);
}
}
}
}
}
}
}
}
}
}
}
}
}
Aggregations