diff --git a/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplate.java b/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplate.java index d66b57ef7..50194de28 100644 --- a/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplate.java +++ b/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplate.java @@ -6,18 +6,24 @@ import com.faforever.neroxis.map.Unit; import com.faforever.neroxis.util.vector.Vector2; +import java.util.LinkedHashSet; import java.util.SequencedMap; import java.util.SequencedSet; +import java.util.stream.Collectors; public record BaseTemplate(Vector2 center, SequencedMap> units) { public void addUnits(Army army, Group group) { units().forEach((name, positions) -> positions.forEach(position -> group.addUnit( new Unit(String.format("%s %s Unit %d", army.getId(), group.getId(), group.getUnitCount()), name, - new Vector2(position).add(center), 0)))); + position.add(center), 0)))); } public void flip(Symmetry symmetry) { - units().values().forEach(positions -> positions.forEach(position -> position.flip(new Vector2(0, 0), symmetry))); + units.entrySet() + .forEach(entry -> entry.setValue(entry.getValue() + .stream() + .map(position -> position.flip(new Vector2(0, 0), symmetry)) + .collect(Collectors.toCollection(LinkedHashSet::new)))); } } diff --git a/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplateLoader.java b/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplateLoader.java index a66829e7c..5162a3cf8 100644 --- a/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplateLoader.java +++ b/shared/src/main/java/com/faforever/neroxis/bases/BaseTemplateLoader.java @@ -4,6 +4,7 @@ import com.faforever.neroxis.util.FileUtil; import com.faforever.neroxis.util.serial.biome.SCUnitSet; import com.faforever.neroxis.util.vector.Vector2; +import com.faforever.neroxis.util.vector.Vector3; import java.io.IOException; import java.io.InputStream; @@ -18,8 +19,8 @@ public class BaseTemplateLoader { - public static final Comparator VECTOR_COMPARATOR = Comparator.comparing(Vector2::getX) - .thenComparing(Vector2::getY); + public static final Comparator VECTOR_COMPARATOR = Comparator.comparing(Vector2::x) + .thenComparing(Vector2::y); private static final Comparator> UNIT_ENTRY_COMPARATOR = Map.Entry.comparingByKey() .thenComparing( Map.Entry::getValue, @@ -133,11 +134,10 @@ private static double extractNumber(Lua.Expression expression) { private static SequencedMap> loadUnitsFromSCUnits(InputStream inputStream) throws IOException { SCUnitSet scUnitSet = FileUtil.deserialize(inputStream, SCUnitSet.class); - scUnitSet.units().forEach(unit -> unit.pos().subtract(scUnitSet.center()).multiply(10f).round(2)); - + Vector3 center = scUnitSet.center(); return scUnitSet.units() .stream() - .map(unit -> Map.entry(unit.ID(), new Vector2(unit.pos()))) + .map(unit -> Map.entry(unit.ID(), new Vector2(unit.pos().subtract(center).multiply(10f).round(2)))) .sorted(UNIT_ENTRY_COMPARATOR) .collect(Collectors.groupingBy(Map.Entry::getKey, LinkedHashMap::new, Collectors.mapping(Map.Entry::getValue, Collectors.toCollection( diff --git a/shared/src/main/java/com/faforever/neroxis/biomes/Biomes.java b/shared/src/main/java/com/faforever/neroxis/biomes/Biomes.java index fd5f3beaf..3dda516ed 100644 --- a/shared/src/main/java/com/faforever/neroxis/biomes/Biomes.java +++ b/shared/src/main/java/com/faforever/neroxis/biomes/Biomes.java @@ -19,11 +19,11 @@ public class Biomes { public static Biome loadBiome(BiomeName biomeName) { String folderPath = biomeName.getFolderName(); + if (!folderPath.endsWith("/")) { + folderPath += "/"; + } if (Biomes.class.getResource(CUSTOM_BIOMES_DIR + folderPath) != null) { folderPath = CUSTOM_BIOMES_DIR + folderPath; - if (!folderPath.endsWith("/")) { - folderPath += "/"; - } } TerrainMaterials terrainMaterials; diff --git a/shared/src/main/java/com/faforever/neroxis/exporter/PreviewGenerator.java b/shared/src/main/java/com/faforever/neroxis/exporter/PreviewGenerator.java index 62ecd6586..a47399e50 100644 --- a/shared/src/main/java/com/faforever/neroxis/exporter/PreviewGenerator.java +++ b/shared/src/main/java/com/faforever/neroxis/exporter/PreviewGenerator.java @@ -96,14 +96,14 @@ private static BufferedImage shadeLayer(BufferedImage image, SCMap map, FloatMas float coefficient = irradiance.getPrimitive(x, y) + ambientCoefficient; - newRGBA[0] = (int) (origRGBA[0] * ((lightingSettings.sunColor().getX() * coefficient) - + lightingSettings.sunAmbience().getX()) + newRGBA[0] = (int) (origRGBA[0] * ((lightingSettings.sunColor().x() * coefficient) + + lightingSettings.sunAmbience().x()) * lightingSettings.lightingMultiplier()); - newRGBA[1] = (int) (origRGBA[1] * ((lightingSettings.sunColor().getY() * coefficient) - + lightingSettings.sunAmbience().getY()) + newRGBA[1] = (int) (origRGBA[1] * ((lightingSettings.sunColor().y() * coefficient) + + lightingSettings.sunAmbience().y()) * lightingSettings.lightingMultiplier()); - newRGBA[2] = (int) (origRGBA[2] * ((lightingSettings.sunColor().getZ() * coefficient) - + lightingSettings.sunAmbience().getZ()) + newRGBA[2] = (int) (origRGBA[2] * ((lightingSettings.sunColor().z() * coefficient) + + lightingSettings.sunAmbience().z()) * lightingSettings.lightingMultiplier()); newRGBA[0] = StrictMath.max(StrictMath.min(newRGBA[0], 255), 0); @@ -171,8 +171,8 @@ public static BufferedImage addMarkers(BufferedImage image, SCMap map) throws IO private static void addMarkerImages(Collection markers, BufferedImage markerImage, BufferedImage preview, SCMap map) { markers.forEach(marker -> { - int x = (int) (marker.getPosition().getX() / map.getSize() * PREVIEW_SIZE - markerImage.getWidth(null) / 2); - int y = (int) (marker.getPosition().getZ() / map.getSize() * PREVIEW_SIZE + int x = (int) (marker.getPosition().x() / map.getSize() * PREVIEW_SIZE - markerImage.getWidth(null) / 2); + int y = (int) (marker.getPosition().z() / map.getSize() * PREVIEW_SIZE - markerImage.getHeight(null) / 2); if (ImageUtil.inImageBounds(x, y, preview)) { preview.getGraphics().drawImage(markerImage, x, y, null); @@ -201,8 +201,8 @@ public static void addReclaimProps(BufferedImage image, SCMap map) { // Draw the boulder for (Prop prop : map.getProps()) { if (prop.isBoulder()) { - int x = (int) (prop.getPosition().getX() / map.getSize() * PREVIEW_SIZE); - int y = (int) (prop.getPosition().getZ() / map.getSize() * PREVIEW_SIZE); + int x = (int) (prop.getPosition().x() / map.getSize() * PREVIEW_SIZE); + int y = (int) (prop.getPosition().z() / map.getSize() * PREVIEW_SIZE); if (x >= 1 && y >= 1 && x < image.getRaster().getWidth()-1 && y < image.getRaster().getHeight()-1) { image.getRaster().setPixel(x, y, boulderRGBA); image.getRaster().setPixel(x+1, y, addRGB(image.getRaster().getPixel(x+1,y,(int[])null), boulderRGBAOutline,0.3f)); diff --git a/shared/src/main/java/com/faforever/neroxis/exporter/SCMapExporter.java b/shared/src/main/java/com/faforever/neroxis/exporter/SCMapExporter.java index 47793b903..08522ab8b 100644 --- a/shared/src/main/java/com/faforever/neroxis/exporter/SCMapExporter.java +++ b/shared/src/main/java/com/faforever/neroxis/exporter/SCMapExporter.java @@ -256,8 +256,8 @@ public static void exportPreview(Path folderPath, SCMap map) throws IOException } public static void exportNormals(Path folderPath, SCMap map) throws IOException { - float size = map.getPlayableArea().getW() - map.getPlayableArea().getX(); - Vector2 topLeftOffset = new Vector2(map.getPlayableArea().getX(), map.getPlayableArea().getY()); + float size = map.getPlayableArea().w() - map.getPlayableArea().x(); + Vector2 topLeftOffset = new Vector2(map.getPlayableArea().x(), map.getPlayableArea().y()); byte[] compressedNormal = map.getCompressedNormal(); final String fileFormat = "dds"; Path decalsPath = Paths.get("env", "decals"); @@ -276,8 +276,8 @@ public static void exportNormals(Path folderPath, SCMap map) throws IOException } public static void exportShadows(Path folderPath, SCMap map) throws IOException { - float size = map.getPlayableArea().getW() - map.getPlayableArea().getX(); - Vector2 topLeftOffset = new Vector2(map.getPlayableArea().getX(), map.getPlayableArea().getY()); + float size = map.getPlayableArea().w() - map.getPlayableArea().x(); + Vector2 topLeftOffset = new Vector2(map.getPlayableArea().x(), map.getPlayableArea().y()); byte[] compressedShadows = map.getCompressedShadows(); final String fileFormat = "dds"; Path decalsPath = Paths.get("env", "decals"); @@ -370,21 +370,21 @@ private static void writeString(String s) throws IOException { } private static void writeVector3f(Vector3 v) throws IOException { - writeFloat(v.getX()); - writeFloat(v.getY()); - writeFloat(v.getZ()); + writeFloat(v.x()); + writeFloat(v.y()); + writeFloat(v.z()); } private static void writeVector4f(Vector4 v) throws IOException { - writeFloat(v.getX()); - writeFloat(v.getY()); - writeFloat(v.getZ()); - writeFloat(v.getW()); + writeFloat(v.x()); + writeFloat(v.y()); + writeFloat(v.z()); + writeFloat(v.w()); } private static void writeVector2f(Vector2 v) throws IOException { - writeFloat(v.getX()); - writeFloat(v.getY()); + writeFloat(v.x()); + writeFloat(v.y()); } private static void writeProp(Prop prop) throws IOException { diff --git a/shared/src/main/java/com/faforever/neroxis/exporter/SaveExporter.java b/shared/src/main/java/com/faforever/neroxis/exporter/SaveExporter.java index 565386999..f92152079 100644 --- a/shared/src/main/java/com/faforever/neroxis/exporter/SaveExporter.java +++ b/shared/src/main/java/com/faforever/neroxis/exporter/SaveExporter.java @@ -32,8 +32,8 @@ public static void exportSave(Path folderPath, SCMap map) throws IOException { out.writeBytes(" Props = {},\n"); out.writeBytes(" Areas = {\n"); out.writeBytes(" ['AREA_1'] = {\n"); - out.writeBytes(String.format(" ['rectangle'] = RECTANGLE( %d, %d, %d, %d ),\n", (int) playableArea.getX(), - (int) playableArea.getY(), (int) playableArea.getZ(), (int) playableArea.getW())); + out.writeBytes(String.format(" ['rectangle'] = RECTANGLE( %d, %d, %d, %d ),\n", (int) playableArea.x(), + (int) playableArea.y(), (int) playableArea.z(), (int) playableArea.w())); out.writeBytes(" },\n"); out.writeBytes(" },\n"); out.writeBytes(" MasterChain = {\n"); diff --git a/shared/src/main/java/com/faforever/neroxis/exporter/ScenarioExporter.java b/shared/src/main/java/com/faforever/neroxis/exporter/ScenarioExporter.java index 983f067bc..db33d10ff 100644 --- a/shared/src/main/java/com/faforever/neroxis/exporter/ScenarioExporter.java +++ b/shared/src/main/java/com/faforever/neroxis/exporter/ScenarioExporter.java @@ -34,8 +34,8 @@ public static void exportScenario(Path folderPath, SCMap map) throws IOException } out.writeBytes(" norushradius = " + map.getNoRushRadius() + ",\n"); for (Spawn spawn : map.getSpawns()) { - out.writeBytes(" norushoffsetX_" + spawn.getId() + " = " + spawn.getNoRushOffset().getX() + ",\n"); - out.writeBytes(" norushoffsetY_" + spawn.getId() + " = " + spawn.getNoRushOffset().getY() + ",\n"); + out.writeBytes(" norushoffsetX_" + spawn.getId() + " = " + spawn.getNoRushOffset().x() + ",\n"); + out.writeBytes(" norushoffsetY_" + spawn.getId() + " = " + spawn.getNoRushOffset().y() + ",\n"); } out.writeBytes(" Configurations = {\n"); out.writeBytes(" ['standard'] = {\n"); diff --git a/shared/src/main/java/com/faforever/neroxis/exporter/ScriptGenerator.java b/shared/src/main/java/com/faforever/neroxis/exporter/ScriptGenerator.java index fdbe9cee8..d07aa4c58 100644 --- a/shared/src/main/java/com/faforever/neroxis/exporter/ScriptGenerator.java +++ b/shared/src/main/java/com/faforever/neroxis/exporter/ScriptGenerator.java @@ -15,7 +15,7 @@ public static void generateScript(SCMap map) { } private static String generateUnexploredScript(SCMap map) { - int mapPlayableSize = (int) (map.getPlayableArea().getW() - map.getPlayableArea().getX()); + int mapPlayableSize = (int) (map.getPlayableArea().w() - map.getPlayableArea().x()); int decalSize = mapPlayableSize * mapPlayableSize / 8192; int checkDecalRange = decalSize / 2 + 24; int checkResourceRange = decalSize / 2 + 32; diff --git a/shared/src/main/java/com/faforever/neroxis/importer/SCMapImporter.java b/shared/src/main/java/com/faforever/neroxis/importer/SCMapImporter.java index 28a878126..864d566ac 100644 --- a/shared/src/main/java/com/faforever/neroxis/importer/SCMapImporter.java +++ b/shared/src/main/java/com/faforever/neroxis/importer/SCMapImporter.java @@ -515,7 +515,7 @@ private static Prop readProp() throws IOException { readVector3f(); // Y rotation readVector3f(); // Z rotation readVector3f(); // scale - float rotation = (float) StrictMath.atan2(rotationX.getZ(), rotationX.getX()); + float rotation = (float) StrictMath.atan2(rotationX.z(), rotationX.x()); return new Prop(path, position, rotation, false); } diff --git a/shared/src/main/java/com/faforever/neroxis/map/SCMap.java b/shared/src/main/java/com/faforever/neroxis/map/SCMap.java index 1969f3b38..becd9166d 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/SCMap.java +++ b/shared/src/main/java/com/faforever/neroxis/map/SCMap.java @@ -41,9 +41,7 @@ public class SCMap { public static final Vector2[] WAVE_NORMAL_MOVEMENTS = {new Vector2(0.5f, -0.95f), new Vector2(0.05f, -0.095f), new Vector2( 0.01f, 0.03f), new Vector2(0.0005f, 0.0009f)}; - public static final String[] WAVE_TEXTURE_PATHS = {"/textures/engine/waves.dds", "/textures/engine/waves.dds", - "/textures/engine/waves.dds", - "/textures/engine/waves.dds"}; // always same? + public static final String[] WAVE_TEXTURE_PATHS = {"/textures/engine/waves.dds", "/textures/engine/waves.dds", "/textures/engine/waves.dds", "/textures/engine/waves.dds"}; // always same? private final List spawns = new ArrayList<>(); private final List mexes = new ArrayList<>(); private final List hydros = new ArrayList<>(); @@ -304,24 +302,24 @@ public void changeStratumSize(int stratumSize) { public void changeMapSize(int contentSize, int boundsSize, Vector2 boundOffset) { int oldSize = size; - Vector2 topLeftOffset = new Vector2(boundOffset.getX() - (float) contentSize / 2, - boundOffset.getY() - (float) contentSize / 2); + Vector2 topLeftOffset = new Vector2(boundOffset.x() - (float) contentSize / 2, + boundOffset.y() - (float) contentSize / 2); float contentScale = (float) contentSize / (float) oldSize; float boundsScale = (float) boundsSize / (float) contentSize; if (contentScale != 1) { scaleMapContent(contentScale); this.size = contentSize; - playableArea.multiply(contentScale); + playableArea = playableArea.multiply(contentScale); } - if (boundsScale != 1 && topLeftOffset.getX() != 0 && topLeftOffset.getY() != 0) { + if (boundsScale != 1 && topLeftOffset.x() != 0 && topLeftOffset.y() != 0) { scaleMapBounds(boundsScale, topLeftOffset); - playableArea.add(topLeftOffset.getX(), topLeftOffset.getY(), topLeftOffset.getX(), topLeftOffset.getY()); + playableArea = playableArea.add(topLeftOffset.x(), topLeftOffset.y(), topLeftOffset.x(), topLeftOffset.y()); this.size = boundsSize; } - if (contentScale != 1 || (boundsScale != 1 && topLeftOffset.getX() != 0 && topLeftOffset.getY() != 0)) { + if (contentScale != 1 || (boundsScale != 1 && topLeftOffset.x() != 0 && topLeftOffset.y() != 0)) { moveObjects(contentScale, topLeftOffset); } } @@ -503,11 +501,11 @@ private void scaleMapBounds(float boundsScale, Vector2 topLeftOffset) { topLeftOffset); normalMap = insertImageIntoNewImageOfSize(normalMap, StrictMath.round(normalMap.getWidth() * boundsScale), StrictMath.round(normalMap.getHeight() * boundsScale), - new Vector2(topLeftOffset).multiply(normalMapScale)); + topLeftOffset.multiply(normalMapScale)); waterMap = insertImageIntoNewImageOfSize(waterMap, StrictMath.round(waterMap.getWidth() * boundsScale), StrictMath.round(waterMap.getHeight() * boundsScale), - new Vector2(topLeftOffset).multiply(waterMapScale)); - Vector2 halvedTopLeftOffset = new Vector2(topLeftOffset).multiply(.5f); + topLeftOffset.multiply(waterMapScale)); + Vector2 halvedTopLeftOffset = topLeftOffset.multiply(.5f); waterFoamMap = insertImageIntoNewImageOfSize(waterFoamMap, StrictMath.round(waterFoamMap.getWidth() * boundsScale), StrictMath.round(waterFoamMap.getHeight() * boundsScale), @@ -526,15 +524,15 @@ private void scaleMapBounds(float boundsScale, Vector2 topLeftOffset) { textureMasksHigh = insertImageIntoNewImageOfSize(textureMasksHigh, StrictMath.round(textureMasksHigh.getWidth() * boundsScale), StrictMath.round(textureMasksHigh.getHeight() * boundsScale), - new Vector2(topLeftOffset).multiply(textureMaskHighScale)); + topLeftOffset.multiply(textureMaskHighScale)); textureMasksLow = insertImageIntoNewImageOfSize(textureMasksLow, StrictMath.round(textureMasksLow.getWidth() * boundsScale), StrictMath.round(textureMasksLow.getHeight() * boundsScale), - new Vector2(topLeftOffset).multiply(textureMaskLowScale)); + topLeftOffset.multiply(textureMaskLowScale)); mapwideTexture = insertImageIntoNewImageOfSize(mapwideTexture, StrictMath.round(mapwideTexture.getWidth() * boundsScale), StrictMath.round(mapwideTexture.getHeight() * boundsScale), - new Vector2(topLeftOffset).multiply(mapwideTextureScale)); + topLeftOffset.multiply(mapwideTextureScale)); } private void moveObjects(float contentScale, Vector2 offset) { @@ -559,7 +557,7 @@ private void moveObjects(float contentScale, Vector2 offset) { decals.forEach(decal -> { Vector3 scale = decal.getScale(); - decal.setScale(new Vector3(scale.getX() * contentScale, scale.getY(), scale.getZ() * contentScale)); + decal.setScale(new Vector3(scale.x() * contentScale, scale.y(), scale.z() * contentScale)); decal.setCutOffLOD(decal.getCutOffLOD() * contentScale); }); @@ -586,10 +584,11 @@ private void setObjectHeights(Collection positionedO positionedObjects.forEach(positionedObject -> { Vector2 position = new Vector2(positionedObject.getPosition()); if (ImageUtil.inImageBounds(position, heightmap)) { - positionedObject.getPosition() - .setY(heightmap.getRaster() - .getPixel((int) position.getX(), (int) position.getY(), new int[]{0})[0] - * heightMapScale); + positionedObject.setPosition(new Vector3(position.x(), heightmap.getRaster() + .getPixel((int) position.x(), + (int) position.y(), + new int[]{0})[0] + * heightMapScale, position.y())); } }); } @@ -648,10 +647,10 @@ public void setTextureMasksScaled(BufferedImage textureMasks, Vector4Mask mask) for (int x = 0; x < textureMasksWidth; x++) { for (int y = 0; y < textureMasksWidth; y++) { Vector4 vector = mask.get(x, y); - int val0 = convertToRawTextureValue(vector.get(0)); - int val1 = convertToRawTextureValue(vector.get(1)); - int val2 = convertToRawTextureValue(vector.get(2)); - int val3 = convertToRawTextureValue(vector.get(3)); + int val0 = convertToRawTextureValue(vector.x()); + int val1 = convertToRawTextureValue(vector.y()); + int val2 = convertToRawTextureValue(vector.z()); + int val3 = convertToRawTextureValue(vector.w()); textureMasks.getRaster().setPixel(x, y, new int[]{val0, val1, val2, val3}); } } diff --git a/shared/src/main/java/com/faforever/neroxis/map/placement/AIMarkerPlacer.java b/shared/src/main/java/com/faforever/neroxis/map/placement/AIMarkerPlacer.java index 2d7658b18..2fe74c1b9 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/placement/AIMarkerPlacer.java +++ b/shared/src/main/java/com/faforever/neroxis/map/placement/AIMarkerPlacer.java @@ -6,24 +6,23 @@ import com.faforever.neroxis.mask.BooleanMask; import com.faforever.neroxis.util.vector.Vector2; -import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; public class AIMarkerPlacer { public static void placeAIMarkers(BooleanMask passable, List markers, String nameFormat) { - LinkedHashSet coordinates = new LinkedHashSet<>(passable.getSpacedCoordinatesEqualTo(true, 32, 8)); - coordinates.addAll(passable.copyAsDistanceField() - .copyAsLocalMaximums(8f, (float) passable.getSize()) - .getSpacedCoordinatesEqualTo(true, 16, 4)); + LinkedHashSet rawCoordinates = new LinkedHashSet<>(passable.getSpacedCoordinatesEqualTo(true, 32, 8)); + rawCoordinates.addAll(passable.copyAsDistanceField() + .copyAsLocalMaximums(8f, (float) passable.getSize()) + .getSpacedCoordinatesEqualTo(true, 16, 4)); LinkedHashSet unusedCoordinates = new LinkedHashSet<>(); - coordinates.forEach(location -> { + rawCoordinates.forEach(location -> { if (!unusedCoordinates.contains(location)) { if (!passable.inTeam(location, false)) { unusedCoordinates.add(location); return; } - coordinates.forEach(location1 -> { + rawCoordinates.forEach(location1 -> { if (location != location1) { if (location.getDistance(location1) < 64) { LinkedHashSet lineCoordinates = location.getLine(location1); @@ -37,18 +36,20 @@ public static void placeAIMarkers(BooleanMask passable, List markers, }); } }); - coordinates.removeAll(unusedCoordinates); - coordinates.forEach(location -> location.roundToNearestHalfPoint()); - List coordinatesList = new ArrayList<>(coordinates); - coordinates.forEach((location) -> { - AIMarker aiMarker = new AIMarker(String.format(nameFormat, coordinatesList.indexOf(location)), location, - new LinkedHashSet<>()); + rawCoordinates.removeAll(unusedCoordinates); + + List coordinates = rawCoordinates.stream().map(Vector2::roundToNearestHalfPoint).toList(); + + for (int i = 0; i < coordinates.size(); i++) { + int index = i; + Vector2 coordinate = coordinates.get(i); + AIMarker aiMarker = new AIMarker(String.format(nameFormat, index), coordinate, new LinkedHashSet<>()); markers.add(aiMarker); List symmetryPoints = passable.getSymmetryPoints(aiMarker.getPosition(), SymmetryType.SPAWN); - symmetryPoints.forEach(symmetryPoint -> markers.add(new AIMarker( - String.format(nameFormat + "s%d", coordinatesList.indexOf(location), - symmetryPoints.indexOf(symmetryPoint)), symmetryPoint, new LinkedHashSet<>()))); - }); + symmetryPoints.forEach(symmetryPoint -> markers.add( + new AIMarker(String.format(nameFormat + "s%d", index, symmetryPoints.indexOf(symmetryPoint)), + symmetryPoint, new LinkedHashSet<>()))); + } markers.forEach(aiMarker -> markers.forEach(aiMarker1 -> { if (aiMarker != aiMarker1 && aiMarker.getPosition().getXZDistance(aiMarker1.getPosition()) <= 128) { LinkedHashSet lineCoordinates = aiMarker.getPosition().getXZLine(aiMarker1.getPosition()); @@ -65,10 +66,11 @@ public static void placeAirAIMarkers(SCMap map) { float airMarkerSpacing = 64; float airMarkerConnectionDistance = (float) StrictMath.sqrt(airMarkerSpacing * airMarkerSpacing * 2) + 1; List airCoordinates = new BooleanMask(map.getSize() + 1, null, null).getSpacedCoordinates( - airMarkerSpacing, (int) airMarkerSpacing / 8); - airCoordinates.forEach((location) -> map.addAirMarker( - new AIMarker(String.format("AirPN%d", airCoordinates.indexOf(location)), - location.roundToNearestHalfPoint(), new LinkedHashSet<>()))); + airMarkerSpacing, (int) airMarkerSpacing / 8).stream().map(Vector2::roundToNearestHalfPoint).toList(); + for (int i = 0; i < airCoordinates.size(); i++) { + Vector2 location = airCoordinates.get(i); + map.addAirMarker(new AIMarker(String.format("AirPN%d", i), location, new LinkedHashSet<>())); + } map.getAirAIMarkers().forEach(aiMarker -> map.getAirAIMarkers().forEach(aiMarker1 -> { if (aiMarker != aiMarker1 && aiMarker.getPosition().getXZDistance(aiMarker1.getPosition()) < airMarkerConnectionDistance) { diff --git a/shared/src/main/java/com/faforever/neroxis/map/placement/DecalPlacer.java b/shared/src/main/java/com/faforever/neroxis/map/placement/DecalPlacer.java index 30fdbee6d..ea4b448e6 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/placement/DecalPlacer.java +++ b/shared/src/main/java/com/faforever/neroxis/map/placement/DecalPlacer.java @@ -25,24 +25,31 @@ public void placeDecals(BooleanMask spawnMask, List paths, float minSepa if (paths != null && !paths.isEmpty()) { BooleanMask spawnMaskCopy = spawnMask.copy(); spawnMaskCopy.limitToSymmetryRegion(); - List coordinates = spawnMaskCopy.getRandomCoordinates(minSeparation, maxSeparation); - coordinates.forEach((location) -> { - float scale = random.nextFloat() * (maxScale - minScale) + minScale; - location.roundToNearestHalfPoint(); - Vector3 rotation = new Vector3(0f, random.nextFloat() * (float) StrictMath.PI, 0f); - Decal decal = new Decal(paths.get(random.nextInt(paths.size())), location, rotation, scale, 1000); - map.addDecal(decal); - List symmetryPoints = spawnMask.getSymmetryPoints(decal.getPosition(), SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); - ArrayList symmetryRotation = spawnMask.getSymmetryRotation(decal.getRotation().getY()); - for (int i = 0; i < symmetryPoints.size(); i++) { - Vector3 symVectorRotation = new Vector3(decal.getRotation().getX(), symmetryRotation.get(i), - decal.getRotation().getZ()); - Decal symDecal = new Decal(decal.getPath(), symmetryPoints.get(i), symVectorRotation, scale, - decal.getCutOffLOD()); - map.addDecal(symDecal); - } - }); + spawnMaskCopy.getRandomCoordinates(minSeparation, maxSeparation) + .stream() + .map(Vector2::roundToNearestHalfPoint) + .forEach((location) -> { + float scale = random.nextFloat() * (maxScale - minScale) + minScale; + Vector3 rotation = new Vector3(0f, random.nextFloat() * (float) StrictMath.PI, 0f); + Decal decal = new Decal(paths.get(random.nextInt(paths.size())), + location.roundToNearestHalfPoint(), rotation, scale, 1000); + map.addDecal(decal); + List symmetryPoints = spawnMask.getSymmetryPoints(decal.getPosition(), + SymmetryType.SPAWN) + .stream() + .map(Vector2::roundToNearestHalfPoint) + .toList(); + List symmetryRotation = spawnMask.getSymmetryRotation(decal.getRotation().y()); + for (int i = 0; i < symmetryPoints.size(); i++) { + Vector3 symVectorRotation = new Vector3(decal.getRotation().x(), + symmetryRotation.get(i), + decal.getRotation().z()); + Decal symDecal = new Decal(decal.getPath(), + symmetryPoints.get(i), + symVectorRotation, scale, decal.getCutOffLOD()); + map.addDecal(symDecal); + } + }); } } } diff --git a/shared/src/main/java/com/faforever/neroxis/map/placement/HydroPlacer.java b/shared/src/main/java/com/faforever/neroxis/map/placement/HydroPlacer.java index 2001e6ef6..ff2da7baa 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/placement/HydroPlacer.java +++ b/shared/src/main/java/com/faforever/neroxis/map/placement/HydroPlacer.java @@ -51,11 +51,9 @@ public void placeHydros(int hydroCount, BooleanMask spawnMask) { private void placeBaseHydros(BooleanMask spawnMask) { boolean spawnHydro = random.nextBoolean(); if (spawnHydro) { - for (int i = 0; - i < map.getSpawnCount(); - i += spawnMask.getSymmetrySettings() - .spawnSymmetry() - .getNumSymPoints()) { + for (int i = 0; i < map.getSpawnCount(); i += spawnMask.getSymmetrySettings() + .spawnSymmetry() + .getNumSymPoints()) { Spawn spawn = map.getSpawn(i); BooleanMask baseHydro = new BooleanMask(spawnMask.getSize(), random.nextLong(), spawnMask.getSymmetrySettings()); @@ -78,18 +76,20 @@ private void placeBaseHydros(BooleanMask spawnMask) { private void placeIndividualHydros(BooleanMask spawnMask, int numHydros, int hydroSpacing) { if (numHydros > 0) { List hydroLocations = spawnMask.getRandomCoordinates(hydroSpacing); - hydroLocations.stream().limit(numHydros).forEachOrdered(location -> { - int hydroId = map.getHydroCount() / spawnMask.getSymmetrySettings() - .spawnSymmetry() - .getNumSymPoints(); + hydroLocations.stream().limit(numHydros).map(Vector2::roundToNearestHalfPoint).forEach(location -> { + int hydroId = map.getHydroCount() / spawnMask.getSymmetrySettings().spawnSymmetry().getNumSymPoints(); Marker hydro = new Marker(String.format("Hydro %d", hydroId), - new Vector3(location.roundToNearestHalfPoint())); + new Vector3(location)); map.addHydro(hydro); - List symmetryPoints = spawnMask.getSymmetryPoints(hydro.getPosition(), SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); - symmetryPoints.forEach(symmetryPoint -> map.addHydro( - new Marker(String.format("Hydro %d sym %d", hydroId, symmetryPoints.indexOf(symmetryPoint)), - new Vector3(symmetryPoint)))); + List symmetryPoints = spawnMask.getSymmetryPoints(hydro.getPosition(), SymmetryType.SPAWN) + .stream() + .map(Vector2::roundToNearestHalfPoint) + .toList(); + for (int i = 0; i < symmetryPoints.size(); i++) { + Vector2 symmetryPoint = symmetryPoints.get(i); + map.addHydro(new Marker(String.format("Hydro %d sym %d", hydroId, i), + new Vector3(symmetryPoint))); + } }); } } diff --git a/shared/src/main/java/com/faforever/neroxis/map/placement/MexPlacer.java b/shared/src/main/java/com/faforever/neroxis/map/placement/MexPlacer.java index 2896b6d97..3720c6683 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/placement/MexPlacer.java +++ b/shared/src/main/java/com/faforever/neroxis/map/placement/MexPlacer.java @@ -87,7 +87,10 @@ public void placeMexes(int mexCount, BooleanMask spawnMask, BooleanMask spawnMas } private void spacePlacedMexes(BooleanMask spawnMask, int mexSpacing, int previousMexCount) { - map.getMexes().stream().skip(previousMexCount).filter(mex -> spawnMask.inTeam(mex.getPosition(), false)) + map.getMexes() + .stream() + .skip(previousMexCount) + .filter(mex -> spawnMask.inTeam(mex.getPosition(), false)) .forEach(mex -> spawnMask.fillCircle(mex.getPosition(), mexSpacing, false)); } @@ -155,21 +158,25 @@ private void placeMexExpansions(BooleanMask spawnMask, int possibleExpMexCount, int expID = map.getLargeExpansionMarkerCount() / spawnMask.getSymmetrySettings() .spawnSymmetry() .getNumSymPoints(); + List symmetryPoints = expansionSpawnMask.getSymmetryPoints(expLocation, SymmetryType.SPAWN) + .stream() + .map(Vector2::roundToNearestHalfPoint) + .toList(); if (expMexCount >= 3) { map.addLargeExpansionMarker( new AIMarker(String.format("Large Expansion Area %d", expID), expLocation, null)); - List symmetryPoints = expansionSpawnMask.getSymmetryPoints(expLocation, SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); - symmetryPoints.forEach(symmetryPoint -> map.addLargeExpansionMarker(new AIMarker( - String.format("Large Expansion Area %d sym %d", expID, symmetryPoints.indexOf(symmetryPoint)), - symmetryPoint, null))); + for (int i = 0; i < symmetryPoints.size(); i++) { + map.addLargeExpansionMarker( + new AIMarker(String.format("Large Expansion Area %d sym %d", expID, i), + symmetryPoints.get(i), + null)); + } } else { map.addExpansionMarker(new AIMarker(String.format("Expansion Area %d", expID), expLocation, null)); - List symmetryPoints = expansionSpawnMask.getSymmetryPoints(expLocation, SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); - symmetryPoints.forEach(symmetryPoint -> map.addExpansionMarker(new AIMarker( - String.format("Expansion Area %d sym %d", expID, symmetryPoints.indexOf(symmetryPoint)), - symmetryPoint, null))); + for (int i = 0; i < symmetryPoints.size(); i++) { + map.addExpansionMarker( + new AIMarker(String.format("Expansion Area %d sym %d", expID, i), symmetryPoints.get(i), null)); + } } placeIndividualMexes(expansion, expMexCount, expMexSpacing); @@ -181,16 +188,21 @@ private void placeMexExpansions(BooleanMask spawnMask, int possibleExpMexCount, private void placeIndividualMexes(BooleanMask spawnMask, int numMexes, int mexSpacing) { if (numMexes > 0) { List mexLocations = spawnMask.getRandomCoordinates(mexSpacing); - mexLocations.stream().limit(numMexes).forEachOrdered(location -> { + mexLocations.stream().limit(numMexes).map(Vector2::roundToNearestHalfPoint).forEach(location -> { int mexID = map.getMexCount() / spawnMask.getSymmetrySettings().spawnSymmetry().getNumSymPoints(); Marker mex = new Marker(String.format("Mex %d", mexID), - new Vector3(location.roundToNearestHalfPoint())); + new Vector3(location)); map.addMex(mex); - List symmetryPoints = spawnMask.getSymmetryPoints(mex.getPosition(), SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); - symmetryPoints.forEach(symmetryPoint -> map.addMex( - new Marker(String.format("Mex %d sym %d", mexID, symmetryPoints.indexOf(symmetryPoint)), - new Vector3(symmetryPoint)))); + List symmetryPoints = spawnMask.getSymmetryPoints(mex.getPosition(), SymmetryType.SPAWN) + .stream() + .map(Vector2::roundToNearestHalfPoint) + .toList(); + for (int i = 0; i < symmetryPoints.size(); i++) { + Vector2 symmetryPoint = symmetryPoints.get(i); + Marker marker = new Marker(String.format("Mex %d sym %d", mexID, i), + new Vector3(symmetryPoint)); + map.addMex(marker); + } }); } } @@ -200,7 +212,7 @@ private boolean isMexExpValid(Vector2 location, float size, BooleanMask spawnMas for (int dx = 0; dx < size; dx++) { for (int dy = 0; dy < size; dy++) { - Vector2 loc = new Vector2(location).add(dx - size / 2, dy - size / 2); + Vector2 loc = location.add(dx - size / 2, dy - size / 2); if (spawnMask.inBounds(loc)) { if (spawnMask.get(loc)) { ++count; diff --git a/shared/src/main/java/com/faforever/neroxis/map/placement/PropPlacer.java b/shared/src/main/java/com/faforever/neroxis/map/placement/PropPlacer.java index d4e4ce2b9..f46a54a12 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/placement/PropPlacer.java +++ b/shared/src/main/java/com/faforever/neroxis/map/placement/PropPlacer.java @@ -27,13 +27,14 @@ public void placeProps(BooleanMask spawnMask, List paths, float minSepar if (paths != null && !paths.isEmpty()) { spawnMask.limitToSymmetryRegion(); List coordinates = spawnMask.getRandomCoordinates(minSeparation, maxSeparation); - coordinates.forEach((location) -> { - location.roundToNearestHalfPoint(); + coordinates.stream().map(Vector2::roundToNearestHalfPoint).forEach(location -> { Prop prop = new Prop(paths.get(random.nextInt(paths.size())), location, random.nextFloat() * (float) StrictMath.PI, isBoulder); map.addProp(prop); - List symmetryPoints = spawnMask.getSymmetryPoints(prop.getPosition(), SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); + List symmetryPoints = spawnMask.getSymmetryPoints(prop.getPosition(), SymmetryType.SPAWN) + .stream() + .map(Vector2::roundToNearestHalfPoint) + .toList(); ArrayList symmetryRotation = spawnMask.getSymmetryRotation(prop.getRotation()); for (int i = 0; i < symmetryPoints.size(); i++) { Prop symProp = new Prop(prop.getPath(), symmetryPoints.get(i), symmetryRotation.get(i), isBoulder); diff --git a/shared/src/main/java/com/faforever/neroxis/map/placement/SpawnPlacer.java b/shared/src/main/java/com/faforever/neroxis/map/placement/SpawnPlacer.java index 7d277bf28..a357563ba 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/placement/SpawnPlacer.java +++ b/shared/src/main/java/com/faforever/neroxis/map/placement/SpawnPlacer.java @@ -8,6 +8,7 @@ import com.faforever.neroxis.map.SymmetrySettings; import com.faforever.neroxis.map.SymmetryType; import com.faforever.neroxis.mask.BooleanMask; +import com.faforever.neroxis.util.vector.Vector; import com.faforever.neroxis.util.vector.Vector2; import java.util.List; @@ -40,10 +41,12 @@ public void placeSpawns(int spawnCount, float teammateSeparation, int teamSepara placeSpawns(spawnCount, StrictMath.max(teammateSeparation - 4, 0), teamSeparation, symmetrySettings); return; } - location.roundToNearestHalfPoint(); + location = location.roundToNearestHalfPoint(); spawnMask.fillCircle(location, teammateSeparation, false); - List symmetryPoints = spawnMask.getSymmetryPoints(location, SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); + List symmetryPoints = spawnMask.getSymmetryPoints(location, SymmetryType.SPAWN) + .stream() + .map(Vector::roundToNearestHalfPoint) + .toList(); symmetryPoints.forEach(symmetryPoint -> spawnMask.fillCircle(symmetryPoint, teamSeparation, false)); addSpawn(location, symmetryPoints); @@ -80,8 +83,10 @@ public void placeSpawns(int spawnCount, BooleanMask spawnMask, float separation) } } spawnMaskCopy.fillCircle(location, separation, false); - List symmetryPoints = spawnMaskCopy.getSymmetryPoints(location, SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); + List symmetryPoints = spawnMaskCopy.getSymmetryPoints(location, SymmetryType.SPAWN) + .stream() + .map(Vector::roundToNearestHalfPoint) + .toList(); symmetryPoints.forEach(symmetryPoint -> spawnMaskCopy.fillCircle(symmetryPoint, separation, false)); if (spawnMaskCopy.getSymmetrySettings().spawnSymmetry() == Symmetry.POINT2) { diff --git a/shared/src/main/java/com/faforever/neroxis/map/placement/UnitPlacer.java b/shared/src/main/java/com/faforever/neroxis/map/placement/UnitPlacer.java index b3957dd1c..12d8c6e9d 100644 --- a/shared/src/main/java/com/faforever/neroxis/map/placement/UnitPlacer.java +++ b/shared/src/main/java/com/faforever/neroxis/map/placement/UnitPlacer.java @@ -60,13 +60,15 @@ public void placeBases(BooleanMask spawnMask, String[] templates, Army army, Gro List coordinates = spawnMask.getRandomCoordinates(separation) .stream() .limit((MAX_UNIT_COUNT - army.getNumUnits()) / numUnitsInTemplate) - .peek(Vector::roundToNearestHalfPoint) + .map(Vector::roundToNearestHalfPoint) .toList(); for (Vector2 location : coordinates) { BaseTemplate base = new BaseTemplate(location, units); base.addUnits(army, group); - List symmetryPoints = spawnMask.getSymmetryPoints(location, SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); + List symmetryPoints = spawnMask.getSymmetryPoints(location, SymmetryType.SPAWN) + .stream() + .map(Vector::roundToNearestHalfPoint) + .toList(); symmetryPoints.forEach(symmetryPoint -> { BaseTemplate symBase = new BaseTemplate(symmetryPoint, base.units()); if (!spawnMask.inTeam(symmetryPoint, false)) { @@ -92,7 +94,7 @@ public void placeUnits(BooleanMask spawnMask, String[] types, Army army, Group g / spawnMask.getSymmetrySettings() .spawnSymmetry() .getNumSymPoints()) - .peek(Vector2::roundToNearestHalfPoint) + .map(Vector2::roundToNearestHalfPoint) .toList(); String type = types[random.nextInt(types.length)]; float rot = random.nextFloat() * 3.14159f; @@ -101,8 +103,10 @@ public void placeUnits(BooleanMask spawnMask, String[] types, Army army, Group g Unit unit = new Unit(String.format("%s %s Unit %d", army.getId(), group.getId(), groupID), type, location, rot); group.addUnit(unit); - List symmetryPoints = spawnMask.getSymmetryPoints(unit.getPosition(), SymmetryType.SPAWN); - symmetryPoints.forEach(Vector2::roundToNearestHalfPoint); + List symmetryPoints = spawnMask.getSymmetryPoints(unit.getPosition(), SymmetryType.SPAWN) + .stream() + .map(Vector2::roundToNearestHalfPoint) + .toList(); ArrayList symmetryRotation = spawnMask.getSymmetryRotation(unit.getRotation()); for (int i = 0; i < symmetryPoints.size(); i++) { group.addUnit( diff --git a/shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java b/shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java index 666180fa2..cc3b59a91 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/BooleanMask.java @@ -540,11 +540,11 @@ public Boolean getMax() { } public boolean getPrimitive(Vector2 location) { - return getPrimitive(StrictMath.round(location.getX()), StrictMath.round(location.getY())); + return getPrimitive(StrictMath.round(location.x()), StrictMath.round(location.y())); } void setPrimitive(Vector2 location, boolean value) { - setPrimitive(StrictMath.round(location.getX()), StrictMath.round(location.getY()), value); + setPrimitive(StrictMath.round(location.x()), StrictMath.round(location.y()), value); } public , U extends ComparableMask> BooleanMask init(ComparableMask other, @@ -622,15 +622,14 @@ public BooleanMask randomWalk(int numWalkers, int numSteps) { public BooleanMask guidedWalkWithBrush(Vector2 start, Vector2 target, String brushName, int size, int numberOfUses, float minValue, float maxValue, int maxStepSize, boolean wrapEdges) { return enqueue(() -> { - Vector2 location = new Vector2(start); BooleanMask brush = loadBrush(brushName, null).setSize(size).copyAsBooleanMask(minValue, maxValue); - float targetX = target.getX(); - float targetY = target.getY(); + float targetX = target.x(); + float targetY = target.y(); if (wrapEdges) { int maskSize = getSize(); int halfSize = maskSize / 2; - float startX = start.getX(); - float startY = start.getY(); + float startX = start.x(); + float startY = start.y(); float distanceToMidX = targetX - startX; float distanceToMidY = targetY - startY; if (StrictMath.abs(distanceToMidX) > halfSize) { @@ -650,10 +649,10 @@ public BooleanMask guidedWalkWithBrush(Vector2 start, Vector2 target, String bru } for (int i = 0; i < numberOfUses; i++) { - addWithOffset(brush, location, true, wrapEdges); - int dx = (targetX > location.getX() ? 1 : -1) * random.nextInt(maxStepSize + 1); - int dy = (targetY > location.getY() ? 1 : -1) * random.nextInt(maxStepSize + 1); - location.add(new Vector2(dx, dy)); + addWithOffset(brush, start, true, wrapEdges); + int dx = (targetX > start.x() ? 1 : -1) * random.nextInt(maxStepSize + 1); + int dy = (targetY > start.y() ? 1 : -1) * random.nextInt(maxStepSize + 1); + start.add(new Vector2(dx, dy)); } }); } @@ -661,23 +660,25 @@ public BooleanMask guidedWalkWithBrush(Vector2 start, Vector2 target, String bru public BooleanMask pathBezier(Vector2 start, Vector2 end, int minOrder, int maxOrder, int numMiddlePoints, float midPointMaxDistance, float midPointMinDistance) { int size = getSize(); - List checkPoints = new ArrayList<>(); - checkPoints.add(new Vector2(start)); + List rawPoints = new ArrayList<>(); + rawPoints.add(start); for (int i = 0; i < numMiddlePoints; i++) { - Vector2 previousLoc = checkPoints.getLast(); + Vector2 previousLoc = rawPoints.getLast(); float angle = (float) ((random.nextFloat() - .5f) * 2 * StrictMath.PI / 2f) + previousLoc.angleTo(end); float magnitude = random.nextFloat() * start.getDistance(end) / numMiddlePoints; - Vector2 nextLoc = previousLoc.copy().addPolar(angle, magnitude); - checkPoints.add(nextLoc); + Vector2 nextLoc = previousLoc.addPolar(angle, magnitude); + rawPoints.add(nextLoc); } - checkPoints.add(end.copy()); - checkPoints.forEach(point -> point.round().clampMin(0f).clampMax(size - 1)); + rawPoints.add(end); + + List checkPoints = rawPoints.stream() + .map(point -> point.round().clampMin(0f).clampMax(size - 1)) + .toList(); for (int i = 0; i < checkPoints.size() - 1; i++) { Vector2 location = checkPoints.get(i); Vector2 nextLoc = checkPoints.get(i + 1); BezierCurve bezierCurve = new BezierCurve(random.nextInt(maxOrder - minOrder) + minOrder, - random.nextLong()); - bezierCurve.transformTo(location, nextLoc); + random.nextLong()).transformTo(location, nextLoc); List points = new ArrayList<>(); for (float j = 0; j <= 1; j += 1f / size) { points.add(bezierCurve.getPoint(j)); @@ -706,24 +707,28 @@ public BooleanMask path(Vector2 start, Vector2 end, float maxStepSize, int numMi SymmetryType symmetryType) { return enqueue(() -> { int size = getSize(); - List checkPoints = new ArrayList<>(); - checkPoints.add(new Vector2(start)); + List rawPoints = new ArrayList<>(); + rawPoints.add(start); for (int i = 0; i < numMiddlePoints; i++) { - Vector2 previousLoc = checkPoints.getLast(); + Vector2 previousLoc = rawPoints.getLast(); float angle = (float) ((random.nextFloat() - .5f) * 2 * StrictMath.PI / 2f) + previousLoc.angleTo(end); if (symmetrySettings.terrainSymmetry() == Symmetry.POINT4 && angle % (StrictMath.PI / 2) < StrictMath.PI / 8) { - angle += (float) ( - (random.nextBoolean() ? -1 : 1) * (random.nextFloat() * .5f + .5f) * 2f * StrictMath.PI - / 4f); + angle += (float) ((random.nextBoolean() ? -1 : 1) + * (random.nextFloat() * .5f + .5f) + * 2f + * StrictMath.PI / 4f); } - float magnitude = - random.nextFloat() * (midPointMaxDistance - midPointMinDistance) + midPointMinDistance; - Vector2 nextLoc = new Vector2(previousLoc).addPolar(angle, magnitude); - checkPoints.add(nextLoc); + float magnitude = random.nextFloat() * (midPointMaxDistance - midPointMinDistance) + + midPointMinDistance; + Vector2 nextLoc = previousLoc.addPolar(angle, magnitude); + rawPoints.add(nextLoc); } - checkPoints.add(new Vector2(end)); - checkPoints.forEach(point -> point.round().clampMin(0f).clampMax(size - 1)); + rawPoints.add(end); + + List checkPoints = rawPoints.stream() + .map(point -> point.round().clampMin(0f).clampMax(size - 1)) + .toList(); int numSteps = 0; for (int i = 0; i < checkPoints.size() - 1; i++) { Vector2 location = checkPoints.get(i); @@ -732,13 +737,14 @@ public BooleanMask path(Vector2 start, Vector2 end, float maxStepSize, int numMi while (location.getDistance(nextLoc) > maxStepSize && numSteps < size * size) { List symmetryPoints = getSymmetryPoints(location, symmetryType); if (inBounds(location) && symmetryPoints.stream().allMatch(this::inBounds)) { - applyAtSymmetryPoints((int) location.getX(), (int) location.getY(), SymmetryType.TERRAIN, + applyAtSymmetryPoints((int) location.x(), (int) location.y(), SymmetryType.TERRAIN, (sx, sy) -> setPrimitive(sx, sy, true)); } float magnitude = StrictMath.max(1, random.nextFloat() * maxStepSize); - float angle = oldAngle * .5f + location.angleTo(nextLoc) * .5f + float angle = oldAngle * .5f + + location.angleTo(nextLoc) * .5f + (random.nextFloat() - .5f) * 2f * maxAngleError; - location.addPolar(angle, magnitude).round(); + location = location.addPolar(angle, magnitude).round(); oldAngle = angle; numSteps++; } @@ -894,7 +900,8 @@ private void markInRadius(float radius, long[] maskCopy, int x, int y, boolean v for (int x2 = minX; x2 < maxX; ++x2) { for (int y2 = minY; y2 < maxY; ++y2) { int bitIndex = bitIndex(x2, y2, size); - if (inBounds(x2, y2, size) && getBit(bitIndex, maskCopy) != value + if (inBounds(x2, y2, size) + && getBit(bitIndex, maskCopy) != value && (x - x2) * (x - x2) + (y - y2) * (y - y2) <= radius2) { setBit(bitIndex, value, maskCopy); } @@ -971,8 +978,14 @@ public BooleanMask outline() { public boolean isEdge(int x, int y) { boolean value = getPrimitive(x, y); int size = getSize(); - return ((x > 0 && getPrimitive(x - 1, y) != value) || (y > 0 && getPrimitive(x, y - 1) != value) || ( - x < size - 1 && getPrimitive(x + 1, y) != value) || (y < size - 1 && getPrimitive(x, y + 1) != value)); + return ((x > 0 && getPrimitive(x - 1, y) != value) + || (y > 0 && getPrimitive(x, y - 1) != value) + || (x + < size - 1 + && getPrimitive(x + + 1, y) + != value) + || (y < size - 1 && getPrimitive(x, y + 1) != value)); } /** @@ -1094,9 +1107,10 @@ public BooleanMask limitToSymmetryRegion(SymmetryType symmetryType) { int minXBound = getMinXBound(symmetryType); int maxXBound = getMaxXBound(symmetryType); return apply((x, y) -> { - setPrimitive(x, y, - getPrimitive(x, y) && !(x < minXBound || x >= maxXBound || y < getMinYBound(x, symmetryType) - || y >= getMaxYBound(x, symmetryType))); + setPrimitive(x, y, getPrimitive(x, y) && !(x < minXBound + || x >= maxXBound + || y < getMinYBound(x, symmetryType) + || y >= getMaxYBound(x, symmetryType))); }); } @@ -1242,7 +1256,7 @@ public LinkedHashSet getShapeCoordinates(Vector2 location, int maxSize) if (getPrimitive(next) == value && !areaHash.contains(next)) { areaHash.add(next); edges.forEach((e) -> { - Vector2 newLocation = new Vector2(next.getX() + e[0], next.getY() + e[1]); + Vector2 newLocation = new Vector2(next.x() + e[0], next.y() + e[1]); if (!queueHash.contains(newLocation) && !areaHash.contains(newLocation) && !edgeHash.contains( newLocation) && inBounds(newLocation)) { queue.add(newLocation); diff --git a/shared/src/main/java/com/faforever/neroxis/mask/FloatMask.java b/shared/src/main/java/com/faforever/neroxis/mask/FloatMask.java index 357e32f5f..2b6638431 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/FloatMask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/FloatMask.java @@ -201,7 +201,7 @@ public float getPrimitive(int x, int y) { } private void setPrimitive(Vector2 location, float value) { - setPrimitive(StrictMath.round(location.getX()), StrictMath.round(location.getY()), value); + setPrimitive(StrictMath.round(location.x()), StrictMath.round(location.y()), value); } Vector3 calculateNormalAt(int x, int y, float scale) { @@ -281,13 +281,13 @@ private void waterDrop(int maxIterations, float x, float y, float friction, floa Vector3 surfaceNormal = calculateNormalAt(sampleX, sampleY, 1f); // If the terrain is flat, stop simulating, the snowball cannot roll any further - if (surfaceNormal.getY() >= 1 && StrictMath.sqrt(xVelocity * xVelocity + yVelocity * yVelocity) < 1) { + if (surfaceNormal.y() >= 1 && StrictMath.sqrt(xVelocity * xVelocity + yVelocity * yVelocity) < 1) { break; } // Calculate the deposition and erosion rate - float deposit = sediment * depositionRate * surfaceNormal.getY(); - float erosion = erosionRate * (1 - surfaceNormal.getY()) * StrictMath.min(1, i * iterationScale); + float deposit = sediment * depositionRate * surfaceNormal.y(); + float erosion = erosionRate * (1 - surfaceNormal.y()) * StrictMath.min(1, i * iterationScale); float sedimentChange = deposit - erosion; @@ -295,8 +295,8 @@ private void waterDrop(int maxIterations, float x, float y, float friction, floa addValueAt((int) xPrev, (int) yPrev, sedimentChange); sediment -= sedimentChange; - xVelocity = (1 - friction) * xVelocity + surfaceNormal.getX() * gravity; - yVelocity = (1 - friction) * yVelocity + surfaceNormal.getZ() * gravity; + xVelocity = (1 - friction) * xVelocity + surfaceNormal.x() * gravity; + yVelocity = (1 - friction) * yVelocity + surfaceNormal.z() * gravity; xPrev = x; yPrev = y; x += xVelocity; @@ -433,21 +433,21 @@ public BooleanMask copyAsShadowMask(Vector3 lightDirection) { } float startHeight = source.getPrimitive(location); int dist = 1; - location.addPolar(angle, 1); + location = location.addPolar(angle, 1); while (source.inBounds(location)) { if (startHeight - source.getPrimitive(location) > dist * slope) { shadowMask.setPrimitive(location, true); } else { break; } - location.addPolar(angle, 1); + location = location.addPolar(angle, 1); ++dist; } }), this).inflate(1).deflate(1); } public float getPrimitive(Vector2 location) { - return getPrimitive(StrictMath.round(location.getX()), StrictMath.round(location.getY())); + return getPrimitive(StrictMath.round(location.x()), StrictMath.round(location.y())); } /** @@ -515,15 +515,15 @@ private void addCalculatedParabolicDistance(boolean useColumns) { } Vector2 current = new Vector2(j, value); Vector2 vertex = vertices.get(index); - float xIntersect = ((current.getY() + current.getX() * current.getX()) - - (vertex.getY() + vertex.getX() * vertex.getX())) / - (2 * current.getX() - 2 * vertex.getX()); - while (xIntersect <= intersections.get(index).getX()) { + float xIntersect = ((current.y() + current.x() * current.x()) - + (vertex.y() + vertex.x() * vertex.x())) / + (2 * current.x() - 2 * vertex.x()); + while (xIntersect <= intersections.get(index).x()) { index -= 1; vertex = vertices.get(index); - xIntersect = ((current.getY() + current.getX() * current.getX()) - - (vertex.getY() + vertex.getX() * vertex.getX())) / - (2 * current.getX() - 2 * vertex.getX()); + xIntersect = ((current.y() + current.x() * current.x()) - + (vertex.y() + vertex.x() * vertex.x())) / + (2 * current.x() - 2 * vertex.x()); } index += 1; if (index < vertices.size()) { @@ -541,12 +541,12 @@ private void addCalculatedParabolicDistance(boolean useColumns) { } index = 0; for (int j = 0; j < size; j++) { - while (intersections.get(index + 1).getX() < j) { + while (intersections.get(index + 1).x() < j) { index += 1; } Vector2 vertex = vertices.get(index); - float dx = j - vertex.getX(); - float height = dx * dx + vertex.getY(); + float dx = j - vertex.x(); + float height = dx * dx + vertex.y(); if (!useColumns) { setPrimitive(i, j, height); } else { diff --git a/shared/src/main/java/com/faforever/neroxis/mask/IntegerMask.java b/shared/src/main/java/com/faforever/neroxis/mask/IntegerMask.java index 8ff376e58..e94e1e015 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/IntegerMask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/IntegerMask.java @@ -80,7 +80,7 @@ private void setPrimitive(int x, int y, int value) { } public int getPrimitive(Vector2 location) { - return getPrimitive(StrictMath.round(location.getX()), StrictMath.round(location.getY())); + return getPrimitive(StrictMath.round(location.x()), StrictMath.round(location.y())); } public int getPrimitive(int x, int y) { @@ -88,7 +88,7 @@ public int getPrimitive(int x, int y) { } private void setPrimitive(Vector2 location, int value) { - setPrimitive(StrictMath.round(location.getX()), StrictMath.round(location.getY()), value); + setPrimitive(StrictMath.round(location.x()), StrictMath.round(location.y()), value); } @Override diff --git a/shared/src/main/java/com/faforever/neroxis/mask/MapMaskMethods.java b/shared/src/main/java/com/faforever/neroxis/mask/MapMaskMethods.java index 1772a8af3..f2793d808 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/MapMaskMethods.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/MapMaskMethods.java @@ -21,7 +21,7 @@ public static BooleanMask connectTeams(SCMap map, long seed, BooleanMask exec, i List startTeamSpawns = map.getSpawns() .stream() .filter(spawn -> spawn.getTeamID() == 0) - .collect(Collectors.toList()); + .toList(); for (int i = 0; i < numConnections; ++i) { Spawn startSpawn = startTeamSpawns.get(random.nextInt(startTeamSpawns.size())); int numMiddlePoints; @@ -31,9 +31,8 @@ public static BooleanMask connectTeams(SCMap map, long seed, BooleanMask exec, i numMiddlePoints = maxMiddlePoints; } Vector2 start = new Vector2(startSpawn.getPosition()); - Vector2 end = new Vector2(start); - float maxMiddleDistance = start.getDistance(end); - exec.connect(start, end, maxStepSize, numMiddlePoints, maxMiddleDistance, maxMiddleDistance / 2, + float maxMiddleDistance = start.getDistance(start); + exec.connect(start, start, maxStepSize, numMiddlePoints, maxMiddleDistance, maxMiddleDistance / 2, (float) (StrictMath.PI / 2), SymmetryType.SPAWN); } return exec; @@ -57,12 +56,13 @@ public static BooleanMask connectTeamsAroundCenter(SCMap map, long seed, Boolean numMiddlePoints = maxMiddlePoints; } Vector2 start = new Vector2(startSpawn.getPosition()); - Vector2 end = new Vector2(start); float offCenterAngle = (float) (StrictMath.PI * (1f / 3f + random.nextFloat() / 3f)); offCenterAngle *= random.nextBoolean() ? 1 : -1; offCenterAngle += start.angleTo(new Vector2(exec.getSize() / 2f, exec.getSize() / 2f)); - end.addPolar(offCenterAngle, random.nextFloat() * exec.getSize() / 2f + exec.getSize() / 2f); - end.clampMax(exec.getSize() - bound).clampMin(bound); + Vector2 end = start.addPolar(offCenterAngle, + random.nextFloat() * exec.getSize() / 2f + exec.getSize() / 2f) + .clampMax(exec.getSize() - bound) + .clampMin(bound); float maxMiddleDistance = start.getDistance(end); exec.connect(start, end, maxStepSize, numMiddlePoints, maxMiddleDistance, maxMiddleDistance / 2, (float) (StrictMath.PI / 2), SymmetryType.SPAWN); @@ -139,8 +139,8 @@ public static BooleanMask pathAroundSpawns(SCMap map, long seed, BooleanMask exe map.getSpawns().forEach(spawn -> { Vector2 start = new Vector2(spawn.getPosition()); for (int i = 0; i < numPaths; i++) { - int endX = (int) (random.nextFloat() * bound + start.getX()); - int endY = (int) (random.nextFloat() * bound + start.getY()); + int endX = (int) (random.nextFloat() * bound + start.x()); + int endY = (int) (random.nextFloat() * bound + start.y()); Vector2 end = new Vector2(endX, endY); int numMiddlePoints = random.nextInt(maxMiddlePoints); float maxMiddleDistance = start.getDistance(end) / numMiddlePoints * 2; diff --git a/shared/src/main/java/com/faforever/neroxis/mask/Mask.java b/shared/src/main/java/com/faforever/neroxis/mask/Mask.java index cb96d6207..db80d5d9d 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/Mask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/Mask.java @@ -165,19 +165,19 @@ public String toString() { } public T get(Vector3 location) { - return get(StrictMath.round(location.getX()), StrictMath.round(location.getZ())); + return get(StrictMath.round(location.x()), StrictMath.round(location.z())); } protected abstract T get(int x, int y); protected void set(Vector3 location, T value) { - set(StrictMath.round(location.getX()), StrictMath.round(location.getZ()), value); + set(StrictMath.round(location.x()), StrictMath.round(location.z()), value); } protected abstract void set(int x, int y, T value); protected void set(Vector2 location, T value) { - set(StrictMath.round(location.getX()), StrictMath.round(location.getY()), value); + set(StrictMath.round(location.x()), StrictMath.round(location.y()), value); } @SneakyThrows @@ -377,7 +377,7 @@ public boolean inBounds(int x, int y) { } public boolean onBoundary(Vector2 location) { - return onBoundary((int) location.getX(), (int) location.getY()); + return onBoundary((int) location.x(), (int) location.y()); } public boolean onBoundary(int x, int y) { @@ -390,7 +390,7 @@ public List getSymmetryPoints(Vector3 point, SymmetryType symmetryType) } public List getSymmetryPoints(Vector2 point, SymmetryType symmetryType) { - return getSymmetryPoints(point.getX(), point.getY(), symmetryType); + return getSymmetryPoints(point.x(), point.y(), symmetryType); } public List getSymmetryPoints(float x, float y, SymmetryType symmetryType) { @@ -404,7 +404,7 @@ public List getSymmetryPointsWithOutOfBounds(Vector3 point, SymmetryTyp } public List getSymmetryPointsWithOutOfBounds(Vector2 point, SymmetryType symmetryType) { - return getSymmetryPointsWithOutOfBounds(point.getX(), point.getY(), symmetryType); + return getSymmetryPointsWithOutOfBounds(point.x(), point.y(), symmetryType); } public List getSymmetryPointsWithOutOfBounds(float x, float y, SymmetryType symmetryType) { @@ -584,7 +584,7 @@ public boolean inTeam(Vector3 pos, boolean reverse) { } public boolean inTeam(Vector2 pos, boolean reverse) { - return inTeam((int) pos.getX(), (int) pos.getY(), reverse); + return inTeam((int) pos.x(), (int) pos.y(), reverse); } public boolean inHalfNoBounds(int x, int y, float angle) { @@ -596,7 +596,7 @@ public boolean inTeamNoBounds(Vector3 pos, boolean reverse) { } public boolean inTeamNoBounds(Vector2 pos, boolean reverse) { - return inTeam((int) pos.getX(), (int) pos.getY(), reverse); + return inTeam((int) pos.x(), (int) pos.y(), reverse); } public boolean inHalfNoBounds(Vector2 pos, float angle) { @@ -628,13 +628,13 @@ public U forceSymmetry(SymmetryType symmetryType, boolean reverse) { } return applyWithSymmetry(symmetryType, (x, y) -> { List symPoints = getSymmetryPoints(x, y, symmetryType); - symPoints.forEach(symPoint -> set(x, y, get((int) symPoint.getX(), (int) symPoint.getY()))); + symPoints.forEach(symPoint -> set(x, y, get((int) symPoint.x(), (int) symPoint.y()))); }); } } public T get(Vector2 location) { - return get(StrictMath.round(location.getX()), StrictMath.round(location.getY())); + return get(StrictMath.round(location.x()), StrictMath.round(location.y())); } public boolean inHalfNoBounds(Vector3 pos, float angle) { @@ -681,7 +681,7 @@ public boolean inHalf(Vector2 pos, float angle) { } public boolean inBounds(Vector2 location) { - return inBounds(StrictMath.round(location.getX()), StrictMath.round(location.getY())); + return inBounds(StrictMath.round(location.x()), StrictMath.round(location.y())); } public U forceSymmetry(SymmetryType symmetryType) { @@ -704,23 +704,86 @@ protected U setWithSymmetry(SymmetryType symmetryType, BiIntFunction valueFun }); } - protected U applyAtSymmetryPointsWithOutOfBounds(Vector2 location, SymmetryType symmetryType, BiIntConsumer action) { - return applyAtSymmetryPointsWithOutOfBounds((int) location.getX(), (int) location.getY(), symmetryType, action); + protected U applyAtSymmetryPointsWithOutOfBounds(Vector2 location, SymmetryType symmetryType, + BiIntConsumer action) { + return applyAtSymmetryPointsWithOutOfBounds((int) location.x(), (int) location.y(), symmetryType, action); } protected U applyAtSymmetryPoints(Vector2 location, SymmetryType symmetryType, BiIntConsumer action) { - return applyAtSymmetryPoints((int) location.getX(), (int) location.getY(), symmetryType, action); + return applyAtSymmetryPoints((int) location.x(), (int) location.y(), symmetryType, action); } protected U applyAtSymmetryPoints(int x, int y, SymmetryType symmetryType, BiIntConsumer action) { return enqueue(() -> { - action.accept(x, y); - List symPoints = getSymmetryPoints(x, y, symmetryType); - symPoints.forEach(symPoint -> action.accept((int) symPoint.getX(), (int) symPoint.getY())); + int size = getSize(); + BiIntConsumer protectedAction = (px, py) -> { + if (!inBounds(px, py, size)) { + return; + } + + action.accept(px, py); + }; + Symmetry symmetry = symmetrySettings.getSymmetry(symmetryType); + + + protectedAction.accept(x, y); + switch (symmetry) { + case POINT2 -> protectedAction.accept(size - x - 1, size - y - 1); + case POINT4 -> { + protectedAction.accept(size - x - 1, size - y - 1); + protectedAction.accept(y, size - x - 1); + protectedAction.accept(size - y - 1, x); + } + case POINT6, POINT8, POINT10, POINT12, POINT14, POINT16 -> { + protectedAction.accept(size - x - 1, size - y - 1); + int numSymPoints = symmetry.getNumSymPoints(); + for (int i = 1; i < numSymPoints / 2; i++) { + float angle = (float) (2 * StrictMath.PI * i / numSymPoints); + Vector2 rotated = getRotatedPoint(x, y, angle); + protectedAction.accept((int) rotated.x(), (int) rotated.y()); + Vector2 antiRotated = getRotatedPoint(x, y, (float) (angle + StrictMath.PI)); + protectedAction.accept((int) antiRotated.x(), (int) antiRotated.y()); + } + } + case POINT3, POINT5, POINT7, POINT9, POINT11, POINT13, POINT15 -> { + int numSymPoints = symmetry.getNumSymPoints(); + for (int i = 1; i < numSymPoints; i++) { + Vector2 rotated = getRotatedPoint(x, y, (float) (2 * StrictMath.PI * i / numSymPoints)); + protectedAction.accept((int) rotated.x(), (int) rotated.y()); + } + } + case X -> protectedAction.accept(size - x - 1, y); + case Z -> protectedAction.accept(x, size - y - 1); + case XZ -> protectedAction.accept(y, x); + case ZX -> protectedAction.accept(size - y - 1, size - x - 1); + case QUAD -> { + if (symmetrySettings.teamSymmetry() == Symmetry.Z) { + protectedAction.accept(x, size - y - 1); + protectedAction.accept(size - x - 1, y); + protectedAction.accept(size - x - 1, size - y - 1); + } else { + protectedAction.accept(size - x - 1, y); + protectedAction.accept(x, size - y - 1); + protectedAction.accept(size - x - 1, size - y - 1); + } + } + case DIAG -> { + if (symmetrySettings.teamSymmetry() == Symmetry.ZX) { + protectedAction.accept(size - y - 1, size - x - 1); + protectedAction.accept(y, x); + protectedAction.accept(size - x - 1, size - y - 1); + } else { + protectedAction.accept(y, x); + protectedAction.accept(size - y - 1, size - x - 1); + protectedAction.accept(size - x - 1, size - y - 1); + } + } + } }); } - protected U applyWithOffset(U other, BiIntObjConsumer action, int xOffset, int yOffset, boolean center, boolean wrapEdges) { + protected U applyWithOffset(U other, BiIntObjConsumer action, int xOffset, int yOffset, boolean center, + boolean wrapEdges) { return enqueue(() -> { int size = getSize(); int otherSize = other.getSize(); @@ -777,11 +840,13 @@ protected U applyAtSymmetryPointsWithOutOfBounds(int x, int y, SymmetryType symm return enqueue(() -> { action.accept(x, y); List symPoints = getSymmetryPointsWithOutOfBounds(x, y, symmetryType); - symPoints.forEach(point -> action.accept((int) point.getX(), (int) point.getY())); + symPoints.forEach(point -> action.accept((int) point.x(), (int) point.y())); }); } - protected void populateCoordinateMaps(int xCoordinate, int yCoordinate, boolean center, boolean wrapEdges, int fromSize, int toSize, Map coordinateXMap, Map coordinateYMap) { + protected void populateCoordinateMaps(int xCoordinate, int yCoordinate, boolean center, boolean wrapEdges, + int fromSize, int toSize, Map coordinateXMap, + Map coordinateYMap) { int offsetX; int offsetY; if (center) { @@ -797,7 +862,8 @@ protected void populateCoordinateMaps(int xCoordinate, int yCoordinate, boolean } } - protected Map getShiftedCoordinateMap(int offset, boolean center, boolean wrapEdges, int fromSize, int toSize) { + protected Map getShiftedCoordinateMap(int offset, boolean center, boolean wrapEdges, int fromSize, + int toSize) { int trueOffset; if (center) { trueOffset = offset - fromSize / 2; @@ -981,11 +1047,11 @@ public U fillCenter(int extent, T value, SymmetryType symmetryType) { } public U fillCircle(Vector3 center, float radius, T value) { - return fillCircle(center.getX(), center.getZ(), radius, value); + return fillCircle(center.x(), center.z(), radius, value); } public U fillCircle(Vector2 center, float radius, T value) { - return fillCircle(center.getX(), center.getY(), radius, value); + return fillCircle(center.x(), center.y(), radius, value); } public U fillCircle(float x, float y, float radius, T value) { @@ -1016,7 +1082,7 @@ public U fillArc(float x, float y, float startAngle, float endAngle, float radiu } public U fillSquare(Vector2 topLeft, int extent, T value) { - return fillSquare((int) topLeft.getX(), (int) topLeft.getY(), extent, value); + return fillSquare((int) topLeft.x(), (int) topLeft.y(), extent, value); } public U fillSquare(int x, int y, int extent, T value) { @@ -1024,7 +1090,7 @@ public U fillSquare(int x, int y, int extent, T value) { } public U fillRect(Vector2 topLeft, int width, int height, T value) { - return fillRect((int) topLeft.getX(), (int) topLeft.getY(), width, height, value); + return fillRect((int) topLeft.x(), (int) topLeft.y(), width, height, value); } public U fillRect(int x, int y, int width, int height, T value) { @@ -1040,7 +1106,7 @@ public U fillRectFromPoints(int x1, int x2, int z1, int z2, T value) { } public U fillParallelogram(Vector2 topLeft, int width, int height, int xSlope, int ySlope, T value) { - return fillParallelogram((int) topLeft.getX(), (int) topLeft.getY(), width, height, xSlope, ySlope, value); + return fillParallelogram((int) topLeft.x(), (int) topLeft.y(), width, height, xSlope, ySlope, value); } public U fillParallelogram(int x, int y, int width, int height, int xSlope, int ySlope, T value) { @@ -1093,7 +1159,7 @@ public U fillEdge(int rimWidth, T value) { protected U fillCoordinates(Collection coordinates, T value) { coordinates.forEach( - location -> applyAtSymmetryPoints((int) location.getX(), (int) location.getY(), SymmetryType.SPAWN, + location -> applyAtSymmetryPoints((int) location.x(), (int) location.y(), SymmetryType.SPAWN, (x, y) -> set(x, y, value))); return (U) this; } diff --git a/shared/src/main/java/com/faforever/neroxis/mask/NormalMask.java b/shared/src/main/java/com/faforever/neroxis/mask/NormalMask.java index 8f1e9a667..2bae92b2e 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/NormalMask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/NormalMask.java @@ -73,9 +73,9 @@ public BufferedImage writeToImage(BufferedImage image) { WritableRaster imageRaster = image.getRaster(); loop((x, y) -> { Vector3 value = get(x, y); - int xV = (byte) StrictMath.min(StrictMath.max((128 * value.getX() + 128), 0), 255); - int yV = (byte) StrictMath.min(StrictMath.max((127 * value.getY() + 128), 0), 255); - int zV = (byte) StrictMath.min(StrictMath.max((128 * value.getZ() + 128), 0), 255); + int xV = (byte) StrictMath.min(StrictMath.max((128 * value.x() + 128), 0), 255); + int yV = (byte) StrictMath.min(StrictMath.max((127 * value.y() + 128), 0), 255); + int zV = (byte) StrictMath.min(StrictMath.max((128 * value.z() + 128), 0), 255); imageRaster.setPixel(x, y, new int[]{xV, zV, yV}); }); return image; @@ -89,13 +89,13 @@ protected Vector3[][] getNullMask(int size) { public NormalMask cross(NormalMask other) { assertCompatibleMask(other); return enqueue(dependencies -> { - Vector3Mask source = (Vector3Mask) dependencies.get(0); + Vector3Mask source = (Vector3Mask) dependencies.getFirst(); set((x, y) -> get(x, y).cross(source.get(x, y))); }, other); } public NormalMask cross(Vector3 vector) { - Vector3 normalizedVector = vector.copy().normalize(); + Vector3 normalizedVector = vector.normalize(); return set((x, y) -> get(x, y).cross(normalizedVector)); } diff --git a/shared/src/main/java/com/faforever/neroxis/mask/OperationsMask.java b/shared/src/main/java/com/faforever/neroxis/mask/OperationsMask.java index 1f5d860bc..c3a583296 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/OperationsMask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/OperationsMask.java @@ -91,7 +91,7 @@ public U add(T val) { } public U addWithOffset(U other, Vector2 offset, boolean centered, boolean wrapEdges) { - return addWithOffset(other, (int) offset.getX(), (int) offset.getY(), centered, wrapEdges); + return addWithOffset(other, (int) offset.x(), (int) offset.y(), centered, wrapEdges); } public U addWithOffset(U other, int xOffset, int yOffset, boolean center, boolean wrapEdges) { @@ -186,7 +186,7 @@ public U subtract(BooleanMask other, U values) { } public U subtractWithOffset(U other, Vector2 offset, boolean centered, boolean wrapEdges) { - return subtractWithOffset(other, (int) offset.getX(), (int) offset.getY(), centered, wrapEdges); + return subtractWithOffset(other, (int) offset.x(), (int) offset.y(), centered, wrapEdges); } public U subtractWithOffset(U other, int xOffset, int yOffset, boolean center, boolean wrapEdges) { @@ -270,7 +270,7 @@ public U multiply(BooleanMask other, U values) { } public U multiplyWithOffset(U other, Vector2 offset, boolean centered, boolean wrapEdges) { - return multiplyWithOffset(other, (int) offset.getX(), (int) offset.getY(), centered, wrapEdges); + return multiplyWithOffset(other, (int) offset.x(), (int) offset.y(), centered, wrapEdges); } public U multiplyWithOffset(U other, int xOffset, int yOffset, boolean center, boolean wrapEdges) { @@ -354,7 +354,7 @@ public U divide(BooleanMask other, U values) { } public U divideWithOffset(U other, Vector2 offset, boolean centered, boolean wrapEdges) { - return divideWithOffset(other, (int) offset.getX(), (int) offset.getY(), centered, wrapEdges); + return divideWithOffset(other, (int) offset.x(), (int) offset.y(), centered, wrapEdges); } public U divideWithOffset(U other, int xOffset, int yOffset, boolean center, boolean wrapEdges) { diff --git a/shared/src/main/java/com/faforever/neroxis/mask/Vector3Mask.java b/shared/src/main/java/com/faforever/neroxis/mask/Vector3Mask.java index 9f0a8cbe8..ea0b9247e 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/Vector3Mask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/Vector3Mask.java @@ -44,8 +44,8 @@ public Vector3Mask(NormalMask other) { public Vector3Mask(NormalMask other, String name) { super(other.getSize(), other.getNextSeed(), other.getSymmetrySettings(), name, other.isParallel()); enqueue(dependencies -> { - NormalMask source = (NormalMask) dependencies.get(0); - set((x, y) -> source.get(x, y).copy()); + NormalMask source = (NormalMask) dependencies.getFirst(); + set((x, y) -> source.get(x, y)); }, other); } @@ -91,7 +91,7 @@ public Vector3Mask setComponents(FloatMask comp0, FloatMask comp1, FloatMask com public Vector3Mask cross(Vector3Mask other) { assertCompatibleMask(other); return enqueue(dependencies -> { - Vector3Mask source = (Vector3Mask) dependencies.get(0); + Vector3Mask source = (Vector3Mask) dependencies.getFirst(); set((x, y) -> get(x, y).cross(source.get(x, y))); }, other); } @@ -107,7 +107,7 @@ public BufferedImage toImage() { WritableRaster imageRaster = image.getRaster(); Vector3 maxComponents = getMaxComponents(); Vector3 minComponents = getMinComponents(); - Vector3 rangeComponents = maxComponents.copy().subtract(minComponents); + Vector3 rangeComponents = maxComponents.subtract(minComponents); loop((x, y) -> imageRaster.setPixel(x, y, get(x, y).subtract(minComponents) .divide(rangeComponents) .multiply(255f) diff --git a/shared/src/main/java/com/faforever/neroxis/mask/Vector4Mask.java b/shared/src/main/java/com/faforever/neroxis/mask/Vector4Mask.java index 8438eb403..1af8a85c6 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/Vector4Mask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/Vector4Mask.java @@ -85,9 +85,8 @@ public BufferedImage toImage() { WritableRaster imageRaster = image.getRaster(); Vector4 maxComponents = getMaxComponents(); Vector4 minComponents = getMinComponents(); - Vector4 rangeComponents = maxComponents.copy().subtract(minComponents); - loop((x, y) -> imageRaster.setPixel(x, y, get(x, y).copy() - .subtract(minComponents) + Vector4 rangeComponents = maxComponents.subtract(minComponents); + loop((x, y) -> imageRaster.setPixel(x, y, get(x, y).subtract(minComponents) .divide(rangeComponents) .multiply(255f, 255f, 255f, 255f - 64f) .add(0f, 0f, 0f, 64f) diff --git a/shared/src/main/java/com/faforever/neroxis/mask/VectorMask.java b/shared/src/main/java/com/faforever/neroxis/mask/VectorMask.java index bdd5e8301..fbbbe14d0 100644 --- a/shared/src/main/java/com/faforever/neroxis/mask/VectorMask.java +++ b/shared/src/main/java/com/faforever/neroxis/mask/VectorMask.java @@ -19,7 +19,12 @@ import java.util.Map; @SuppressWarnings({"unchecked", "UnusedReturnValue", "unused"}) -public abstract sealed class VectorMask, U extends VectorMask> extends OperationsMask permits NormalMask, Vector2Mask, Vector3Mask, Vector4Mask { +public abstract sealed class VectorMask, U extends VectorMask> extends + OperationsMask permits + NormalMask, + Vector2Mask, + Vector3Mask, + Vector4Mask { protected T[][] mask; public VectorMask(BufferedImage sourceImage, Long seed, SymmetrySettings symmetrySettings, float scaleFactor, @@ -45,11 +50,12 @@ public VectorMask(Long seed, String name, FloatMask... components) { assertCompatibleComponents(components); enqueue(dependencies -> { List sources = dependencies.stream().map(dep -> ((FloatMask) dep)).toList(); - apply((x, y) -> { - T value = getZeroValue(); + set((x, y) -> { + T value = mask[x][y]; for (int i = 0; i < numComponents; ++i) { - value.set(i, sources.get(i).get(x, y)); + value = value.withComponent(i, sources.get(i).get(x, y)); } + return value; }); }, components); } @@ -83,7 +89,7 @@ public U blur(int radius) { public U blur(int radius, BooleanMask other) { assertCompatibleMask(other); return enqueue(dependencies -> { - BooleanMask limiter = (BooleanMask) dependencies.get(0); + BooleanMask limiter = (BooleanMask) dependencies.getFirst(); T[][] innerCount = getInnerCount(); set((x, y) -> limiter.get(x, y) ? calculateAreaAverage(radius, x, y, innerCount).round().divide(1000) : get( x, y)); @@ -92,7 +98,7 @@ public U blur(int radius, BooleanMask other) { @Override protected U copyFrom(U other) { - return enqueue(dependencies -> fill(((U) dependencies.get(0)).mask), other); + return enqueue(dependencies -> fill(((U) dependencies.getFirst()).mask), other); } @Override @@ -138,12 +144,12 @@ public String toHash() throws NoSuchAlgorithmException { @Override public T get(int x, int y) { - return mask[x][y].copy(); + return mask[x][y]; } @Override protected void set(int x, int y, T value) { - mask[x][y] = value.copy(); + mask[x][y] = value; } @Override @@ -163,8 +169,7 @@ protected U setSizeInternal(int newSize) { T[][] oldMask = mask; mask = getNullMask(newSize); Map coordinateMap = getSymmetricScalingCoordinateMap(oldSize, newSize); - setWithSymmetry(SymmetryType.SPAWN, - (x, y) -> oldMask[coordinateMap.get(x)][coordinateMap.get(y)].copy()); + setWithSymmetry(SymmetryType.SPAWN, (x, y) -> oldMask[coordinateMap.get(x)][coordinateMap.get(y)]); } }); } @@ -176,15 +181,15 @@ protected T[][] getInnerCount() { } protected void calculateInnerValue(T[][] innerCount, int x, int y, T val) { - innerCount[x][y] = val.copy().multiply(1000).round(); + innerCount[x][y] = val.multiply(1000).round(); if (x > 0) { - innerCount[x][y].add(innerCount[x - 1][y]); + innerCount[x][y] = innerCount[x][y].add(innerCount[x - 1][y]); } if (y > 0) { - innerCount[x][y].add(innerCount[x][y - 1]); + innerCount[x][y] = innerCount[x][y].add(innerCount[x][y - 1]); } if (x > 0 && y > 0) { - innerCount[x][y].subtract(innerCount[x - 1][y - 1]); + innerCount[x][y] = innerCount[x][y].subtract(innerCount[x - 1][y - 1]); } } @@ -227,19 +232,19 @@ public float getMaxMagnitude() { public T getMaxComponents() { return Arrays.stream(mask) .flatMap(Arrays::stream) - .reduce((first, second) -> first.copy().max(second)) + .reduce(Vector::max) .orElseThrow(() -> new IllegalStateException("Empty Mask")); } public T getMinComponents() { return Arrays.stream(mask) .flatMap(Arrays::stream) - .reduce((first, second) -> first.copy().min(second)) + .reduce(Vector::min) .orElseThrow(() -> new IllegalStateException("Empty Mask")); } protected void setComponentAt(Vector2 loc, float value, int component) { - setComponentAt((int) loc.getX(), (int) loc.getY(), value, component); + setComponentAt((int) loc.x(), (int) loc.y(), value, component); } protected U addScalar(ToFloatBiIntFunction valueFunction) { @@ -259,25 +264,25 @@ protected U divideScalar(ToFloatBiIntFunction valueFunction) { } protected void addScalarAt(Vector2 loc, float value) { - addScalarAt((int) loc.getX(), (int) loc.getY(), value); + addScalarAt((int) loc.x(), (int) loc.y(), value); } protected void addScalarAt(int x, int y, float value) { - mask[x][y].add(value); + mask[x][y] = mask[x][y].add(value); } protected void subtractScalarAt(Vector2 loc, float value) { - subtractScalarAt((int) loc.getX(), (int) loc.getY(), value); + subtractScalarAt((int) loc.x(), (int) loc.y(), value); } protected void subtractScalarAt(int x, int y, float value) { - mask[x][y].subtract(value); + mask[x][y] = mask[x][y].subtract(value); } public U blurComponent(int radius, int component, BooleanMask other) { assertCompatibleMask(other); return enqueue(dependencies -> { - BooleanMask limiter = (BooleanMask) dependencies.get(0); + BooleanMask limiter = (BooleanMask) dependencies.getFirst(); int[][] innerCount = getComponentInnerCount(component); setComponent( (x, y) -> limiter.get(x, y) ? calculateComponentAreaAverage(radius, x, y, innerCount) / 1000f : get( @@ -286,19 +291,19 @@ public U blurComponent(int radius, int component, BooleanMask other) { } protected void multiplyScalarAt(Vector2 loc, float value) { - multiplyScalarAt((int) loc.getX(), (int) loc.getY(), value); + multiplyScalarAt((int) loc.x(), (int) loc.y(), value); } protected void multiplyScalarAt(int x, int y, float value) { - mask[x][y].multiply(value); + mask[x][y] = mask[x][y].multiply(value); } protected void divideScalarAt(Vector2 loc, float value) { - divideScalarAt((int) loc.getX(), (int) loc.getY(), value); + divideScalarAt((int) loc.x(), (int) loc.y(), value); } protected void divideScalarAt(int x, int y, float value) { - mask[x][y].divide(value); + mask[x][y] = mask[x][y].divide(value); } protected int[][] getComponentInnerCount(int component) { @@ -316,18 +321,18 @@ protected void calculateComponentInnerValue(int[][] innerCount, int x, int y, in public T getSum() { return Arrays.stream(mask) .flatMap(Arrays::stream) - .reduce((first, second) -> first.copy().add(second)) + .reduce(Vector::add) .orElseThrow(() -> new IllegalStateException("Empty Mask")); } @Override protected void addValueAt(int x, int y, T value) { - mask[x][y].add(value); + mask[x][y] = mask[x][y].add(value); } @Override protected void subtractValueAt(int x, int y, T value) { - mask[x][y].subtract(value); + mask[x][y] = mask[x][y].subtract(value); } @Override @@ -339,48 +344,48 @@ public T getAvg() { @Override protected void multiplyValueAt(int x, int y, T value) { - mask[x][y].multiply(value); + mask[x][y] = mask[x][y].multiply(value); } @Override protected void divideValueAt(int x, int y, T value) { - mask[x][y].divide(value); + mask[x][y] = mask[x][y].divide(value); } protected void setComponentAt(int x, int y, float value, int component) { - mask[x][y].set(component, value); + mask[x][y] = mask[x][y].withComponent(component, value); } protected void addComponentAt(Vector2 loc, float value, int component) { - addComponentAt((int) loc.getX(), (int) loc.getY(), value, component); + addComponentAt((int) loc.x(), (int) loc.y(), value, component); } protected void addComponentAt(int x, int y, float value, int component) { - mask[x][y].add(value, component); + mask[x][y] = mask[x][y].add(value, component); } protected void subtractComponentAt(Vector2 loc, float value, int component) { - subtractComponentAt((int) loc.getX(), (int) loc.getY(), value, component); + subtractComponentAt((int) loc.x(), (int) loc.y(), value, component); } protected void subtractComponentAt(int x, int y, float value, int component) { - mask[x][y].subtract(value, component); + mask[x][y] = mask[x][y].subtract(value, component); } protected void multiplyComponentAt(Vector2 loc, float value, int component) { - multiplyComponentAt((int) loc.getX(), (int) loc.getY(), value, component); + multiplyComponentAt((int) loc.x(), (int) loc.y(), value, component); } protected void multiplyComponentAt(int x, int y, float value, int component) { - mask[x][y].multiply(value, component); + mask[x][y] = mask[x][y].multiply(value, component); } protected void divideComponentAt(Vector2 loc, float value, int component) { - divideComponentAt((int) loc.getX(), (int) loc.getY(), value, component); + divideComponentAt((int) loc.x(), (int) loc.y(), value, component); } protected void divideComponentAt(int x, int y, float value, int component) { - mask[x][y].divide(value, component); + mask[x][y] = mask[x][y].divide(value, component); } public U addScalar(float value) { @@ -427,11 +432,11 @@ protected U subtractComponent(ToFloatBiIntFunction valueFunction, int component) } public U clampComponentMin(float floor) { - return apply((x, y) -> get(x, y).clampMin(floor)); + return set((x, y) -> get(x, y).clampMin(floor)); } public U clampComponentMax(float ceiling) { - return apply((x, y) -> get(x, y).clampMax(ceiling)); + return set((x, y) -> get(x, y).clampMax(ceiling)); } public U randomize(float scale) { @@ -511,7 +516,7 @@ public U addComponent(float value, int component) { public U setComponent(FloatMask other, int component) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); + FloatMask source = (FloatMask) dependencies.getFirst(); setComponent(source::getPrimitive, component); }, other); } @@ -532,14 +537,14 @@ public U addComponentWithSymmetry(SymmetryType symmetryType, ToFloatBiIntFunctio public U addComponent(BooleanMask other, float value, int component) { return enqueue(dependencies -> { - BooleanMask source = (BooleanMask) dependencies.get(0); + BooleanMask source = (BooleanMask) dependencies.getFirst(); addComponent((x, y) -> source.get(x, y) ? value : 0, component); }, other); } public U addComponent(FloatMask other, int component) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); + FloatMask source = (FloatMask) dependencies.getFirst(); addComponent(source::get, component); }, other); } @@ -566,14 +571,14 @@ public U multiplyComponentWithSymmetry(SymmetryType symmetryType, ToFloatBiIntFu public U subtractComponent(BooleanMask other, float value, int component) { return enqueue(dependencies -> { - BooleanMask source = (BooleanMask) dependencies.get(0); + BooleanMask source = (BooleanMask) dependencies.getFirst(); subtractComponent((x, y) -> source.get(x, y) ? value : 0, component); }, other); } public U subtractComponent(FloatMask other, int component) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); + FloatMask source = (FloatMask) dependencies.getFirst(); subtractComponent(source::get, component); }, other); } @@ -592,14 +597,14 @@ protected U divideComponentWithSymmetry(SymmetryType symmetryType, ToFloatBiIntF public U multiplyComponent(BooleanMask other, float value, int component) { return enqueue(dependencies -> { - BooleanMask source = (BooleanMask) dependencies.get(0); + BooleanMask source = (BooleanMask) dependencies.getFirst(); multiplyComponent((x, y) -> source.get(x, y) ? value : 0, component); }, other); } public U multiplyComponent(FloatMask other, int component) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); + FloatMask source = (FloatMask) dependencies.getFirst(); multiplyComponent(source::get, component); }, other); } @@ -610,14 +615,14 @@ public U divideComponent(float value, int component) { public U divideComponent(BooleanMask other, float value, int component) { return enqueue(dependencies -> { - BooleanMask source = (BooleanMask) dependencies.get(0); + BooleanMask source = (BooleanMask) dependencies.getFirst(); divideComponent((x, y) -> source.get(x, y) ? value : 0, component); }, other); } public U divideComponent(FloatMask other, int component) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); + FloatMask source = (FloatMask) dependencies.getFirst(); divideComponent(source::get, component); }, other); } @@ -651,47 +656,48 @@ public FloatMask[] splitComponentMasks() { return components; } - public U setComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, boolean wrapEdges) { + public U setComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, + boolean wrapEdges) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); - applyComponentWithOffset(source, this::setComponentAt, component, xOffset, yOffset, - center, wrapEdges); + FloatMask source = (FloatMask) dependencies.getFirst(); + applyComponentWithOffset(source, this::setComponentAt, component, xOffset, yOffset, center, wrapEdges); }, other); } - public U addComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, boolean wrapEdges) { + public U addComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, + boolean wrapEdges) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); - applyComponentWithOffset(source, this::addComponentAt, component, xOffset, yOffset, - center, wrapEdges); + FloatMask source = (FloatMask) dependencies.getFirst(); + applyComponentWithOffset(source, this::addComponentAt, component, xOffset, yOffset, center, wrapEdges); }, other); } - public U subtractComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, boolean wrapEdges) { + public U subtractComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, + boolean wrapEdges) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); - applyComponentWithOffset(source, this::subtractComponentAt, component, xOffset, - yOffset, center, wrapEdges); + FloatMask source = (FloatMask) dependencies.getFirst(); + applyComponentWithOffset(source, this::subtractComponentAt, component, xOffset, yOffset, center, wrapEdges); }, other); } - public U multiplyComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, boolean wrapEdges) { + public U multiplyComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, + boolean wrapEdges) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); - applyComponentWithOffset(source, this::multiplyComponentAt, component, xOffset, - yOffset, center, wrapEdges); + FloatMask source = (FloatMask) dependencies.getFirst(); + applyComponentWithOffset(source, this::multiplyComponentAt, component, xOffset, yOffset, center, wrapEdges); }, other); } - public U divideComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, boolean wrapEdges) { + public U divideComponentWithOffset(FloatMask other, int component, int xOffset, int yOffset, boolean center, + boolean wrapEdges) { return enqueue(dependencies -> { - FloatMask source = (FloatMask) dependencies.get(0); - applyComponentWithOffset(source, this::divideComponentAt, component, xOffset, - yOffset, center, wrapEdges); + FloatMask source = (FloatMask) dependencies.getFirst(); + applyComponentWithOffset(source, this::divideComponentAt, component, xOffset, yOffset, center, wrapEdges); }, other); } - private U applyComponentWithOffset(FloatMask other, BiIntFloatIntConsumer action, int component, int xOffset, int yOffset, boolean center, boolean wrapEdges) { + private U applyComponentWithOffset(FloatMask other, BiIntFloatIntConsumer action, int component, int xOffset, + int yOffset, boolean center, boolean wrapEdges) { return enqueue(() -> { int size = getSize(); int otherSize = other.getSize(); diff --git a/shared/src/main/java/com/faforever/neroxis/util/BezierCurve.java b/shared/src/main/java/com/faforever/neroxis/util/BezierCurve.java index 8766ce88f..e8b888632 100644 --- a/shared/src/main/java/com/faforever/neroxis/util/BezierCurve.java +++ b/shared/src/main/java/com/faforever/neroxis/util/BezierCurve.java @@ -46,10 +46,9 @@ public Vector2 getPoint(float t) { if (t < 0 || t > 1) { throw new IllegalArgumentException("t must be between 0 and 1"); } - Vector2 pointOnCurve = new Vector2(); + Vector2 pointOnCurve = new Vector2(0, 0); for (int i = 0; i < controlPoints.length; ++i) { - pointOnCurve.add(controlPoints[i].copy() - .multiply((float) (coefficients[i] + pointOnCurve = pointOnCurve.add(controlPoints[i].multiply((float) (coefficients[i] * StrictMath.pow((1 - t), (order - i)) * StrictMath.pow(t, i)))); } @@ -61,7 +60,7 @@ public BezierCurve transformTo(Vector2 newStart, Vector2 newEnd) { Vector2 currentEnd = getEnd(); float distanceRatio = newStart.getDistance(newEnd) / currentStart.getDistance(currentEnd); float angleDifference = newStart.angleTo(newEnd) - currentStart.angleTo(currentEnd); - Vector2 positionDifference = newStart.copy().subtract(currentStart); + Vector2 positionDifference = newStart.subtract(currentStart); return rotate(angleDifference).scale(distanceRatio).translate(positionDifference); } @@ -74,30 +73,35 @@ public Vector2 getEnd() { } private BezierCurve translate(Vector2 translationVector) { - return translate(translationVector.getX(), translationVector.getY()); + return translate(translationVector.x(), translationVector.y()); } private BezierCurve translate(float xTranslation, float yTranslation) { - for (Vector2 controlPoint : controlPoints) { - controlPoint.add(xTranslation, yTranslation); + Vector2[] newControlPoints = new Vector2[controlPoints.length]; + for (int i = 1; i < controlPoints.length; i++) { + newControlPoints[i] = controlPoints[i].add(xTranslation, yTranslation); } - return this; + return new BezierCurve(newControlPoints); } private BezierCurve scale(float factor) { - Vector2 origin = controlPoints[0].copy(); - for (Vector2 controlPoint : controlPoints) { - controlPoint.subtract(origin).multiply(factor).add(origin); + Vector2[] newControlPoints = new Vector2[controlPoints.length]; + Vector2 origin = controlPoints[0]; + newControlPoints[0] = origin; + for (int i = 1; i < controlPoints.length; i++) { + newControlPoints[i] = controlPoints[i].subtract(origin).multiply(factor).add(origin); } - return this; + return new BezierCurve(newControlPoints); } private BezierCurve rotate(float angle) { - Vector2 origin = controlPoints[0].copy(); - for (Vector2 controlPoint : controlPoints) { - controlPoint.subtract(origin).rotate(angle).add(origin); + Vector2[] newControlPoints = new Vector2[controlPoints.length]; + Vector2 origin = controlPoints[0]; + newControlPoints[0] = origin; + for (int i = 1; i < controlPoints.length; i++) { + newControlPoints[i] = controlPoints[i].subtract(origin).rotate(angle).add(origin); } - return this; + return new BezierCurve(newControlPoints); } @Override diff --git a/shared/src/main/java/com/faforever/neroxis/util/ImageUtil.java b/shared/src/main/java/com/faforever/neroxis/util/ImageUtil.java index f27649e69..a56cb2791 100644 --- a/shared/src/main/java/com/faforever/neroxis/util/ImageUtil.java +++ b/shared/src/main/java/com/faforever/neroxis/util/ImageUtil.java @@ -76,8 +76,8 @@ public static BufferedImage insertImageIntoNewImageOfSize(BufferedImage image, i Raster imageRaster = image.getData(); for (int x = 0; x < image.getWidth(); x++) { for (int y = 0; y < image.getHeight(); y++) { - int newX = x + (int) locToInsertTopLeft.getX(); - int newY = y + (int) locToInsertTopLeft.getY(); + int newX = x + (int) locToInsertTopLeft.x(); + int newY = y + (int) locToInsertTopLeft.y(); if (inImageBounds(newX, newY, newImage)) { newImageRaster.setPixel(newX, newY, imageRaster.getPixel(x, y, new int[image.getColorModel() .getNumComponents()])); @@ -98,9 +98,9 @@ public static void writeNormalDDS(NormalMask imageMask, Path path) throws IOExce for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { Vector3 value = imageMask.get(x, y); - byte xV = (byte) StrictMath.min(StrictMath.max((128 * value.getX() + 128), 0), 255); - byte yV = (byte) StrictMath.min(StrictMath.max((128 * (1 - value.getY()) + 127), 0), 255); - byte zV = (byte) StrictMath.min(StrictMath.max((128 * value.getZ() + 128), 0), 255); + byte xV = (byte) StrictMath.min(StrictMath.max((128 * value.x() + 128), 0), 255); + byte yV = (byte) StrictMath.min(StrictMath.max((128 * (1 - value.y()) + 127), 0), 255); + byte zV = (byte) StrictMath.min(StrictMath.max((128 * value.z() + 128), 0), 255); imageBytes.put(yV); imageBytes.put(zV); imageBytes.put((byte) 0); @@ -183,8 +183,8 @@ public static BufferedImage getMapwideTexture(NormalMask normalMask, FloatMask w for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { Vector3 normalValue = normalMask.get(x, y); - int xV = (byte) StrictMath.min(StrictMath.max(128 * normalValue.getX() + 127, 0), 255); - int yV = (byte) StrictMath.min(StrictMath.max(128 * normalValue.getZ() + 127, 0), 255); + int xV = (byte) StrictMath.min(StrictMath.max(128 * normalValue.x() + 127, 0), 255); + int yV = (byte) StrictMath.min(StrictMath.max(128 * normalValue.z() + 127, 0), 255); int zV = (byte) StrictMath.min(StrictMath.max(waterDepth.get(x, y) * 255, 0), 255); int wV = (byte) StrictMath.min(StrictMath.max(shadowMask.get(x, y) * 255, 0), 255); imageRaster.setPixel(x, y, new int[]{xV, yV, zV, wV}); @@ -200,9 +200,9 @@ public static byte[] compressNormal(NormalMask mask) { for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { Vector3 value = mask.get(x, y); - int xV = (byte) StrictMath.min(StrictMath.max((128 * value.getX() + 128), 0), 255); - int yV = (byte) StrictMath.min(StrictMath.max((255 * (1 - value.getY())), 0), 255); - int zV = (byte) StrictMath.min(StrictMath.max((128 * value.getZ() + 128), 0), 255); + int xV = (byte) StrictMath.min(StrictMath.max((128 * value.x() + 128), 0), 255); + int yV = (byte) StrictMath.min(StrictMath.max((255 * (1 - value.y())), 0), 255); + int zV = (byte) StrictMath.min(StrictMath.max((128 * value.z() + 128), 0), 255); imageByteBuffer.put((byte) yV); imageByteBuffer.put((byte) zV); imageByteBuffer.put((byte) 0); @@ -216,7 +216,6 @@ public static byte[] compressShadow(FloatMask mask, LightingSettings lightingSet int size = mask.getSize(); int length = size * size * 4; Vector3 shadowFillColor = lightingSettings.shadowFillColor() - .copy() .add(lightingSettings.sunAmbience()) .divide(4); float opacityScale = lightingSettings.lightingMultiplier() / 4; @@ -224,9 +223,9 @@ public static byte[] compressShadow(FloatMask mask, LightingSettings lightingSet for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { float value = mask.get(x, y); - int r = (byte) StrictMath.min(StrictMath.max(shadowFillColor.getX() * 128, 0), 255); - int g = (byte) StrictMath.min(StrictMath.max(shadowFillColor.getY() * 128, 0), 255); - int b = (byte) StrictMath.min(StrictMath.max(shadowFillColor.getZ() * 128, 0), 255); + int r = (byte) StrictMath.min(StrictMath.max(shadowFillColor.x() * 128, 0), 255); + int g = (byte) StrictMath.min(StrictMath.max(shadowFillColor.y() * 128, 0), 255); + int b = (byte) StrictMath.min(StrictMath.max(shadowFillColor.z() * 128, 0), 255); int a = (byte) StrictMath.min(StrictMath.max((1 - value) * opacityScale * 255, 0), 255); imageByteBuffer.put((byte) r); imageByteBuffer.put((byte) g); @@ -244,9 +243,9 @@ public static BufferedImage normalToARGB(NormalMask mask) { for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { Vector3 value = mask.get(x, y); - int xV = (byte) StrictMath.min(StrictMath.max((128 * value.getX() + 128), 0), 255); - int yV = (byte) StrictMath.min(StrictMath.max((255 * (1 - value.getY())), 0), 255); - int zV = (byte) StrictMath.min(StrictMath.max((128 * value.getZ() + 128), 0), 255); + int xV = (byte) StrictMath.min(StrictMath.max((128 * value.x() + 128), 0), 255); + int yV = (byte) StrictMath.min(StrictMath.max((255 * (1 - value.y())), 0), 255); + int zV = (byte) StrictMath.min(StrictMath.max((128 * value.z() + 128), 0), 255); imageRaster.setPixel(x, y, new int[]{yV, zV, 0, xV}); } } @@ -260,10 +259,10 @@ public static byte[] compressVector4(Vector4Mask mask) { for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { Vector4 value = mask.get(x, y); - int xV = (byte) StrictMath.min(StrictMath.max(value.getX(), 0), 255); - int yV = (byte) StrictMath.min(StrictMath.max(value.getY(), 0), 255); - int zV = (byte) StrictMath.min(StrictMath.max(value.getZ(), 0), 255); - int wV = (byte) StrictMath.min(StrictMath.max(value.getW(), 0), 255); + int xV = (byte) StrictMath.min(StrictMath.max(value.x(), 0), 255); + int yV = (byte) StrictMath.min(StrictMath.max(value.y(), 0), 255); + int zV = (byte) StrictMath.min(StrictMath.max(value.z(), 0), 255); + int wV = (byte) StrictMath.min(StrictMath.max(value.w(), 0), 255); imageByteBuffer.put((byte) xV); imageByteBuffer.put((byte) yV); imageByteBuffer.put((byte) zV); @@ -343,6 +342,6 @@ public static void writeAutoScaledPNGFromMask(FloatMask mask, Path path) throws } public static boolean inImageBounds(Vector2 position, BufferedImage image) { - return inImageBounds((int) position.getX(), (int) position.getY(), image); + return inImageBounds((int) position.x(), (int) position.y(), image); } } diff --git a/shared/src/main/java/com/faforever/neroxis/util/functional/FloatConsumer.java b/shared/src/main/java/com/faforever/neroxis/util/functional/FloatConsumer.java new file mode 100644 index 000000000..eaa1b98ad --- /dev/null +++ b/shared/src/main/java/com/faforever/neroxis/util/functional/FloatConsumer.java @@ -0,0 +1,8 @@ +package com.faforever.neroxis.util.functional; + +@FunctionalInterface +public interface FloatConsumer { + + void accept(float value); + +} diff --git a/shared/src/main/java/com/faforever/neroxis/util/functional/FloatSupplier.java b/shared/src/main/java/com/faforever/neroxis/util/functional/FloatSupplier.java new file mode 100644 index 000000000..13959121d --- /dev/null +++ b/shared/src/main/java/com/faforever/neroxis/util/functional/FloatSupplier.java @@ -0,0 +1,8 @@ +package com.faforever.neroxis.util.functional; + +@FunctionalInterface +public interface FloatSupplier { + + float getAsFloat(); + +} diff --git a/shared/src/main/java/com/faforever/neroxis/util/functional/FloatUnaryOperator.java b/shared/src/main/java/com/faforever/neroxis/util/functional/FloatUnaryOperator.java new file mode 100644 index 000000000..7d37f0f0f --- /dev/null +++ b/shared/src/main/java/com/faforever/neroxis/util/functional/FloatUnaryOperator.java @@ -0,0 +1,6 @@ +package com.faforever.neroxis.util.functional; + +@FunctionalInterface +public interface FloatUnaryOperator { + float applyAsFloat(float value); +} diff --git a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector.java b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector.java index d8898448e..5ffba1c1e 100644 --- a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector.java +++ b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector.java @@ -1,43 +1,31 @@ package com.faforever.neroxis.util.vector; -import lombok.EqualsAndHashCode; +import com.faforever.neroxis.util.functional.FloatSupplier; +import com.faforever.neroxis.util.functional.FloatUnaryOperator; -import java.util.Arrays; import java.util.Random; -@EqualsAndHashCode @SuppressWarnings("unchecked") -public abstract class Vector> { - public static final int X = 0; - public static final int Y = 1; - public static final int Z = 2; - public static final int W = 3; - public static final int R = 0; - public static final int G = 1; - public static final int B = 2; - public static final int A = 3; - protected final float[] components; +public sealed interface Vector> permits Vector2, Vector3, Vector4 { + int X = 0; + int Y = 1; + int Z = 2; + int W = 3; + int R = 0; + int G = 1; + int B = 2; + int A = 3; - protected Vector(int dimension) { - this(new float[dimension]); - } - - protected Vector(float... components) { - this.components = components; - } + VectorComponentAccessor getComponentAccessor(int i); - public abstract T copy(); + int getDimension(); - public float get(int i) { - return components[i]; - } + float[] toArray(); - public void set(int i, float value) { - components[i] = value; - } + T transform(Transformer transformer); - public void set(T other) { - System.arraycopy(other.components, 0, components, 0, getDimension()); + default float get(int i) { + return getComponentAccessor(i).get((T) this); } private void assertEqualDimension(int dimension) { @@ -48,305 +36,198 @@ private void assertEqualDimension(int dimension) { } } - public T randomize(Random random, float minValue, float maxValue) { - float range = maxValue - minValue; - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = random.nextFloat() * range + minValue; - } - return (T) this; + default T withComponent(int component, float value) { + return transform(Transformer.matchingComponent(component, () -> value)); } - public T randomize(Random random, float scale) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = random.nextFloat() * scale; - } - return (T) this; + default T randomize(Random random, float minValue, float maxValue) { + float range = maxValue - minValue; + return transform(Transformer.fromSupplier(() -> random.nextFloat() * range + minValue)); } - public T max(float value) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.max(components[i], value); - } - return (T) this; + default T randomize(Random random, float scale) { + return transform(Transformer.fromSupplier(() -> random.nextFloat() * scale)); } - public T max(float... values) { - assertEqualDimension(values.length); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.max(components[i], values[i]); - } - return (T) this; + default T max(float value) { + return transform(Transformer.fromOldValue(oldValue -> StrictMath.max(value, oldValue))); } - public int getDimension() { - return components.length; + default T max(float... values) { + assertEqualDimension(values.length); + return transform((index, oldValue) -> StrictMath.max(values[index], oldValue)); } - public T max(T other) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.max(components[i], other.components[i]); - } - return (T) this; + default T max(T other) { + return transform((index, oldValue) -> StrictMath.max(other.get(index), oldValue)); } - public T clampMin(float floor) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.max(components[i], floor); - } - return (T) this; + default T clampMin(float floor) { + return transform(Transformer.fromOldValue(oldValue -> StrictMath.max(floor, oldValue))); } - public T min(float value) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.min(components[i], value); - } - return (T) this; + default T min(float value) { + return transform(Transformer.fromOldValue(oldValue -> StrictMath.min(value, oldValue))); } - public T min(float... values) { + default T min(float... values) { assertEqualDimension(values.length); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.min(components[i], values[i]); - } - return (T) this; + return transform((index, oldValue) -> StrictMath.min(values[index], oldValue)); } - public T min(T other) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.min(components[i], other.components[i]); - } - return (T) this; + default T min(T other) { + return transform((index, oldValue) -> StrictMath.min(other.get(index), oldValue)); } - public T clampMax(float ceiling) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.min(components[i], ceiling); - } - return (T) this; + default T clampMax(float ceiling) { + return transform(Transformer.fromOldValue(oldValue -> StrictMath.min(ceiling, oldValue))); } - public T round() { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.round(components[i]); - } - return (T) this; + default T round() { + return transform(Transformer.fromOldValue(StrictMath::round)); } - public T round(int places) { - float magnitude = (float) StrictMath.pow(10, places); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.round(components[i] * magnitude) / magnitude; - } - return (T) this; + default T round(int places) { + float placesFactor = (float) StrictMath.pow(10, places); + return transform(Transformer.fromOldValue(oldValue -> StrictMath.round(oldValue * placesFactor) / placesFactor)); } - public T floor() { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = (float) StrictMath.floor(components[i]); - } - return (T) this; + default T floor() { + return transform(Transformer.fromOldValue(oldValue -> (float) StrictMath.floor(oldValue))); } - public T ceil() { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = (float) StrictMath.ceil(components[i]); - } - return (T) this; + default T ceil() { + return transform(Transformer.fromOldValue(oldValue -> (float) StrictMath.ceil(oldValue))); } - public T normalize() { - float magnitude = getMagnitude(); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] /= magnitude; - } - return (T) this; + default T normalize() { + return divide(getMagnitude()); } - public float getMagnitude() { - float sum = 0; - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - sum += components[i] * components[i]; - } - return (float) StrictMath.sqrt(sum); - } - - public T add(T other) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] += other.components[i]; - } - return (T) this; + default T add(T other) { + return transform((index, oldValue) -> oldValue + other.get(index)); } - public T add(float... values) { + default T add(float... values) { assertEqualDimension(values.length); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] += values[i]; - } - return (T) this; + return transform((index, oldValue) -> oldValue + values[index]); } - public T add(float value) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] += value; - } - return (T) this; + default T add(float value) { + return transform(Transformer.fromOldValue(oldValue -> oldValue + value)); } - public T add(float value, int component) { - components[component] += value; - return (T) this; + default T add(float value, int component) { + return transform(Transformer.matchingComponent(component, oldValue -> oldValue + value)); } - public T subtract(T other) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] -= other.components[i]; - } - return (T) this; + default T subtract(T other) { + return transform((index, oldValue) -> oldValue - other.get(index)); } - public T subtract(float... values) { + default T subtract(float... values) { assertEqualDimension(values.length); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] -= values[i]; - } - return (T) this; + return transform((index, oldValue) -> oldValue - values[index]); } - public T subtract(float value) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] -= value; - } - return (T) this; + default T subtract(float value) { + return transform(Transformer.fromOldValue(oldValue -> oldValue - value)); } - public T subtract(float value, int component) { - components[component] -= value; - return (T) this; + default T subtract(float value, int component) { + return transform(Transformer.matchingComponent(component, oldValue -> oldValue - value)); } - public T multiply(T other) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] *= other.components[i]; - } - return (T) this; + default T multiply(T other) { + return transform((index, oldValue) -> oldValue * other.get(index)); } - public T multiply(float... values) { + default T multiply(float... values) { assertEqualDimension(values.length); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] *= values[i]; - } - return (T) this; + return transform((index, oldValue) -> oldValue * values[index]); } - public T multiply(float value) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] *= value; - } - return (T) this; + default T multiply(float value) { + return transform(Transformer.fromOldValue(oldValue -> oldValue * value)); } - public T multiply(float value, int component) { - components[component] -= value; - return (T) this; + default T multiply(float value, int component) { + return transform(Transformer.matchingComponent(component, oldValue -> oldValue * value)); } - public T divide(T other) { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] /= other.components[i]; - } - return (T) this; + default T divide(T other) { + return transform((index, oldValue) -> oldValue / other.get(index)); } - public T divide(float... values) { - assertEqualDimension(values.length); - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] /= values[i]; - } - return (T) this; + default T divide(float... values) { + return transform((index, oldValue) -> oldValue / values[index]); + } + + default T divide(float value) { + return transform(Transformer.fromOldValue(oldValue -> oldValue / value)); + } + + default T divide(float value, int component) { + return transform(Transformer.matchingComponent(component, oldValue -> oldValue / value)); + } + + default T roundToNearestHalfPoint() { + return transform(Transformer.fromOldValue(oldValue -> StrictMath.round(oldValue - .5f) + .5f)); } - public T divide(float value) { + default float getMagnitude() { + float sum = 0; int dimension = getDimension(); for (int i = 0; i < dimension; ++i) { - components[i] /= value; + sum += get(i) * get(i); } - return (T) this; - } - - public T divide(float value, int component) { - components[component] -= value; - return (T) this; + return (float) StrictMath.sqrt(sum); } - public float getDistance(T other) { + default float getDistance(T other) { float sum = 0; int dimension = getDimension(); for (int i = 0; i < dimension; ++i) { - float diff = components[i] - other.components[i]; + float diff = get(i) - other.get(i); sum += diff * diff; } return (float) StrictMath.sqrt(sum); } - public float getAngle(T other) { + default float getAngle(T other) { return (float) StrictMath.acos(dot(other) / getMagnitude() / other.getMagnitude()); } - public float dot(T other) { + default float dot(T other) { float sum = 0; int dimension = getDimension(); for (int i = 0; i < dimension; ++i) { - sum += components[i] * other.components[i]; + sum += get(i) * other.get(i); } return sum; } - public T roundToNearestHalfPoint() { - int dimension = getDimension(); - for (int i = 0; i < dimension; ++i) { - components[i] = StrictMath.round(components[i] - .5f) + .5f; + interface Transformer { + float transform(int component, float currentValue); + + static Transformer fromOldValue(FloatUnaryOperator operator) { + return (index, oldValue) -> operator.applyAsFloat(oldValue); } - return (T) this; - } - public float[] toArray() { - return components; - } + static Transformer fromSupplier(FloatSupplier supplier) { + return (index, oldValue) -> supplier.getAsFloat(); + } - @Override - public String toString() { - String[] strings = new String[components.length]; - for (int i = 0; i < components.length; ++i) { - strings[i] = String.format("%9f", components[i]); + static Transformer matchingComponent(int component, FloatUnaryOperator operator) { + return (index, oldValue) -> index == component ? operator.applyAsFloat(oldValue) : oldValue; } - return Arrays.toString(strings).replace("[", "").replace("]", ""); + + static Transformer matchingComponent(int component, FloatSupplier supplier) { + return (index, oldValue) -> index == component ? supplier.getAsFloat() : oldValue; + } + } + + interface VectorComponentAccessor> { + float get(T vector); } } diff --git a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector2.java b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector2.java index 28ab96387..05c2577ea 100644 --- a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector2.java +++ b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector2.java @@ -4,25 +4,21 @@ import java.awt.Dimension; import java.awt.Point; +import java.util.Arrays; import java.util.LinkedHashSet; -public class Vector2 extends Vector { - public Vector2() { - super(2); - } +public record Vector2(float x, float y) implements Vector { - public Vector2(Vector2 other) { - this(other.getX(), other.getY()); + public Vector2() { + this(0, 0); } - public Vector2(float x, float y) { - super(x, y); + private Vector2(float... values) { + this(values[0], values[1]); } public Vector2(Vector3 location) { - super(2); - setX(location.getX()); - setY(location.getZ()); + this(location.x(), location.z()); } public Vector2(Dimension other) { @@ -33,30 +29,28 @@ public Vector2(Point other) { this((float) other.getX(), (float) other.getY()); } - public float getX() { - return components[Vector.X]; - } - - public void setX(float x) { - components[Vector.X] = x; - } - - public float getY() { - return components[Vector.Y]; + @Override + public VectorComponentAccessor getComponentAccessor(int i) { + return switch (i) { + case Vector.X -> Vector2::x; + case Vector.Y -> Vector2::y; + default -> throw new UnsupportedOperationException("Unsupported component: " + i); + }; } - public void setY(float y) { - components[Vector.Y] = y; + @Override + public Vector2 transform(Transformer transformer) { + return new Vector2(transformer.transform(Vector.X, x()), transformer.transform(Vector.Y, y())); } - public void set(Dimension other) { - setX((float) other.getWidth()); - setY((float) other.getHeight()); + @Override + public int getDimension() { + return 2; } - public void set(Point other) { - setX((float) other.getX()); - setY((float) other.getY()); + @Override + public float[] toArray() { + return new float[]{x, y}; } public float angleTo(Vector3 location) { @@ -64,8 +58,8 @@ public float angleTo(Vector3 location) { } public float angleTo(Vector2 location) { - float dx = location.getX() - getX(); - float dy = location.getY() - getY(); + float dx = location.x() - x(); + float dy = location.y() - y(); return (float) StrictMath.atan2(dy, dx); } @@ -75,8 +69,8 @@ public LinkedHashSet getLine(Vector2 location) { while (currentPoint.getDistance(location) > 1) { line.add(currentPoint); float angle = currentPoint.angleTo(location); - currentPoint = new Vector2((float) (currentPoint.getX() + StrictMath.cos(angle)), - (float) (currentPoint.getY() + StrictMath.sin(angle))); + currentPoint = new Vector2((float) (currentPoint.x() + StrictMath.cos(angle)), + (float) (currentPoint.y() + StrictMath.sin(angle))); } return line; } @@ -85,29 +79,31 @@ public Vector2 addPolar(float angle, float magnitude) { return add((float) (magnitude * StrictMath.cos(angle)), (float) (magnitude * StrictMath.sin(angle))); } - public void flip(Vector2 center, Symmetry symmetry) { - switch (symmetry) { - case X -> setX(2 * center.getX() - getX()); - case Z -> setY(2 * center.getY() - getY()); - case XZ, ZX, POINT2 -> { - setX(2 * center.getX() - getX()); - setY(2 * center.getY() - getY()); - } - } + public Vector2 flip(Vector2 center, Symmetry symmetry) { + return switch (symmetry) { + case X -> new Vector2(2 * center.x() - x(), y); + case Z -> new Vector2(x, 2 * center.y() - y()); + case XZ, ZX, POINT2 -> new Vector2(2 * center.x() - x(), 2 * center.y() - y()); + case POINT3, NONE, DIAG, QUAD, POINT16, POINT15, POINT14, POINT13, POINT12, POINT11, POINT10, POINT9, + POINT8, POINT7, POINT6, POINT5, POINT4 -> this; + }; } public Vector2 rotate(float angle) { - float oldX = getX(); - float oldY = getY(); + float oldX = x(); + float oldY = y(); float cos = (float) StrictMath.cos(angle); float sin = (float) StrictMath.sin(angle); - setX(oldX * cos - oldY * sin); - setY(oldX * sin + oldY * cos); - return this; + return new Vector2(oldX * cos - oldY * sin, oldX * sin + oldY * cos); } @Override - public Vector2 copy() { - return new Vector2(this); + public String toString() { + float[] values = toArray(); + String[] strings = new String[values.length]; + for (int i = 0; i < values.length; ++i) { + strings[i] = String.format("%9f", get(i)); + } + return Arrays.toString(strings).replace("[", "").replace("]", ""); } } diff --git a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector3.java b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector3.java index 9789d0fee..d091a88c1 100644 --- a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector3.java +++ b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector3.java @@ -1,60 +1,57 @@ package com.faforever.neroxis.util.vector; +import java.util.Arrays; import java.util.LinkedHashSet; -public class Vector3 extends Vector { +public record Vector3(float x, float y, float z) implements Vector { public Vector3() { - super(3); + this(0, 0, 0); } - public Vector3(Vector3 other) { - this(other.getX(), other.getY(), other.getZ()); + private Vector3(float... values) { + this(values[0], values[1], values[2]); } public Vector3(Vector2 other) { - this(other.getX(), 0f, other.getY()); + this(other.x(), 0f, other.y()); } - public Vector3(float x, float y, float z) { - super(x, y, z); - } - - public float getX() { - return components[Vector.X]; - } - - public void setX(float x) { - components[Vector.X] = x; - } - - public float getY() { - return components[Vector.Y]; + @Override + public VectorComponentAccessor getComponentAccessor(int i) { + return switch (i) { + case Vector.X -> Vector3::x; + case Vector.Y -> Vector3::y; + case Vector.Z -> Vector3::z; + default -> throw new UnsupportedOperationException("Unsupported component: " + i); + }; } - public void setY(float y) { - components[Vector.Y] = y; + @Override + public Vector3 transform(Transformer transformer) { + return new Vector3(transformer.transform(Vector.X, x()), transformer.transform(Vector.Y, y()), transformer.transform(Vector.Z, z())); } - public float getZ() { - return components[Vector.Z]; + @Override + public int getDimension() { + return 3; } - public void setZ(float z) { - components[Vector.Z] = z; + @Override + public float[] toArray() { + return new float[]{x, y, z}; } public Vector3 cross(Vector3 other) { - Vector3 cross = new Vector3(); - float x = getX(); - float oX = other.getX(); - float y = getY(); - float oY = other.getY(); - float z = getZ(); - float oZ = other.getZ(); - cross.setX(y * oZ - z * oY); - cross.setY(z * oX - x * oZ); - cross.setZ(x * oY - y * oX); - return cross; + float x = x(); + float oX = other.x(); + float y = y(); + float oY = other.y(); + float z = z(); + float oZ = other.z(); + float newX = y * oZ - z * oY; + float newY = z * oX - x * oZ; + float newZ = x * oY - y * oX; + return new Vector3(newX, newY, newZ); } public float getXZDistance(Vector2 location) { @@ -62,8 +59,8 @@ public float getXZDistance(Vector2 location) { } public float getXZDistance(Vector3 location) { - float dx = getX() - location.getX(); - float dz = getZ() - location.getZ(); + float dx = x() - location.x(); + float dz = z() - location.z(); return (float) StrictMath.sqrt(dx * dx + dz * dz); } @@ -74,28 +71,27 @@ public LinkedHashSet getXZLine(Vector3 location) { while (currentPoint.getDistance(targetPoint) > 1) { line.add(currentPoint); float angle = currentPoint.angleTo(location); - currentPoint = new Vector2(StrictMath.round(currentPoint.getX() + StrictMath.cos(angle)), - StrictMath.round(currentPoint.getY() + StrictMath.sin(angle))); + currentPoint = new Vector2(StrictMath.round(currentPoint.x() + StrictMath.cos(angle)), + StrictMath.round(currentPoint.y() + StrictMath.sin(angle))); } return line; } public float getAzimuth() { - return (float) StrictMath.atan2(getZ(), getX()); + return (float) StrictMath.atan2(z(), x()); } public float getElevation() { - return (float) StrictMath.atan2(getY(), StrictMath.sqrt(getX() * getX() + getZ() * getZ())); - } - - public Vector3 roundXYToNearestHalfPoint() { - setX(StrictMath.round(getX() - .5f) + .5f); - setZ(StrictMath.round(getZ() - .5f) + .5f); - return this; + return (float) StrictMath.atan2(y(), StrictMath.sqrt(x() * x() + z() * z())); } @Override - public Vector3 copy() { - return new Vector3(this); + public String toString() { + float[] values = toArray(); + String[] strings = new String[values.length]; + for (int i = 0; i < values.length; ++i) { + strings[i] = String.format("%9f", get(i)); + } + return Arrays.toString(strings).replace("[", "").replace("]", ""); } } diff --git a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector4.java b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector4.java index 6a83860af..4985bf9f5 100644 --- a/shared/src/main/java/com/faforever/neroxis/util/vector/Vector4.java +++ b/shared/src/main/java/com/faforever/neroxis/util/vector/Vector4.java @@ -1,52 +1,51 @@ package com.faforever.neroxis.util.vector; -public class Vector4 extends Vector { - public Vector4() { - super(4); - } - - public Vector4(Vector4 other) { - this(other.getX(), other.getY(), other.getZ(), other.getW()); - } - - public Vector4(float x, float y, float z, float w) { - super(x, y, z, w); - } - - public float getX() { - return components[Vector.X]; - } +import java.util.Arrays; - public void setX(float x) { - components[Vector.X] = x; - } +public record Vector4(float x, float y, float z, float w) implements Vector { - public float getY() { - return components[Vector.Y]; + public Vector4() { + this(0, 0, 0, 0); } - public void setY(float y) { - components[Vector.Y] = y; + private Vector4(float... values) { + this(values[0], values[1], values[2], values[3]); } - public float getW() { - return components[Vector.W]; + @Override + public VectorComponentAccessor getComponentAccessor(int i) { + return switch (i) { + case Vector.X -> Vector4::x; + case Vector.Y -> Vector4::y; + case Vector.Z -> Vector4::z; + case Vector.W -> Vector4::w; + default -> throw new UnsupportedOperationException("Unsupported component: " + i); + }; } - public void setW(float w) { - components[Vector.W] = w; + @Override + public Vector4 transform(Transformer transformer) { + return new Vector4(transformer.transform(Vector.X, x()), transformer.transform(Vector.Y, y()), + transformer.transform(Vector.Z, z()), transformer.transform(Vector.W, w())); } - public float getZ() { - return components[Vector.Z]; + @Override + public int getDimension() { + return 4; } - public void setZ(float z) { - components[Vector.Z] = z; + @Override + public float[] toArray() { + return new float[]{x, y, z, w}; } @Override - public Vector4 copy() { - return new Vector4(this); + public String toString() { + float[] values = toArray(); + String[] strings = new String[values.length]; + for (int i = 0; i < values.length; ++i) { + strings[i] = String.format("%9f", get(i)); + } + return Arrays.toString(strings).replace("[", "").replace("]", ""); } } diff --git a/shared/src/main/java/com/faforever/neroxis/visualization/EntryPanel.java b/shared/src/main/java/com/faforever/neroxis/visualization/EntryPanel.java index e4f388efd..ea7f06a66 100644 --- a/shared/src/main/java/com/faforever/neroxis/visualization/EntryPanel.java +++ b/shared/src/main/java/com/faforever/neroxis/visualization/EntryPanel.java @@ -47,8 +47,8 @@ public void setValueLabel() { if (maskPanel.getMask() != null) { Vector2 maskCoords = maskPanel.getMouseOnMask(); if (maskPanel.getMask().inBounds(maskCoords)) { - valueLabel.setText(String.format("X: %5.0f, Y: %5.0f Value: %s", maskCoords.getX(), maskCoords.getY(), - maskPanel.getMask().get(maskCoords).toString())); + valueLabel.setText(String.format("X: %5.0f, Y: %5.0f Value: %s", maskCoords.x(), maskCoords.y(), + maskPanel.getMask().get(maskCoords).toString())); } } } diff --git a/shared/src/main/java/com/faforever/neroxis/visualization/MaskPanel.java b/shared/src/main/java/com/faforever/neroxis/visualization/MaskPanel.java index cd4c6df4e..ebaa2715c 100644 --- a/shared/src/main/java/com/faforever/neroxis/visualization/MaskPanel.java +++ b/shared/src/main/java/com/faforever/neroxis/visualization/MaskPanel.java @@ -16,10 +16,10 @@ class MaskPanel extends JPanel { private final EntryPanel entryPanel; - private final Vector2 lastMousePosition = new Vector2(); - private final Vector2 fractionalImageOffset = new Vector2(); - private final Vector2 imageZoomFactor = new Vector2(); private float userZoomLevel = 0; + private Vector2 fractionalImageOffset = new Vector2(); + private Vector2 imageZoomFactor = new Vector2(); + private Vector2 lastMousePosition = new Vector2(); private BufferedImage image; @Getter private Mask mask; @@ -68,9 +68,7 @@ private Vector2 canvasCoordinatesToMaskCoordinates(Vector2 canvasCoords) { } private Vector2 canvasCoordinatesToFractionalMaskCoordinates(Vector2 canvasCoords) { - return canvasCoords.copy() - .divide(getFullScalingVector().multiply(mask.getSize())) - .subtract(fractionalImageOffset); + return canvasCoords.divide(getFullScalingVector().multiply(mask.getSize())).subtract(fractionalImageOffset); } private Vector2 getFullScalingVector() { @@ -86,14 +84,15 @@ protected void paintComponent(Graphics g) { super.paintComponent(g); if (mask != null) { - imageZoomFactor.setX((float) getWidth() / image.getWidth()); - imageZoomFactor.setY((float) getHeight() / image.getHeight()); + imageZoomFactor = new Vector2((float) getWidth() / image.getWidth(), + (float) getHeight() / image.getHeight()); + Vector2 fullScalingVector = getFullScalingVector(); - Vector2 imageOffset = fractionalImageOffset.copy().multiply(mask.getSize()); + Vector2 imageOffset = fractionalImageOffset.multiply(mask.getSize()); AffineTransform at = new AffineTransform(); - at.scale(fullScalingVector.getX(), fullScalingVector.getY()); - at.translate(imageOffset.getX(), imageOffset.getY()); + at.scale(fullScalingVector.x(), fullScalingVector.y()); + at.translate(imageOffset.x(), imageOffset.y()); AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); BufferedImage newImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); op.filter(image, newImage); @@ -108,13 +107,13 @@ private class CanvasMouseListener extends MouseInputAdapter { @Override public void mouseWheelMoved(MouseWheelEvent e) { if (mask != null) { - lastMousePosition.set(e.getPoint()); + lastMousePosition = new Vector2(e.getPoint()); Vector2 oldMousePositionOnMask = canvasCoordinatesToFractionalMaskCoordinates(lastMousePosition); - userZoomLevel = (float) StrictMath.min( - StrictMath.max(userZoomLevel - e.getWheelRotation() * .25, 0), - MathUtil.log2(mask.getSize())); + userZoomLevel = (float) StrictMath.min(StrictMath.max(userZoomLevel - e.getWheelRotation() * .25, 0), + MathUtil.log2(mask.getSize())); Vector2 newMousePositionOnMask = canvasCoordinatesToFractionalMaskCoordinates(lastMousePosition); - fractionalImageOffset.subtract(oldMousePositionOnMask).add(newMousePositionOnMask); + fractionalImageOffset = fractionalImageOffset.subtract(oldMousePositionOnMask) + .add(newMousePositionOnMask); boundOffset(); repaint(); } @@ -124,24 +123,23 @@ public void mouseWheelMoved(MouseWheelEvent e) { public void mouseDragged(MouseEvent e) { if (mask != null) { Vector2 newMousePosition = new Vector2(e.getPoint()); - fractionalImageOffset.subtract(lastMousePosition.copy() - .subtract(newMousePosition) - .divide(getFullScalingVector().multiply( - mask.getSize()))); + fractionalImageOffset = fractionalImageOffset.subtract(lastMousePosition.subtract(newMousePosition) + .divide(getFullScalingVector().multiply( + mask.getSize()))); boundOffset(); - lastMousePosition.set(newMousePosition); + lastMousePosition = newMousePosition; repaint(); } } @Override public void mouseMoved(MouseEvent e) { - lastMousePosition.set(e.getPoint()); + lastMousePosition = new Vector2(e.getPoint()); entryPanel.setValueLabel(); } private void boundOffset() { - fractionalImageOffset.min(0).max(1 / getUserScaleFactor() - 1); + fractionalImageOffset = fractionalImageOffset.min(0).max(1 / getUserScaleFactor() - 1); } } } diff --git a/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapForcer.java b/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapForcer.java index 1437c3d2b..8e60aba9c 100644 --- a/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapForcer.java +++ b/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/MapForcer.java @@ -183,8 +183,8 @@ private void forceWaveGenerators(Collection waveGenerators) { SymmetryType.SPAWN); List symmetryRotation = heightMask.getSymmetryRotation(waveGenerator.getRotation()); for (int i = 0; i < symmetryPoints.size(); i++) { - Vector3 newPosition = new Vector3(symmetryPoints.get(i)); - newPosition.setY(waveGenerator.getPosition().getY()); + Vector2 symmetryPoint = symmetryPoints.get(i); + Vector3 newPosition = new Vector3(symmetryPoint.x(), waveGenerator.getPosition().y(), symmetryPoint.y()); forceedWaveGenerators.add( new WaveGenerator(waveGenerator.getTextureName(), waveGenerator.getRampName(), newPosition, symmetryRotation.get(i), waveGenerator.getVelocity())); @@ -269,9 +269,9 @@ private void forceSpawns(Collection spawns) { SymmetryType.SPAWN); for (int i = 0; i < symmetryPoints.size(); ++i) { Vector2 symmetryPoint = symmetryPoints.get(i); - Vector2 symmetricNoRushOffset = new Vector2(spawn.getNoRushOffset()); + Vector2 symmetricNoRushOffset = spawn.getNoRushOffset(); if (!heightMask.inTeam(symmetryPoint, false)) { - symmetricNoRushOffset.flip(new Vector2(0, 0), + symmetricNoRushOffset = symmetricNoRushOffset.flip(new Vector2(0, 0), heightMask.getSymmetrySettings().spawnSymmetry()); } forceedSpawns.add(new Spawn("", symmetryPoint, symmetricNoRushOffset, i + 1)); @@ -339,10 +339,10 @@ private void forceDecals(Collection decals) { decal.getCutOffLOD())); List symmetryPoints = heightMask.getSymmetryPointsWithOutOfBounds(decal.getPosition(), SymmetryType.SPAWN); - List symmetryRotation = heightMask.getSymmetryRotation(decal.getRotation().getY()); + List symmetryRotation = heightMask.getSymmetryRotation(decal.getRotation().y()); for (int i = 0; i < symmetryPoints.size(); i++) { - Vector3 symVectorRotation = new Vector3(decal.getRotation().getX(), symmetryRotation.get(i), - decal.getRotation().getZ()); + Vector3 symVectorRotation = new Vector3(decal.getRotation().x(), symmetryRotation.get(i), + decal.getRotation().z()); forceedDecals.add(new Decal(decal.getPath(), new Vector3(symmetryPoints.get(i)), symVectorRotation, decal.getScale(), decal.getCutOffLOD())); } diff --git a/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/cli/LocationOptions.java b/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/cli/LocationOptions.java index 5c2b5d740..9dcf232c2 100644 --- a/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/cli/LocationOptions.java +++ b/toolsuite/src/main/java/com/faforever/neroxis/toolsuite/cli/LocationOptions.java @@ -1,20 +1,21 @@ package com.faforever.neroxis.toolsuite.cli; +import com.faforever.neroxis.util.vector.Vector; import com.faforever.neroxis.util.vector.Vector2; import lombok.Getter; import picocli.CommandLine; @Getter public class LocationOptions { - private final Vector2 location = new Vector2(); + private Vector2 location = new Vector2(); @CommandLine.Option(names = "--x", required = true, description = "x-coordinate") public void setX(float x) { - location.setX(x); + location = location.withComponent(Vector.X, x); } @CommandLine.Option(names = "--y", required = true, description = "y-coordinate") public void setY(float y) { - location.setY(y); + location = location.withComponent(Vector.Y, y); } } diff --git a/utilities/src/main/java/com/faforever/neroxis/utilities/TemplateNormalizer.java b/utilities/src/main/java/com/faforever/neroxis/utilities/TemplateNormalizer.java index 1c6423ab0..b2ee914af 100644 --- a/utilities/src/main/java/com/faforever/neroxis/utilities/TemplateNormalizer.java +++ b/utilities/src/main/java/com/faforever/neroxis/utilities/TemplateNormalizer.java @@ -40,10 +40,10 @@ public static void normalizeUnits(SequencedMap> un float minY = Float.MAX_VALUE; for (SequencedSet positions : units.values()) { for (Vector2 position : positions) { - maxX = StrictMath.max(maxX, position.getX()); - minX = StrictMath.min(minX, position.getX()); - maxY = StrictMath.max(maxY, position.getY()); - minY = StrictMath.min(minY, position.getY()); + maxX = StrictMath.max(maxX, position.x()); + minX = StrictMath.min(minX, position.x()); + maxY = StrictMath.max(maxY, position.y()); + minY = StrictMath.min(minY, position.y()); } } float centerX = (maxX + minX) / 2; @@ -60,8 +60,8 @@ public static void normalizeUnits(SequencedMap> un out.writeBytes(String.format("\t\ttype = '%s',\n", type)); out.writeBytes("\t\torders = '',\n"); out.writeBytes("\t\tplatoon = '',\n"); - out.writeBytes(String.format("\t\tPosition = { %f, 0, %f },\n", position.getX() - centerX, - position.getY() - centerY)); + out.writeBytes(String.format("\t\tPosition = { %f, 0, %f },\n", position.x() - centerX, + position.y() - centerY)); out.writeBytes("\t\tOrientation = { 0, 0, 0 },\n"); out.writeBytes("\t},\n"); count++;