commit bee1d997f2646a1e3da2419be3fe320f5e182e1f
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Jan 24 02:45:51 2020 +0000

    RubikCube: add new WinEffectGlow

diff --git a/src/main/java/org/distorted/effect/BaseEffect.java b/src/main/java/org/distorted/effect/BaseEffect.java
index 793768cd..91f6f15a 100644
--- a/src/main/java/org/distorted/effect/BaseEffect.java
+++ b/src/main/java/org/distorted/effect/BaseEffect.java
@@ -252,6 +252,8 @@ public class BaseEffect
       }
 
   ////////////////////////////////////////////////////////////////////////////////
+  // map the (0..100) range of the SeekBar into (0..5000) milliseconds, in 100ms
+  // increments.
 
     public static int translatePos(int pos)
       {
diff --git a/src/main/java/org/distorted/effect/scramble/ScrambleEffectNone.java b/src/main/java/org/distorted/effect/scramble/ScrambleEffectNone.java
index 6e5fd295..9836f7fa 100644
--- a/src/main/java/org/distorted/effect/scramble/ScrambleEffectNone.java
+++ b/src/main/java/org/distorted/effect/scramble/ScrambleEffectNone.java
@@ -19,13 +19,13 @@
 
 package org.distorted.effect.scramble;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 public class ScrambleEffectNone extends ScrambleEffect
   {
   public void createEffects(int duration)
diff --git a/src/main/java/org/distorted/effect/solve/SolveEffectNone.java b/src/main/java/org/distorted/effect/solve/SolveEffectNone.java
index ca2bd2c5..abc74043 100644
--- a/src/main/java/org/distorted/effect/solve/SolveEffectNone.java
+++ b/src/main/java/org/distorted/effect/solve/SolveEffectNone.java
@@ -19,13 +19,13 @@
 
 package org.distorted.effect.solve;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 public class SolveEffectNone extends SolveEffect
   {
   public void createEffectsPhase0(int duration)
diff --git a/src/main/java/org/distorted/effect/solve/SolveEffectSpin.java b/src/main/java/org/distorted/effect/solve/SolveEffectSpin.java
index b650887d..574c35d2 100644
--- a/src/main/java/org/distorted/effect/solve/SolveEffectSpin.java
+++ b/src/main/java/org/distorted/effect/solve/SolveEffectSpin.java
@@ -19,8 +19,6 @@
 
 package org.distorted.effect.solve;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectRotate;
 import org.distorted.library.type.Dynamic;
@@ -28,6 +26,8 @@ import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 public class SolveEffectSpin extends SolveEffect
   {
   public void createEffectsPhase0(int duration)
diff --git a/src/main/java/org/distorted/effect/win/WinEffect.java b/src/main/java/org/distorted/effect/win/WinEffect.java
index 7d7d149f..acd4cd65 100644
--- a/src/main/java/org/distorted/effect/win/WinEffect.java
+++ b/src/main/java/org/distorted/effect/win/WinEffect.java
@@ -37,6 +37,7 @@ public abstract class WinEffect extends BaseEffect implements EffectListener
     {
     NONE   (WinEffectNone.class),
     SPIN   (WinEffectSpin.class),
+    GLOW   (WinEffectGlow.class),
     ;
 
     final Class<? extends WinEffect> effect;
@@ -48,7 +49,6 @@ public abstract class WinEffect extends BaseEffect implements EffectListener
     }
 
   private static final int NUM_EFFECTS = Type.values().length;
-  private static final int NUM_PHASES  = 2;
   private static final int FAKE_EFFECT_ID = -2;
   private static final Type[] types;
 
@@ -66,29 +66,14 @@ public abstract class WinEffect extends BaseEffect implements EffectListener
   private EffectListener mListener;
   private int mDuration;
   private int mEffectReturned;
-  private int[] mCubeEffectNumber, mNodeEffectNumber;
-  private int mPhase;
+  private int mCubeEffectNumber, mNodeEffectNumber;
 
   RubikCube mCube;
   DistortedScreen mScreen;
-  Effect[][] mCubeEffects;
-  int[][] mCubeEffectPosition;
-  Effect[][] mNodeEffects;
-  int[][] mNodeEffectPosition;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  WinEffect()
-    {
-    mPhase        =  0;
-
-    mCubeEffectNumber   = new int[NUM_PHASES];
-    mNodeEffectNumber   = new int[NUM_PHASES];
-    mCubeEffectPosition = new int[NUM_PHASES][];
-    mNodeEffectPosition = new int[NUM_PHASES][];
-    mCubeEffects        = new Effect[NUM_PHASES][];
-    mNodeEffects        = new Effect[NUM_PHASES][];
-    }
+  Effect[] mCubeEffects;
+  int[] mCubeEffectPosition;
+  Effect[] mNodeEffects;
+  int[] mNodeEffectPosition;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -113,56 +98,38 @@ public abstract class WinEffect extends BaseEffect implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  abstract void createEffectsPhase0(int duration);
-  abstract void createEffectsPhase1(int duration);
+  abstract void createEffects(int duration);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void effectFinished(final long effectID)
     {
-    int total = mCubeEffectNumber[mPhase]+mNodeEffectNumber[mPhase];
+    int total = mCubeEffectNumber+mNodeEffectNumber;
 
-    for(int i=0; i<mCubeEffectNumber[mPhase]; i++)
+    for(int i=0; i<mCubeEffectNumber; i++)
       {
-      long id = mCubeEffects[mPhase][i].getID();
+      long id = mCubeEffects[i].getID();
 
       if( effectID == id )
         {
-        if( ++mEffectReturned == total ) effectAction(mPhase);
+        if( ++mEffectReturned == total ) mListener.effectFinished(FAKE_EFFECT_ID);
         mCube.remove(id);
         return;
         }
       }
-    for(int i=0; i<mNodeEffectNumber[mPhase]; i++)
+    for(int i=0; i<mNodeEffectNumber; i++)
       {
-      long id = mNodeEffects[mPhase][i].getID();
+      long id = mNodeEffects[i].getID();
 
       if( effectID == id )
         {
-        if( ++mEffectReturned == total ) effectAction(mPhase);
+        if( ++mEffectReturned == total ) mListener.effectFinished(FAKE_EFFECT_ID);
         mCube.getEffects().abortById(id);
         return;
         }
       }
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void effectAction(int phase)
-    {
-    switch(phase)
-      {
-      case 0: mEffectReturned = 0;
-              mPhase          = 1;
-              mCube.solve();
-              createEffectsPhase1(mDuration);
-              assignEffects(mPhase);
-              break;
-      case 1: mListener.effectFinished(FAKE_EFFECT_ID);
-              break;
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public long start(int duration, RubikRenderer renderer)
@@ -172,36 +139,36 @@ public abstract class WinEffect extends BaseEffect implements EffectListener
     mListener = renderer;
     mDuration = duration;
 
-    createEffectsPhase0(mDuration);
-    assignEffects(mPhase);
+    createEffects(mDuration);
+    assignEffects();
 
     return FAKE_EFFECT_ID;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void assignEffects(int phase)
+  private void assignEffects()
     {
-    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
-    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
+    mCubeEffectNumber = ( mCubeEffects!=null ) ? mCubeEffects.length : 0;
+    mNodeEffectNumber = ( mNodeEffects!=null ) ? mNodeEffects.length : 0;
 
-    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
+    if( mCubeEffectNumber==0 && mNodeEffectNumber==0 )
       {
-      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
+      throw new RuntimeException("Cube and Node Effects both not created!");
       }
 
-    for(int i=0; i<mCubeEffectNumber[phase]; i++)
+    for(int i=0; i<mCubeEffectNumber; i++)
       {
-      mCube.apply(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
-      mCubeEffects[phase][i].notifyWhenFinished(this);
+      mCube.apply(mCubeEffects[i],mCubeEffectPosition[i]);
+      mCubeEffects[i].notifyWhenFinished(this);
       }
 
     DistortedEffects nodeEffects = mCube.getEffects();
 
-    for(int i=0; i<mNodeEffectNumber[phase]; i++)
+    for(int i=0; i<mNodeEffectNumber; i++)
       {
-      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
-      mNodeEffects[phase][i].notifyWhenFinished(this);
+      nodeEffects.apply(mNodeEffects[i],mNodeEffectPosition[i]);
+      mNodeEffects[i].notifyWhenFinished(this);
       }
     }
 
@@ -220,7 +187,7 @@ public abstract class WinEffect extends BaseEffect implements EffectListener
         }
       catch(NoSuchMethodException ex)
         {
-        android.util.Log.e("SolveEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
+        android.util.Log.e("WinEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
         method = null;
         }
 
@@ -230,7 +197,7 @@ public abstract class WinEffect extends BaseEffect implements EffectListener
         }
       catch(Exception ex)
         {
-        android.util.Log.e("SolveEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
+        android.util.Log.e("WinEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
         }
       }
     }
diff --git a/src/main/java/org/distorted/effect/win/WinEffectGlow.java b/src/main/java/org/distorted/effect/win/WinEffectGlow.java
new file mode 100644
index 00000000..eeb748ef
--- /dev/null
+++ b/src/main/java/org/distorted/effect/win/WinEffectGlow.java
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.effect.win;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.PostprocessEffectGlow;
+import org.distorted.library.effect.VertexEffectSink;
+import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic4D;
+import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+
+import static org.distorted.magic.RubikRenderer.TEXTURE_SIZE;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class WinEffectGlow extends WinEffect
+  {
+  private static final int[] colors = new int[] {0,0,1,  1,0,1,  1,0,0,  1,1,0,  0,1,0,  1,1,1}; // blue, pink, red, yellow, green, white
+  private static final int INDEX = 5;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void createEffects(int duration)
+    {
+    mNodeEffectPosition = new int[] {-1, -1};
+    mNodeEffects        = new Effect[mNodeEffectPosition.length];
+
+    Dynamic1D radiusDyn = new Dynamic1D(duration,1.0f);
+    radiusDyn.add(new Static1D( 0));
+    radiusDyn.add(new Static1D(50));
+    radiusDyn.add(new Static1D( 0));
+
+    Dynamic4D color= new Dynamic4D(duration,1.0f);
+    Static4D P1    = new Static4D(colors[3*INDEX],colors[3*INDEX+1], colors[3*INDEX+2], 0.0f);
+    Static4D P2    = new Static4D(colors[3*INDEX],colors[3*INDEX+1], colors[3*INDEX+2], 0.5f);
+    color.add(P1);
+    color.add(P2);
+    color.add(P1);
+
+    mNodeEffects[0] = new PostprocessEffectGlow(radiusDyn,color);
+
+    Dynamic1D degreeDyn= new Dynamic1D(duration,1.0f);
+    degreeDyn.add(new Static1D(1.0f));
+    degreeDyn.add(new Static1D(2.5f));
+    degreeDyn.add(new Static1D(1.0f));
+
+    float centerPoint = TEXTURE_SIZE*0.5f;
+    Static3D center = new Static3D(centerPoint,centerPoint,centerPoint);
+
+    mNodeEffects[1] = new VertexEffectSink(degreeDyn,center);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Effect. Called by reflection from the parent class.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+    PostprocessEffectGlow.enable();
+    VertexEffectSink.enable();
+    }
+  }
diff --git a/src/main/java/org/distorted/effect/win/WinEffectNone.java b/src/main/java/org/distorted/effect/win/WinEffectNone.java
index adebf3ae..c2381345 100644
--- a/src/main/java/org/distorted/effect/win/WinEffectNone.java
+++ b/src/main/java/org/distorted/effect/win/WinEffectNone.java
@@ -19,35 +19,23 @@
 
 package org.distorted.effect.win;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
 
-public class WinEffectNone extends WinEffect
-  {
-  public void createEffectsPhase0(int duration)
-    {
-    Dynamic3D d0 = new Dynamic3D(1,0.5f);
-    d0.add(new Static3D(0,0,0));
-
-    mCubeEffectPosition[0] = new int[] {-1};
-    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
-    mCubeEffects[0][0]     = new MatrixEffectMove(d0);
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void createEffectsPhase1(int duration)
+public class WinEffectNone extends WinEffect
+  {
+  public void createEffects(int duration)
     {
     Dynamic3D d0 = new Dynamic3D(1,0.5f);
     d0.add(new Static3D(0,0,0));
 
-    mCubeEffectPosition[1]  = new int[] {-1};
-    mCubeEffects[1]         = new Effect[mCubeEffectPosition[1].length];
-    mCubeEffects[1][0]      = new MatrixEffectMove(d0);
+    mCubeEffectPosition = new int[] {-1};
+    mCubeEffects        = new Effect[mCubeEffectPosition.length];
+    mCubeEffects[0]     = new MatrixEffectMove(d0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effect/win/WinEffectSpin.java b/src/main/java/org/distorted/effect/win/WinEffectSpin.java
index 24f7dd32..3dec9ee7 100644
--- a/src/main/java/org/distorted/effect/win/WinEffectSpin.java
+++ b/src/main/java/org/distorted/effect/win/WinEffectSpin.java
@@ -19,8 +19,6 @@
 
 package org.distorted.effect.win;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectRotate;
 import org.distorted.library.type.Dynamic;
@@ -28,12 +26,14 @@ import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 public class WinEffectSpin extends WinEffect
   {
-  public void createEffectsPhase0(int duration)
+  public void createEffects(int duration)
     {
-    mCubeEffectPosition[0] = new int[] {3};
-    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+    mCubeEffectPosition = new int[] {3};
+    mCubeEffects        = new Effect[mCubeEffectPosition.length];
 
     Static3D axis  = new Static3D(1,0,0);
     Static3D center= new Static3D(0,0,0);
@@ -46,28 +46,12 @@ public class WinEffectSpin extends WinEffect
     d0.add(new Static1D( 3*36));
     d0.add(new Static1D( 6*36));
     d0.add(new Static1D(10*36));
-    mCubeEffects[0][0] = new MatrixEffectRotate(d0,axis,center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void createEffectsPhase1(int duration)
-    {
-    mCubeEffectPosition[1] = new int[] {3};
-    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
-
-    Static3D axis  = new Static3D(1,0,0);
-    Static3D center= new Static3D(0,0,0);
+    d0.add(new Static1D(14*36));
+    d0.add(new Static1D(17*36));
+    d0.add(new Static1D(19*36));
+    d0.add(new Static1D(20*36));
 
-    Dynamic1D d1 = new Dynamic1D(duration/2, 1.0f);
-    d1.setMode(Dynamic.MODE_JUMP);
-    d1.setConvexity(0.0f);
-    d1.add(new Static1D( 0*36));
-    d1.add(new Static1D( 4*36));
-    d1.add(new Static1D( 7*36));
-    d1.add(new Static1D( 9*36));
-    d1.add(new Static1D(10*36));
-    mCubeEffects[1][0] = new MatrixEffectRotate(d1,axis,center);
+    mCubeEffects[0] = new MatrixEffectRotate(d0,axis,center);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikRenderer.java b/src/main/java/org/distorted/magic/RubikRenderer.java
index 85540442..f77fb873 100644
--- a/src/main/java/org/distorted/magic/RubikRenderer.java
+++ b/src/main/java/org/distorted/magic/RubikRenderer.java
@@ -316,7 +316,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
 
      mEffectID[index] = type.startEffect(this);
 
-     if( mEffectID[index] == -1 )
+     if( mEffectID[index] < 0 )
        {
        mCanUI     = true;
        mCanRotate = true;
