commit aaeef3282e25be8ae9dc00c71adb9c17e8399509
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Mar 22 22:08:05 2023 +0100

    Support split type 'EDGE_COIN' in case of every shape.

diff --git a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlDodecahedron.java b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlDodecahedron.java
index 16975a6a..2a8f35bb 100644
--- a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlDodecahedron.java
+++ b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlDodecahedron.java
@@ -112,8 +112,10 @@ public class TouchControlDodecahedron extends TouchControlShapeConstant
       {
       case TYPE_NOT_SPLIT      : return 0;
       case TYPE_SPLIT_EDGE     : return partEdge(point,face);
+      case TYPE_SPLIT_EDGE_COIN: float y = point[1];
+                                 float x = point[0];
+                                 return partEdge(point,face) + (x*x+y*y < DIST2D*DIST2D ? 0:5 );
       case TYPE_SPLIT_CORNER   : // not supported
-      case TYPE_SPLIT_EDGE_COIN: // not supported
       }
 
     return 0;
diff --git a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlHexahedron.java b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlHexahedron.java
index 6a879196..900c37fb 100644
--- a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlHexahedron.java
+++ b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlHexahedron.java
@@ -36,6 +36,24 @@ public class TouchControlHexahedron extends TouchControlShapeConstant
     super(object,D3D,FACE_AXIS);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int partEdge(float[] point, int face)
+    {
+    boolean e0 = point[0] > 0;
+    boolean e1 = point[1] > 0;
+    return e0 ? (e1 ? 0:1) : (e1 ? 3:2);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int partCorner(float[] point, int face)
+    {
+    boolean c0 = point[1] >= point[0];
+    boolean c1 = point[1] >=-point[0];
+    return c0 ? (c1 ? 0:3) : (c1 ? 1:2);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 //  corner    edge
 //  \ 0 /     3 | 0
@@ -43,18 +61,16 @@ public class TouchControlHexahedron extends TouchControlShapeConstant
 //   / \        |
 //  / 2 \     2 | 1
 
-  int returnPart(int type, int face, float[] touchPoint)
+  int returnPart(int type, int face, float[] point)
     {
     switch(type)
       {
-      case TYPE_NOT_SPLIT     : return 0;
-      case TYPE_SPLIT_EDGE    : boolean e0 = touchPoint[0] > 0;
-                                boolean e1 = touchPoint[1] > 0;
-                                return e0 ? (e1 ? 0:1) : (e1 ? 3:2);
-      case TYPE_SPLIT_CORNER  : boolean c0 = touchPoint[1] >= touchPoint[0];
-                                boolean c1 = touchPoint[1] >=-touchPoint[0];
-                                return c0 ? (c1 ? 0:3) : (c1 ? 1:2);
-      case TYPE_SPLIT_EDGE_COIN: // not supported
+      case TYPE_NOT_SPLIT      : return 0;
+      case TYPE_SPLIT_EDGE     : return partEdge(point,face);
+      case TYPE_SPLIT_CORNER   : return partCorner(point,face);
+      case TYPE_SPLIT_EDGE_COIN: float y = point[1];
+                                 float x = point[0];
+                                 return partEdge(point,face) + (x*x+y*y < DIST2D*DIST2D ? 0:4 );
       }
 
     return 0;
diff --git a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlIcosahedron.java b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlIcosahedron.java
index 3dcc0233..1f8f3a4c 100644
--- a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlIcosahedron.java
+++ b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlIcosahedron.java
@@ -138,43 +138,54 @@ public class TouchControlIcosahedron extends TouchControlShapeConstant
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// corner    edge
-//   |       \ 0 /
-// 2 | 0      \ /
-//  / \      2 | 1
-// / 1 \       |
 
-  int returnPart(int type, int face, float[] touchPoint)
+  private int partEdge(float[] point, int face)
     {
-    switch(type)
-      {
-      case TYPE_NOT_SPLIT   : return 0;
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
 
-      case TYPE_SPLIT_EDGE  : float y1 = (isFaceInverted(face) ? touchPoint[1] : -touchPoint[1]);
-                              float x1 = touchPoint[0];
+    boolean e0 = x>0;
+    boolean e1 = y>( SQ3/3)*x;
+    boolean e2 = y>(-SQ3/3)*x;
 
-                              boolean e0 = x1>0;
-                              boolean e1 = y1>( SQ3/3)*x1;
-                              boolean e2 = y1>(-SQ3/3)*x1;
+    if(  e1 && e2 ) return 0;
+    if( !e1 && e0 ) return 1;
+    return 2;
+    }
 
-                              if(  e1 && e2 ) return 0;
-                              if( !e1 && e0 ) return 1;
-                              if( !e0 &&!e2 ) return 2;
-                              return 0;
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-      case TYPE_SPLIT_CORNER: float y2 = (isFaceInverted(face) ? touchPoint[1] : -touchPoint[1]);
-                              float x2 = touchPoint[0];
+  private int partCorner(float[] point, int face)
+    {
+    float y2 = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x2 = point[0];
 
-                              boolean c0 = x2>0;
-                              boolean c1 = y2>( SQ3/3)*x2;
-                              boolean c2 = y2>(-SQ3/3)*x2;
+    boolean c0 = x2>0;
+    boolean c1 = y2>( SQ3/3)*x2;
+    boolean c2 = y2>(-SQ3/3)*x2;
 
-                              if(  c0 && c2 ) return 0;
-                              if( !c1 &&!c2 ) return 1;
-                              if( !c0 && c1 ) return 2;
-                              return 0;
+    if(  c0 && c2 ) return 0;
+    if( !c1 &&!c2 ) return 1;
+    return 2;
+    }
 
-      case TYPE_SPLIT_EDGE_COIN: //  not supported
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// corner    edge
+//   |       \ 0 /
+// 2 | 0      \ /
+//  / \      2 | 1
+// / 1 \       |
+
+  int returnPart(int type, int face, float[] point)
+    {
+    switch(type)
+      {
+      case TYPE_NOT_SPLIT      : return 0;
+      case TYPE_SPLIT_EDGE     : return partEdge(point,face);
+      case TYPE_SPLIT_CORNER   : return partCorner(point,face);
+      case TYPE_SPLIT_EDGE_COIN: float y = point[1];
+                                 float x = point[0];
+                                 return partEdge(point,face) + (x*x+y*y < DIST2D*DIST2D ? 0:3 );
       }
 
     return 0;
@@ -182,10 +193,10 @@ public class TouchControlIcosahedron extends TouchControlShapeConstant
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  boolean isInsideFace(int face, float[] p)
+  boolean isInsideFace(int face, float[] point)
     {
-    float y = (isFaceInverted(face) ? p[1] : -p[1]);
-    float x = p[0];
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
     return (y >= -DIST2D) && (y <= DIST2D*(2-6*x)) && (y <= DIST2D*(2+6*x));
     }
 }
diff --git a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlOctahedron.java b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlOctahedron.java
index 1d6b3b49..33942882 100644
--- a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlOctahedron.java
+++ b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlOctahedron.java
@@ -38,43 +38,61 @@ public class TouchControlOctahedron extends TouchControlShapeConstant
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// corner    edge
-//   |       \ 0 /
-// 2 | 0      \ /
-//  / \      2 | 1
-// / 1 \       |
 
-  int returnPart(int type, int face, float[] touchPoint)
+  private boolean isFaceInverted(int face)
     {
-    switch(type)
-      {
-      case TYPE_NOT_SPLIT   : return 0;
+    return (face%2)==0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int partEdge(float[] point, int face)
+    {
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
+
+    boolean e0 = x>0;
+    boolean e1 = y>( SQ3/3)*x;
+    boolean e2 = y>(-SQ3/3)*x;
 
-      case TYPE_SPLIT_EDGE  : float y1 = (face%2 == 0 ? touchPoint[1] : -touchPoint[1]);
-                              float x1 = touchPoint[0];
+    if(  e1 && e2 ) return 0;
+    if( !e1 && e0 ) return 1;
+    return 2;
+    }
 
-                              boolean e0 = x1>0;
-                              boolean e1 = y1>( SQ3/3)*x1;
-                              boolean e2 = y1>(-SQ3/3)*x1;
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-                              if(  e1 && e2 ) return 0;
-                              if( !e1 && e0 ) return 1;
-                              if( !e0 &&!e2 ) return 2;
-                              return 0;
+  private int partCorner(float[] point, int face)
+    {
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
 
-      case TYPE_SPLIT_CORNER: float y2 = (face%2 == 0 ? touchPoint[1] : -touchPoint[1]);
-                              float x2 = touchPoint[0];
+    boolean c0 = x>0;
+    boolean c1 = y>( SQ3/3)*x;
+    boolean c2 = y>(-SQ3/3)*x;
 
-                              boolean c0 = x2>0;
-                              boolean c1 = y2>( SQ3/3)*x2;
-                              boolean c2 = y2>(-SQ3/3)*x2;
+    if(  c0 && c2 ) return 0;
+    if( !c1 &&!c2 ) return 1;
+    return 2;
+    }
 
-                              if(  c0 && c2 ) return 0;
-                              if( !c1 &&!c2 ) return 1;
-                              if( !c0 && c1 ) return 2;
-                              return 0;
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// corner    edge
+//   |       \ 0 /
+// 2 | 0      \ /
+//  / \      2 | 1
+// / 1 \       |
 
-      case TYPE_SPLIT_EDGE_COIN: //  not supported
+  int returnPart(int type, int face, float[] point)
+    {
+    switch(type)
+      {
+      case TYPE_NOT_SPLIT       : return 0;
+      case TYPE_SPLIT_EDGE      : return partEdge(point,face);
+      case TYPE_SPLIT_CORNER    : return partCorner(point,face);
+      case TYPE_SPLIT_EDGE_COIN : float y = point[1];
+                                  float x = point[0];
+                                  return partEdge(point,face) + (x*x+y*y < DIST2D*DIST2D ? 0:3 );
       }
 
     return 0;
@@ -89,10 +107,10 @@ public class TouchControlOctahedron extends TouchControlShapeConstant
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  boolean isInsideFace(int face, float[] p)
+  boolean isInsideFace(int face, float[] point)
     {
-    float y = (face%2 == 0 ? p[1] : -p[1]);
-    float x = p[0];
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
     return (y >= -DIST2D) && (y <= DIST2D*(2-6*x)) && (y <= DIST2D*(2+6*x));
     }
 }
diff --git a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlTetrahedron.java b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlTetrahedron.java
index 2a39d12e..dffcf91b 100644
--- a/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlTetrahedron.java
+++ b/src/main/java/org/distorted/objectlib/touchcontrol/TouchControlTetrahedron.java
@@ -37,6 +37,45 @@ public class TouchControlTetrahedron extends TouchControlShapeConstant
     super(object,D3D,FACE_AXIS);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean isFaceInverted(int face)
+    {
+    return face>1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int partEdge(float[] point, int face)
+    {
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
+
+    boolean e0 = x>0;
+    boolean e1 = y>( SQ3/3)*x;
+    boolean e2 = y>(-SQ3/3)*x;
+
+    if(  e1 && e2 ) return 0;
+    if( !e1 && e0 ) return 1;
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int partCorner(float[] point, int face)
+    {
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
+
+    boolean c0 = x>0;
+    boolean c1 = y>( SQ3/3)*x;
+    boolean c2 = y>(-SQ3/3)*x;
+
+    if(  c0 && c2 ) return 0;
+    if( !c1 &&!c2 ) return 1;
+    return 2;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // corner    edge
 //   |       \ 0 /
@@ -46,48 +85,16 @@ public class TouchControlTetrahedron extends TouchControlShapeConstant
 //
 // COIN: pieces inside the coin just like in EDGE; outside +=3.
 
-  int returnPart(int type, int face, float[] touchPoint)
+  int returnPart(int type, int face, float[] point)
     {
     switch(type)
       {
       case TYPE_NOT_SPLIT      : return 0;
-
-      case TYPE_SPLIT_EDGE     : float y1 = (face > 1 ? touchPoint[1] : -touchPoint[1]);
-                                 float x1 = touchPoint[0];
-
-                                 boolean e0 = x1>0;
-                                 boolean e1 = y1>( SQ3/3)*x1;
-                                 boolean e2 = y1>(-SQ3/3)*x1;
-
-                                 if(  e1 && e2 ) return 0;
-                                 if( !e1 && e0 ) return 1;
-                                 if( !e0 &&!e2 ) return 2;
-                                 return 0;
-
-      case TYPE_SPLIT_CORNER:    float y2 = (face > 1 ? touchPoint[1] : -touchPoint[1]);
-                                 float x2 = touchPoint[0];
-
-                                 boolean c0 = x2>0;
-                                 boolean c1 = y2>( SQ3/3)*x2;
-                                 boolean c2 = y2>(-SQ3/3)*x2;
-
-                                 if(  c0 && c2 ) return 0;
-                                 if( !c1 &&!c2 ) return 1;
-                                 if( !c0 && c1 ) return 2;
-                                 return 0;
-      case TYPE_SPLIT_EDGE_COIN: float y3 = (face > 1 ? touchPoint[1] : -touchPoint[1]);
-                                 float x3 = touchPoint[0];
-
-                                 boolean s0 = x3>0;
-                                 boolean s1 = y3>( SQ3/3)*x3;
-                                 boolean s2 = y3>(-SQ3/3)*x3;
-
-                                 int add = (x3*x3+y3*y3<DIST2D*DIST2D ? 0:3 );
-
-                                 if(  s1 && s2 ) return add;
-                                 if( !s1 && s0 ) return add+1;
-                                 if( !s0 &&!s2 ) return add+2;
-                                 return 0;
+      case TYPE_SPLIT_EDGE     : return partEdge(point,face);
+      case TYPE_SPLIT_CORNER   : return partCorner(point,face);
+      case TYPE_SPLIT_EDGE_COIN: float y = point[1];
+                                 float x = point[0];
+                                 return partEdge(point,face) + (x*x+y*y < DIST2D*DIST2D ? 0:3 );
       }
 
     return 0;
@@ -104,10 +111,10 @@ public class TouchControlTetrahedron extends TouchControlShapeConstant
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  boolean isInsideFace(int face, float[] p)
+  boolean isInsideFace(int face, float[] point)
     {
-    float y = (face > 1 ? p[1] : -p[1]);
-    float x = p[0];
+    float y = (isFaceInverted(face) ? point[1] : -point[1]);
+    float x = point[0];
     return (y >= -DIST2D) && (y <= DIST2D*(2-6*x)) && (y <= DIST2D*(2+6*x));
     }
 }
