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;
}
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;
}
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);
}
}
Aggregations