commit b62eb334703a66561cad405bddff0a5da5a7b137
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sun Apr 7 19:22:16 2019 +0100

    Many things.
    
    1) make the Dynamic.setDuration() able to be called AFTER the Dynamic has already been run. (and rename it to 'makeRunNowFor()' )
    2) remove the automatic removal of zero Effects from EffectQueues.
    3) adjust several Apps to cope with 2)
    4) add post-rotation to Rubik (still not finished)

diff --git a/src/main/java/org/distorted/examples/deform/DeformRenderer.java b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
index 3b8d167..8bfb148 100644
--- a/src/main/java/org/distorted/examples/deform/DeformRenderer.java
+++ b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
@@ -34,6 +34,8 @@ import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.mesh.MeshFlat;
 
+import org.distorted.library.message.EffectListener;
+import org.distorted.library.message.EffectMessage;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
@@ -46,15 +48,15 @@ import android.opengl.GLSurfaceView;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-class DeformRenderer implements GLSurfaceView.Renderer 
+class DeformRenderer implements GLSurfaceView.Renderer , EffectListener
    {
    private static final int NUM_VECTORS =  8;
    private static final int NUM_LINES   = 10;
 
    private GLSurfaceView mView;
-   private DistortedTexture stretchTexture;
-   private DistortedEffects stretchEffects;
-   private MeshBase stretchMesh;
+   private DistortedTexture mTexture;
+   private DistortedEffects mEffects;
+   private MeshBase mMesh;
    private DistortedScreen mScreen;
    private Static3D mTouchPoint;
 
@@ -80,11 +82,13 @@ class DeformRenderer implements GLSurfaceView.Renderer
       { 
       mView = view;
 
-      stretchEffects = new DistortedEffects();
+      mEffects    = new DistortedEffects();
       mRegion     = new Static4D(0,0,0,0);
       mMove       = new Static3D(0,0,0);
       mTouchPoint = new Static3D(0,0,0);
 
+      mEffects.registerForMessages(this);
+
       // DISTORT
       Dynamic3D releasedDistortDynamic = new Dynamic3D(NUM_VECTORS*500, 0.5f);
       releasedDistortDynamic.setMode(Dynamic3D.MODE_PATH);
@@ -143,7 +147,7 @@ class DeformRenderer implements GLSurfaceView.Renderer
       mReleasedDeform  = new VertexEffectDeform ( releasedDeformDynamic , mTouchPoint, mRegion);
       mReleasedShear   = new MatrixEffectShear  ( releasedShearDynamic  , mTouchPoint         );
 
-      stretchEffects.apply(new MatrixEffectMove(mMove));
+      mEffects.apply(new MatrixEffectMove(mMove));
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -161,6 +165,18 @@ class DeformRenderer implements GLSurfaceView.Renderer
       mRegion.set4(mRadius*scrWidth);
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// keep aborting the 'released' effects, otherwise we are quickly going to run out of room in
+// effect queues.
+
+   public void effectMessage(final EffectMessage em, final long effectID, final long objectID)
+     {
+     switch(em)
+        {
+        case EFFECT_FINISHED: mEffects.abortById(effectID); break;
+        }
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
    public void onDrawFrame(GL10 glUnused)
@@ -181,9 +197,9 @@ class DeformRenderer implements GLSurfaceView.Renderer
      int w=width/2;
      int h=height/2;
 
-     if( stretchMesh!=null ) stretchMesh.markForDeletion();
+     if( mMesh!=null ) mMesh.markForDeletion();
 
-     stretchMesh = new MeshFlat(50,50*h/w);
+     mMesh = new MeshFlat(50,50*h/w);
      Bitmap stretchBitmap = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
      stretchCanvas = new Canvas(stretchBitmap);
 
@@ -199,13 +215,13 @@ class DeformRenderer implements GLSurfaceView.Renderer
        stretchCanvas.drawRect(              0, h*i/NUM_LINES-1, w              , h*i/NUM_LINES+1, paint);
        }
 
-     if( stretchTexture==null ) stretchTexture = new DistortedTexture(w,h);
-     stretchTexture.setTexture(stretchBitmap);
+     if( mTexture==null ) mTexture = new DistortedTexture(w,h);
+     mTexture.setTexture(stretchBitmap);
 
      mMove.set(scrWidth/4,scrHeight/4,0);
 
      mScreen.detachAll();
-     mScreen.attach(stretchTexture,stretchEffects,stretchMesh);
+     mScreen.attach(mTexture,mEffects,mMesh);
 
      mScreen.resize(width, height);
      }
@@ -244,15 +260,15 @@ class DeformRenderer implements GLSurfaceView.Renderer
      switch(mMode)
        {
        case DISTORT: vDistort[0].set(0,0,0);
-                     stretchEffects.apply(mMovingDistort);
+                     mEffects.apply(mMovingDistort);
                      mLastEffect = mMovingDistort.getID();
                      break;
        case DEFORM : vDeform[0].set(0,0,0);
-                     stretchEffects.apply(mMovingDeform);
+                     mEffects.apply(mMovingDeform);
                      mLastEffect = mMovingDeform.getID();
                      break;
        case SHEAR  : vShear[0].set(0,0,0);
-                     stretchEffects.apply(mMovingShear);
+                     mEffects.apply(mMovingShear);
                      mLastEffect = mMovingShear.getID();
                      break;
        }
@@ -277,7 +293,7 @@ class DeformRenderer implements GLSurfaceView.Renderer
 
    void up()
      {
-     stretchEffects.abortById(mLastEffect);
+     mEffects.abortById(mLastEffect);
 
      float damp = -0.65f;
 
@@ -288,21 +304,21 @@ class DeformRenderer implements GLSurfaceView.Renderer
                        vDistort[i].set( vDistort[i-1].get1()*damp, vDistort[i-1].get2()*damp, 0 );
                        }
                      vDistort[NUM_VECTORS-1].set(0,0,0);
-                     stretchEffects.apply(mReleasedDistort);
+                     mEffects.apply(mReleasedDistort);
                      break;
        case DEFORM : for(int i=1; i<NUM_VECTORS-1; i++)
                        {
                        vDeform[i].set( vDeform[i-1].get1()*damp, vDeform[i-1].get2()*damp, 0 );
                        }
                      vDeform[NUM_VECTORS-1].set(0,0,0);
-                     stretchEffects.apply(mReleasedDeform);
+                     mEffects.apply(mReleasedDeform);
                      break;
        case SHEAR  : for(int i=1; i<NUM_VECTORS-1; i++)
                        {
                        vShear[i].set( vShear[i-1].get1()*damp, vShear[i-1].get2()*damp, 0 );
                        }
                      vShear[NUM_VECTORS-1].set(0,0,0);
-                     stretchEffects.apply(mReleasedShear);
+                     mEffects.apply(mReleasedShear);
                      break;
        }
      }
diff --git a/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java b/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java
index b0e5224..2328e6b 100644
--- a/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java
+++ b/src/main/java/org/distorted/examples/dynamic/DynamicSurfaceView.java
@@ -148,9 +148,9 @@ public class DynamicSurfaceView extends GLSurfaceView
       {
       mDuration = duration;
       
-      di1D.setDuration(duration);
-      di2D.setDuration(duration);
-      di3D.setDuration(duration);
+      di1D.makeRunNowFor(duration);
+      di2D.makeRunNowFor(duration);
+      di3D.makeRunNowFor(duration);
       }
 
 ///////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
index ec22c3a..6780057 100644
--- a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
+++ b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
@@ -102,11 +102,13 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
      {
      switch(em)
         {
-        case EFFECT_REMOVED: if( !addNewBubble() )
-                               {
-                               android.util.Log.e("Listener", "failed to add new bubble - this should never happen!");
-                               }
-                             break;
+        case EFFECT_FINISHED: mEffects.abortById(effectID);
+
+                              if( !addNewBubble() )
+                                {
+                                android.util.Log.e("Listener", "failed to add new bubble - this should never happen!");
+                                }
+                              break;
         }
      }
    
diff --git a/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java b/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
index 6fc601d..d5fd7f1 100644
--- a/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
+++ b/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
@@ -139,8 +139,6 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
 
    private void makeGlow(int leaf)
      {
-     //android.util.Log.e("glow", "glowing: "+leaf);
-
      mGlowing = leaf;
      mLeafEffects[leaf].apply(mGlow[leaf]);
      }
@@ -152,13 +150,12 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
      {
      switch(em)
        {
-       case EFFECT_FINISHED: //android.util.Log.e("glow", "effectMessage FINISHED");
+       case EFFECT_FINISHED: mLeafEffects[mGlowing].abortById(effectID);
+
                              int glowing = mGlowing+1;
                              if( glowing>=NUM_LEAVES ) glowing = 0;
                              makeGlow(glowing);
                              break;
-       default:              //android.util.Log.e("glow", "effectMessage REMOVED");
-                             break;
        }
      }
 
diff --git a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
index 8d85a64..e85c7b8 100644
--- a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
+++ b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
@@ -85,7 +85,7 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
       }
     
     rot.setCount(0);
-    rot.setDuration(8000);
+    rot.makeRunNowFor(8000);
     rot.setMode(Dynamic.MODE_LOOP);
 
     mMove   = new Static3D(0,0,0);
diff --git a/src/main/java/org/distorted/examples/rubik/RubikCube.java b/src/main/java/org/distorted/examples/rubik/RubikCube.java
index 59a03c4..66e9740 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikCube.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikCube.java
@@ -32,6 +32,7 @@ import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshCubes;
+import org.distorted.library.message.EffectListener;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
@@ -53,8 +54,9 @@ class RubikCube
     private Static3D[][][] mRotationAxis;
     private Dynamic1D[][][] mRotationAngle;
     private Static3D[][][] mCurrentPosition;
-    private Static1D mRotationAngleStatic;
+    private Static1D mRotationAngleStatic, mRotationAngleNearest;
     private DistortedTexture mTexture;
+    private DistortedEffects mEffectsListeningForNow;
 
     private int mRotAxis, mRotRow;
     private int mSize;
@@ -65,7 +67,9 @@ class RubikCube
       {
       mSize = size;
 
-      mRotationAngleStatic = new Static1D(0);
+      mRotationAngleStatic  = new Static1D(0);
+      mRotationAngleNearest = new Static1D(0);
+
       mRotAxis= RubikSurfaceView.VECTX;
       mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
 
@@ -192,23 +196,71 @@ class RubikCube
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    void continueRotation(float angle)
+    void continueRotation(float angleInDegrees)
+      {
+      mRotationAngleStatic.set1(angleInDegrees);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private int computeNearestAngle(float angle)
       {
-      mRotationAngleStatic.set1(angle);
+      final int NEAREST = 90;
+
+      int tmp = (int)((angle+NEAREST/2)/NEAREST);
+      if( angle< -(NEAREST/2) ) tmp-=1;
+
+      return NEAREST*tmp;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    void finishRotationCalledOnNextRender()
+    void finishRotationCalledOnNextRender(EffectListener listener)
       {
-      float nearestAngle = (mRotationAngleStatic.get1()+45.0f)/90.0f;
-      if( nearestAngle<0 ) nearestAngle-=1.0f;
-      int nearestAngleInDegrees = 90*(4-((int)nearestAngle+4)%4);
+      boolean first = true;
+      int nearestAngleInDegrees = computeNearestAngle(mRotationAngleStatic.get1());
+
+
+      android.util.Log.e("cube", "finish: angle="+((int)mRotationAngleStatic.get1())+" ret: "+nearestAngleInDegrees);
+
+
+      mRotationAngleNearest.set1(nearestAngleInDegrees);
+
+      for(int x=0; x<mSize; x++)
+        for(int y=0; y<mSize; y++)
+          for(int z=0; z<mSize; z++)
+            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
+              {
+              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
+                {
+                mRotationAngle[x][y][z].makeRunNowFor(2000);
+                mRotationAngle[x][y][z].add(mRotationAngleNearest);
+
+                if( first )
+                  {
+                  first = false;
+                  mEffectsListeningForNow = mEffects[x][y][z];
+                  mEffectsListeningForNow.registerForMessages(listener);
+                  }
+                }
+              }
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    void removeRotationCalledOnNextRender(EffectListener listener)
+      {
+      mEffectsListeningForNow.deregisterForMessages(listener);
+
+      int nearestAngleInDegrees = computeNearestAngle(mRotationAngleStatic.get1());
       double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
-      float sinA = (float)Math.sin(nearestAngleInRadians*0.5);
+      float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
       float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
 
+      android.util.Log.e("cube", "remove: angle="+((int)mRotationAngleStatic.get1())+" ret: "+nearestAngleInDegrees);
+
       mRotationAngleStatic.set1(0);
+      mRotationAngleNearest.set1(0);
 
       float qx=0,qy=0,qz=0;
 
@@ -228,6 +280,7 @@ class RubikCube
               {
               if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
                 {
+                mRotationAngle[x][y][z].makeRunNowFor(0);
                 mRotationAngle[x][y][z].removeAll();
                 mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
                 modifyCurrentPosition(x,y,z,quat);
diff --git a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
index 54cf38f..f691060 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
@@ -24,6 +24,8 @@ import android.opengl.GLSurfaceView;
 import org.distorted.library.effect.VertexEffectSink;
 import org.distorted.library.main.Distorted;
 import org.distorted.library.main.DistortedScreen;
+import org.distorted.library.message.EffectListener;
+import org.distorted.library.message.EffectMessage;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
@@ -32,11 +34,11 @@ import javax.microedition.khronos.opengles.GL10;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-class RubikRenderer implements GLSurfaceView.Renderer
+class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
 {
     private static final int NUM_CUBES = 4;
     private static final float CUBE_SCREEN_RATIO = 0.5f;
-    private static final float CAMERA_DISTANCE = 0.5f;     // 0.5 of the length of max(scrHeight,scrWidth)
+    private static final float CAMERA_DISTANCE   = 0.5f;  // 0.5 of the length of max(scrHeight,scrWidth)
 
     private RubikSurfaceView mView;
     private DistortedScreen mScreen;
@@ -44,7 +46,7 @@ class RubikRenderer implements GLSurfaceView.Renderer
     private Static4D mQuatCurrent, mQuatAccumulated;
     private Static4D mTempCurrent, mTempAccumulated;
     private float mCubeSizeInScreenSpace;
-    private boolean mFinishRotation, mFinishDragCurrent, mFinishDragAccumulated;
+    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated;
     private RubikCube mCube;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -64,6 +66,7 @@ class RubikRenderer implements GLSurfaceView.Renderer
       mScale = new Static3D(1,1,1);
 
       mFinishRotation        = false;
+      mRemoveRotation        = false;
       mFinishDragCurrent     = false;
       mFinishDragAccumulated = false;
 
@@ -71,7 +74,9 @@ class RubikRenderer implements GLSurfaceView.Renderer
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-   
+// various things are done here delayed, 'after the next render' as not to be done mid-render and
+// cause artifacts.
+
     public void onDrawFrame(GL10 glUnused) 
       {
       mScreen.render( System.currentTimeMillis() );
@@ -91,10 +96,27 @@ class RubikRenderer implements GLSurfaceView.Renderer
       if( mFinishRotation )
         {
         mFinishRotation=false;
-        mCube.finishRotationCalledOnNextRender();
+        mCube.finishRotationCalledOnNextRender(this);
+        }
+
+      if( mRemoveRotation )
+        {
+        mRemoveRotation=false;
+        mCube.removeRotationCalledOnNextRender(this);
         }
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// EffectListener. The library sends a message to us when it's time to call 'removeRotation'
+
+   public void effectMessage(final EffectMessage em, final long effectID, final long objectID)
+     {
+     switch(em)
+        {
+        case EFFECT_FINISHED: mRemoveRotation = true; break;
+        }
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
     
     public void onSurfaceChanged(GL10 glUnused, int width, int height) 
@@ -141,9 +163,7 @@ class RubikRenderer implements GLSurfaceView.Renderer
     private float computeFOV(float cameraDistance, int screenHeight)
       {
       double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
-      float fovInDegrees = (float)(2*halfFOVInRadians*(180/Math.PI));
-
-      return fovInDegrees;
+      return (float)(2*halfFOVInRadians*(180/Math.PI));
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java b/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
index 3b30b12..69ee161 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
@@ -63,8 +63,6 @@ class RubikSurfaceView extends GLSurfaceView
       {
       super(context);
 
-      mDragging = false;
-      mBeginRot = false;
       mRotationVect = VECT[0];
 
       mPoint = new float[3];
@@ -109,9 +107,8 @@ class RubikSurfaceView extends GLSurfaceView
                                        mY = y;
                                        mLastTouchedFace = faceTouched(x,y);
 
-                                       if( mLastTouchedFace != NONE ) mBeginRot = true;
-                                       else                           mDragging = true;
-
+                                       if( mLastTouchedFace != NONE ) { mBeginRot = true; mDragging = false; }
+                                       else                           { mDragging = true; mBeginRot = false; }
                                        break;
          case MotionEvent.ACTION_MOVE: if( mDragging )
                                          {
@@ -120,9 +117,9 @@ class RubikSurfaceView extends GLSurfaceView
                                          }
                                        else if( mBeginRot )
                                          {
-                                         int minimumToRotate = (mScreenMin*mScreenMin)/100;
+                                         int minimumDistToStartRotating = (mScreenMin*mScreenMin)/100;
 
-                                         if( (mX-x)*(mX-x)+(mY-y)*(mY-y)>minimumToRotate )
+                                         if( (mX-x)*(mX-x)+(mY-y)*(mY-y) > minimumDistToStartRotating )
                                            {
                                            addNewRotation(x,y);
                                            mBeginRot = false;
@@ -134,10 +131,6 @@ class RubikSurfaceView extends GLSurfaceView
                                          }
                                        break;
          case MotionEvent.ACTION_UP  : if( !mDragging ) finishRotation();
-
-                                       mDragging = false;
-                                       mBeginRot = false;
-
                                        mQuatAccumulated.set(quatMultiply(mQuatCurrent, mQuatAccumulated));
                                        mQuatCurrent.set(0f, 0f, 0f, 1f);
                                        mRenderer.setQuatCurrent(mQuatCurrent);
@@ -366,9 +359,9 @@ class RubikSurfaceView extends GLSurfaceView
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// given precomputed mCam and mPoi, respectively camera and touch point positions in ScreenSpace,
-// cast this touch point onto the 'face' and write the cast coords to 'output'.
-// Center of the 'face' = (0,0)
+// given precomputed mCamera and mPoint, respectively camera and touch point positions in ScreenSpace,
+// cast this touch point onto the surface defined by the 'face' and write the cast coords to 'output'.
+// Center of the 'face' = (0,0), third coord always +- cubeHalfSize.
 
     private void castTouchPointOntoFace(int face, float cubeHalfSize, float[] output)
       {
@@ -398,6 +391,9 @@ class RubikSurfaceView extends GLSurfaceView
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// retFace{X,Y,Z}axis: 3 functions which return which real AXIS gets mapped to which when we look
+// directly at a given face. For example, when we look at the RIGHT face of the cube (with TOP still
+// in the top) then the 'real' X axis becomes the 'Z' axis, thus retFaceZaxis(RIGHT) = VECTX.
 
     private int retFaceXaxis(int face)
       {
diff --git a/src/main/java/org/distorted/examples/wind/WindEffectsManager.java b/src/main/java/org/distorted/examples/wind/WindEffectsManager.java
index 332c5ed..6e3066a 100644
--- a/src/main/java/org/distorted/examples/wind/WindEffectsManager.java
+++ b/src/main/java/org/distorted/examples/wind/WindEffectsManager.java
@@ -131,9 +131,9 @@ class WindEffectsManager
     shearFactor.set2(tanAngle);
     scaleFactor.set1(1/(float)Math.sqrt(1+tanAngle*tanAngle));
 
-    windDynamic1.setDuration( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
-    windDynamic2.setDuration( wind > 0 ? 720 +  8000/wind : Long.MAX_VALUE);
-    windDynamic3.setDuration( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
+    windDynamic1.makeRunNowFor( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
+    windDynamic2.makeRunNowFor( wind > 0 ? 720 +  8000/wind : Long.MAX_VALUE);
+    windDynamic3.makeRunNowFor( wind > 0 ? 900 + 10000/wind : Long.MAX_VALUE);
 
     float wave2 = mHeight*( 0.05f + 0.002f*wind);
     windFactor21.set1(wave2);
