/**
* Copyright 2014
* SMEdit https://github.com/StarMade/SMEdit
* SMTools https://github.com/StarMade/SMTools
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
**/
package jo.sm.ship.logic;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import jo.sm.data.BlockTypes;
import jo.sm.data.BooleanMatrix3D;
import jo.sm.data.SparseMatrix;
import jo.sm.mods.IPluginCallback;
import jo.sm.ship.data.Block;
import jo.vecmath.Point3i;
/**
* @Auther Jo Jaquinta for SMEdit Classic - version 1.0
**/
public class HullLogic {
public static void power(SparseMatrix<Block> grid) {
Map<Short, Short> filter = new HashMap<>();
for (int color = 0; color < BlockTypes.HULL_COLOR_MAP[0].length; color++) {
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.HULL_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERHULL_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.WEDGE_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERWEDGE_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.CORNER_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERCORNER_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.PENTA_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERPENTA_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.TETRA_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERTETRA_COLORS][color]);
}
doFilter(grid, filter);
}
public static void unpower(SparseMatrix<Block> grid) {
Map<Short, Short> filter = new HashMap<>();
for (int color = 0; color < BlockTypes.HULL_COLOR_MAP[0].length; color++) {
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERHULL_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.HULL_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERWEDGE_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.WEDGE_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERCORNER_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.CORNER_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERPENTA_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.PENTA_COLORS][color]);
filter.put(BlockTypes.HULL_COLOR_MAP[BlockTypes.POWERTETRA_COLORS][color], BlockTypes.HULL_COLOR_MAP[BlockTypes.TETRA_COLORS][color]);
}
doFilter(grid, filter);
}
private static void doFilter(SparseMatrix<Block> grid, Map<Short, Short> filter) {
for (Iterator<Point3i> i = grid.iterator(); i.hasNext();) {
Point3i coords = i.next();
Block block = grid.get(coords);
if (block == null) {
continue;
}
short oldID = block.getBlockID();
if (!filter.containsKey(oldID)) {
continue;
}
short newID = filter.get(oldID);
if (newID != -1) {
block.setBlockID(newID);
}
}
}
public static Set<Point3i> findExterior(SparseMatrix<Block> grid, IPluginCallback cb) {
Point3i lower = new Point3i();
Point3i upper = new Point3i();
grid.getBounds(lower, upper);
if (cb != null) {
cb.setStatus("Calculating exterior");
cb.startTask((upper.x - lower.x + 3) * (upper.y - lower.y + 3)
+ (upper.x - lower.x + 3) * (upper.z - lower.z + 3)
+ (upper.z - lower.z + 3) * (upper.y - lower.y + 3)
);
}
Set<Point3i> exterior = new HashSet<>();
Point3i p = new Point3i();
// do z
for (p.x = lower.x - 1; p.x <= upper.x + 1; p.x++) {
for (p.y = lower.y - 1; p.y <= upper.y + 1; p.y++) {
if (cb != null) {
cb.workTask(1);
}
// lower to upper
for (p.z = lower.z; p.z <= upper.z + 1; p.z++) {
if (grid.contains(p)) {
break;
} else {
exterior.add(new Point3i(p));
}
}
if (p.z < upper.z) // upper to lower
{
for (p.z = upper.z + 1; p.z >= lower.z; p.z--) {
if (grid.contains(p)) {
break;
} else {
exterior.add(new Point3i(p));
}
}
}
}
}
// do y
for (p.x = lower.x - 1; p.x <= upper.x; p.x++) {
for (p.z = lower.z - 1; p.z <= upper.z; p.z++) {
if (cb != null) {
cb.workTask(1);
}
// lower to upper
for (p.y = lower.y; p.y <= upper.y; p.y++) {
if (grid.contains(p)) {
break;
} else {
exterior.add(new Point3i(p));
}
}
if (p.y < upper.y) // upper to lower
{
for (p.y = upper.y; p.y >= lower.y; p.y--) {
if (grid.contains(p)) {
break;
} else {
exterior.add(new Point3i(p));
}
}
}
}
}
// do x
for (p.y = lower.y - 1; p.y <= upper.y; p.y++) {
for (p.z = lower.z - 1; p.z <= upper.z; p.z++) {
if (cb != null) {
cb.workTask(1);
}
// lower to upper
for (p.x = lower.x; p.x <= upper.x; p.x++) {
if (grid.contains(p)) {
break;
} else {
exterior.add(new Point3i(p));
}
}
if (p.x < upper.x) // upper to lower
{
for (p.x = upper.x; p.x >= lower.x; p.x--) {
if (grid.contains(p)) {
break;
} else {
exterior.add(new Point3i(p));
}
}
}
}
}
if (cb != null) {
cb.endTask();
}
return exterior;
}
public static BooleanMatrix3D findExteriorMatrix(SparseMatrix<Block> grid, IPluginCallback cb) {
Point3i lower = new Point3i();
Point3i upper = new Point3i();
grid.getBounds(lower, upper);
if (cb != null) {
cb.setStatus("Calculating exterior");
cb.startTask((upper.x - lower.x + 3) * (upper.y - lower.y + 3)
+ (upper.x - lower.x + 3) * (upper.z - lower.z + 3)
+ (upper.z - lower.z + 3) * (upper.y - lower.y + 3)
);
}
BooleanMatrix3D exterior = new BooleanMatrix3D();
Point3i p = new Point3i();
// do z
for (p.x = lower.x - 1; p.x <= upper.x + 1; p.x++) {
for (p.y = lower.y - 1; p.y <= upper.y + 1; p.y++) {
if (cb != null) {
cb.workTask(1);
}
// lower to upper
for (p.z = lower.z; p.z <= upper.z + 1; p.z++) {
if (grid.contains(p)) {
break;
} else {
exterior.set(p);
}
}
if (p.z < upper.z) // upper to lower
{
for (p.z = upper.z + 1; p.z >= lower.z; p.z--) {
if (grid.contains(p)) {
break;
} else {
exterior.set(p);
}
}
}
}
}
// do y
for (p.x = lower.x - 1; p.x <= upper.x; p.x++) {
for (p.z = lower.z - 1; p.z <= upper.z; p.z++) {
if (cb != null) {
cb.workTask(1);
}
// lower to upper
for (p.y = lower.y; p.y <= upper.y; p.y++) {
if (grid.contains(p)) {
break;
} else {
exterior.set(p);
}
}
if (p.y < upper.y) // upper to lower
{
for (p.y = upper.y; p.y >= lower.y; p.y--) {
if (grid.contains(p)) {
break;
} else {
exterior.set(p);
}
}
}
}
}
// do x
for (p.y = lower.y - 1; p.y <= upper.y; p.y++) {
for (p.z = lower.z - 1; p.z <= upper.z; p.z++) {
if (cb != null) {
cb.workTask(1);
}
// lower to upper
for (p.x = lower.x; p.x <= upper.x; p.x++) {
if (grid.contains(p)) {
break;
} else {
exterior.set(p);
}
}
if (p.x < upper.x) // upper to lower
{
for (p.x = upper.x; p.x >= lower.x; p.x--) {
if (grid.contains(p)) {
break;
} else {
exterior.set(p);
}
}
}
}
}
if (cb != null) {
cb.endTask();
}
return exterior;
}
}