commit 483ae94ed8a90bbcddce8fc6841f58b6a9bb86c2
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sun Apr 7 14:12:39 2019 +0100

    RubikApp: properly compute cameraDistance and FOV.

diff --git a/src/main/java/org/distorted/examples/rubik/RubikCube.java b/src/main/java/org/distorted/examples/rubik/RubikCube.java
index f6e5e4b..59a03c4 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikCube.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikCube.java
@@ -254,15 +254,10 @@ class RubikCube
     private void modifyCurrentPosition(int x, int y, int z, Static4D quat)
       {
       Static3D current = mCurrentPosition[x][y][z];
-      float beforeX = current.get1();
-      float beforeY = current.get2();
-      float beforeZ = current.get3();
-
       float diff = 0.5f*(mSize-1);
-
-      float cubitCenterX = beforeX - diff;
-      float cubitCenterY = beforeY - diff;
-      float cubitCenterZ = beforeZ - diff;
+      float cubitCenterX = current.get1() - diff;
+      float cubitCenterY = current.get2() - diff;
+      float cubitCenterZ = current.get3() - diff;
 
       Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
       Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
@@ -326,29 +321,15 @@ class RubikCube
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    float getWidth()
-      {
-      return mTexture.getWidth();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    float getHeight()
-      {
-      return mTexture.getHeight();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    float getDepth()
+    float getTextureSize()
       {
-      return mTexture.getDepth(mCubes[0][0][0]);
+      return TEXTURE_SIZE;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    float getSizeInModelSpace()
+    float getSize()
       {
-      return mSize*TEXTURE_SIZE;
+      return mSize;
       }
 }
diff --git a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
index 312cf44..54cf38f 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
@@ -36,13 +36,14 @@ class RubikRenderer implements GLSurfaceView.Renderer
 {
     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 RubikSurfaceView mView;
     private DistortedScreen mScreen;
     private Static3D mMove, mScale;
     private Static4D mQuatCurrent, mQuatAccumulated;
     private Static4D mTempCurrent, mTempAccumulated;
-    private float mScaleFactor;
+    private float mCubeSizeInScreenSpace;
     private boolean mFinishRotation, mFinishDragCurrent, mFinishDragAccumulated;
     private RubikCube mCube;
 
@@ -98,21 +99,19 @@ class RubikRenderer implements GLSurfaceView.Renderer
     
     public void onSurfaceChanged(GL10 glUnused, int width, int height) 
       {
-      float fovInDegrees = (width>height ? 60.0f : 90.0f);
+      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
+      float fovInDegrees   = computeFOV(cameraDistance,height);
 
       mScreen.setProjection( fovInDegrees, 0.1f);
-
       mView.setScreenSize(width,height);
-      mView.recomputeCameraDistance(fovInDegrees*Math.PI/180);
-
-      float w = mCube.getWidth();
-      float h = mCube.getHeight();
-      float d = mCube.getDepth();
+      mView.setCameraDist(cameraDistance);
 
-      mScaleFactor = CUBE_SCREEN_RATIO*(width>height ? height:width)/mCube.getSizeInModelSpace();
+      mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(width>height ? height:width);
+      float texSize = mCube.getTextureSize();
+      float scaleFactor = mCubeSizeInScreenSpace/(texSize*mCube.getSize());
 
-      mMove.set( (width-mScaleFactor*w)/2 , (height-mScaleFactor*h)/2 , -mScaleFactor*d/2 );
-      mScale.set(mScaleFactor,mScaleFactor,mScaleFactor);
+      mMove.set( (width-scaleFactor*texSize)/2 , (height-scaleFactor*texSize)/2 , -scaleFactor*texSize/2 );
+      mScale.set(scaleFactor,scaleFactor,scaleFactor);
 
       mScreen.resize(width, height);
       }
@@ -137,6 +136,16 @@ 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;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // no this will not race with onDrawFrame
 
@@ -149,7 +158,7 @@ class RubikRenderer implements GLSurfaceView.Renderer
 
     float returnCubeSizeInScreenSpace()
       {
-      return mScaleFactor*mCube.getSizeInModelSpace();
+      return mCubeSizeInScreenSpace;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java b/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
index b086443..3b30b12 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
@@ -160,9 +160,9 @@ class RubikSurfaceView extends GLSurfaceView
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    void recomputeCameraDistance(double fovInRadians)
+    void setCameraDist(float distance)
       {
-      mCameraDistance = (float)((mScreenHeight*0.5f)/Math.tan(fovInRadians*0.5));
+      mCameraDistance = distance;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -224,6 +224,8 @@ class RubikSurfaceView extends GLSurfaceView
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// 240 --> moving finger from the middle of the vertical screen to the right edge will rotate a
+// given face by 240/2 = 120 degrees.
 
     private void continueRotation(int x, int y)
       {
