commit c4cfd83afd9286abe959895b97ba207a46a436e1
Author: leszek <leszek@koltunski.pl>
Date:   Fri Dec 20 00:08:21 2024 +0100

    Glow cubits involved in the phase.

diff --git a/src/main/java/org/distorted/phasedsolver/SolverActivity.java b/src/main/java/org/distorted/phasedsolver/SolverActivity.java
index 38bd4aa..f849ca1 100644
--- a/src/main/java/org/distorted/phasedsolver/SolverActivity.java
+++ b/src/main/java/org/distorted/phasedsolver/SolverActivity.java
@@ -123,7 +123,7 @@ public class SolverActivity extends Activity implements SolutionListener, Adapte
       {
       mCurrSolver = pos;
       String[] phaseNames = createSolver();
-      mLowerPane.updateNames(this,phaseNames);
+      mLowerPane.updateNames(phaseNames);
       int ordinal = getObjectOrdinal();
       ObjectControl control = getControl();
       control.changeObject(ordinal, MODE_NORM, mAsset);
@@ -172,10 +172,10 @@ public class SolverActivity extends Activity implements SolutionListener, Adapte
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void Left(View v)       { mLowerPane.backMove(this); }
-  public void Right(View v)      { mLowerPane.nextMove(this); }
-  public void PhaseLeft(View v)  { mLowerPane.backPhase(this); }
-  public void PhaseRight(View v) { mLowerPane.nextPhase(this); }
+  public void Left(View v)       { mLowerPane.backMove(); }
+  public void Right(View v)      { mLowerPane.nextMove(); }
+  public void PhaseLeft(View v)  { mLowerPane.backPhase(); }
+  public void PhaseRight(View v) { mLowerPane.nextPhase(); }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -226,7 +226,7 @@ public class SolverActivity extends Activity implements SolutionListener, Adapte
       for(int m=1; m<=numMoves; m++)
         moves[index++] = mObject.findMove(solution[m]);
 
-      mLowerPane.setSolution(this, moves, phase, mSolver.getSubPhases(phase));
+      mLowerPane.setSolution(moves, phase, mSolver.getSubPhases(phase));
       }
 
     long time = System.currentTimeMillis();
@@ -263,7 +263,7 @@ public class SolverActivity extends Activity implements SolutionListener, Adapte
     {
     ObjectControl control = getControl();
     control.fastScrambleObject(1000,20);
-    mLowerPane.clearMoves(this);
+    mLowerPane.clearMoves();
 
     mNumMoves = 0;
     mMoves = "";
@@ -276,7 +276,7 @@ public class SolverActivity extends Activity implements SolutionListener, Adapte
     {
     ObjectControl control = getControl();
     control.solveObject();
-    mLowerPane.clearMoves(this);
+    mLowerPane.clearMoves();
 
     mNumMoves = 0;
     mMoves = "";
diff --git a/src/main/java/org/distorted/phasedsolver/SolverLowerPane.java b/src/main/java/org/distorted/phasedsolver/SolverLowerPane.java
index 651c19e..121cb7a 100644
--- a/src/main/java/org/distorted/phasedsolver/SolverLowerPane.java
+++ b/src/main/java/org/distorted/phasedsolver/SolverLowerPane.java
@@ -11,62 +11,98 @@ package org.distorted.phasedsolver;
 
 import android.widget.TextView;
 
+import org.distorted.library.effect.PostprocessEffectGlow;
+import org.distorted.library.main.DistortedEffects;
+import org.distorted.library.mesh.MeshBase;
+import org.distorted.library.message.EffectListener;
+import org.distorted.library.type.Dynamic2D;
+import org.distorted.library.type.Dynamic4D;
+import org.distorted.library.type.Static2D;
+import org.distorted.library.type.Static4D;
 import org.distorted.objectlib.helpers.MovesFinished;
 import org.distorted.objectlib.main.ObjectControl;
+import org.distorted.objectlib.main.TwistyObject;
+
+import java.lang.ref.WeakReference;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class SolverLowerPane implements MovesFinished
+public class SolverLowerPane implements MovesFinished, EffectListener
 {
   private static final int MOVES_PLACE_0 = 100;
   private static final int MOVES_PLACE_1 = 101;
   private static final int MILLIS_PER_DEGREE = 6;
+  private static final int FLASH_TIME = 1200;
 
   private final TextView mText, mPhase;
   private String[] mPhaseNames;
   private int mNumPhases;
   private int[][][] mMoves;
-  private int[][] mCubitsInvolved;
+  private int[][] mCubitsNotInvolved;
   private int mNumMoves,mCurrMove,mCurrPhase;
   private boolean mCanMove;
-  private ObjectControl mControl;
+
+  private final Dynamic2D mHaloAndRadiusDyn;
+  private final Dynamic4D mColorDyn;
+  private final PostprocessEffectGlow mGlow;
+  private final WeakReference<SolverActivity> mAct;
+  private boolean mEffectWorking;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   SolverLowerPane(SolverActivity act, String[] names)
     {
+    mAct = new WeakReference<>(act);
+
     mText  = act.findViewById(R.id.solverText);
     mPhase = act.findViewById(R.id.solverPhaseName);
 
+    mHaloAndRadiusDyn = new Dynamic2D(FLASH_TIME,1.0f);
+    mHaloAndRadiusDyn.add(new Static2D( 0, 0));
+    mHaloAndRadiusDyn.add(new Static2D(10,5));
+
+    mColorDyn = new Dynamic4D(FLASH_TIME,1.0f);
+
+    final int[] colors  = new int[] {1,1,1}; // white
+
+    Static4D P1 = new Static4D(colors[0],colors[1],colors[2], 0.0f);
+    Static4D P2 = new Static4D(colors[0],colors[1],colors[2], 1.0f);
+    mColorDyn.add(P1);
+    mColorDyn.add(P2);
+
+    mGlow = new PostprocessEffectGlow(mHaloAndRadiusDyn,mColorDyn);
+
     mPhaseNames = names;
     mNumPhases = names.length;
     mMoves = new int[mNumPhases][][];
-    mCubitsInvolved = new int[mNumPhases][];
+    mCubitsNotInvolved = new int[mNumPhases][];
     mCanMove = true;
-    setSolution(act,null,0,null);
+    setSolution(null,0,null);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void updateNames(SolverActivity act, String[] names)
+  void updateNames(String[] names)
     {
     mPhaseNames = names;
     mNumPhases = names.length;
     mMoves = new int[mNumPhases][][];
-    mCubitsInvolved = new int[mNumPhases][];
+    mCubitsNotInvolved = new int[mNumPhases][];
     mCanMove = true;
-    setSolution(act,null,0,null);
+    setSolution(null,0,null);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void backPhase(SolverActivity act)
+  void backPhase()
     {
+    SolverActivity act = mAct.get();
+    ObjectControl control = act.getControl();
+
     if( mCurrMove>0 )
       {
       int[][] moves = transformMoves(mMoves[mCurrPhase],0,mCurrMove, false);
-      mControl = act.getControl();
-      mControl.applyScrambles(moves);
+      control.applyScrambles(moves);
       mCurrMove = 0;
       }
     else if( mCurrPhase>0 )
@@ -74,17 +110,15 @@ public class SolverLowerPane implements MovesFinished
       mCurrPhase--;
       mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
       int[][] moves = transformMoves(mMoves[mCurrPhase],0,mNumMoves, false);
-      mControl = act.getControl();
-      mControl.applyScrambles(moves);
+      control.applyScrambles(moves);
       }
     else
       {
       mCurrPhase = mNumPhases-1;
       mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
       mCurrMove = mNumMoves;
-      mControl = act.getControl();
       int[][] moves = transformMoves(mMoves, true);
-      mControl.applyScrambles(moves);
+      control.applyScrambles(moves);
       }
 
     setText(act);
@@ -92,34 +126,34 @@ public class SolverLowerPane implements MovesFinished
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void nextPhase(SolverActivity act)
+  void nextPhase()
     {
+    SolverActivity act = mAct.get();
+    ObjectControl control = act.getControl();
+
     if( mCurrPhase<mNumPhases-1 )
       {
-      mControl = act.getControl();
-      glowCubits(mControl,mCubitsInvolved[mCurrPhase]);
       int[][] moves = transformMoves(mMoves[mCurrPhase],mCurrMove,mNumMoves, true);
-      mControl.applyScrambles(moves);
+      control.applyScrambles(moves);
       mCurrPhase++;
       mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
       mCurrMove = 0;
+      glowCubits(mCubitsNotInvolved[mCurrPhase-1]);
       }
     else if( mCurrMove<mNumMoves )
       {
-      mControl = act.getControl();
-      glowCubits(mControl,mCubitsInvolved[mCurrPhase]);
       int[][] moves = transformMoves(mMoves[mCurrPhase],mCurrMove,mNumMoves, true);
-      mControl.applyScrambles(moves);
+      control.applyScrambles(moves);
       mCurrMove = mNumMoves;
+      glowCubits(mCubitsNotInvolved[mCurrPhase]);
       }
     else
       {
-      mControl = act.getControl();
       mCurrPhase = 0;
       mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
       mCurrMove = 0;
       int[][] moves = transformMoves(mMoves, false);
-      mControl.applyScrambles(moves);
+      control.applyScrambles(moves);
       }
 
     setText(act);
@@ -207,43 +241,77 @@ public class SolverLowerPane implements MovesFinished
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void glowCubits(ObjectControl control, int[] cubits)
+  private void glowCubits(int[] cubits)
     {
-    StringBuilder sb = new StringBuilder();
-    sb.append("Glowing: ");
-
-    for( int c: cubits )
+    if( !mEffectWorking )
       {
-      sb.append(' ');
-      sb.append(c);
+      mEffectWorking = true;
+      SolverActivity act=mAct.get();
+      ObjectControl control = act.getControl();
+      TwistyObject object=control.getObject();
+      DistortedEffects effects=object.getObjectEffects();
+      effects.apply(mGlow);
+
+      MeshBase mesh=object.getObjectMesh();
+      mesh.setComponentsNotAffectedByPostprocessing(cubits);
+
+      mHaloAndRadiusDyn.resetToBeginning();
+      mColorDyn.resetToBeginning();
+      mGlow.notifyWhenFinished(this);
       }
-
-    android.util.Log.e("D", sb.toString() );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int[] computeCubitsInvolved(int[][] subphases)
+  public void effectFinished(long id)
     {
-    int numCubits = 0;
-    for(int[] sub : subphases) numCubits += (sub==null ? 0 : sub.length);
+    SolverActivity act=mAct.get();
+    ObjectControl control = act.getControl();
+    TwistyObject object=control.getObject();
+    DistortedEffects effects=object.getObjectEffects();
+    effects.abortById(id);
 
-    int[] ret = new int[numCubits];
-    int index = 0;
+    mEffectWorking = false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int[] computeCubitsNotInvolved(int[][] subphases, int numCubits)
+    {
+    int numCubitsInvolved = 0;
+    boolean[] involved = new boolean[numCubits];
 
     for(int[] sub : subphases)
       if( sub!=null )
         for(int s : sub)
-          ret[index++] = s;
+          {
+          numCubitsInvolved++;
+          involved[s] = true;
+          }
+
+    int[] ret = new int[numCubits-numCubitsInvolved];
+    int index = 0;
+
+    for(int c=0; c<numCubits; c++)
+      if( !involved[c] ) ret[index++] = c;
 
     return ret;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void setSolution(SolverActivity act, int[][] moves, int phase, int[][] subphases)
+  void setSolution(int[][] moves, int phase, int[][] subphases)
     {
-    mCubitsInvolved[phase] = subphases==null ? null : computeCubitsInvolved(subphases);
+    SolverActivity act=mAct.get();
+
+    if( subphases!=null )
+      {
+      ObjectControl control=act.getControl();
+      TwistyObject object=control.getObject();
+      int numCubits=object.getNumCubits();
+      mCubitsNotInvolved[phase]= computeCubitsNotInvolved(subphases, numCubits);
+      }
+
     mMoves[phase] = moves;
     if( phase==0 ) mNumMoves = (moves==null ? 0 : moves.length);
     mCurrPhase = 0;
@@ -254,29 +322,31 @@ public class SolverLowerPane implements MovesFinished
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void clearMoves(SolverActivity act)
+  void clearMoves()
     {
     for(int p=0; p<mNumPhases; p++) mMoves[p] = null;
     mNumMoves = 0;
     mCurrPhase= 0;
     mCurrMove = 0;
 
-    setText(act);
+    setText(mAct.get());
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void backMove(SolverActivity act)
+  void backMove()
     {
     if( mMoves!=null && mCanMove )
       {
+      SolverActivity act=mAct.get();
+
       if( mCurrMove>0 )
         {
         mCanMove = false;
         int[] move = mMoves[mCurrPhase][--mCurrMove];
-        mControl = act.getControl();
-        mControl.blockTouch(MOVES_PLACE_0);
-        mControl.addRotation(this, move[0], (1<<move[1]), -move[2], MILLIS_PER_DEGREE);
+        ObjectControl control = act.getControl();
+        control.blockTouch(MOVES_PLACE_0);
+        control.addRotation(this, move[0], (1<<move[1]), -move[2], MILLIS_PER_DEGREE);
         }
       else if( mCurrPhase>0 )
         {
@@ -289,10 +359,9 @@ public class SolverLowerPane implements MovesFinished
         mCurrPhase = mNumPhases-1;
         mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
         mCurrMove = mNumMoves;
-        mControl = act.getControl();
-
         int[][] moves = transformMoves(mMoves, true);
-        mControl.applyScrambles(moves);
+        ObjectControl control = act.getControl();
+        control.applyScrambles(moves);
         }
 
       setText(act);
@@ -301,24 +370,26 @@ public class SolverLowerPane implements MovesFinished
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void nextMove(SolverActivity act)
+  void nextMove()
     {
     if( mMoves!=null && mCanMove )
       {
+      SolverActivity act=mAct.get();
+
       if( mCurrMove<mNumMoves )
         {
         mCanMove = false;
         int[] move = mMoves[mCurrPhase][mCurrMove++];
-        mControl = act.getControl();
-        mControl.blockTouch(MOVES_PLACE_1);
-        mControl.addRotation(this, move[0], (1<<move[1]), move[2], MILLIS_PER_DEGREE);
+        ObjectControl control = act.getControl();
+        control.blockTouch(MOVES_PLACE_1);
+        control.addRotation(this, move[0], (1<<move[1]), move[2], MILLIS_PER_DEGREE);
 
         if( mCurrPhase==mNumPhases-1 && mCurrMove==mNumMoves )
-          glowCubits(mControl,mCubitsInvolved[mCurrPhase]);
+          glowCubits(mCubitsNotInvolved[mCurrPhase]);
         }
       else if( mCurrPhase<mNumPhases-1 )
         {
-        glowCubits(mControl,mCubitsInvolved[mCurrPhase]);
+        glowCubits(mCubitsNotInvolved[mCurrPhase]);
         mCurrPhase++;
         mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
         mCurrMove = 0;
@@ -329,8 +400,8 @@ public class SolverLowerPane implements MovesFinished
         mNumMoves = mMoves[mCurrPhase]==null ? 0 : mMoves[mCurrPhase].length;
         mCurrMove = 0;
         int[][] moves = transformMoves(mMoves, false);
-        mControl = act.getControl();
-        mControl.applyScrambles(moves);
+        ObjectControl control = act.getControl();
+        control.applyScrambles(moves);
         }
 
       setText(act);
@@ -342,6 +413,9 @@ public class SolverLowerPane implements MovesFinished
   public void onActionFinished(final long effectID)
     {
     mCanMove = true;
-    mControl.unblockRotation();
+
+    SolverActivity act=mAct.get();
+    ObjectControl control = act.getControl();
+    control.unblockRotation();
     }
 }
diff --git a/src/main/java/org/distorted/phasedsolver/SolverRenderer.java b/src/main/java/org/distorted/phasedsolver/SolverRenderer.java
index a9bae20..5394920 100644
--- a/src/main/java/org/distorted/phasedsolver/SolverRenderer.java
+++ b/src/main/java/org/distorted/phasedsolver/SolverRenderer.java
@@ -13,13 +13,12 @@ import android.content.res.Resources;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.effect.EffectType;
-import org.distorted.library.effect.PostprocessEffectBorder;
+import org.distorted.library.effect.PostprocessEffectGlow;
 import org.distorted.library.effect.VertexEffectQuaternion;
 import org.distorted.library.effect.VertexEffectRotate;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.mesh.MeshBase;
-import org.distorted.objectlib.effects.BaseEffect;
 import org.distorted.objectlib.main.ObjectControl;
 
 import java.io.InputStream;
@@ -80,8 +79,7 @@ class SolverRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Library
 
       VertexEffectRotate.enable();
       VertexEffectQuaternion.enable();
-      PostprocessEffectBorder.enable();
-      BaseEffect.Type.enableEffects();
+      PostprocessEffectGlow.enable();
 
       DistortedLibrary.onSurfaceCreated(this);
       }
