commit bdb341bc3c57906d9f971ba34e715a9a7fb2e784
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Tue Nov 8 12:43:46 2016 +0000

    Dynamics: Introduce 2 Modes of operation:
    
    - 'random access' mode, where we are able to call a single Dynamic from multiple thread simultaneously.
    - 'sequential' mode, which only permits sequential interpolation from one client.
    
    The second mode has an advantage when one needs to change mDuration: it keeps on interpolating smoothly. In the first mode, this is not possible.

diff --git a/src/main/java/org/distorted/library/EffectQueueFragment.java b/src/main/java/org/distorted/library/EffectQueueFragment.java
index 03e3989..7a54524 100644
--- a/src/main/java/org/distorted/library/EffectQueueFragment.java
+++ b/src/main/java/org/distorted/library/EffectQueueFragment.java
@@ -89,13 +89,13 @@ class EffectQueueFragment extends EffectQueue
 
       if( mInter[1][i]!=null )
         {
-        mInter[1][i].interpolateMain( mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i]);
+        mInter[1][i].interpolateMain( mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i], step);
 
         mUniforms[NUM_UNIFORMS*i+4] = mUniforms[NUM_UNIFORMS*i+4]-mObjHalfX;
         mUniforms[NUM_UNIFORMS*i+5] =-mUniforms[NUM_UNIFORMS*i+5]+mObjHalfY;
         }
 
-      if( mInter[2][i]!=null ) mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+1, mCurrentDuration[i]);
+      if( mInter[2][i]!=null ) mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+1, mCurrentDuration[i], step);
 
       mCurrentDuration[i] += step;
       }
@@ -151,7 +151,9 @@ class EffectQueueFragment extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects); 
 
       if( data instanceof Dynamic1D)
+        {
         mInter[0][mNumEffects] = (Dynamic1D)data;
+        }
       else if( data instanceof Static1D )
         {
         mInter[0][mNumEffects] = null;
@@ -181,7 +183,9 @@ class EffectQueueFragment extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
       if( data instanceof Dynamic1D)
+        {
         mInter[0][mNumEffects] = (Dynamic1D)data;
+        }
       else if( data instanceof Static1D )
         {
         mInter[0][mNumEffects] = null;
@@ -190,7 +194,9 @@ class EffectQueueFragment extends EffectQueue
       else return -1;
 
       if( region instanceof Dynamic4D)
+        {
         mInter[1][mNumEffects] = (Dynamic4D)region;
+        }
       else if( region instanceof Static4D )
         {
         mInter[1][mNumEffects]  = null;
@@ -219,7 +225,9 @@ class EffectQueueFragment extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
       if( level instanceof Dynamic1D)
+        {
         mInter[0][mNumEffects] = (Dynamic1D)level;
+        }
       else if( level instanceof Static1D )
         {
         mInter[0][mNumEffects] = null;
@@ -241,7 +249,9 @@ class EffectQueueFragment extends EffectQueue
       else return -1;
 
       if( region instanceof Dynamic4D)
+        {
         mInter[1][mNumEffects] = (Dynamic4D)region;
+        }
       else if( region instanceof Static4D )
         {
         mInter[1][mNumEffects]  = null;
@@ -268,7 +278,9 @@ class EffectQueueFragment extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
       if( level instanceof Dynamic1D)
+        {
         mInter[0][mNumEffects] = (Dynamic1D)level;
+        }
       else if( level instanceof Static1D )
         {
         mInter[0][mNumEffects] = null;
diff --git a/src/main/java/org/distorted/library/EffectQueueMatrix.java b/src/main/java/org/distorted/library/EffectQueueMatrix.java
index 3fd011f..b21bfa0 100644
--- a/src/main/java/org/distorted/library/EffectQueueMatrix.java
+++ b/src/main/java/org/distorted/library/EffectQueueMatrix.java
@@ -126,7 +126,7 @@ class EffectQueueMatrix extends EffectQueue
 
       if( mInter[1][i]!=null )
         {
-        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i]);
+        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i], step);
         }
 
       mCurrentDuration[i] += step;
@@ -260,7 +260,10 @@ class EffectQueueMatrix extends EffectQueue
       {
       mInter[1][mNumEffects] = null;
 
-           if( vector instanceof Dynamic3D) mInter[0][mNumEffects] = (Dynamic3D)vector;
+      if( vector instanceof Dynamic3D)
+        {
+        mInter[0][mNumEffects] = (Dynamic3D)vector;
+        }
       else if( vector instanceof Static3D )
         {
         mInter[0][mNumEffects] = null;
@@ -283,7 +286,10 @@ class EffectQueueMatrix extends EffectQueue
     {
     if( mMax[INDEX]>mNumEffects )
       {
-           if( angle instanceof Dynamic1D) mInter[0][mNumEffects] = (Dynamic1D)angle;
+      if( angle instanceof Dynamic1D)
+        {
+        mInter[0][mNumEffects] = (Dynamic1D)angle;
+        }
       else if( angle instanceof Static1D)
         {
         mInter[0][mNumEffects] = null;
@@ -295,7 +301,10 @@ class EffectQueueMatrix extends EffectQueue
       mUniforms[NUM_UNIFORMS*mNumEffects+2] = axis.getY();
       mUniforms[NUM_UNIFORMS*mNumEffects+3] = axis.getZ();
 
-      if( center instanceof Dynamic3D) mInter[1][mNumEffects] = (Dynamic3D)center;
+      if( center instanceof Dynamic3D)
+        {
+        mInter[1][mNumEffects] = (Dynamic3D)center;
+        }
       else if( center instanceof Static3D )
         {
         mInter[1][mNumEffects] = null;
@@ -318,8 +327,14 @@ class EffectQueueMatrix extends EffectQueue
     {
     if( mMax[INDEX]>mNumEffects )
       {
-           if( data instanceof Dynamic4D  ) mInter[0][mNumEffects] = (Dynamic4D)data;
-      else if( data instanceof DynamicQuat) mInter[0][mNumEffects] = (DynamicQuat)data;
+      if( data instanceof Dynamic4D  )
+        {
+        mInter[0][mNumEffects] = (Dynamic4D)data;
+        }
+      else if( data instanceof DynamicQuat)
+        {
+        mInter[0][mNumEffects] = (DynamicQuat)data;
+        }
       else if( data instanceof Static4D   )
         {
         mInter[0][mNumEffects] = null;
@@ -330,7 +345,10 @@ class EffectQueueMatrix extends EffectQueue
         }
       else return -1;
 
-      if( center instanceof Dynamic3D) mInter[1][mNumEffects] = (Dynamic3D)center;
+      if( center instanceof Dynamic3D)
+        {
+        mInter[1][mNumEffects] = (Dynamic3D)center;
+        }
       else if( center instanceof Static3D )
         {
         mInter[1][mNumEffects] = null;
@@ -353,7 +371,10 @@ class EffectQueueMatrix extends EffectQueue
     {
     if( mMax[INDEX]>mNumEffects )
       {
-           if( shear instanceof Dynamic3D) mInter[0][mNumEffects] = (Dynamic3D)shear;
+      if( shear instanceof Dynamic3D)
+        {
+        mInter[0][mNumEffects] = (Dynamic3D)shear;
+        }
       else if( shear instanceof Static3D )
         {
         mInter[0][mNumEffects] = null;
@@ -363,7 +384,10 @@ class EffectQueueMatrix extends EffectQueue
         }
       else return -1;
 
-      if( center instanceof Dynamic3D) mInter[1][mNumEffects] = (Dynamic3D)center;
+      if( center instanceof Dynamic3D)
+        {
+        mInter[1][mNumEffects] = (Dynamic3D)center;
+        }
       else if( center instanceof Static3D )
         {
         mInter[1][mNumEffects] = null;
diff --git a/src/main/java/org/distorted/library/EffectQueueVertex.java b/src/main/java/org/distorted/library/EffectQueueVertex.java
index 2754467..8f0ac99 100644
--- a/src/main/java/org/distorted/library/EffectQueueVertex.java
+++ b/src/main/java/org/distorted/library/EffectQueueVertex.java
@@ -104,12 +104,12 @@ class EffectQueueVertex extends EffectQueue
 
       if( mInter[1][i]!=null )  // region
         {
-        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+8, mCurrentDuration[i]);
+        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+8, mCurrentDuration[i], step);
         }
 
       if( mInter[2][i]!=null )  // center
         {
-        mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+6, mCurrentDuration[i]);
+        mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+6, mCurrentDuration[i], step);
 
         mUniforms[NUM_UNIFORMS*i+6] = mUniforms[NUM_UNIFORMS*i+6]-mObjHalfX;
         mUniforms[NUM_UNIFORMS*i+7] =-mUniforms[NUM_UNIFORMS*i+7]+mObjHalfY;
@@ -194,7 +194,9 @@ class EffectQueueVertex extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
       if( data instanceof Dynamic5D)
+        {
         mInter[0][mNumEffects] = (Dynamic5D)data;
+        }
       else if( data instanceof Static5D)
         {
         Static5D tmp = (Static5D)data;
@@ -223,7 +225,9 @@ class EffectQueueVertex extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);    
 
       if( data instanceof Dynamic3D)
+        {
         mInter[0][mNumEffects] = (Dynamic3D)data;
+        }
       else if( data instanceof Static3D)
         {
         Static3D tmp = (Static3D)data;
@@ -250,7 +254,9 @@ class EffectQueueVertex extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
       if( data instanceof Dynamic1D)
+        {
         mInter[0][mNumEffects] = (Dynamic1D)data;
+        }
       else if( data instanceof Static1D)
         {
         mInter[0][mNumEffects] = null;
@@ -273,7 +279,9 @@ class EffectQueueVertex extends EffectQueue
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
       if( data instanceof Dynamic1D)
+        {
         mInter[0][mNumEffects] = (Dynamic1D)data;
+        }
       else if( data instanceof Static1D)
         {
         mInter[0][mNumEffects] = null;
@@ -320,7 +328,9 @@ class EffectQueueVertex extends EffectQueue
       }
 
     if( center instanceof Dynamic2D)
+      {
       mInter[2][mNumEffects] = (Dynamic2D)center;
+      }
     else if( center instanceof Static2D)
       {
       mInter[2][mNumEffects] = null;
diff --git a/src/main/java/org/distorted/library/type/Dynamic.java b/src/main/java/org/distorted/library/type/Dynamic.java
index 9e2a53a..65b2dd4 100644
--- a/src/main/java/org/distorted/library/type/Dynamic.java
+++ b/src/main/java/org/distorted/library/type/Dynamic.java
@@ -66,6 +66,21 @@ public abstract class Dynamic
    */
   public static final int MODE_JUMP = 2; 
 
+  /**
+   * The default mode of access. When in this mode, we are able to call interpolate() with points in time
+   * in any random order. This means one single Dynamic can be used in many effects simultaneously.
+   * On the other hand, when in this mode, it is not possible to smoothly interpolate when mDuration suddenly
+   * changes.
+   */
+  public static final int ACCESS_RANDOM     = 0;
+  /**
+   * Set the mode to ACCESS_SEQUENTIAL if you need to change mDuration and you would rather have the Dynamic
+   * keep on smoothly interpolating.
+   * On the other hand, in this mode, a Dynamic can only be accessed in sequential manner, which means one
+   * one Dynamic can only be used in one effect at a time.
+   */
+  public static final int ACCESS_SEQUENTIAL = 1;
+
   protected int mDimension;
   protected int numPoints;
   protected int mSegment;       // between which pair of points are we currently? (in case of PATH this is a bit complicated!)
@@ -73,6 +88,8 @@ public abstract class Dynamic
   protected int mMode;          // LOOP, PATH or JUMP
   protected long mDuration;     // number of milliseconds it takes to do a full loop/path from first vector to the last and back to the first
   protected float mCount;       // number of loops/paths we will do; mCount = 1.5 means we go from the first vector to the last, back to first, and to the last again. 
+  protected double mLastPos;
+  protected int mAccessMode;
 
   protected class VectorNoise
     {
@@ -160,57 +177,14 @@ public abstract class Dynamic
     mCount     = count;
     mDimension = dimension;
     mSegment   = -1;
+    mLastPos   = -1;
+    mAccessMode= ACCESS_RANDOM;
 
     baseV      = new float[mDimension][mDimension];
     buf        = new float[mDimension];
     old        = new float[mDimension];
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-  
-  public void interpolateMain(float[] buffer, int offset, long currentDuration)
-    {
-    if( mDuration<=0.0f ) 
-      {
-      interpolate(buffer,offset,mCount-(int)mCount);  
-      }
-    else
-      {
-      double x = (double)currentDuration/mDuration;
-           
-      if( x<=mCount || mCount<=0.0f )
-        {
-        interpolate(buffer,offset, (float)(x-(int)x) );
-        }
-      }
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public boolean interpolateMain(float[] buffer, int offset, long currentDuration, long step)
-    {
-    if( mDuration<=0.0f ) 
-      {
-      interpolate(buffer,offset,mCount-(int)mCount);
-      return false;
-      }
-     
-    double x = (double)currentDuration/mDuration;
-           
-    if( x<=mCount || mCount<=0.0f )
-      {
-      interpolate(buffer,offset, (float)(x-(int)x) );
-        
-      if( currentDuration+step > mDuration*mCount && mCount>0.0f )
-        {
-        interpolate(buffer,offset,mCount-(int)mCount);
-        return true;
-        }
-      }
-    
-    return false;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   protected float noise(float time,int vecNum)
@@ -626,6 +600,96 @@ if( last_non_zero != lastNon )
     mDuration = duration;
     }
 
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the access mode this Dynamic will be working in.
+ *
+ * @param mode ACCESS_RANDOM or ACCESS_SEQUENTIAL.
+ *             see {@link Dynamic#ACCESS_RANDOM}.
+ *             see {@link Dynamic#ACCESS_SEQUENTIAL}.
+ */
+  public void setAccessMode(int mode)
+    {
+    mAccessMode = mode;
+    mLastPos = -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
+ *
+ * @param buffer Float buffer we will write the resulting Static1D to.
+ * @param offset Offset in the buffer where to write the result.
+ * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
+ *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
+ */
+
+  public void interpolateMain(float[] buffer, int offset, long time)
+    {
+    if( mDuration<=0.0f )
+      {
+      interpolate(buffer,offset,mCount-(int)mCount);
+      }
+    else
+      {
+      double pos = (double)time/mDuration;
+
+      if( pos<=mCount || mCount<=0.0f )
+        {
+        interpolate(buffer,offset, (float)(pos-(int)pos) );
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
+ * <p>
+ * This version differs from the previous in that it returns a boolean value which indicates whether
+ * the interpolation is finished.
+ *
+ * @param buffer Float buffer we will write the resulting Static1D to.
+ * @param offset Offset in the buffer where to write the result.
+ * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
+ *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
+ * @param step Time difference between now and the last time we called this function. Needed to figure out
+ *             if the previous time we were called the effect wasn't finished yet, but now it is.
+ * @return true if the interpolation reached its end.
+ */
+  public boolean interpolateMain(float[] buffer, int offset, long time, long step)
+    {
+    if( mDuration<=0.0f )
+      {
+      interpolate(buffer,offset,mCount-(int)mCount);
+      return false;
+      }
+
+    double pos;
+
+    if( mAccessMode==ACCESS_SEQUENTIAL )
+      {
+      pos = mLastPos<0 ? (double)time/mDuration : (double)step/mDuration + mLastPos;
+      mLastPos = pos;
+      }
+    else
+      {
+      pos = (double)time/mDuration;
+      }
+
+    if( pos<=mCount || mCount<=0.0f )
+      {
+      interpolate(buffer,offset, (float)(pos-(int)pos) );
+
+      if( time+step > mDuration*mCount && mCount>0.0f )
+        {
+        interpolate(buffer,offset,mCount-(int)mCount);
+        return true;
+        }
+      }
+
+    return false;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// end of DistortedInterpolator
   }
diff --git a/src/main/java/org/distorted/library/type/Dynamic1D.java b/src/main/java/org/distorted/library/type/Dynamic1D.java
index d197967..64e719d 100644
--- a/src/main/java/org/distorted/library/type/Dynamic1D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic1D.java
@@ -375,17 +375,7 @@ public class Dynamic1D extends Dynamic implements Data1D
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
- * <p>
- * Since this is a 1-dimensional Dynamic, the resulting interpolated Static1D gets written
- * to a single location in the buffer: buffer[offset]. 
- * 
- * @param buffer Float buffer we will write the resulting Static1D to.
- * @param offset Offset in the buffer where to write the result.
- * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
- *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
- */
+
   synchronized void interpolate(float[] buffer, int offset, float time)
     {
     switch(numPoints)
diff --git a/src/main/java/org/distorted/library/type/Dynamic2D.java b/src/main/java/org/distorted/library/type/Dynamic2D.java
index d9e988f..9ee1f57 100644
--- a/src/main/java/org/distorted/library/type/Dynamic2D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic2D.java
@@ -396,17 +396,7 @@ public class Dynamic2D extends Dynamic implements Data2D
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
- * <p>
- * Since this is a 2-dimensional Dynamic, the resulting interpolated Static2D gets written
- * to two locations in the buffer: buffer[offset] and buffer[offset+1]. 
- * 
- * @param buffer Float buffer we will write the resulting Static2D to.
- * @param offset Offset in the buffer where to write the result.
- * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
- *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
- */  
+
   synchronized void interpolate(float[] buffer, int offset, float time)
     {
     switch(numPoints)
diff --git a/src/main/java/org/distorted/library/type/Dynamic3D.java b/src/main/java/org/distorted/library/type/Dynamic3D.java
index 11215e4..1257e34 100644
--- a/src/main/java/org/distorted/library/type/Dynamic3D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic3D.java
@@ -426,17 +426,7 @@ private float oldTime;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
- * <p>
- * Since this is a 3-dimensional Dynamic, the resulting interpolated Static3D gets written
- * to three locations in the buffer: buffer[offset], buffer[offset+1] and buffer[offset+2]. 
- * 
- * @param buffer Float buffer we will write the resulting Static3D to.
- * @param offset Offset in the buffer where to write the result.
- * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
- *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
- */    
+
   synchronized void interpolate(float[] buffer, int offset, float time)
     {  
     switch(numPoints)
diff --git a/src/main/java/org/distorted/library/type/Dynamic4D.java b/src/main/java/org/distorted/library/type/Dynamic4D.java
index 4d2d6ec..148d766 100644
--- a/src/main/java/org/distorted/library/type/Dynamic4D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic4D.java
@@ -438,17 +438,7 @@ public class Dynamic4D extends Dynamic implements Data4D
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
- * <p>
- * Since this is a 4-dimensional Dynamic, the resulting interpolated Static4D gets written
- * to four locations in the buffer: buffer[offset], buffer[offset+1], buffer[offset+2] and buffer[offset+3]. 
- * 
- * @param buffer Float buffer we will write the resulting Static4D to.
- * @param offset Offset in the buffer where to write the result.
- * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
- *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
- */    
+
   synchronized void interpolate(float[] buffer, int offset, float time)
     {  
     switch(numPoints)
diff --git a/src/main/java/org/distorted/library/type/Dynamic5D.java b/src/main/java/org/distorted/library/type/Dynamic5D.java
index 51ed65c..50a852e 100644
--- a/src/main/java/org/distorted/library/type/Dynamic5D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic5D.java
@@ -457,17 +457,7 @@ public class Dynamic5D extends Dynamic implements Data5D
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
- * <p>
- * Since this is a 5-dimensional Dynamic, the resulting interpolated Static5D gets written
- * to five locations in the buffer: buffer[offset],...,buffer[offset+4]. 
- * 
- * @param buffer Float buffer we will write the resulting Static5D to.
- * @param offset Offset in the buffer where to write the result.
- * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
- *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
- */    
+
   synchronized void interpolate(float[] buffer, int offset, float time)
     {  
     switch(numPoints)
diff --git a/src/main/java/org/distorted/library/type/DynamicQuat.java b/src/main/java/org/distorted/library/type/DynamicQuat.java
index c2ed490..3687a7c 100644
--- a/src/main/java/org/distorted/library/type/DynamicQuat.java
+++ b/src/main/java/org/distorted/library/type/DynamicQuat.java
@@ -133,6 +133,8 @@ public class DynamicQuat extends Dynamic implements Data4D
     mMode      = MODE_LOOP;
     mDuration  = duration;
     mCount     = count;
+    mLastPos   = -1;
+    mAccessMode= ACCESS_RANDOM;
     mDimension = 4;
     }
 
@@ -321,7 +323,7 @@ public class DynamicQuat extends Dynamic implements Data4D
  * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
  *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
  */    
-  public synchronized void interpolate(float[] buffer, int offset, float time)
+  synchronized void interpolate(float[] buffer, int offset, float time)
     {  
     switch(numPoints)
       {
