Search in sources :

Example 1 with DefaultFilter

use of org.pepsoft.worldpainter.panels.DefaultFilter in project WorldPainter by Captain-Chaos.

the class MappingOp method go.

@Override
public Void go() throws ScriptException {
    goCalled();
    // Check preconditions
    if ((heightMap == null) && (layer == null) && (terrainIndex == -1)) {
        throw new ScriptException("No data source (heightMap, layer or terrain) specified");
    }
    if ((mode != Mode.SET_TERRAIN) && (layer == null)) {
        throw new ScriptException("layer not specified");
    }
    if (world == null) {
        throw new ScriptException("world not specified");
    }
    boolean greyScaleMapPresent = false;
    for (int mappedValue : mapping) {
        if (mappedValue != -1) {
            greyScaleMapPresent = true;
            break;
        }
    }
    final boolean colourMapPresent = !colourMapping.isEmpty();
    if ((greyScaleMapPresent || colourMapPresent) && (heightMap == null)) {
        throw new ScriptException("Mapping specified but no height map specified");
    } else if (heightMap != null) {
        if ((!greyScaleMapPresent) && (!colourMapPresent)) {
            throw new ScriptException("mapping not specified");
        }
        if (greyScaleMapPresent && colourMapPresent) {
            throw new ScriptException("Cannot mix grey scale and colour mapping");
        }
        if (layer != null) {
            if (layer.dataSize == Layer.DataSize.NONE) {
                throw new ScriptException("Layer of unsupported type specified: " + layer);
            }
            int bits;
            switch(layer.dataSize) {
                case BIT:
                case BIT_PER_CHUNK:
                    bits = 1;
                    break;
                case NIBBLE:
                    bits = 4;
                    break;
                case BYTE:
                    bits = 8;
                    break;
                default:
                    throw new InternalError();
            }
            int maxValue = (1 << bits) - 1;
            if (greyScaleMapPresent) {
                for (int mappedValue : mapping) {
                    if ((mappedValue < -1) || (mappedValue > maxValue)) {
                        throw new ScriptException("Invalid destination level " + mappedValue + " specified for " + bits + "-bit layer " + layer);
                    }
                }
            } else {
                for (Map.Entry<Integer, Integer> entry : colourMapping.entrySet()) {
                    int mappedValue = entry.getValue();
                    if ((mappedValue < 0) || (mappedValue > maxValue)) {
                        throw new ScriptException("Invalid destination level " + mappedValue + " specified for " + bits + "-bit layer " + layer);
                    }
                }
            }
        } else {
            if (greyScaleMapPresent) {
                for (int mappedValue : mapping) {
                    if ((mappedValue < -1) || (mappedValue >= Terrain.VALUES.length)) {
                        throw new ScriptException("Invalid terrain index " + mappedValue + " specified");
                    }
                }
            } else {
                for (Map.Entry<Integer, Integer> entry : colourMapping.entrySet()) {
                    int mappedValue = entry.getValue();
                    if ((mappedValue < 0) || (mappedValue >= Terrain.VALUES.length)) {
                        throw new ScriptException("Invalid terrain index " + mappedValue + " specified");
                    }
                }
            }
        }
    }
    final Dimension dimension = world.getDimension(dimIndex);
    if (dimension == null) {
        throw new ScriptException("Non existent dimension specified");
    }
    final HeightMap scaledHeightMap;
    Rectangle extent = new Rectangle(dimension.getLowestX() << TILE_SIZE_BITS, dimension.getLowestY() << TILE_SIZE_BITS, dimension.getWidth() << TILE_SIZE_BITS, dimension.getHeight() << TILE_SIZE_BITS);
    final boolean smoothScalingAllowed = greyScaleMapPresent && (mode != Mode.SET_TERRAIN) && (!Biome.INSTANCE.equals(layer)) && (!Annotations.INSTANCE.equals(layer));
    if (heightMap != null) {
        if ((scale != 100) || (offsetX != 0) || (offsetY != 0)) {
            // TODO ?
            boolean smoothScaling = (scale != 100) && smoothScalingAllowed;
            scaledHeightMap = TransformingHeightMap.build().withHeightMap(heightMap).withScale(scale).withOffset(offsetX, offsetY).now();
        } else {
            scaledHeightMap = heightMap;
        }
        if (scaledHeightMap.getExtent() != null) {
            extent = extent.intersection(scaledHeightMap.getExtent());
        }
    } else {
        scaledHeightMap = null;
    }
    final int x1 = extent.x, y1 = extent.y;
    final int x2 = extent.x + extent.width, y2 = extent.y + extent.height;
    final boolean bitLayer = (layer != null) && ((layer.getDataSize() == Layer.DataSize.BIT) || (layer.getDataSize() == Layer.DataSize.BIT_PER_CHUNK));
    if (filter instanceof DefaultFilter) {
        ((DefaultFilter) filter).setDimension(dimension);
    }
    for (int x = x1; x < x2; x++) {
        for (int y = y1; y < y2; y++) {
            int valueOut;
            if (scaledHeightMap != null) {
                if (colourMapPresent) {
                    int colour = scaledHeightMap.getColour(x, y);
                    if (colourMapping.containsKey(colour)) {
                        valueOut = colourMapping.get(colour);
                    } else {
                        continue;
                    }
                } else {
                    int valueIn = (int) (scaledHeightMap.getHeight(x, y) + 0.5f);
                    if ((valueIn < 0) || (valueIn > 65535)) {
                        continue;
                    }
                    valueOut = mapping[valueIn];
                    if (valueOut == -1) {
                        continue;
                    }
                }
            } else if (layer != null) {
                valueOut = layerValue;
            } else {
                valueOut = terrainIndex;
            }
            if (filter != null) {
                float filterValue = filter.modifyStrength(x, y, 1.0f);
                if (filterValue == 0.0f) {
                    continue;
                } else if (smoothScalingAllowed && (filterValue != 1.0f)) {
                    valueOut = (int) (filterValue * valueOut + 0.5f);
                }
            }
            switch(mode) {
                case SET_TERRAIN:
                    dimension.setTerrainAt(x, y, Terrain.VALUES[valueOut]);
                    break;
                case SET:
                    if (bitLayer) {
                        dimension.setBitLayerValueAt(layer, x, y, (valueOut != 0));
                    } else {
                        dimension.setLayerValueAt(layer, x, y, valueOut);
                    }
                    break;
                case SET_WHEN_HIGHER:
                    if (bitLayer) {
                        if (valueOut != 0) {
                            dimension.setBitLayerValueAt(layer, x, y, true);
                        }
                    } else {
                        if (dimension.getLayerValueAt(layer, x, y) < valueOut) {
                            dimension.setLayerValueAt(layer, x, y, valueOut);
                        }
                    }
                    break;
                case SET_WHEN_LOWER:
                    if (bitLayer) {
                        if (valueOut == 0) {
                            dimension.setBitLayerValueAt(layer, x, y, false);
                        }
                    } else {
                        if (dimension.getLayerValueAt(layer, x, y) > valueOut) {
                            dimension.setLayerValueAt(layer, x, y, valueOut);
                        }
                    }
                    break;
            }
        }
    }
    return null;
}
Also used : TransformingHeightMap(org.pepsoft.worldpainter.heightMaps.TransformingHeightMap) HeightMap(org.pepsoft.worldpainter.HeightMap) DefaultFilter(org.pepsoft.worldpainter.panels.DefaultFilter) Dimension(org.pepsoft.worldpainter.Dimension)

Example 2 with DefaultFilter

use of org.pepsoft.worldpainter.panels.DefaultFilter in project WorldPainter by Captain-Chaos.

the class App method createButtonForOperation.

private JToggleButton createButtonForOperation(final Operation operation, char mnemonic) {
    BufferedImage icon = operation.getIcon();
    JToggleButton button = new JToggleButton();
    if (operation instanceof SetSpawnPoint) {
        setSpawnPointToggleButton = button;
    }
    button.setMargin(App.BUTTON_INSETS);
    if (icon != null) {
        button.setIcon(new ImageIcon(icon));
    }
    if (operation.getName().equalsIgnoreCase(operation.getDescription())) {
        button.setToolTipText(operation.getName());
    } else {
        button.setToolTipText(operation.getName() + ": " + operation.getDescription());
    }
    if (mnemonic != 0) {
        button.setMnemonic(mnemonic);
    }
    button.addItemListener(event -> {
        if (event.getStateChange() == ItemEvent.DESELECTED) {
            if (operation instanceof RadiusOperation) {
                view.setDrawBrush(false);
            }
            try {
                operation.setActive(false);
            } catch (PropertyVetoException e) {
                logger.error("Property veto exception while deactivating operation " + operation, e);
            }
            activeOperation = null;
            if (toolSettingsPanel.getComponentCount() > 0) {
                toolSettingsPanel.removeAll();
                validate();
            }
        } else {
            if (operation instanceof PaintOperation) {
                programmaticChange = true;
                try {
                    if (operation instanceof MouseOrTabletOperation) {
                        ((MouseOrTabletOperation) operation).setLevel(level);
                        if (operation instanceof RadiusOperation) {
                            ((RadiusOperation) operation).setFilter(filter);
                        }
                        if (operation instanceof BrushOperation) {
                            ((BrushOperation) operation).setBrush(brushRotation == 0 ? brush : RotatedBrush.rotate(brush, brushRotation));
                            selectBrushButton(brush);
                            view.setBrushShape(brush.getBrushShape());
                            view.setBrushRotation(brushRotation);
                        }
                    }
                    levelSlider.setValue((int) (level * 100));
                    brushRotationSlider.setValue(brushRotation);
                } finally {
                    programmaticChange = false;
                }
                if (filter instanceof DefaultFilter) {
                    brushOptions.setFilter((DefaultFilter) filter);
                } else {
                    brushOptions.setFilter(null);
                }
                ((PaintOperation) operation).setPaint(paint);
            } else {
                programmaticChange = true;
                try {
                    if (operation instanceof MouseOrTabletOperation) {
                        ((MouseOrTabletOperation) operation).setLevel(toolLevel);
                        if (operation instanceof RadiusOperation) {
                            ((RadiusOperation) operation).setFilter(toolFilter);
                        }
                        if (operation instanceof BrushOperation) {
                            ((BrushOperation) operation).setBrush(toolBrushRotation == 0 ? toolBrush : RotatedBrush.rotate(toolBrush, toolBrushRotation));
                            selectBrushButton(toolBrush);
                            view.setBrushShape(toolBrush.getBrushShape());
                            view.setBrushRotation(toolBrushRotation);
                        }
                    }
                    levelSlider.setValue((int) (toolLevel * 100));
                    brushRotationSlider.setValue(toolBrushRotation);
                } finally {
                    programmaticChange = false;
                }
                if (toolFilter instanceof DefaultFilter) {
                    brushOptions.setFilter((DefaultFilter) toolFilter);
                } else {
                    brushOptions.setFilter(null);
                }
            }
            if (operation instanceof RadiusOperation) {
                view.setDrawBrush(true);
                view.setRadius(radius);
                ((RadiusOperation) operation).setRadius(radius);
            }
            activeOperation = operation;
            updateLayerVisibility();
            updateBrushRotation();
            try {
                operation.setActive(true);
            } catch (PropertyVetoException e) {
                deselectTool();
                Toolkit.getDefaultToolkit().beep();
                return;
            }
            if (closeCallout("callout_1")) {
                // brush, close the "select brush" callout too
                if (!(operation instanceof RadiusOperation)) {
                    closeCallout("callout_2");
                }
                // close the "select paint" callout too
                if (!(operation instanceof PaintOperation)) {
                    closeCallout("callout_3");
                }
            }
            JPanel optionsPanel = operation.getOptionsPanel();
            if (optionsPanel != null) {
                toolSettingsPanel.add(optionsPanel, BorderLayout.CENTER);
                dockingManager.resetLayout();
            }
        }
    });
    button.putClientProperty(HELP_KEY_KEY, "Operation/" + operation.getClass().getSimpleName());
    toolButtonGroup.add(button);
    return button;
}
Also used : PropertyVetoException(java.beans.PropertyVetoException) DefaultFilter(org.pepsoft.worldpainter.panels.DefaultFilter) BufferedImage(java.awt.image.BufferedImage)

Example 3 with DefaultFilter

use of org.pepsoft.worldpainter.panels.DefaultFilter in project WorldPainter by Captain-Chaos.

the class Height method tick.

// @Override
// protected void altPressed() {
// dimensionSnapshot = getDimension().getSnapshot();
// }
// 
// @Override
// protected void altReleased() {
// dimensionSnapshot = null;
// }
@Override
protected void tick(int centreX, int centreY, boolean inverse, boolean first, float dynamicLevel) {
    float adjustment = (float) Math.pow(dynamicLevel * getLevel() * 2, 2.0);
    Dimension dimension = getDimension();
    int minHeight, maxHeight;
    if (getFilter() instanceof DefaultFilter) {
        DefaultFilter filter = (DefaultFilter) getFilter();
        if (filter.getAboveLevel() != -1) {
            minHeight = filter.getAboveLevel();
        } else {
            minHeight = Integer.MIN_VALUE;
        }
        if (filter.getBelowLevel() != -1) {
            maxHeight = filter.getBelowLevel();
        } else {
            maxHeight = Integer.MAX_VALUE;
        }
    } else {
        minHeight = Integer.MIN_VALUE;
        maxHeight = Integer.MAX_VALUE;
    }
    boolean applyTheme = options.isApplyTheme();
    dimension.setEventsInhibited(true);
    try {
        int radius = getEffectiveRadius();
        float maxZ = dimension.getMaxHeight() - 1;
        for (int x = centreX - radius; x <= centreX + radius; x++) {
            for (int y = centreY - radius; y <= centreY + radius; y++) {
                float currentHeight = dimension.getHeightAt(x, y);
                float targetHeight = inverse ? Math.max(currentHeight - adjustment, minHeight) : Math.min(currentHeight + adjustment, maxHeight);
                if (targetHeight < 0.0f) {
                    targetHeight = 0.0f;
                } else if (targetHeight > maxZ) {
                    targetHeight = maxZ;
                }
                float strength = getFullStrength(centreX, centreY, x, y);
                if (strength > 0.0f) {
                    float newHeight = strength * targetHeight + (1 - strength) * currentHeight;
                    if (inverse ? (newHeight < currentHeight) : (newHeight > currentHeight)) {
                        dimension.setHeightAt(x, y, newHeight);
                        if (applyTheme) {
                            dimension.applyTheme(x, y);
                        }
                    }
                }
            }
        }
    } finally {
        dimension.setEventsInhibited(false);
    }
}
Also used : DefaultFilter(org.pepsoft.worldpainter.panels.DefaultFilter) Dimension(org.pepsoft.worldpainter.Dimension)

Aggregations

DefaultFilter (org.pepsoft.worldpainter.panels.DefaultFilter)3 Dimension (org.pepsoft.worldpainter.Dimension)2 BufferedImage (java.awt.image.BufferedImage)1 PropertyVetoException (java.beans.PropertyVetoException)1 HeightMap (org.pepsoft.worldpainter.HeightMap)1 TransformingHeightMap (org.pepsoft.worldpainter.heightMaps.TransformingHeightMap)1