commit 8647eae208134b23d107c82079f7bc404f80b734
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Apr 6 15:57:40 2019 +0100

    Improve the architecture of the Rubik App: new RubikCube class.

diff --git a/src/main/java/org/distorted/examples/rubik/RubikActivity.java b/src/main/java/org/distorted/examples/rubik/RubikActivity.java
index 2bab5fc..76ca66d 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikActivity.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikActivity.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
+// Copyright 2019 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Distorted.                                                               //
 //                                                                                               //
diff --git a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
index 3a352d1..589947e 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
+// Copyright 2019 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Distorted.                                                               //
 //                                                                                               //
@@ -19,23 +19,11 @@
 
 package org.distorted.examples.rubik;
 
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.opengl.GLSurfaceView;
 
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.effect.MatrixEffectQuaternion;
-import org.distorted.library.effect.MatrixEffectRotate;
-import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.effect.VertexEffectSink;
 import org.distorted.library.main.Distorted;
-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.type.Dynamic1D;
-import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
@@ -46,32 +34,18 @@ import javax.microedition.khronos.opengles.GL10;
 
 class RubikRenderer implements GLSurfaceView.Renderer
 {
-            static final int NUM_CUBES =   4;
-    private static final int SIZE      = 200;
+    static final int NUM_CUBES = 4;
     private static final float CUBE_SCREEN_RATIO = 0.5f;
 
-    private static final Static3D VectX = new Static3D(1,0,0);
-    private static final Static3D VectY = new Static3D(0,1,0);
-    private static final Static3D VectZ = new Static3D(0,0,1);
-
     private GLSurfaceView mView;
-    private DistortedTexture mTexture;
     private DistortedScreen mScreen;
-    private Static3D mMove, mScale, mCenter;
-    private MeshCubes[][][] mCubes;
-    private DistortedEffects[][][] mEffects;
-    private Static4D[][][] mQuatScramble;
-    private Static3D[][][] mRotationAxis;
-    private Dynamic1D[][][] mRotationAngle;
-    private Static3D[][][] mCurrentPosition;
-    private Static1D mRotationAngleStatic;
-    private int mRotAxis, mRotRow;
-
-    private int mScreenWidth, mScreenHeight;
-
+    private Static3D mMove, mScale;
     private Static4D mQuatCurrent, mQuatAccumulated;
     private Static4D mTempCurrent, mTempAccumulated;
-    int mScreenMin;
+    private float mScaleFactor;
+    private int mScreenWidth, mScreenHeight;
+    private boolean mFinishRotation, mFinishDragCurrent, mFinishDragAccumulated;
+    private RubikCube mCube;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -80,94 +54,20 @@ class RubikRenderer implements GLSurfaceView.Renderer
       mView = v;
 
       mScreen = new DistortedScreen();
-      mScreen.setProjection(90.0f, 0.1f);
 
       mTempCurrent     = new Static4D(0,0,0,1);
       mTempAccumulated = initializeQuat();
       mQuatCurrent     = new Static4D(0,0,0,1);
       mQuatAccumulated = initializeQuat();
 
-      mCubes = new MeshCubes[NUM_CUBES][NUM_CUBES][NUM_CUBES];
-      mEffects = new DistortedEffects[NUM_CUBES][NUM_CUBES][NUM_CUBES];
-      Static3D[][][] cubeVectors = new Static3D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
-
-      mQuatScramble   = new Static4D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
-      mRotationAxis   = new Static3D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
-      mRotationAngle  = new Dynamic1D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
-      mCurrentPosition= new Static3D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
-
-      float sinkDegree = 3.0f - 1.8f/NUM_CUBES; // f(1)=1.2, f(inf)=3
-
-      VertexEffectSink sink = new VertexEffectSink( new Static1D(sinkDegree),
-                                                    new Static3D(SIZE*0.5f, SIZE*0.5f, SIZE*0.5f),
-                                                    new Static4D(0,0,0, SIZE*0.72f) );
       mMove  = new Static3D(0,0,0);
       mScale = new Static3D(1,1,1);
-      mCenter= new Static3D(0,0,0);
-
-      mRotationAngleStatic = new Static1D(0);
-      mRotAxis= RubikSurfaceView.VECTN;
-
-      MatrixEffectMove       move  = new MatrixEffectMove(mMove);
-      MatrixEffectScale      scale = new MatrixEffectScale(mScale);
-      MatrixEffectQuaternion quat1 = new MatrixEffectQuaternion(mQuatCurrent    , mCenter);
-      MatrixEffectQuaternion quat2 = new MatrixEffectQuaternion(mQuatAccumulated, mCenter);
-
-      // 3x2 bitmap = 6 squares:
-      //
-      // RED     GREEN   BLUE
-      // YELLOW  WHITE   BROWN
-
-      final float ze = 0.0f;
-      final float ot = 1.0f/3.0f;
-      final float tt = 2.0f/3.0f;
-      final float oh = 1.0f/2.0f;
-      final float of = 1.0f/40.0f;
-
-      final Static4D mapFront = new Static4D(ze,oh, ze+ot,oh+oh);
-      final Static4D mapBack  = new Static4D(tt,ze, tt+ot,ze+oh);
-      final Static4D mapLeft  = new Static4D(ot,ze, ot+ot,ze+oh);
-      final Static4D mapRight = new Static4D(ze,ze, ze+ot,ze+oh);
-      final Static4D mapTop   = new Static4D(tt,oh, tt+ot,oh+oh);
-      final Static4D mapBottom= new Static4D(ot,oh, ot+ot,oh+oh);
-
-      final Static4D mapBlack = new Static4D(ze,ze, ze+of,ze+of);
-
-      Static4D tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom;
-      float nc = 0.5f*(NUM_CUBES-1);
-      int vertices = (int)(24.0f/NUM_CUBES + 2.0f);
-
-      for(int x = 0; x< NUM_CUBES; x++)
-        for(int y = 0; y< NUM_CUBES; y++)
-          for(int z = 0; z< NUM_CUBES; z++)
-            {
-            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 ) // only the external walls
-              {
-              tmpLeft  = (x==            0 ? mapLeft  :mapBlack);
-              tmpRight = (x== NUM_CUBES -1 ? mapRight :mapBlack);
-              tmpFront = (z== NUM_CUBES -1 ? mapFront :mapBlack);
-              tmpBack  = (z==            0 ? mapBack  :mapBlack);
-              tmpTop   = (y== NUM_CUBES -1 ? mapTop   :mapBlack);
-              tmpBottom= (y==            0 ? mapBottom:mapBlack);
-
-              mCubes[x][y][z]           = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
-              cubeVectors[x][y][z]      = new Static3D( SIZE*(x-nc), SIZE*(y-nc), SIZE*(z-nc) );
-              mQuatScramble[x][y][z]    = new Static4D(0,0,0,1);
-              mRotationAngle[x][y][z]   = new Dynamic1D();
-              mRotationAxis[x][y][z]    = new Static3D(1,0,0);
-              mCurrentPosition[x][y][z] = new Static3D(x,y,z);
-
-              mEffects[x][y][z] = new DistortedEffects();
-              mEffects[x][y][z].apply(sink);
-              mEffects[x][y][z].apply(move);
-              mEffects[x][y][z].apply(scale);
-              mEffects[x][y][z].apply(quat1);
-              mEffects[x][y][z].apply(quat2);
-              mEffects[x][y][z].apply( new MatrixEffectRotate( mRotationAngle[x][y][z], mRotationAxis[x][y][z], mCenter));
-              mEffects[x][y][z].apply( new MatrixEffectQuaternion(mQuatScramble[x][y][z], mCenter));
-              mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) );
-              }
-            }
+
+      mFinishRotation        = false;
+      mFinishDragCurrent     = false;
+      mFinishDragAccumulated = false;
+
+      mCube = new RubikCube(NUM_CUBES, mMove, mScale, mQuatCurrent, mQuatAccumulated);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -176,27 +76,42 @@ class RubikRenderer implements GLSurfaceView.Renderer
       {
       mScreen.render( System.currentTimeMillis() );
 
-      mQuatCurrent.set(mTempCurrent);
-      mQuatAccumulated.set(mTempAccumulated);
+      if( mFinishDragCurrent )
+        {
+        mFinishDragCurrent = false;
+        mQuatCurrent.set(mTempCurrent);
+        }
+
+      if( mFinishDragAccumulated )
+        {
+        mFinishDragAccumulated = false;
+        mQuatAccumulated.set(mTempAccumulated);
+        }
+
+      if( mFinishRotation )
+        {
+        mFinishRotation=false;
+        mCube.finishRotationCalledOnNextRender();
+        }
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
     
     public void onSurfaceChanged(GL10 glUnused, int width, int height) 
       {
+      mScreen.setProjection( width>height ? 60.0f : 90.0f, 0.1f);
+
       mScreenWidth = width;
       mScreenHeight= height;
-      mScreenMin = width<height ? width:height;
 
-      float w = mTexture.getWidth();
-      float h = mTexture.getHeight();
-      float d = mTexture.getDepth(mCubes[0][0][0]);
+      float w = mCube.getWidth();
+      float h = mCube.getHeight();
+      float d = mCube.getDepth();
 
-      float factor = CUBE_SCREEN_RATIO*(width>height ? height/h:width/w)/ NUM_CUBES;
+      mScaleFactor = CUBE_SCREEN_RATIO*(width>height ? height/h:width/w)/ NUM_CUBES;
 
-      mCenter.set(w/2,h/2,d/2);
-      mMove.set( (width-factor*w)/2 , (height-factor*h)/2 , -factor*d/2 );
-      mScale.set(factor,factor,factor);
+      mMove.set( (width-mScaleFactor*w)/2 , (height-mScaleFactor*h)/2 , -mScaleFactor*d/2 );
+      mScale.set(mScaleFactor,mScaleFactor,mScaleFactor);
 
       mScreen.resize(width, height);
       }
@@ -205,55 +120,9 @@ class RubikRenderer implements GLSurfaceView.Renderer
     
     public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
       {
-      Bitmap bitmap;
-
-      final int S = 128;
-      final int W = 3*S;
-      final int H = 2*S;
-      final int R = S/10;
-      final int M = S/20;
-
-      Paint paint = new Paint();
-      bitmap = Bitmap.createBitmap(W,H, Bitmap.Config.ARGB_8888);
-      Canvas canvas = new Canvas(bitmap);
-
-      paint.setAntiAlias(true);
-      paint.setTextAlign(Paint.Align.CENTER);
-      paint.setStyle(Paint.Style.FILL);
-
-      // 3x2 bitmap = 6 squares:
-      //
-      // RED     GREEN   BLUE
-      // YELLOW  WHITE   BROWN
-
-      paint.setColor(0xff000000);                                  // BLACK BACKGROUND
-      canvas.drawRect(0, 0, W, H, paint);                          //
-
-      paint.setColor(0xffff0000);                                  // RED
-      canvas.drawRoundRect(    M,   M,   S-M,   S-M, R, R, paint); //
-      paint.setColor(0xff00ff00);                                  // GREEN
-      canvas.drawRoundRect(  S+M,   M, 2*S-M,   S-M, R, R, paint); //
-      paint.setColor(0xff0000ff);                                  // BLUE
-      canvas.drawRoundRect(2*S+M,   M, 3*S-M,   S-M, R, R, paint); //
-      paint.setColor(0xffffff00);                                  // YELLOW
-      canvas.drawRoundRect(    M, S+M,   S-M, 2*S-M, R, R, paint); //
-      paint.setColor(0xffffffff);                                  // WHITE
-      canvas.drawRoundRect(  S+M, S+M, 2*S-M, 2*S-M, R, R, paint); //
-      paint.setColor(0xffb5651d);                                  // BROWN
-      canvas.drawRoundRect(2*S+M, S+M, 3*S-M, 2*S-M, R, R, paint); //
-
-      if( mTexture==null ) mTexture = new DistortedTexture(SIZE,SIZE);
-      mTexture.setTexture(bitmap);
-
+      mCube.createTexture();
       mScreen.detachAll();
-
-      for(int x = 0; x< NUM_CUBES; x++)
-        for(int y = 0; y< NUM_CUBES; y++)
-          for(int z = 0; z< NUM_CUBES; z++)
-            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 ) // only the external walls
-              {
-              mScreen.attach(mTexture,mEffects[x][y][z],mCubes[x][y][z]);
-              }
+      mCube.attachToScreen(mScreen);
 
       VertexEffectSink.enable();
 
@@ -267,6 +136,14 @@ class RubikRenderer implements GLSurfaceView.Renderer
         }
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// no this will not race with onDrawFrame
+
+    void finishRotation()
+      {
+      mFinishRotation = true;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     float returnCameraDistance()
@@ -279,153 +156,39 @@ class RubikRenderer implements GLSurfaceView.Renderer
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// NUM_CUBES individual little cubes, each SIZE in size, times 'scaleFactor' (see onSurfaceChanged)
+// NUM_CUBES individual little cubes, each TEXTURE_SIZE in size, times 'scaleFactor' (see onSurfaceChanged)
 
     float returnCubeSize()
       {
-      float w = mTexture.getWidth();
-      float h = mTexture.getHeight();
-      float max = (mScreenWidth>mScreenHeight ? mScreenHeight/h:mScreenWidth/w);
-      float scaleFactor = CUBE_SCREEN_RATIO*max/NUM_CUBES;
-
-      return scaleFactor*NUM_CUBES*SIZE;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    void addNewRotation(int vector, int row )
-      {
-      Static3D axis = VectX;
-
-      switch(vector)
-        {
-        case RubikSurfaceView.VECTX: axis = VectX; break;
-        case RubikSurfaceView.VECTY: axis = VectY; break;
-        case RubikSurfaceView.VECTZ: axis = VectZ; break;
-        }
-
-      mRotAxis = vector;
-      mRotRow  = row;
-
-      mRotationAngleStatic.set1(0.0f);
-
-      for(int x = 0; x< NUM_CUBES; x++)
-        for(int y = 0; y< NUM_CUBES; y++)
-          for(int z = 0; z< NUM_CUBES; z++)
-            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 )
-              {
-              if( belongsToRotation(x,y,z,vector,row) )
-                {
-                mRotationAxis[x][y][z].set(axis);
-                mRotationAngle[x][y][z].add(mRotationAngleStatic);
-                }
-              }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    void continueRotation(float angle)
-      {
-      mRotationAngleStatic.set1(200.0f*angle/mScreenMin);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    void finishRotation()
-      {
-      float nearestAngle = (mRotationAngleStatic.get1()+45.0f)/90.0f;
-      if( nearestAngle<0 ) nearestAngle-=1.0f;
-      int nearestAngleInDegrees = 90*(4-((int)nearestAngle+4)%4);
-      double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
-      float sinA = (float)Math.sin(nearestAngleInRadians*0.5);
-      float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
-
-      mRotationAngleStatic.set1(0);
-
-      float qx=0,qy=0,qz=0;
-
-      switch(mRotAxis)
-        {
-        case RubikSurfaceView.VECTX: qx=1; break;
-        case RubikSurfaceView.VECTY: qy=1; break;
-        case RubikSurfaceView.VECTZ: qz=1; break;
-        }
-
-      Static4D quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
-
-      for(int x = 0; x< NUM_CUBES; x++)
-        for(int y = 0; y< NUM_CUBES; y++)
-          for(int z = 0; z< NUM_CUBES; z++)
-            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 )
-              {
-              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
-                {
-                mRotationAngle[x][y][z].removeAll();
-                mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
-                modifyCurrentPosition(x,y,z,quat);
-                }
-              }
+      return mScaleFactor*NUM_CUBES*RubikCube.TEXTURE_SIZE;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    private boolean belongsToRotation(int x, int y, int z, int vector, int row)
+    float getScreenWidth()
       {
-      switch(vector)
-        {
-        case RubikSurfaceView.VECTX: return mCurrentPosition[x][y][z].get1()==row;
-        case RubikSurfaceView.VECTY: return mCurrentPosition[x][y][z].get2()==row;
-        case RubikSurfaceView.VECTZ: return mCurrentPosition[x][y][z].get3()==row;
-        }
-
-      return false;
+      return mScreenWidth;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    private void modifyCurrentPosition(int x, int y, int z, Static4D quat)
+    float getScreenHeight()
       {
-      Static3D current = mCurrentPosition[x][y][z];
-      float beforeX = current.get1();
-      float beforeY = current.get2();
-      float beforeZ = current.get3();
-
-      float diff = 0.5f*(NUM_CUBES-1);
-
-      float cubitCenterX = beforeX - diff;
-      float cubitCenterY = beforeY - diff;
-      float cubitCenterZ = beforeZ - diff;
-
-      Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
-      Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
-
-      float rotatedX = rotatedCenter.get1() + diff;
-      float rotatedY = rotatedCenter.get2() + diff;
-      float rotatedZ = rotatedCenter.get3() + diff;
-
-      int roundedX = (int)(rotatedX+0.1f);
-      int roundedY = (int)(rotatedY+0.1f);
-      int roundedZ = (int)(rotatedZ+0.1f);
-
-      //android.util.Log.e("rubik", "before: ("+((int)beforeX)+","+((int)beforeY)+","+((int)beforeZ)+") after: ("+roundedX+","+roundedY+","+roundedZ+")");
-
-      mCurrentPosition[x][y][z].set1(roundedX);
-      mCurrentPosition[x][y][z].set2(roundedY);
-      mCurrentPosition[x][y][z].set3(roundedZ);
+      return mScreenHeight;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    float getScreenWidth()
+    RubikCube getCube()
       {
-      return mScreenWidth;
+      return mCube;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    float getScreenHeight()
+    int getScreenMin()
       {
-      return mScreenHeight;
+      return mScreenWidth<mScreenHeight ? mScreenWidth:mScreenHeight;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -441,6 +204,7 @@ class RubikRenderer implements GLSurfaceView.Renderer
     void setQuatCurrent(Static4D current)
       {
       mTempCurrent.set(current);
+      mFinishDragCurrent = true;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -448,5 +212,6 @@ class RubikRenderer implements GLSurfaceView.Renderer
     void setQuatAccumulated(Static4D accumulated)
       {
       mTempAccumulated.set(accumulated);
+      mFinishDragAccumulated = true;
       }
 }
diff --git a/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java b/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
index b6e4608..d797cdd 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
+// Copyright 2019 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Distorted.                                                               //
 //                                                                                               //
@@ -54,6 +54,7 @@ class RubikSurfaceView extends GLSurfaceView
     private Static4D mQuatCurrent, mQuatAccumulated;
     private int mRotationVect;
     private RubikRenderer mRenderer;
+    private RubikCube mCube;
 
     private float mPoiX, mPoiY, mPoiZ, mCamX, mCamY, mCamZ;
     private float mStartX, mStartY, mStartZ;
@@ -70,6 +71,7 @@ class RubikSurfaceView extends GLSurfaceView
       mRotationVect = VECTN;
 
       mRenderer = new RubikRenderer(this);
+      mCube = mRenderer.getCube();
 
       mQuatCurrent     = new Static4D(0,0,0,1);
       mQuatAccumulated = mRenderer.initializeQuat();
@@ -113,7 +115,8 @@ class RubikSurfaceView extends GLSurfaceView
                                          }
                                        else if( mRotating )
                                          {
-                                         int minimumToRotate = (mRenderer.mScreenMin*mRenderer.mScreenMin)/36;
+                                         int screenMin = mRenderer.getScreenMin();
+                                         int minimumToRotate = (screenMin*screenMin)/64;
 
                                          if( (mX-x)*(mX-x)+(mY-y)*(mY-y)>minimumToRotate )
                                            {
@@ -191,7 +194,7 @@ class RubikSurfaceView extends GLSurfaceView
       mStartY = diffY + mStartY;
       mStartZ = diffZ + mStartZ;
 
-      mRenderer.addNewRotation(mRotationVect,row);
+      mCube.addNewRotation(mRotationVect,row);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -241,7 +244,7 @@ class RubikSurfaceView extends GLSurfaceView
       float dY = mY-y;
       float calibration = (float)Math.sqrt(dX*dX+dY*dY);
 
-      mRenderer.continueRotation(calibration*sign);
+      mCube.continueRotation(calibration*sign, mRenderer.getScreenMin());
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -249,7 +252,6 @@ class RubikSurfaceView extends GLSurfaceView
     private void finishRotation()
       {
       mRotationVect = VECTN;
-
       mRenderer.finishRotation();
       }
 
@@ -339,7 +341,7 @@ class RubikSurfaceView extends GLSurfaceView
         axisY /= axisL;
         axisZ /= axisL;
 
-        float cosA = (float)Math.cos(axisL*Math.PI/mRenderer.mScreenMin);
+        float cosA = (float)Math.cos(axisL*Math.PI/mRenderer.getScreenMin());
         float sinA = (float)Math.sqrt(1-cosA*cosA);
 
         return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
