commit 27a0979ff5230990cbaa19467b6fc0d861377bbf
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Jun 8 11:45:50 2020 +0100

    Rename SizeChange to ObjectChange.
    bump version to 1.2.2

diff --git a/build.gradle b/build.gradle
index 27b30c51..be2534f1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,8 +15,8 @@ android {
         applicationId "org.distorted.magic"
         minSdkVersion 21
         targetSdkVersion 29
-        versionCode 8
-        versionName "1.2.1"
+        versionCode 9
+        versionName "1.2.2"
     }
 
     buildTypes {
@@ -35,8 +35,8 @@ android {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    implementation 'com.google.firebase:firebase-analytics:17.4.2'
-    implementation 'com.google.firebase:firebase-crashlytics:17.0.0'
+    implementation 'com.google.firebase:firebase-analytics:17.4.3'
+    implementation 'com.google.firebase:firebase-crashlytics:17.0.1'
 
     api project(':distorted-library')
     implementation 'androidx.appcompat:appcompat:1.1.0'
diff --git a/src/main/java/org/distorted/effects/BaseEffect.java b/src/main/java/org/distorted/effects/BaseEffect.java
index 5aced68f..e20a4fc3 100644
--- a/src/main/java/org/distorted/effects/BaseEffect.java
+++ b/src/main/java/org/distorted/effects/BaseEffect.java
@@ -24,7 +24,7 @@ import java.lang.reflect.Method;
 import android.content.SharedPreferences;
 
 import org.distorted.effects.scramble.ScrambleEffect;
-import org.distorted.effects.sizechange.SizeChangeEffect;
+import org.distorted.effects.objectchange.ObjectChangeEffect;
 import org.distorted.effects.solve.SolveEffect;
 import org.distorted.effects.win.WinEffect;
 import org.distorted.library.main.DistortedScreen;
@@ -37,7 +37,7 @@ public class BaseEffect
   {
   public enum Type
     {
-    SIZECHANGE  ( 20, 1, R.string.sizechange_effect , SizeChangeEffect.class),
+    SIZECHANGE  ( 20, 1, R.string.objectchange_effect, ObjectChangeEffect.class),
     SOLVE       ( 20, 1, R.string.solve_effect      , SolveEffect.class     ),
     SCRAMBLE    ( 60, 1, R.string.scramble_effect   , ScrambleEffect.class  ),
     WIN         ( 20, 1, R.string.win_effect        , WinEffect.class       ),
diff --git a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java
new file mode 100644
index 00000000..21ba74ca
--- /dev/null
+++ b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java
@@ -0,0 +1,281 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effects.objectchange;
+
+import org.distorted.effects.BaseEffect;
+import org.distorted.library.effect.Effect;
+import org.distorted.library.main.DistortedEffects;
+import org.distorted.library.main.DistortedScreen;
+import org.distorted.library.message.EffectListener;
+import org.distorted.main.RubikPostRender;
+import org.distorted.objects.RubikObject;
+
+import java.lang.reflect.Method;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public abstract class ObjectChangeEffect extends BaseEffect implements EffectListener
+{
+  public enum Type
+    {
+    NONE         (ObjectChangeEffectNone.class        ),
+    TRANSPARENCY (ObjectChangeEffectTransparency.class),
+    MOVE         (ObjectChangeEffectMove.class        ),
+    ROUND        (ObjectChangeEffectRound.class       ),
+    SCALE        (ObjectChangeEffectScale.class       ),
+    ;
+
+    final Class<? extends ObjectChangeEffect> effect;
+
+    Type(Class<? extends ObjectChangeEffect> effect)
+      {
+      this.effect= effect;
+      }
+    }
+
+  private static int NUM_EFFECTS = Type.values().length;
+  private static final int NUM_PHASES  = 2;
+  private static final int FAKE_EFFECT_ID  = -1;
+  private static final Type[] types;
+
+  static
+    {
+    int i=0;
+    types = new Type[NUM_EFFECTS];
+
+    for(Type type: Type.values())
+      {
+      types[i++] = type;
+      }
+    }
+
+  private EffectListener mListener;
+  private int mDuration;
+  private int[] mEffectReturned;
+  private int[] mCubeEffectNumber, mNodeEffectNumber;
+  private int[] mEffectFinished;
+  private boolean[] mPhaseActive;
+  private RubikObject[] mObject;
+
+  DistortedScreen mScreen;
+  Effect[][] mCubeEffects;
+  int[][] mCubeEffectPosition;
+  Effect[][] mNodeEffects;
+  int[][] mNodeEffectPosition;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectChangeEffect()
+    {
+    mPhaseActive        = new boolean[NUM_PHASES];
+    mEffectReturned     = new int[NUM_PHASES];
+    mCubeEffectNumber   = new int[NUM_PHASES];
+    mNodeEffectNumber   = new int[NUM_PHASES];
+    mEffectFinished     = new int[NUM_PHASES];
+    mCubeEffectPosition = new int[NUM_PHASES][];
+    mNodeEffectPosition = new int[NUM_PHASES][];
+    mCubeEffects        = new Effect[NUM_PHASES][];
+    mNodeEffects        = new Effect[NUM_PHASES][];
+    mObject             = new RubikObject[NUM_PHASES];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  abstract int createEffectsPhase0(int duration);
+  abstract int createEffectsPhase1(int duration);
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void effectFinishedPhase(final long effectID, int phase)
+    {
+    for(int i=0; i<mCubeEffectNumber[phase]; i++)
+      {
+      long id = mCubeEffects[phase][i].getID();
+
+      if( effectID == id )
+        {
+        effectReturned(phase);
+        mObject[phase].remove(id);
+        return;
+        }
+      }
+    for(int i=0; i<mNodeEffectNumber[phase]; i++)
+      {
+      long id = mNodeEffects[phase][i].getID();
+
+      if( effectID == id )
+        {
+        effectReturned(phase);
+        mObject[phase].getEffects().abortById(id);
+        return;
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void effectReturned(int phase)
+    {
+    mEffectReturned[phase]++;
+
+    if( mEffectReturned[phase] == mEffectFinished[phase] )
+      {
+      switch(phase)
+        {
+        case 0: mPhaseActive[1] = true;
+                mEffectFinished[1] = createEffectsPhase1(mDuration);
+                assignEffects(1);
+                mScreen.attach(mObject[1]);
+                break;
+        case 1: mListener.effectFinished(FAKE_EFFECT_ID);
+                break;
+        }
+      }
+    if( mEffectReturned[phase] == mCubeEffectNumber[phase]+mNodeEffectNumber[phase] )
+      {
+      switch(phase)
+        {
+        case 0: mPhaseActive[0] = false;
+                mScreen.detach(mObject[0]);
+                break;
+        case 1: mPhaseActive[1] = false;
+                break;
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void assignEffects(int phase)
+    {
+    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
+    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
+
+    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
+      {
+      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
+      }
+
+    for(int i=0; i<mCubeEffectNumber[phase]; i++)
+      {
+      mObject[phase].apply(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
+      mCubeEffects[phase][i].notifyWhenFinished(this);
+      }
+
+    DistortedEffects nodeEffects = mObject[phase].getEffects();
+
+    for(int i=0; i<mNodeEffectNumber[phase]; i++)
+      {
+      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
+      mNodeEffects[phase][i].notifyWhenFinished(this);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void effectFinished(final long effectID)
+    {
+    if( mPhaseActive[0] ) effectFinishedPhase(effectID,0);
+    if( mPhaseActive[1] ) effectFinishedPhase(effectID,1);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @SuppressWarnings("unused")
+  public static String[] getNames()
+    {
+    String[] names = new String[NUM_EFFECTS];
+
+    for( int i=0; i<NUM_EFFECTS; i++)
+      {
+      names[i] = types[i].name();
+      }
+
+    return names;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @SuppressWarnings("unused")
+  public static ObjectChangeEffect create(int ordinal) throws InstantiationException, IllegalAccessException
+    {
+    return types[ordinal].effect.newInstance();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @SuppressWarnings("unused")
+  public long start(int duration, DistortedScreen screen, RubikPostRender post)
+    {
+    mScreen   = screen;
+    mObject[0]= post.getOldObject();
+    mObject[1]= post.getObject();
+    mListener = post;
+    mDuration = duration;
+
+    if( mObject[0]!=null )
+      {
+      mPhaseActive[0] = true;
+      mEffectFinished[0] = createEffectsPhase0(mDuration);
+      assignEffects(0);
+      }
+    else
+      {
+      mPhaseActive[1] = true;
+      mEffectFinished[1] = createEffectsPhase1(mDuration);
+      assignEffects(1);
+      mScreen.attach(mObject[1]);
+      }
+
+    return FAKE_EFFECT_ID;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @SuppressWarnings("unused")
+  public static void enableEffects()
+    {
+    Method method;
+
+    for(Type type: Type.values())
+      {
+      try
+        {
+        method = type.effect.getDeclaredMethod("enable");  // enable not public, thus getDeclaredMethod
+        }
+      catch(NoSuchMethodException ex)
+        {
+        android.util.Log.e("SizeChangeEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
+        method = null;
+        }
+
+      try
+        {
+        if( method!=null ) method.invoke(null);
+        }
+      catch(Exception ex)
+        {
+        android.util.Log.e("SizeChangeEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
+        }
+      }
+    }
+}
diff --git a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectMove.java b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectMove.java
new file mode 100644
index 00000000..9a9da892
--- /dev/null
+++ b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectMove.java
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effects.objectchange;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectMove;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ObjectChangeEffectMove extends ObjectChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    int w = mScreen.getWidth();
+    int h = mScreen.getHeight();
+    int xmove = w/2 + (w<h?w:h)/2;
+
+    mNodeEffectPosition[0] = new int[] {1};
+    mNodeEffects[0]        = new Effect[mNodeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
+    d0.add(new Static3D(    0,0,0));
+    d0.add(new Static3D(xmove,0,0));
+    mNodeEffects[0][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    int w = mScreen.getWidth();
+    int h = mScreen.getHeight();
+    int xmove = w/2 + (w<h?w:h)/2;
+
+    mNodeEffectPosition[1] = new int[] {1};
+    mNodeEffects[1]        = new Effect[mNodeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
+    d0.add(new Static3D(-xmove,0,0));
+    d0.add(new Static3D(     0,0,0));
+    mNodeEffects[1][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Effect. Called by reflection from the parent class.
+// Matrix Effects do not have to be enabled.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
+
diff --git a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectNone.java b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectNone.java
new file mode 100644
index 00000000..3502135d
--- /dev/null
+++ b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectNone.java
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effects.objectchange;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectMove;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ObjectChangeEffectNone extends ObjectChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    mCubeEffectPosition[0] = new int[] {-1};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(1,0.5f);
+    d0.add(new Static3D(0,0,0));
+    mCubeEffects[0][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    mCubeEffectPosition[1] = new int[] {-1};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(1,0.5f);
+    d0.add(new Static3D(0,0,0));
+    mCubeEffects[1][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// enable all effects used in this Effect (here: none).  Called by reflection from the parent class.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
diff --git a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectRound.java b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectRound.java
new file mode 100644
index 00000000..a238dfab
--- /dev/null
+++ b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectRound.java
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effects.objectchange;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectMove;
+import org.distorted.library.effect.MatrixEffectScale;
+import org.distorted.library.type.Dynamic;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+import static org.distorted.objects.RubikObject.NODE_FBO_SIZE;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ObjectChangeEffectRound extends ObjectChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    float X = NODE_FBO_SIZE /3;
+
+    mCubeEffectPosition[0] = new int[] {6,7};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
+    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
+    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
+    mCubeEffects[0][0] = new MatrixEffectScale(d0);
+
+    Dynamic3D d1 = new Dynamic3D(duration/2, 0.5f);
+    d1.setMode(Dynamic.MODE_PATH);
+    d1.add(new Static3D( 0, 0, 0));
+    d1.add(new Static3D(+X, 0, 0));
+    d1.add(new Static3D( 0, 0, 0));
+    mCubeEffects[0][1] = new MatrixEffectMove(d1);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    float X = NODE_FBO_SIZE /3;
+
+    mCubeEffectPosition[1] = new int[] {6,7};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
+    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
+    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
+    mCubeEffects[1][0] = new MatrixEffectScale(d0);
+
+    Dynamic3D d1 = new Dynamic3D(duration/2, 0.5f);
+    d1.setMode(Dynamic.MODE_PATH);
+    d1.add(new Static3D( 0, 0, 0));
+    d1.add(new Static3D(-X, 0, 0));
+    d1.add(new Static3D( 0, 0, 0));
+    mCubeEffects[1][1] = new MatrixEffectMove(d1);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Effect. Called by reflection from the parent class.
+// Matrix Effects do not have to be enabled.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
+
diff --git a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectScale.java b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectScale.java
new file mode 100644
index 00000000..cfe3ea33
--- /dev/null
+++ b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectScale.java
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effects.objectchange;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectScale;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ObjectChangeEffectScale extends ObjectChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    mCubeEffectPosition[0] = new int[] {6};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
+    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
+    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
+    mCubeEffects[0][0] = new MatrixEffectScale(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    mCubeEffectPosition[1] = new int[] {6};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
+    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
+    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
+    mCubeEffects[1][0] = new MatrixEffectScale(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Effect. Called by reflection from the parent class.
+// Matrix Effects do not have to be enabled.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
+
diff --git a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectTransparency.java b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectTransparency.java
new file mode 100644
index 00000000..12ad6639
--- /dev/null
+++ b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffectTransparency.java
@@ -0,0 +1,100 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.effects.objectchange;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.FragmentEffectAlpha;
+import org.distorted.library.effect.VertexEffectWave;
+import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic5D;
+import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static5D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ObjectChangeEffectTransparency extends ObjectChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    mNodeEffectPosition[0] = new int[] {-1,-1};
+    mNodeEffects[0]        = new Effect[mNodeEffectPosition[0].length];
+
+    float init_amplitude = 0.0f;
+    float end_amplitude  = 1/8.0f;
+    float length         = 1/8.0f;
+    float init_phase     = 360.0f;
+    float end_phase      = 0.0f;
+    float alpha          = 30.0f;
+    float beta           = 90.0f;
+
+    Dynamic5D d1 = new Dynamic5D(duration/2, 0.5f);
+    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
+    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
+    Static3D center = new Static3D(0,0,0);
+    mNodeEffects[0][0] = new VertexEffectWave(d1, center, null);
+
+    Dynamic1D d0 = new Dynamic1D(duration/2, 0.5f);
+    d0.add(new Static1D(1.0f));
+    d0.add(new Static1D(0.0f));
+    mNodeEffects[0][1] = new FragmentEffectAlpha(d0);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    mNodeEffectPosition[1] = new int[] {-1,-1};
+    mNodeEffects[1]        = new Effect[mNodeEffectPosition[1].length];
+
+    float init_amplitude = 1/8.0f;
+    float end_amplitude  = 0.0f;
+    float length         = 1/8.0f;
+    float init_phase     = 0.0f;
+    float end_phase      = 360.0f;
+    float alpha          = 30.0f;
+    float beta           = 90.0f;
+
+    Dynamic5D d1 = new Dynamic5D(duration/2, 0.5f);
+    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
+    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
+    Static3D center = new Static3D(0,0,0);
+    mNodeEffects[1][0] = new VertexEffectWave(d1, center, null);
+
+    Dynamic1D d0 = new Dynamic1D(duration/2, 0.5f);
+    d0.add(new Static1D(0.0f));
+    d0.add(new Static1D(1.0f));
+    mNodeEffects[1][1] = new FragmentEffectAlpha(d0);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Effect. Called by reflection from the parent class.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+    FragmentEffectAlpha.enable();
+    VertexEffectWave.enable();
+    }
+  }
diff --git a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffect.java b/src/main/java/org/distorted/effects/sizechange/SizeChangeEffect.java
deleted file mode 100644
index 4e7faa60..00000000
--- a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffect.java
+++ /dev/null
@@ -1,281 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.effects.sizechange;
-
-import org.distorted.effects.BaseEffect;
-import org.distorted.library.effect.Effect;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedScreen;
-import org.distorted.library.message.EffectListener;
-import org.distorted.main.RubikPostRender;
-import org.distorted.objects.RubikObject;
-
-import java.lang.reflect.Method;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class SizeChangeEffect extends BaseEffect implements EffectListener
-{
-  public enum Type
-    {
-    NONE         (SizeChangeEffectNone.class        ),
-    TRANSPARENCY (SizeChangeEffectTransparency.class),
-    MOVE         (SizeChangeEffectMove.class        ),
-    ROUND        (SizeChangeEffectRound.class       ),
-    SCALE        (SizeChangeEffectScale.class       ),
-    ;
-
-    final Class<? extends SizeChangeEffect> effect;
-
-    Type(Class<? extends SizeChangeEffect> effect)
-      {
-      this.effect= effect;
-      }
-    }
-
-  private static int NUM_EFFECTS = Type.values().length;
-  private static final int NUM_PHASES  = 2;
-  private static final int FAKE_EFFECT_ID  = -1;
-  private static final Type[] types;
-
-  static
-    {
-    int i=0;
-    types = new Type[NUM_EFFECTS];
-
-    for(Type type: Type.values())
-      {
-      types[i++] = type;
-      }
-    }
-
-  private EffectListener mListener;
-  private int mDuration;
-  private int[] mEffectReturned;
-  private int[] mCubeEffectNumber, mNodeEffectNumber;
-  private int[] mEffectFinished;
-  private boolean[] mPhaseActive;
-  private RubikObject[] mObject;
-
-  DistortedScreen mScreen;
-  Effect[][] mCubeEffects;
-  int[][] mCubeEffectPosition;
-  Effect[][] mNodeEffects;
-  int[][] mNodeEffectPosition;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  SizeChangeEffect()
-    {
-    mPhaseActive        = new boolean[NUM_PHASES];
-    mEffectReturned     = new int[NUM_PHASES];
-    mCubeEffectNumber   = new int[NUM_PHASES];
-    mNodeEffectNumber   = new int[NUM_PHASES];
-    mEffectFinished     = new int[NUM_PHASES];
-    mCubeEffectPosition = new int[NUM_PHASES][];
-    mNodeEffectPosition = new int[NUM_PHASES][];
-    mCubeEffects        = new Effect[NUM_PHASES][];
-    mNodeEffects        = new Effect[NUM_PHASES][];
-    mObject             = new RubikObject[NUM_PHASES];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  abstract int createEffectsPhase0(int duration);
-  abstract int createEffectsPhase1(int duration);
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void effectFinishedPhase(final long effectID, int phase)
-    {
-    for(int i=0; i<mCubeEffectNumber[phase]; i++)
-      {
-      long id = mCubeEffects[phase][i].getID();
-
-      if( effectID == id )
-        {
-        effectReturned(phase);
-        mObject[phase].remove(id);
-        return;
-        }
-      }
-    for(int i=0; i<mNodeEffectNumber[phase]; i++)
-      {
-      long id = mNodeEffects[phase][i].getID();
-
-      if( effectID == id )
-        {
-        effectReturned(phase);
-        mObject[phase].getEffects().abortById(id);
-        return;
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void effectReturned(int phase)
-    {
-    mEffectReturned[phase]++;
-
-    if( mEffectReturned[phase] == mEffectFinished[phase] )
-      {
-      switch(phase)
-        {
-        case 0: mPhaseActive[1] = true;
-                mEffectFinished[1] = createEffectsPhase1(mDuration);
-                assignEffects(1);
-                mScreen.attach(mObject[1]);
-                break;
-        case 1: mListener.effectFinished(FAKE_EFFECT_ID);
-                break;
-        }
-      }
-    if( mEffectReturned[phase] == mCubeEffectNumber[phase]+mNodeEffectNumber[phase] )
-      {
-      switch(phase)
-        {
-        case 0: mPhaseActive[0] = false;
-                mScreen.detach(mObject[0]);
-                break;
-        case 1: mPhaseActive[1] = false;
-                break;
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void assignEffects(int phase)
-    {
-    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
-    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
-
-    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
-      {
-      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
-      }
-
-    for(int i=0; i<mCubeEffectNumber[phase]; i++)
-      {
-      mObject[phase].apply(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
-      mCubeEffects[phase][i].notifyWhenFinished(this);
-      }
-
-    DistortedEffects nodeEffects = mObject[phase].getEffects();
-
-    for(int i=0; i<mNodeEffectNumber[phase]; i++)
-      {
-      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
-      mNodeEffects[phase][i].notifyWhenFinished(this);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void effectFinished(final long effectID)
-    {
-    if( mPhaseActive[0] ) effectFinishedPhase(effectID,0);
-    if( mPhaseActive[1] ) effectFinishedPhase(effectID,1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @SuppressWarnings("unused")
-  public static String[] getNames()
-    {
-    String[] names = new String[NUM_EFFECTS];
-
-    for( int i=0; i<NUM_EFFECTS; i++)
-      {
-      names[i] = types[i].name();
-      }
-
-    return names;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @SuppressWarnings("unused")
-  public static SizeChangeEffect create(int ordinal) throws InstantiationException, IllegalAccessException
-    {
-    return types[ordinal].effect.newInstance();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @SuppressWarnings("unused")
-  public long start(int duration, DistortedScreen screen, RubikPostRender post)
-    {
-    mScreen   = screen;
-    mObject[0]= post.getOldObject();
-    mObject[1]= post.getObject();
-    mListener = post;
-    mDuration = duration;
-
-    if( mObject[0]!=null )
-      {
-      mPhaseActive[0] = true;
-      mEffectFinished[0] = createEffectsPhase0(mDuration);
-      assignEffects(0);
-      }
-    else
-      {
-      mPhaseActive[1] = true;
-      mEffectFinished[1] = createEffectsPhase1(mDuration);
-      assignEffects(1);
-      mScreen.attach(mObject[1]);
-      }
-
-    return FAKE_EFFECT_ID;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @SuppressWarnings("unused")
-  public static void enableEffects()
-    {
-    Method method;
-
-    for(Type type: Type.values())
-      {
-      try
-        {
-        method = type.effect.getDeclaredMethod("enable");  // enable not public, thus getDeclaredMethod
-        }
-      catch(NoSuchMethodException ex)
-        {
-        android.util.Log.e("SizeChangeEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
-        method = null;
-        }
-
-      try
-        {
-        if( method!=null ) method.invoke(null);
-        }
-      catch(Exception ex)
-        {
-        android.util.Log.e("SizeChangeEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
-        }
-      }
-    }
-}
diff --git a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectMove.java b/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectMove.java
deleted file mode 100644
index 77d6af3d..00000000
--- a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectMove.java
+++ /dev/null
@@ -1,77 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.effects.sizechange;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectMove extends SizeChangeEffect
-  {
-  public int createEffectsPhase0(int duration)
-    {
-    int w = mScreen.getWidth();
-    int h = mScreen.getHeight();
-    int xmove = w/2 + (w<h?w:h)/2;
-
-    mNodeEffectPosition[0] = new int[] {1};
-    mNodeEffects[0]        = new Effect[mNodeEffectPosition[0].length];
-
-    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
-    d0.add(new Static3D(    0,0,0));
-    d0.add(new Static3D(xmove,0,0));
-    mNodeEffects[0][0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int createEffectsPhase1(int duration)
-    {
-    int w = mScreen.getWidth();
-    int h = mScreen.getHeight();
-    int xmove = w/2 + (w<h?w:h)/2;
-
-    mNodeEffectPosition[1] = new int[] {1};
-    mNodeEffects[1]        = new Effect[mNodeEffectPosition[1].length];
-
-    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
-    d0.add(new Static3D(-xmove,0,0));
-    d0.add(new Static3D(     0,0,0));
-    mNodeEffects[1][0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Effect. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectNone.java b/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectNone.java
deleted file mode 100644
index 0d35d48f..00000000
--- a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectNone.java
+++ /dev/null
@@ -1,65 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.effects.sizechange;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectNone extends SizeChangeEffect
-  {
-  public int createEffectsPhase0(int duration)
-    {
-    mCubeEffectPosition[0] = new int[] {-1};
-    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
-
-    Dynamic3D d0 = new Dynamic3D(1,0.5f);
-    d0.add(new Static3D(0,0,0));
-    mCubeEffects[0][0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int createEffectsPhase1(int duration)
-    {
-    mCubeEffectPosition[1] = new int[] {-1};
-    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
-
-    Dynamic3D d0 = new Dynamic3D(1,0.5f);
-    d0.add(new Static3D(0,0,0));
-    mCubeEffects[1][0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// enable all effects used in this Effect (here: none).  Called by reflection from the parent class.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
diff --git a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectRound.java b/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectRound.java
deleted file mode 100644
index 5a32158b..00000000
--- a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectRound.java
+++ /dev/null
@@ -1,91 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.effects.sizechange;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.type.Dynamic;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-import static org.distorted.objects.RubikObject.NODE_FBO_SIZE;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectRound extends SizeChangeEffect
-  {
-  public int createEffectsPhase0(int duration)
-    {
-    float X = NODE_FBO_SIZE /3;
-
-    mCubeEffectPosition[0] = new int[] {6,7};
-    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
-
-    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
-    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
-    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
-    mCubeEffects[0][0] = new MatrixEffectScale(d0);
-
-    Dynamic3D d1 = new Dynamic3D(duration/2, 0.5f);
-    d1.setMode(Dynamic.MODE_PATH);
-    d1.add(new Static3D( 0, 0, 0));
-    d1.add(new Static3D(+X, 0, 0));
-    d1.add(new Static3D( 0, 0, 0));
-    mCubeEffects[0][1] = new MatrixEffectMove(d1);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int createEffectsPhase1(int duration)
-    {
-    float X = NODE_FBO_SIZE /3;
-
-    mCubeEffectPosition[1] = new int[] {6,7};
-    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
-
-    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
-    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
-    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
-    mCubeEffects[1][0] = new MatrixEffectScale(d0);
-
-    Dynamic3D d1 = new Dynamic3D(duration/2, 0.5f);
-    d1.setMode(Dynamic.MODE_PATH);
-    d1.add(new Static3D( 0, 0, 0));
-    d1.add(new Static3D(-X, 0, 0));
-    d1.add(new Static3D( 0, 0, 0));
-    mCubeEffects[1][1] = new MatrixEffectMove(d1);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Effect. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectScale.java b/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectScale.java
deleted file mode 100644
index b2ec5a84..00000000
--- a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectScale.java
+++ /dev/null
@@ -1,69 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.effects.sizechange;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectScale extends SizeChangeEffect
-  {
-  public int createEffectsPhase0(int duration)
-    {
-    mCubeEffectPosition[0] = new int[] {6};
-    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
-
-    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
-    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
-    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
-    mCubeEffects[0][0] = new MatrixEffectScale(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int createEffectsPhase1(int duration)
-    {
-    mCubeEffectPosition[1] = new int[] {6};
-    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
-
-    Dynamic3D d0 = new Dynamic3D(duration/2, 0.5f);
-    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
-    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
-    mCubeEffects[1][0] = new MatrixEffectScale(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Effect. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectTransparency.java b/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectTransparency.java
deleted file mode 100644
index 1141e0ba..00000000
--- a/src/main/java/org/distorted/effects/sizechange/SizeChangeEffectTransparency.java
+++ /dev/null
@@ -1,100 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.effects.sizechange;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.FragmentEffectAlpha;
-import org.distorted.library.effect.VertexEffectWave;
-import org.distorted.library.type.Dynamic1D;
-import org.distorted.library.type.Dynamic5D;
-import org.distorted.library.type.Static1D;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static5D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectTransparency extends SizeChangeEffect
-  {
-  public int createEffectsPhase0(int duration)
-    {
-    mNodeEffectPosition[0] = new int[] {-1,-1};
-    mNodeEffects[0]        = new Effect[mNodeEffectPosition[0].length];
-
-    float init_amplitude = 0.0f;
-    float end_amplitude  = 1/8.0f;
-    float length         = 1/8.0f;
-    float init_phase     = 360.0f;
-    float end_phase      = 0.0f;
-    float alpha          = 30.0f;
-    float beta           = 90.0f;
-
-    Dynamic5D d1 = new Dynamic5D(duration/2, 0.5f);
-    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
-    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
-    Static3D center = new Static3D(0,0,0);
-    mNodeEffects[0][0] = new VertexEffectWave(d1, center, null);
-
-    Dynamic1D d0 = new Dynamic1D(duration/2, 0.5f);
-    d0.add(new Static1D(1.0f));
-    d0.add(new Static1D(0.0f));
-    mNodeEffects[0][1] = new FragmentEffectAlpha(d0);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int createEffectsPhase1(int duration)
-    {
-    mNodeEffectPosition[1] = new int[] {-1,-1};
-    mNodeEffects[1]        = new Effect[mNodeEffectPosition[1].length];
-
-    float init_amplitude = 1/8.0f;
-    float end_amplitude  = 0.0f;
-    float length         = 1/8.0f;
-    float init_phase     = 0.0f;
-    float end_phase      = 360.0f;
-    float alpha          = 30.0f;
-    float beta           = 90.0f;
-
-    Dynamic5D d1 = new Dynamic5D(duration/2, 0.5f);
-    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
-    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
-    Static3D center = new Static3D(0,0,0);
-    mNodeEffects[1][0] = new VertexEffectWave(d1, center, null);
-
-    Dynamic1D d0 = new Dynamic1D(duration/2, 0.5f);
-    d0.add(new Static1D(0.0f));
-    d0.add(new Static1D(1.0f));
-    mNodeEffects[1][1] = new FragmentEffectAlpha(d0);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Effect. Called by reflection from the parent class.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-    FragmentEffectAlpha.enable();
-    VertexEffectWave.enable();
-    }
-  }
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index 06a6394d..82c3b408 100755
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">SIE</string>
     <string name="solution">Lösung</string>
     <string name="ready">Bereit?</string>
-    <string name="sizechange_effect">Effekt Größenänderung</string>
+    <string name="objectchange_effect">Effekt Größenänderung</string>
     <string name="solve_effect">Effekt Lösen</string>
     <string name="scramble_effect">Effekt Verdrehen</string>
     <string name="win_effect">Effekt Gewinnen</string>
diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml
index 449f10fb..80c35174 100755
--- a/src/main/res/values-es/strings.xml
+++ b/src/main/res/values-es/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">TÚ</string>
     <string name="solution">Solución</string>
     <string name="ready">¿Listo?</string>
-    <string name="sizechange_effect">Efecto de cambio de tamaño</string>
+    <string name="objectchange_effect">Efecto de cambio de tamaño</string>
     <string name="solve_effect">Efecto de solución</string>
     <string name="scramble_effect">Efecto de revolver</string>
     <string name="win_effect">Efecto ganador</string>
diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml
index a3f66cd6..b97eea4b 100755
--- a/src/main/res/values-fr/strings.xml
+++ b/src/main/res/values-fr/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">VOUS</string>
     <string name="solution">Solution</string>
     <string name="ready">Prêt ?</string>
-    <string name="sizechange_effect">Effet de changement de taille</string>
+    <string name="objectchange_effect">Effet de changement de taille</string>
     <string name="solve_effect">Effet de résolution</string>
     <string name="scramble_effect">Effet de brouillage</string>
     <string name="win_effect">Effet de victoire</string>
diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml
index 72d68b47..bfa6d591 100755
--- a/src/main/res/values-it/strings.xml
+++ b/src/main/res/values-it/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">TU</string>
     <string name="solution">Soluzione</string>
     <string name="ready">Sei pronto?</string>
-    <string name="sizechange_effect">Effetto cambio di dimensioni</string>
+    <string name="objectchange_effect">Effetto cambio di dimensioni</string>
     <string name="solve_effect">Risolvi l\'effetto</string>
     <string name="scramble_effect">Rimescola l\'effetto</string>
     <string name="win_effect">Vinci l\'effetto</string>
diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml
index 851d5f5d..f4dadebf 100755
--- a/src/main/res/values-ja/strings.xml
+++ b/src/main/res/values-ja/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">あなた</string>
     <string name="solution">解答</string>
     <string name="ready">準備はいいですか？</string>
-    <string name="sizechange_effect">サイズ変更のエフェクト</string>
+    <string name="objectchange_effect">サイズ変更のエフェクト</string>
     <string name="solve_effect">解答のエフェクト</string>
     <string name="scramble_effect">スクランブルのエフェクト</string>
     <string name="win_effect">勝利のエフェクト</string>
diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml
index cef5c417..a6078c7b 100755
--- a/src/main/res/values-ko/strings.xml
+++ b/src/main/res/values-ko/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">나</string>
     <string name="solution">해결</string>
     <string name="ready">준비되셨나요?</string>
-    <string name="sizechange_effect">크기 변화 효과</string>
+    <string name="objectchange_effect">크기 변화 효과</string>
     <string name="solve_effect">해결 효과</string>
     <string name="scramble_effect">스크램블 효과</string>
     <string name="win_effect">승리 효과</string>
diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml
index 026f57c3..09e5d843 100644
--- a/src/main/res/values-pl/strings.xml
+++ b/src/main/res/values-pl/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">TY</string>
     <string name="solution">Rozwiązanie</string>
     <string name="ready">Gotowy?</string>
-    <string name="sizechange_effect">Efekt Zmiany</string>
+    <string name="objectchange_effect">Efekt Zmiany</string>
     <string name="solve_effect">Efekt Rozwiązania</string>
     <string name="scramble_effect">Efekt Pomieszania</string>
     <string name="win_effect">Efekt Zwycięstwa</string>
diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml
index 407f3548..08e71685 100755
--- a/src/main/res/values-ru/strings.xml
+++ b/src/main/res/values-ru/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">ВЫ</string>
     <string name="solution">Решение</string>
     <string name="ready">Готовы?</string>
-    <string name="sizechange_effect">Эффект изменения размера</string>
+    <string name="objectchange_effect">Эффект изменения размера</string>
     <string name="solve_effect">Эффект решения</string>
     <string name="scramble_effect">Эффект скрамбла</string>
     <string name="win_effect">Эффект победы</string>
diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml
index 0f121259..314fc4cc 100644
--- a/src/main/res/values-zh-rCN/strings.xml
+++ b/src/main/res/values-zh-rCN/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">你</string>
     <string name="solution">解决方案</string>
     <string name="ready">准备就绪？</string>
-    <string name="sizechange_effect">尺寸变化效果</string>
+    <string name="objectchange_effect">尺寸变化效果</string>
     <string name="solve_effect">解决效果</string>
     <string name="scramble_effect">搅混效果</string>
     <string name="win_effect">胜利效果</string>
diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml
index e271d242..c4749bb5 100644
--- a/src/main/res/values-zh-rTW/strings.xml
+++ b/src/main/res/values-zh-rTW/strings.xml
@@ -22,7 +22,7 @@
     <string name="you">你</string>
     <string name="solution">解决方案</string>
     <string name="ready">準備好了？</string>
-    <string name="sizechange_effect">尺寸變化效果</string>
+    <string name="objectchange_effect">尺寸變化效果</string>
     <string name="solve_effect">解决效果</string>
     <string name="scramble_effect">攪混效果</string>
     <string name="win_effect">勝利效果</string>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 459572fe..f31e65b3 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -24,7 +24,7 @@
     <string name="you">YOU</string>
     <string name="solution">Solution</string>
     <string name="ready">Ready?</string>
-    <string name="sizechange_effect">Size Change Effect</string>
+    <string name="objectchange_effect">Object Change Effect</string>
     <string name="solve_effect">Solve Effect</string>
     <string name="scramble_effect">Scramble Effect</string>
     <string name="win_effect">Win Effect</string>
