commit da56b12f6f63a11f3c4acc0926504d4983ff2be3
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sun Mar 20 23:30:35 2022 +0100

    Beginnings of support for display of a collection of bandaged cubits in the CreatorView.

diff --git a/src/main/java/org/distorted/bandaged/BandagedCreatorActivity.java b/src/main/java/org/distorted/bandaged/BandagedCreatorActivity.java
index bbb6f458..b4906e62 100644
--- a/src/main/java/org/distorted/bandaged/BandagedCreatorActivity.java
+++ b/src/main/java/org/distorted/bandaged/BandagedCreatorActivity.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
diff --git a/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java b/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
index 66f3497c..ac5ec10f 100644
--- a/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
+++ b/src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
@@ -21,11 +21,10 @@ package org.distorted.bandaged;
 
 import android.opengl.GLSurfaceView;
 
-import org.distorted.library.effect.EffectType;
-import org.distorted.library.effect.VertexEffectQuaternion;
-import org.distorted.library.effect.VertexEffectRotate;
 import org.distorted.library.main.DistortedLibrary;
+import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedScreen;
+import org.distorted.library.type.Static4D;
 
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
@@ -37,15 +36,72 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
    private final BandagedCreatorView mView;
    private final DistortedScreen mScreen;
 
+   private final BandagedCubit[] mCubits;
+
+   private float[][] POSITIONS = new float[][]
+        {
+          {-1.0f, +1.0f, +1.0f},
+          {-1.0f, +1.0f, +0.0f},
+          {-1.0f, +1.0f, -1.0f},
+          {-1.0f,  0.0f, +1.0f},
+          {-1.0f,  0.0f, +0.0f},
+          {-1.0f,  0.0f, -1.0f},
+          {-1.0f, -1.0f, +1.0f},
+          {-1.0f, -1.0f, +0.0f},
+          {-1.0f, -1.0f, -1.0f},
+          { 0.0f, -1.0f, +1.0f},
+          { 0.0f, -1.0f, +0.0f},
+          { 0.0f, +1.0f, +1.0f},
+          { 0.0f, +1.0f, +0.0f},
+          { 0.0f, +1.0f, -1.0f},
+          { 0.0f,  0.0f, +1.0f},
+          { 0.0f,  0.0f, -1.0f},
+          { 1.0f, +1.0f, +1.0f},
+          { 1.0f, +1.0f, +0.0f},
+          { 1.0f, +1.0f, -1.0f},
+          { 1.0f,  0.0f, +1.0f},
+          { 1.0f,  0.0f, +0.0f},
+          { 1.0f, -1.0f, +1.0f},
+          { 1.0f,  0.0f, -1.0f },
+          { 1.0f, -1.0f, -1.0f },
+          { 1.0f, -1.0f, +0.0f },
+          { 0.0f, -1.0f, -1.0f },
+        };
+
+   Static4D mQuat1, mQuat2;
+   int mScreenMin;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    BandagedCreatorRenderer(BandagedCreatorView v)
      {
      final float BRIGHTNESS = 0.333f;
 
+     mQuat1 = new Static4D(0,0,0,1);
+     mQuat2 = new Static4D(0,0,0,1);
+
      mView = v;
      mScreen = new DistortedScreen();
      mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
+
+     mCubits = createCubits();
+     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   private BandagedCubit[] createCubits()
+     {
+     int len = POSITIONS.length;
+     BandagedCubit[] cubits = new BandagedCubit[len];
+
+     for(int c=0; c<len; c++)
+       {
+       cubits[c] = new BandagedCubit(POSITIONS[c],mQuat1,mQuat2,1.0f);
+       DistortedNode node = cubits[c].getNode();
+       mScreen.attach(node);
+       }
+
+     return cubits;
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -62,6 +118,7 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
    @Override
    public void onSurfaceChanged(GL10 glUnused, int width, int height)
       {
+      mScreenMin = Math.min(width, height);
       mScreen.resize(width,height);
       }
 
@@ -70,10 +127,6 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
    @Override
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
       {
-      DistortedLibrary.setMax(EffectType.VERTEX,25);
-      VertexEffectRotate.enable();
-      VertexEffectQuaternion.enable();
-
       DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
       }
 
@@ -83,11 +136,4 @@ public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, Distorte
      {
      android.util.Log.e("CREATOR", "unexpected exception: "+ex.getMessage() );
      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   DistortedScreen getScreen()
-     {
-     return mScreen;
-     }
 }
diff --git a/src/main/java/org/distorted/bandaged/BandagedCreatorScreen.java b/src/main/java/org/distorted/bandaged/BandagedCreatorScreen.java
index 1ea50466..c88ac69e 100644
--- a/src/main/java/org/distorted/bandaged/BandagedCreatorScreen.java
+++ b/src/main/java/org/distorted/bandaged/BandagedCreatorScreen.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
diff --git a/src/main/java/org/distorted/bandaged/BandagedCreatorView.java b/src/main/java/org/distorted/bandaged/BandagedCreatorView.java
index 33db3dcd..b7234b02 100644
--- a/src/main/java/org/distorted/bandaged/BandagedCreatorView.java
+++ b/src/main/java/org/distorted/bandaged/BandagedCreatorView.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
@@ -25,6 +25,7 @@ import android.content.pm.ConfigurationInfo;
 import android.opengl.GLES30;
 import android.opengl.GLSurfaceView;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
@@ -32,6 +33,8 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
 public class BandagedCreatorView extends GLSurfaceView
 {
+    private final static int DIRECTION_SENSITIVITY=  12;
+    private int mX, mY;
     private BandagedCreatorRenderer mRenderer;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -42,6 +45,9 @@ public class BandagedCreatorView extends GLSurfaceView
       {
       super(context,attrs);
 
+      mX = -1;
+      mY = -1;
+
       if(!isInEditMode())
         {
         BandagedCreatorActivity act = (BandagedCreatorActivity)context;
@@ -77,18 +83,83 @@ public class BandagedCreatorView extends GLSurfaceView
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    @Override
-    public void onPause()
+    public BandagedCreatorRenderer getRenderer()
       {
-      super.onPause();
+      return mRenderer;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    @Override
-    public void onResume()
+    private void resetQuats()
       {
-      super.onResume();
+      float qx = mRenderer.mQuat1.get0();
+      float qy = mRenderer.mQuat1.get1();
+      float qz = mRenderer.mQuat1.get2();
+      float qw = mRenderer.mQuat1.get3();
+
+      float rx = mRenderer.mQuat2.get0();
+      float ry = mRenderer.mQuat2.get1();
+      float rz = mRenderer.mQuat2.get2();
+      float rw = mRenderer.mQuat2.get3();
+
+      float tx = rw*qx - rz*qy + ry*qz + rx*qw;
+      float ty = rw*qy + rz*qx + ry*qw - rx*qz;
+      float tz = rw*qz + rz*qw - ry*qx + rx*qy;
+      float tw = rw*qw - rz*qz - ry*qy - rx*qx;
+
+      mRenderer.mQuat1.set(0f, 0f, 0f, 1f);
+      mRenderer.mQuat2.set(tx, ty, tz, tw);
       }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    @Override public boolean onTouchEvent(MotionEvent event)
+      {
+      int action = event.getAction();
+      int x = (int)event.getX();
+      int y = (int)event.getY();
+
+      switch(action)
+         {
+         case MotionEvent.ACTION_DOWN: mX = x;
+                                       mY = y;
+                                       break;
+
+         case MotionEvent.ACTION_MOVE: if( mX>=0 && mY>= 0 )
+                                         {
+                                         float px = mY-y;
+                                         float py = mX-x;
+                                         float pz = 0;
+                                         float plen = (float)Math.sqrt(px*px + py*py + pz*pz);
+
+                                         if( plen>0 )
+                                           {
+                                           px /= plen;
+                                           py /= plen;
+                                           pz /= plen;
+
+                                           float cosA = (float)Math.cos(plen*3.14f/mRenderer.mScreenMin);
+                                           float sinA = (float)Math.sqrt(1-cosA*cosA);
+
+                                           mRenderer.mQuat1.set(px*sinA, py*sinA, pz*sinA, cosA);
+                                           }
+                                         }
+                                       if( (mX-x)*(mX-x) + (mY-y)*(mY-y) > mRenderer.mScreenMin*mRenderer.mScreenMin/(DIRECTION_SENSITIVITY*DIRECTION_SENSITIVITY) )
+                                         {
+                                         mX = x;
+                                         mY = y;
+                                         resetQuats();
+                                         }
+                                       break;
+
+         case MotionEvent.ACTION_UP  : mX = -1;
+                                       mY = -1;
+        	                             resetQuats();
+                                       break;
+         }
+
+      return true;
+      }
+
 }
 
diff --git a/src/main/java/org/distorted/bandaged/BandagedCubit.java b/src/main/java/org/distorted/bandaged/BandagedCubit.java
new file mode 100644
index 00000000..63e98860
--- /dev/null
+++ b/src/main/java/org/distorted/bandaged/BandagedCubit.java
@@ -0,0 +1,104 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2022 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube 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 General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.bandaged;
+
+import org.distorted.library.effect.MatrixEffectMove;
+import org.distorted.library.effect.MatrixEffectQuaternion;
+import org.distorted.library.effect.MatrixEffectScale;
+import org.distorted.library.main.DistortedEffects;
+import org.distorted.library.main.DistortedNode;
+import org.distorted.library.main.DistortedTexture;
+import org.distorted.library.mesh.MeshBase;
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+import org.distorted.objectlib.helpers.FactoryBandaged3x3Cubit;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class BandagedCubit
+{
+    private static final Static3D CENTER = new Static3D(0,0,0);
+
+    private final DistortedNode mNode;
+    private final DistortedTexture mTexture;
+    private final DistortedEffects mEffects;
+    private final MeshBase mMesh;
+    private final float[] mPosition;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private Static3D computeMove(float[] position)
+      {
+      int numCenters = position.length/3;
+      float totalX=0.0f, totalY=0.0f, totalZ=0.0f;
+
+      for(int center=0; center<numCenters; center++)
+        {
+        totalX += position[3*center  ];
+        totalY += position[3*center+1];
+        totalZ += position[3*center+2];
+        }
+
+      totalX /= numCenters;
+      totalY /= numCenters;
+      totalZ /= numCenters;
+
+      return new Static3D(totalX,totalY,totalZ);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public BandagedCubit(float[] position, Static4D quat1, Static4D quat2, float scale)
+      {
+      mPosition = position;
+
+      FactoryBandaged3x3Cubit factory = FactoryBandaged3x3Cubit.getInstance();
+      mMesh = factory.createMesh(position);
+
+      mTexture = new DistortedTexture();
+      mTexture.setColorARGB(0xffffffff);
+
+      Static3D move = computeMove(position);
+      Static3D objectScale = new Static3D(scale,scale,scale);
+
+      MatrixEffectScale scaleEffect = new MatrixEffectScale(objectScale);
+      MatrixEffectQuaternion quat1Effect = new MatrixEffectQuaternion(quat1, CENTER);
+      MatrixEffectQuaternion quat2Effect = new MatrixEffectQuaternion(quat2, CENTER);
+      MatrixEffectMove moveEffect = new MatrixEffectMove(move);
+
+      mEffects = new DistortedEffects();
+      mEffects.apply(quat1Effect);
+      mEffects.apply(quat2Effect);
+      mEffects.apply(scaleEffect);
+      mEffects.apply(moveEffect);
+
+      mNode = new DistortedNode(mTexture,mEffects,mMesh);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public DistortedNode getNode()
+      {
+      return mNode;
+      }
+}
+
diff --git a/src/main/java/org/distorted/bandaged/BandagedPlayActivity.java b/src/main/java/org/distorted/bandaged/BandagedPlayActivity.java
index 715971ed..3e31ee93 100644
--- a/src/main/java/org/distorted/bandaged/BandagedPlayActivity.java
+++ b/src/main/java/org/distorted/bandaged/BandagedPlayActivity.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
diff --git a/src/main/java/org/distorted/bandaged/BandagedPlayLibInterface.java b/src/main/java/org/distorted/bandaged/BandagedPlayLibInterface.java
index 5b401cc5..de9d55ea 100644
--- a/src/main/java/org/distorted/bandaged/BandagedPlayLibInterface.java
+++ b/src/main/java/org/distorted/bandaged/BandagedPlayLibInterface.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
diff --git a/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java b/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java
index 913b0d48..430dca0b 100644
--- a/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java
+++ b/src/main/java/org/distorted/bandaged/BandagedPlayRenderer.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
diff --git a/src/main/java/org/distorted/bandaged/BandagedPlayScreen.java b/src/main/java/org/distorted/bandaged/BandagedPlayScreen.java
index 5c03add3..22f14ada 100644
--- a/src/main/java/org/distorted/bandaged/BandagedPlayScreen.java
+++ b/src/main/java/org/distorted/bandaged/BandagedPlayScreen.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
diff --git a/src/main/java/org/distorted/bandaged/BandagedPlayView.java b/src/main/java/org/distorted/bandaged/BandagedPlayView.java
index fb8e2a84..eb6c5413 100644
--- a/src/main/java/org/distorted/bandaged/BandagedPlayView.java
+++ b/src/main/java/org/distorted/bandaged/BandagedPlayView.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
+// Copyright 2022 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
