commit b1bfcdc73f533113d00f4863d951221fe2d10941
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Jun 12 14:48:37 2023 +0200

    Beginnings of MeshMultigon (does not work yet)

diff --git a/src/main/java/org/distorted/library/mesh/MeshMultigon.java b/src/main/java/org/distorted/library/mesh/MeshMultigon.java
new file mode 100644
index 0000000..f3feac1
--- /dev/null
+++ b/src/main/java/org/distorted/library/mesh/MeshMultigon.java
@@ -0,0 +1,148 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2023 Leszek Koltunski  leszek@koltunski.pl                                          //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// This library is free software; you can redistribute it and/or                                 //
+// modify it under the terms of the GNU Lesser General Public                                    //
+// License as published by the Free Software Foundation; either                                  //
+// version 2.1 of the License, or (at your option) any later version.                            //
+//                                                                                               //
+// This library is distributed in the hope that it will be useful,                               //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                             //
+// Lesser General Public License for more details.                                               //
+//                                                                                               //
+// You should have received a copy of the GNU Lesser General Public                              //
+// License along with this library; if not, write to the Free Software                           //
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.mesh;
+
+/**
+ * Create a 'multigon' mesh - a union of several polygons.
+ *
+ * <p>
+ * Specify several lists of vertices. Each list defines one polygon. (@see MeshPolygon).
+ * If two such polygons share an edge (or several edges) then the edge in both of them is
+ * marked 'up'.
+ */
+public class MeshMultigon extends MeshBase
+  {
+  private static final float MAX_ERROR = 0.0001f;
+
+  private boolean isSame(float[] v1, float[] v2)
+    {
+    float dx = v1[0]-v2[0];
+    float dy = v1[1]-v2[1];
+    return (dx*dx + dy*dy < MAX_ERROR);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean isUp(float[][][] vertices, int polygon, int edge)
+    {
+    float[][] p = vertices[polygon];
+    int lenP = p.length;
+    int len  = vertices.length;
+    int next = (edge==lenP-1 ? 0 : edge+1);
+
+    float[] v1 = p[edge];
+    float[] v2 = p[next];
+
+    for(int i=0; i<len; i++)
+      if( i!=polygon )
+        {
+        int num = vertices[i].length;
+
+        for(int j=0; j<num; j++)
+          {
+          int n = (j==num-1 ? 0 : j+1);
+          if( isSame(v2,vertices[i][j]) && isSame(v1,vertices[i][n]) ) return true;
+          }
+        }
+
+    return false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean[][] computeUp(float[][] vertices, float[][] centers)
+    {
+    int num = vertices.length;
+    boolean[][] up = new boolean[num][];
+    float[][][] v = new float[num][][];
+
+    for(int i=0; i<num; i++)
+      {
+      int len = vertices[i].length/2;
+      v[i] = new float[len][2];
+
+      for(int j=0; j<len; j++)
+        {
+        v[i][j][0] = vertices[i][2*j  ] + centers[i][0];
+        v[i][j][1] = vertices[i][2*j+1] + centers[i][1];
+        }
+      }
+
+    for(int i=0; i<num; i++)
+      {
+      int len = vertices[i].length/2;
+      up[i] = new boolean[len];
+      for(int j=0; j<len; j++) up[i][j] = isUp(v,i,j);
+      }
+
+    return up;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Specify several lists of vertices. Each list defines one polygon. (@see MeshPolygon).
+ * If two such polygons share an edge (or several edges) then the edge in both of them is
+ * marked 'up'.
+ *
+ * @param vertices   an array of arrays, each specifying vertices of a single polygon.
+ * @param band       see MeshPolygon. Shared among all polygons.
+ * @param exIndex    see MeshPolygon. Shared among all polygons.
+ * @param exVertices see MeshPolygon. Shared among all polygons.
+ * @param centers    for each polygon, coordinates of its center.
+ */
+  public MeshMultigon(float[][] vertices, float[] band, int exIndex, int exVertices, float[][] centers)
+    {
+    super();
+
+    int numPolygons = vertices.length;
+    MeshPolygon[] meshes = new MeshPolygon[numPolygons];
+    boolean[][] up = computeUp(vertices,centers);
+
+    for(int i=0; i<numPolygons; i++)
+      meshes[i] = new MeshPolygon(vertices[i],band,up[i],exIndex,exVertices,centers[i][0],centers[i][1]);
+
+    join(meshes);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Copy constructor.
+ */
+  public MeshMultigon(MeshMultigon mesh, boolean deep)
+    {
+    super(mesh,deep);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Copy the Mesh.
+ *
+ * @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices,
+ *             normals and inflates (the rest, in particular the mVertAttribs2 containing texture
+ *             coordinates and effect associations, is always deep copied)
+ */
+  public MeshMultigon copy(boolean deep)
+    {
+    return new MeshMultigon(this,deep);
+    }
+ }
\ No newline at end of file
