commit db5d943eee52f307e7e8bdaf1d1e0c24684402ca
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Wed Jun 22 13:52:42 2016 +0100

    Rename Effects3D to Matrix3D

diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index d9218d1..63eac2e 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -34,7 +34,7 @@
         <activity android:name=".olimpic.OlimpicActivity" />  
         <activity android:name=".cubes.CubesActivity" />       
         <activity android:name=".quaternion.QuaternionActivity" />          
-        <activity android:name=".effects3d.Effects3DActivity" />  
+        <activity android:name=".matrix3d.Matrix3DActivity" />
         <activity android:name=".plainmonalisa.PlainMonaLisaActivity" />
         <activity android:name=".save.SaveActivity"/>
     </application>
diff --git a/src/main/java/org/distorted/examples/TableOfContents.java b/src/main/java/org/distorted/examples/TableOfContents.java
index 1755e62..3461bf4 100644
--- a/src/main/java/org/distorted/examples/TableOfContents.java
+++ b/src/main/java/org/distorted/examples/TableOfContents.java
@@ -53,7 +53,7 @@ import org.distorted.examples.fbo.FBOActivity;
 import org.distorted.examples.starwars.StarWarsActivity;
 import org.distorted.examples.cubes.CubesActivity;
 import org.distorted.examples.quaternion.QuaternionActivity;
-import org.distorted.examples.effects3d.Effects3DActivity;
+import org.distorted.examples.matrix3d.Matrix3DActivity;
 import org.distorted.examples.plainmonalisa.PlainMonaLisaActivity;
 import org.distorted.examples.save.SaveActivity;
 
@@ -251,11 +251,11 @@ public class TableOfContents extends ListActivity
    
    {
       final Map<String, Object> item = new HashMap<>();
-      item.put(ITEM_IMAGE, R.drawable.icon_example_effects3d);
-      item.put(ITEM_TITLE, (i+1)+". "+getText(R.string.example_effects3d));
-      item.put(ITEM_SUBTITLE, getText(R.string.example_effects3d_subtitle));
+      item.put(ITEM_IMAGE, R.drawable.icon_example_matrix3d);
+      item.put(ITEM_TITLE, (i+1)+". "+getText(R.string.example_matrix3d));
+      item.put(ITEM_SUBTITLE, getText(R.string.example_matrix3d_subtitle));
       data.add(item);
-      activityMapping.put(i++, Effects3DActivity.class);
+      activityMapping.put(i++, Matrix3DActivity.class);
    }
 
    {
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java b/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
deleted file mode 100644
index 4009b54..0000000
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
+++ /dev/null
@@ -1,387 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.examples.effects3d;
-
-import org.distorted.library.Distorted;
-import org.distorted.examples.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.opengl.GLSurfaceView;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.SeekBar;
-import android.widget.TextView;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class Effects3DActivity extends Activity implements OnSeekBarChangeListener
-{
-    public static final int MOVE   =0;
-    public static final int SCALE  =1;
-    public static final int ROTATE =2;
-    public static final int SHEAR  =3;
-	
-    private SeekBar bar;
-    private TextView textMove, textScale, textRotate, textShear;
-    private int moveX, moveY, moveZ;
-    private int scaleX, scaleY, scaleZ;
-    private int rotateX, rotateY, rotateZ, rotateA;
-    private int shearX, shearY, shearZ;
-    
-    private int maxX, maxY, maxZ;
-    
-    private float fmoveX, fmoveY, fmoveZ;
-    private float fscaleX, fscaleY, fscaleZ;
-    private float frotateX, frotateY, frotateZ, frotateA;
-    private float fshearX, fshearY, fshearZ;
-    
-    private int[] effects = new int[4];
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    protected void onCreate(Bundle icicle) 
-      {
-      super.onCreate(icicle);
-      setContentView(R.layout.effects3dlayout);
-      Default(null);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void Default(View view)
-      {
-      effects[0] = MOVE;
-      effects[1] = SCALE;
-      effects[2] = ROTATE;
-      effects[3] = SHEAR;
-    
-      moveX = 50;
-      moveY = 50;
-      moveZ = 50;
-      
-      scaleX = 50;
-      scaleY = 50;
-      scaleZ = 50;
-      
-      rotateX = 100;
-      rotateY =  50;
-      rotateZ =  50;
-      rotateA =  50;
-      
-      shearX = 50;
-      shearY = 50;
-      shearZ = 50;
-      
-      addViews();
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    private void addViews()
-      {
-      LinearLayout layout = (LinearLayout)findViewById(R.id.matrix3dlayout);
-    
-      layout.removeAllViews();
-      
-      View move   = getLayoutInflater().inflate(R.layout.effects3dmove   , null);
-      View scale  = getLayoutInflater().inflate(R.layout.effects3dscale  , null);
-      View rotate = getLayoutInflater().inflate(R.layout.effects3drotate , null);
-      View shear  = getLayoutInflater().inflate(R.layout.effects3dshear  , null);
-     
-      for( int i=effects.length-1 ; i>=0 ; i-- )
-        {
-        switch(effects[i])
-          {
-          case MOVE  : layout.addView(move   , 0); break; 
-          case SCALE : layout.addView(scale  , 0); break;
-          case ROTATE: layout.addView(rotate , 0); break;
-          case SHEAR : layout.addView(shear  , 0); break;
-          }
-        }
-      
-      textMove  = (TextView)findViewById(R.id.matrix3dmoveText);
-      textScale = (TextView)findViewById(R.id.matrix3dscaleText);
-      textRotate= (TextView)findViewById(R.id.matrix3drotateText);
-      textShear = (TextView)findViewById(R.id.matrix3dshearText);
-     
-      setMoveText();
-      setScaleText();
-      setRotateText();
-      setShearText();
-      
-      setBar(R.id.matrix3dmoveBar1, moveX);
-      setBar(R.id.matrix3dmoveBar2, moveY);
-      setBar(R.id.matrix3dmoveBar3, moveZ);
-      
-      setBar(R.id.matrix3dscaleBar1, scaleX);
-      setBar(R.id.matrix3dscaleBar2, scaleY);
-      setBar(R.id.matrix3dscaleBar3, scaleZ);
-      
-      setBar(R.id.matrix3drotateBar1, rotateX);
-      setBar(R.id.matrix3drotateBar2, rotateY);
-      setBar(R.id.matrix3drotateBar3, rotateZ);
-      setBar(R.id.matrix3drotateBar4, rotateA);
-      
-      setBar(R.id.matrix3dshearBar1, shearX);
-      setBar(R.id.matrix3dshearBar2, shearY);
-      setBar(R.id.matrix3dshearBar3, shearZ);
-      
-      Effects3DRenderer.setOrder(effects);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void moveUp(int effect)
-      {
-      int len = effects.length-1;	
-      int index = -1;
-      
-      for(int i=0; i<=len; i++)	
-        {
-        if( effects[i]==effect ) 
-          {
-          index=i;
-          break;
-          }
-        }
-      
-      if( index==0 )
-        {
-        for(int i=0; i<len; i++)
-          effects[i] = effects[i+1];
-    	
-        effects[len] = effect;
-        }
-      else if( index>0 )
-        {
-        effects[index]   = effects[index-1];
-        effects[index-1] = effect;
-        }
-      
-      addViews();
-      }
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void ButtonMove(View v)
-      {
-      moveUp(MOVE); 	
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void ButtonScale(View v)
-      {
-      moveUp(SCALE); 	
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void ButtonRotate(View v)
-      {
-      moveUp(ROTATE); 	
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void ButtonShear(View v)
-      {
-      moveUp(SHEAR); 	
-      }
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    private void setBar(int id, int value)
-      {
-      bar = (SeekBar)findViewById(id);
-      bar.setOnSeekBarChangeListener(this); 
-      bar.setProgress(value);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void computeMove()
-      {
-      fmoveX = (moveX-50)*maxX/50.0f;
-      fmoveY = (moveY-50)*maxY/50.0f;
-      fmoveZ = (moveZ-50)*maxZ/50.0f;
-
-      Effects3DRenderer.setMove( fmoveX, fmoveY, fmoveZ);
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void setMoveText()
-      {
-      fmoveX = ((int)(100*fmoveX))/100.0f;
-      fmoveY = ((int)(100*fmoveY))/100.0f;
-      fmoveZ = ((int)(100*fmoveZ))/100.0f;
-      
-      textMove.setText("move("+fmoveX+" , "+fmoveY+" , "+fmoveZ+")");
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void computeScale()
-      {
-      fscaleX = (scaleX>50 ? 0.18f : 0.018f)*(scaleX-50)+1;
-      fscaleY = (scaleY>50 ? 0.18f : 0.018f)*(scaleY-50)+1;
-      fscaleZ = (scaleZ>50 ? 0.18f : 0.018f)*(scaleZ-50)+1;
-
-      Effects3DRenderer.setScale(fscaleX, fscaleY, fscaleZ);
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void setScaleText()
-      {
-      fscaleX = ((int)(100*fscaleX))/100.0f;
-      fscaleY = ((int)(100*fscaleY))/100.0f;
-      fscaleZ = ((int)(100*fscaleZ))/100.0f;
-      
-      textScale.setText("scale("+fscaleX+" , "+fscaleY+" , "+fscaleZ+")");
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void computeRotate()
-      {
-      frotateX = (rotateX-50)/50.0f;
-      frotateY = (rotateY-50)/50.0f;
-      frotateZ = (rotateZ-50)/50.0f;
-    
-      Effects3DRenderer.setRotate( frotateA, frotateX, frotateY, frotateZ );
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void setRotateText()
-      {
-      frotateX = ((int)(100*frotateX))/100.0f;
-      frotateY = ((int)(100*frotateY))/100.0f;
-      frotateZ = ((int)(100*frotateZ))/100.0f;
-      
-      frotateA = ((rotateA-50)*180)/50;
-      
-      textRotate.setText("rotate( "+frotateA+" ("+frotateX+","+frotateY+","+frotateZ+") )");
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void computeShear()
-      {
-      fshearX = (shearX-50)/25.0f;
-      fshearY = (shearY-50)/25.0f;
-      fshearZ = (shearZ-50)/25.0f;
-    		
-      Effects3DRenderer.setShear( fshearX, fshearY, fshearZ );
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private void setShearText()
-      {
-      fshearX = ((int)(100*fshearX))/100.0f;
-      fshearY = ((int)(100*fshearY))/100.0f;
-      fshearZ = ((int)(100*fshearZ))/100.0f;
-      
-      textShear.setText("shear("+fshearX+" , "+fshearY+" , "+fshearZ+")");	
-      }
-   
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    protected void onPause() 
-      {
-      GLSurfaceView mView = (GLSurfaceView) this.findViewById(R.id.effects3dSurfaceView);
-      mView.onPause(); 
-      super.onPause();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    protected void onResume() 
-      {
-      super.onResume();
-      GLSurfaceView mView = (GLSurfaceView) this.findViewById(R.id.effects3dSurfaceView); 
-      mView.onResume();
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) 
-      {
-      super.onWindowFocusChanged(hasFocus);
-  
-      GLSurfaceView mView = (GLSurfaceView) this.findViewById(R.id.effects3dSurfaceView);
-      
-      maxX = mView.getWidth();
-      maxY = mView.getHeight();
-      maxZ = (maxX+maxY)/2;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    @Override
-    protected void onDestroy() 
-      {
-      Distorted.onDestroy();  
-      super.onDestroy();
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    public void onProgressChanged(SeekBar bar, int progress, boolean fromUser) 
-      {
-      switch (bar.getId()) 
-        {
-        case R.id.matrix3dmoveBar1  : moveX = progress; computeMove()  ; setMoveText()  ; break;
-        case R.id.matrix3dmoveBar2  : moveY = progress; computeMove()  ; setMoveText()  ; break;
-        case R.id.matrix3dmoveBar3  : moveZ = progress; computeMove()  ; setMoveText()  ; break;
-        
-        case R.id.matrix3dscaleBar1 : scaleX= progress; computeScale() ; setScaleText() ; break;
-        case R.id.matrix3dscaleBar2 : scaleY= progress; computeScale() ; setScaleText() ; break;
-        case R.id.matrix3dscaleBar3 : scaleZ= progress; computeScale() ; setScaleText() ; break;
-        
-        case R.id.matrix3drotateBar1: rotateX=progress; computeRotate(); setRotateText(); break;
-        case R.id.matrix3drotateBar2: rotateY=progress; computeRotate(); setRotateText(); break;
-        case R.id.matrix3drotateBar3: rotateZ=progress; computeRotate(); setRotateText(); break;
-        case R.id.matrix3drotateBar4: rotateA=progress; computeRotate(); setRotateText(); break;
-        
-        case R.id.matrix3dshearBar1 : shearX= progress; computeShear() ; setShearText() ; break;
-        case R.id.matrix3dshearBar2 : shearY= progress; computeShear() ; setShearText() ; break;
-        case R.id.matrix3dshearBar3 : shearZ= progress; computeShear() ; setShearText() ; break;
-        }
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void onStartTrackingTouch(SeekBar bar) { }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public void onStopTrackingTouch(SeekBar bar)  { }
-    
-}
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java b/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
deleted file mode 100644
index 71f1e62..0000000
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
+++ /dev/null
@@ -1,190 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.examples.effects3d;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-import org.distorted.examples.R;
-
-import org.distorted.library.DistortedCubes;
-import org.distorted.library.EffectTypes;
-import org.distorted.library.type.Dynamic1D;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static1D;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.library.type.Dynamic4D;
-import org.distorted.library.Distorted;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.opengl.GLES20;
-import android.opengl.GLSurfaceView;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class Effects3DRenderer implements GLSurfaceView.Renderer 
-{
-    private static final int SIZE = 100;
-	
-    private GLSurfaceView mView;
-    private static DistortedCubes mCube;
-
-    private static int[] order;
-    
-    private static Dynamic3D mMoveInter, mScaleInter, mShearInter;
-    private static Dynamic4D mDynamicRotate;
-
-    private static Static3D mZeroPoint, mMovePoint, mScalePoint, mShearPoint;
-    private static Static4D mRotatePoint;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public static void setMove(float x, float y, float z)
-      {
-      mMovePoint.set(x, y, z);
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public static void setScale(float x, float y, float z)
-      {
-      mScalePoint.set(x, y, z);
-      }
-     
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public static void setRotate(float a, float x, float y, float z)
-      {
-      mRotatePoint.set(a,x,y,z);
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public static void setShear(float x, float y, float z)
-      {
-      mShearPoint.set(x, y, z);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public static void setOrder(int[] effects)
-      {
-      order = effects;
-      setMatrixEffects();
-      }
-      
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public static void setMatrixEffects()
-      {
-      mCube.abortEffects(EffectTypes.MATRIX);
-	
-      for( int i=0; i<=order.length-1 ; i++ )
-        {
-        switch(order[i])
-          {
-          case Effects3DActivity.MOVE  : mCube.move(mMoveInter)                 ; break;
-          case Effects3DActivity.SCALE : mCube.scale(mScaleInter)               ; break;
-          case Effects3DActivity.ROTATE: mCube.rotate(mDynamicRotate,mZeroPoint); break;
-          case Effects3DActivity.SHEAR : mCube.shear(mShearInter, mZeroPoint)   ; break;
-          }
-        }
-      }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    public Effects3DRenderer(GLSurfaceView v) 
-      {
-      mView = v;
-      mCube = new DistortedCubes( 1, "1", SIZE);
-      
-      mZeroPoint   = new Static3D(0,0,0);
-      mMovePoint   = new Static3D(0,0,0);
-      mScalePoint  = new Static3D(1,1,1);
-      mShearPoint  = new Static3D(0,0,0);
-      mRotatePoint = new Static4D(0,1,0,0);
-
-      mMoveInter    = new Dynamic3D();
-      mScaleInter   = new Dynamic3D();
-      mShearInter   = new Dynamic3D();
-      mDynamicRotate= new Dynamic4D();
-
-      mMoveInter.add(mMovePoint);
-      mScaleInter.add(mScalePoint);
-      mShearInter.add(mShearPoint);
-      mDynamicRotate.add(mRotatePoint);
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-   
-    public void onDrawFrame(GL10 glUnused) 
-      {
-      GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-      GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
-      
-      mCube.draw(System.currentTimeMillis());
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
-      {
-      setMatrixEffects();
-
-      Distorted.onSurfaceChanged(width, height); 
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
-      {
-      InputStream is = mView.getContext().getResources().openRawResource(R.raw.grid);
-      Bitmap bitmap;
-        
-      try 
-        {
-        bitmap = BitmapFactory.decodeStream(is);
-        } 
-      finally 
-        {
-        try 
-          {
-          is.close();
-          } 
-        catch(IOException e) { }
-        }  
-      
-      mCube.setBitmap(bitmap);
-      
-      try
-        {
-        Distorted.onSurfaceCreated(mView.getContext());
-        }
-      catch(Exception ex)
-        {
-        android.util.Log.e("Quaternion", ex.getMessage() );
-        }
-      }
-}
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DSurfaceView.java b/src/main/java/org/distorted/examples/effects3d/Effects3DSurfaceView.java
deleted file mode 100644
index 38eb9ae..0000000
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DSurfaceView.java
+++ /dev/null
@@ -1,50 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.examples.effects3d;
-
-import android.content.Context;
-import android.opengl.GLSurfaceView;
-import android.os.Build;
-import android.util.AttributeSet;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class Effects3DSurfaceView extends GLSurfaceView 
-{
-///////////////////////////////////////////////////////////////////////////////////////////////////
-   
-    public Effects3DSurfaceView(Context c, AttributeSet attrs) 
-      {
-      super(c, attrs);
-      
-      if(!isInEditMode())
-        {
-        setEGLContextClientVersion(2);
-        
-        if( Build.FINGERPRINT.startsWith("generic") )
-          { 
-          setEGLConfigChooser(8, 8, 8, 8, 16, 0);   
-          }
-        
-        setRenderer(new Effects3DRenderer(this));
-        }
-      }
-}
-
diff --git a/src/main/java/org/distorted/examples/matrix3d/Matrix3DActivity.java b/src/main/java/org/distorted/examples/matrix3d/Matrix3DActivity.java
new file mode 100644
index 0000000..e647e86
--- /dev/null
+++ b/src/main/java/org/distorted/examples/matrix3d/Matrix3DActivity.java
@@ -0,0 +1,387 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.examples.matrix3d;
+
+import org.distorted.library.Distorted;
+import org.distorted.examples.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.opengl.GLSurfaceView;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class Matrix3DActivity extends Activity implements OnSeekBarChangeListener
+{
+    public static final int MOVE   =0;
+    public static final int SCALE  =1;
+    public static final int ROTATE =2;
+    public static final int SHEAR  =3;
+	
+    private SeekBar bar;
+    private TextView textMove, textScale, textRotate, textShear;
+    private int moveX, moveY, moveZ;
+    private int scaleX, scaleY, scaleZ;
+    private int rotateX, rotateY, rotateZ, rotateA;
+    private int shearX, shearY, shearZ;
+    
+    private int maxX, maxY, maxZ;
+    
+    private float fmoveX, fmoveY, fmoveZ;
+    private float fscaleX, fscaleY, fscaleZ;
+    private float frotateX, frotateY, frotateZ, frotateA;
+    private float fshearX, fshearY, fshearZ;
+    
+    private int[] effects = new int[4];
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onCreate(Bundle icicle) 
+      {
+      super.onCreate(icicle);
+      setContentView(R.layout.matrix3dlayout);
+      Default(null);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void Default(View view)
+      {
+      effects[0] = MOVE;
+      effects[1] = SCALE;
+      effects[2] = ROTATE;
+      effects[3] = SHEAR;
+    
+      moveX = 50;
+      moveY = 50;
+      moveZ = 50;
+      
+      scaleX = 50;
+      scaleY = 50;
+      scaleZ = 50;
+      
+      rotateX = 100;
+      rotateY =  50;
+      rotateZ =  50;
+      rotateA =  50;
+      
+      shearX = 50;
+      shearY = 50;
+      shearZ = 50;
+      
+      addViews();
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    private void addViews()
+      {
+      LinearLayout layout = (LinearLayout)findViewById(R.id.matrix3dlayout);
+    
+      layout.removeAllViews();
+      
+      View move   = getLayoutInflater().inflate(R.layout.matrix3dmove, null);
+      View scale  = getLayoutInflater().inflate(R.layout.matrix3dscale, null);
+      View rotate = getLayoutInflater().inflate(R.layout.matrix3drotate, null);
+      View shear  = getLayoutInflater().inflate(R.layout.matrix3dshear, null);
+     
+      for( int i=effects.length-1 ; i>=0 ; i-- )
+        {
+        switch(effects[i])
+          {
+          case MOVE  : layout.addView(move   , 0); break; 
+          case SCALE : layout.addView(scale  , 0); break;
+          case ROTATE: layout.addView(rotate , 0); break;
+          case SHEAR : layout.addView(shear  , 0); break;
+          }
+        }
+      
+      textMove  = (TextView)findViewById(R.id.matrix3dmoveText);
+      textScale = (TextView)findViewById(R.id.matrix3dscaleText);
+      textRotate= (TextView)findViewById(R.id.matrix3drotateText);
+      textShear = (TextView)findViewById(R.id.matrix3dshearText);
+     
+      setMoveText();
+      setScaleText();
+      setRotateText();
+      setShearText();
+      
+      setBar(R.id.matrix3dmoveBar1, moveX);
+      setBar(R.id.matrix3dmoveBar2, moveY);
+      setBar(R.id.matrix3dmoveBar3, moveZ);
+      
+      setBar(R.id.matrix3dscaleBar1, scaleX);
+      setBar(R.id.matrix3dscaleBar2, scaleY);
+      setBar(R.id.matrix3dscaleBar3, scaleZ);
+      
+      setBar(R.id.matrix3drotateBar1, rotateX);
+      setBar(R.id.matrix3drotateBar2, rotateY);
+      setBar(R.id.matrix3drotateBar3, rotateZ);
+      setBar(R.id.matrix3drotateBar4, rotateA);
+      
+      setBar(R.id.matrix3dshearBar1, shearX);
+      setBar(R.id.matrix3dshearBar2, shearY);
+      setBar(R.id.matrix3dshearBar3, shearZ);
+      
+      Matrix3DRenderer.setOrder(effects);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void moveUp(int effect)
+      {
+      int len = effects.length-1;	
+      int index = -1;
+      
+      for(int i=0; i<=len; i++)	
+        {
+        if( effects[i]==effect ) 
+          {
+          index=i;
+          break;
+          }
+        }
+      
+      if( index==0 )
+        {
+        for(int i=0; i<len; i++)
+          effects[i] = effects[i+1];
+    	
+        effects[len] = effect;
+        }
+      else if( index>0 )
+        {
+        effects[index]   = effects[index-1];
+        effects[index-1] = effect;
+        }
+      
+      addViews();
+      }
+ 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void ButtonMove(View v)
+      {
+      moveUp(MOVE); 	
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void ButtonScale(View v)
+      {
+      moveUp(SCALE); 	
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void ButtonRotate(View v)
+      {
+      moveUp(ROTATE); 	
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void ButtonShear(View v)
+      {
+      moveUp(SHEAR); 	
+      }
+ 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    private void setBar(int id, int value)
+      {
+      bar = (SeekBar)findViewById(id);
+      bar.setOnSeekBarChangeListener(this); 
+      bar.setProgress(value);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void computeMove()
+      {
+      fmoveX = (moveX-50)*maxX/50.0f;
+      fmoveY = (moveY-50)*maxY/50.0f;
+      fmoveZ = (moveZ-50)*maxZ/50.0f;
+
+      Matrix3DRenderer.setMove( fmoveX, fmoveY, fmoveZ);
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void setMoveText()
+      {
+      fmoveX = ((int)(100*fmoveX))/100.0f;
+      fmoveY = ((int)(100*fmoveY))/100.0f;
+      fmoveZ = ((int)(100*fmoveZ))/100.0f;
+      
+      textMove.setText("move("+fmoveX+" , "+fmoveY+" , "+fmoveZ+")");
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void computeScale()
+      {
+      fscaleX = (scaleX>50 ? 0.18f : 0.018f)*(scaleX-50)+1;
+      fscaleY = (scaleY>50 ? 0.18f : 0.018f)*(scaleY-50)+1;
+      fscaleZ = (scaleZ>50 ? 0.18f : 0.018f)*(scaleZ-50)+1;
+
+      Matrix3DRenderer.setScale(fscaleX, fscaleY, fscaleZ);
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void setScaleText()
+      {
+      fscaleX = ((int)(100*fscaleX))/100.0f;
+      fscaleY = ((int)(100*fscaleY))/100.0f;
+      fscaleZ = ((int)(100*fscaleZ))/100.0f;
+      
+      textScale.setText("scale("+fscaleX+" , "+fscaleY+" , "+fscaleZ+")");
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void computeRotate()
+      {
+      frotateX = (rotateX-50)/50.0f;
+      frotateY = (rotateY-50)/50.0f;
+      frotateZ = (rotateZ-50)/50.0f;
+    
+      Matrix3DRenderer.setRotate( frotateA, frotateX, frotateY, frotateZ );
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void setRotateText()
+      {
+      frotateX = ((int)(100*frotateX))/100.0f;
+      frotateY = ((int)(100*frotateY))/100.0f;
+      frotateZ = ((int)(100*frotateZ))/100.0f;
+      
+      frotateA = ((rotateA-50)*180)/50;
+      
+      textRotate.setText("rotate( "+frotateA+" ("+frotateX+","+frotateY+","+frotateZ+") )");
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void computeShear()
+      {
+      fshearX = (shearX-50)/25.0f;
+      fshearY = (shearY-50)/25.0f;
+      fshearZ = (shearZ-50)/25.0f;
+    		
+      Matrix3DRenderer.setShear( fshearX, fshearY, fshearZ );
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void setShearText()
+      {
+      fshearX = ((int)(100*fshearX))/100.0f;
+      fshearY = ((int)(100*fshearY))/100.0f;
+      fshearZ = ((int)(100*fshearZ))/100.0f;
+      
+      textShear.setText("shear("+fshearX+" , "+fshearY+" , "+fshearZ+")");	
+      }
+   
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onPause() 
+      {
+      GLSurfaceView mView = (GLSurfaceView) this.findViewById(R.id.matrix3dSurfaceView);
+      mView.onPause(); 
+      super.onPause();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onResume() 
+      {
+      super.onResume();
+      GLSurfaceView mView = (GLSurfaceView) this.findViewById(R.id.matrix3dSurfaceView);
+      mView.onResume();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) 
+      {
+      super.onWindowFocusChanged(hasFocus);
+  
+      GLSurfaceView mView = (GLSurfaceView) this.findViewById(R.id.matrix3dSurfaceView);
+      
+      maxX = mView.getWidth();
+      maxY = mView.getHeight();
+      maxZ = (maxX+maxY)/2;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onDestroy() 
+      {
+      Distorted.onDestroy();  
+      super.onDestroy();
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    public void onProgressChanged(SeekBar bar, int progress, boolean fromUser) 
+      {
+      switch (bar.getId()) 
+        {
+        case R.id.matrix3dmoveBar1  : moveX = progress; computeMove()  ; setMoveText()  ; break;
+        case R.id.matrix3dmoveBar2  : moveY = progress; computeMove()  ; setMoveText()  ; break;
+        case R.id.matrix3dmoveBar3  : moveZ = progress; computeMove()  ; setMoveText()  ; break;
+        
+        case R.id.matrix3dscaleBar1 : scaleX= progress; computeScale() ; setScaleText() ; break;
+        case R.id.matrix3dscaleBar2 : scaleY= progress; computeScale() ; setScaleText() ; break;
+        case R.id.matrix3dscaleBar3 : scaleZ= progress; computeScale() ; setScaleText() ; break;
+        
+        case R.id.matrix3drotateBar1: rotateX=progress; computeRotate(); setRotateText(); break;
+        case R.id.matrix3drotateBar2: rotateY=progress; computeRotate(); setRotateText(); break;
+        case R.id.matrix3drotateBar3: rotateZ=progress; computeRotate(); setRotateText(); break;
+        case R.id.matrix3drotateBar4: rotateA=progress; computeRotate(); setRotateText(); break;
+        
+        case R.id.matrix3dshearBar1 : shearX= progress; computeShear() ; setShearText() ; break;
+        case R.id.matrix3dshearBar2 : shearY= progress; computeShear() ; setShearText() ; break;
+        case R.id.matrix3dshearBar3 : shearZ= progress; computeShear() ; setShearText() ; break;
+        }
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void onStartTrackingTouch(SeekBar bar) { }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void onStopTrackingTouch(SeekBar bar)  { }
+    
+}
diff --git a/src/main/java/org/distorted/examples/matrix3d/Matrix3DRenderer.java b/src/main/java/org/distorted/examples/matrix3d/Matrix3DRenderer.java
new file mode 100644
index 0000000..d070da6
--- /dev/null
+++ b/src/main/java/org/distorted/examples/matrix3d/Matrix3DRenderer.java
@@ -0,0 +1,188 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.examples.matrix3d;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import org.distorted.examples.R;
+
+import org.distorted.library.DistortedCubes;
+import org.distorted.library.EffectTypes;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+import org.distorted.library.type.Dynamic4D;
+import org.distorted.library.Distorted;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class Matrix3DRenderer implements GLSurfaceView.Renderer
+{
+    private static final int SIZE = 100;
+	
+    private GLSurfaceView mView;
+    private static DistortedCubes mCube;
+
+    private static int[] order;
+    
+    private static Dynamic3D mMoveInter, mScaleInter, mShearInter;
+    private static Dynamic4D mDynamicRotate;
+
+    private static Static3D mZeroPoint, mMovePoint, mScalePoint, mShearPoint;
+    private static Static4D mRotatePoint;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public static void setMove(float x, float y, float z)
+      {
+      mMovePoint.set(x, y, z);
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public static void setScale(float x, float y, float z)
+      {
+      mScalePoint.set(x, y, z);
+      }
+     
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public static void setRotate(float a, float x, float y, float z)
+      {
+      mRotatePoint.set(a,x,y,z);
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public static void setShear(float x, float y, float z)
+      {
+      mShearPoint.set(x, y, z);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public static void setOrder(int[] effects)
+      {
+      order = effects;
+      setMatrixEffects();
+      }
+      
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public static void setMatrixEffects()
+      {
+      mCube.abortEffects(EffectTypes.MATRIX);
+	
+      for( int i=0; i<=order.length-1 ; i++ )
+        {
+        switch(order[i])
+          {
+          case Matrix3DActivity.MOVE  : mCube.move(mMoveInter)                 ; break;
+          case Matrix3DActivity.SCALE : mCube.scale(mScaleInter)               ; break;
+          case Matrix3DActivity.ROTATE: mCube.rotate(mDynamicRotate,mZeroPoint); break;
+          case Matrix3DActivity.SHEAR : mCube.shear(mShearInter, mZeroPoint)   ; break;
+          }
+        }
+      }
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public Matrix3DRenderer(GLSurfaceView v)
+      {
+      mView = v;
+      mCube = new DistortedCubes( 1, "1", SIZE);
+      
+      mZeroPoint   = new Static3D(0,0,0);
+      mMovePoint   = new Static3D(0,0,0);
+      mScalePoint  = new Static3D(1,1,1);
+      mShearPoint  = new Static3D(0,0,0);
+      mRotatePoint = new Static4D(0,1,0,0);
+
+      mMoveInter    = new Dynamic3D();
+      mScaleInter   = new Dynamic3D();
+      mShearInter   = new Dynamic3D();
+      mDynamicRotate= new Dynamic4D();
+
+      mMoveInter.add(mMovePoint);
+      mScaleInter.add(mScalePoint);
+      mShearInter.add(mShearPoint);
+      mDynamicRotate.add(mRotatePoint);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+   
+    public void onDrawFrame(GL10 glUnused) 
+      {
+      GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+      GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+      
+      mCube.draw(System.currentTimeMillis());
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
+      {
+      setMatrixEffects();
+
+      Distorted.onSurfaceChanged(width, height); 
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
+      {
+      InputStream is = mView.getContext().getResources().openRawResource(R.raw.grid);
+      Bitmap bitmap;
+        
+      try 
+        {
+        bitmap = BitmapFactory.decodeStream(is);
+        } 
+      finally 
+        {
+        try 
+          {
+          is.close();
+          } 
+        catch(IOException e) { }
+        }  
+      
+      mCube.setBitmap(bitmap);
+      
+      try
+        {
+        Distorted.onSurfaceCreated(mView.getContext());
+        }
+      catch(Exception ex)
+        {
+        android.util.Log.e("Quaternion", ex.getMessage() );
+        }
+      }
+}
diff --git a/src/main/java/org/distorted/examples/matrix3d/Matrix3DSurfaceView.java b/src/main/java/org/distorted/examples/matrix3d/Matrix3DSurfaceView.java
new file mode 100644
index 0000000..7bdc879
--- /dev/null
+++ b/src/main/java/org/distorted/examples/matrix3d/Matrix3DSurfaceView.java
@@ -0,0 +1,50 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.examples.matrix3d;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Build;
+import android.util.AttributeSet;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class Matrix3DSurfaceView extends GLSurfaceView
+{
+///////////////////////////////////////////////////////////////////////////////////////////////////
+   
+    public Matrix3DSurfaceView(Context c, AttributeSet attrs)
+      {
+      super(c, attrs);
+      
+      if(!isInEditMode())
+        {
+        setEGLContextClientVersion(2);
+        
+        if( Build.FINGERPRINT.startsWith("generic") )
+          { 
+          setEGLConfigChooser(8, 8, 8, 8, 16, 0);   
+          }
+        
+        setRenderer(new Matrix3DRenderer(this));
+        }
+      }
+}
+
diff --git a/src/main/res/drawable-hdpi/icon_example_effects3d.png b/src/main/res/drawable-hdpi/icon_example_effects3d.png
deleted file mode 100644
index 8074c9b..0000000
Binary files a/src/main/res/drawable-hdpi/icon_example_effects3d.png and /dev/null differ
diff --git a/src/main/res/drawable-hdpi/icon_example_matrix3d.png b/src/main/res/drawable-hdpi/icon_example_matrix3d.png
new file mode 100644
index 0000000..8074c9b
Binary files /dev/null and b/src/main/res/drawable-hdpi/icon_example_matrix3d.png differ
diff --git a/src/main/res/layout/effects3dlayout.xml b/src/main/res/layout/effects3dlayout.xml
deleted file mode 100644
index d7d2724..0000000
--- a/src/main/res/layout/effects3dlayout.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:orientation="vertical" >
-
-    <org.distorted.examples.effects3d.Effects3DSurfaceView
-        android:id="@+id/effects3dSurfaceView"
-        android:layout_width="fill_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1" />
-
-    <Button
-        android:id="@+id/button1"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:onClick="Default"
-        android:text="@string/Default" />
-
-    <ScrollView
-        android:id="@+id/matrix3dscrollView"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="0.82" >
-
-        <LinearLayout
-            android:id="@+id/matrix3dlayout"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical" >
-        </LinearLayout>
-
-    </ScrollView>
-
-</LinearLayout>
diff --git a/src/main/res/layout/effects3dmove.xml b/src/main/res/layout/effects3dmove.xml
deleted file mode 100644
index 6758825..0000000
--- a/src/main/res/layout/effects3dmove.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:id="@id/matrix3dRowMove"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal" >
-
-                <LinearLayout
-                    android:layout_width="0dp"
-                    android:layout_height="wrap_content"
-                    android:layout_weight="0.8"
-                    android:orientation="vertical" >
-
-                    <TextView
-                        android:id="@+id/matrix3dmoveText"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginStart="5dp"
-                        android:layout_marginTop="3dp"
-                        android:textAppearance="?android:attr/textAppearanceLarge" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dmoveBar1"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dmoveBar2"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dmoveBar3"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                </LinearLayout>
-
-                <Button
-                    android:id="@+id/matrix3dUpMove"
-                    android:layout_width="60dp"
-                    android:layout_height="fill_parent"
-                    android:onClick="ButtonMove"
-                    android:text="@string/Up" />
-
-            </LinearLayout>
diff --git a/src/main/res/layout/effects3drotate.xml b/src/main/res/layout/effects3drotate.xml
deleted file mode 100644
index df898da..0000000
--- a/src/main/res/layout/effects3drotate.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:id="@+id/matrix3dRowRotate"
-                android:orientation="horizontal"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" >
-
-                <LinearLayout
-                    android:layout_width="0dp"
-                    android:layout_height="match_parent"
-                    android:layout_weight="0.70"
-                    android:orientation="vertical" >
-
-                    <TextView
-                        android:id="@+id/matrix3drotateText"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginStart="5dp"
-                        android:layout_marginTop="3dp"
-                        android:textAppearance="?android:attr/textAppearanceLarge" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3drotateBar4"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3drotateBar1"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3drotateBar2"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3drotateBar3"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                </LinearLayout>
-
-                <Button
-                    android:id="@+id/matrix3dUpRotate"
-                    android:layout_width="60dp"
-                    android:layout_height="fill_parent"
-                    android:onClick="ButtonRotate"
-                    android:text="@string/Up" />
-
-            </LinearLayout>
\ No newline at end of file
diff --git a/src/main/res/layout/effects3dscale.xml b/src/main/res/layout/effects3dscale.xml
deleted file mode 100644
index 3c91178..0000000
--- a/src/main/res/layout/effects3dscale.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:id="@+id/matrix3dRowScale"
-                android:orientation="horizontal"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" >
-
-                <LinearLayout
-                    android:layout_width="0dp"
-                    android:layout_height="match_parent"
-                    android:layout_weight="0.70"
-                    android:orientation="vertical" >
-
-                    <TextView
-                        android:id="@+id/matrix3dscaleText"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginStart="5dp"
-                        android:layout_marginTop="3dp"
-                        android:textAppearance="?android:attr/textAppearanceLarge" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dscaleBar1"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dscaleBar2"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dscaleBar3"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                </LinearLayout>
-
-                <Button
-                    android:id="@+id/matrix3dUpScale"
-                    android:layout_width="60dp"
-                    android:layout_height="fill_parent"
-                    android:onClick="ButtonScale"
-                    android:text="@string/Up" />
-
-            </LinearLayout>
-           
\ No newline at end of file
diff --git a/src/main/res/layout/effects3dshear.xml b/src/main/res/layout/effects3dshear.xml
deleted file mode 100644
index 236b462..0000000
--- a/src/main/res/layout/effects3dshear.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:id="@+id/matrix3dRowShear"
-                android:orientation="horizontal"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" >
-
-                <LinearLayout
-                    android:layout_width="0dp"
-                    android:layout_height="match_parent"
-                    android:layout_weight="0.70"
-                    android:orientation="vertical" >
-
-                    <TextView
-                        android:id="@+id/matrix3dshearText"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginStart="5dp"
-                        android:layout_marginTop="3dp"
-                        android:textAppearance="?android:attr/textAppearanceLarge" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dshearBar1"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dshearBar2"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                    <SeekBar
-                        android:id="@+id/matrix3dshearBar3"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="end"
-                        android:layout_marginEnd="5dp"
-                        android:layout_marginLeft="5dp"
-                        android:layout_marginRight="5dp" />
-
-                </LinearLayout>
-
-                <Button
-                    android:id="@+id/matrix3dUpShear"
-                    android:layout_width="60dp"
-                    android:layout_height="fill_parent"
-                    android:onClick="ButtonShear"
-                    android:text="@string/Up" />
-
-            </LinearLayout>
\ No newline at end of file
diff --git a/src/main/res/layout/matrix3dlayout.xml b/src/main/res/layout/matrix3dlayout.xml
new file mode 100644
index 0000000..6102314
--- /dev/null
+++ b/src/main/res/layout/matrix3dlayout.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <org.distorted.examples.matrix3d.Matrix3DSurfaceView
+        android:id="@+id/matrix3dSurfaceView"
+        android:layout_width="fill_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
+
+    <Button
+        android:id="@+id/button1"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:onClick="Default"
+        android:text="@string/Default" />
+
+    <ScrollView
+        android:id="@+id/matrix3dscrollView"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="0.82" >
+
+        <LinearLayout
+            android:id="@+id/matrix3dlayout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical" >
+        </LinearLayout>
+
+    </ScrollView>
+
+</LinearLayout>
diff --git a/src/main/res/layout/matrix3dmove.xml b/src/main/res/layout/matrix3dmove.xml
new file mode 100644
index 0000000..6758825
--- /dev/null
+++ b/src/main/res/layout/matrix3dmove.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@id/matrix3dRowMove"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal" >
+
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0.8"
+                    android:orientation="vertical" >
+
+                    <TextView
+                        android:id="@+id/matrix3dmoveText"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginStart="5dp"
+                        android:layout_marginTop="3dp"
+                        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dmoveBar1"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dmoveBar2"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dmoveBar3"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                </LinearLayout>
+
+                <Button
+                    android:id="@+id/matrix3dUpMove"
+                    android:layout_width="60dp"
+                    android:layout_height="fill_parent"
+                    android:onClick="ButtonMove"
+                    android:text="@string/Up" />
+
+            </LinearLayout>
diff --git a/src/main/res/layout/matrix3drotate.xml b/src/main/res/layout/matrix3drotate.xml
new file mode 100644
index 0000000..df898da
--- /dev/null
+++ b/src/main/res/layout/matrix3drotate.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@+id/matrix3dRowRotate"
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" >
+
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="0.70"
+                    android:orientation="vertical" >
+
+                    <TextView
+                        android:id="@+id/matrix3drotateText"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginStart="5dp"
+                        android:layout_marginTop="3dp"
+                        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3drotateBar4"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3drotateBar1"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3drotateBar2"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3drotateBar3"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                </LinearLayout>
+
+                <Button
+                    android:id="@+id/matrix3dUpRotate"
+                    android:layout_width="60dp"
+                    android:layout_height="fill_parent"
+                    android:onClick="ButtonRotate"
+                    android:text="@string/Up" />
+
+            </LinearLayout>
\ No newline at end of file
diff --git a/src/main/res/layout/matrix3dscale.xml b/src/main/res/layout/matrix3dscale.xml
new file mode 100644
index 0000000..3c91178
--- /dev/null
+++ b/src/main/res/layout/matrix3dscale.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@+id/matrix3dRowScale"
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" >
+
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="0.70"
+                    android:orientation="vertical" >
+
+                    <TextView
+                        android:id="@+id/matrix3dscaleText"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginStart="5dp"
+                        android:layout_marginTop="3dp"
+                        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dscaleBar1"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dscaleBar2"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dscaleBar3"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                </LinearLayout>
+
+                <Button
+                    android:id="@+id/matrix3dUpScale"
+                    android:layout_width="60dp"
+                    android:layout_height="fill_parent"
+                    android:onClick="ButtonScale"
+                    android:text="@string/Up" />
+
+            </LinearLayout>
+           
\ No newline at end of file
diff --git a/src/main/res/layout/matrix3dshear.xml b/src/main/res/layout/matrix3dshear.xml
new file mode 100644
index 0000000..236b462
--- /dev/null
+++ b/src/main/res/layout/matrix3dshear.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@+id/matrix3dRowShear"
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" >
+
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="0.70"
+                    android:orientation="vertical" >
+
+                    <TextView
+                        android:id="@+id/matrix3dshearText"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginStart="5dp"
+                        android:layout_marginTop="3dp"
+                        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dshearBar1"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dshearBar2"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                    <SeekBar
+                        android:id="@+id/matrix3dshearBar3"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="end"
+                        android:layout_marginEnd="5dp"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp" />
+
+                </LinearLayout>
+
+                <Button
+                    android:id="@+id/matrix3dUpShear"
+                    android:layout_width="60dp"
+                    android:layout_height="fill_parent"
+                    android:onClick="ButtonShear"
+                    android:text="@string/Up" />
+
+            </LinearLayout>
\ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 9009628..35e455c 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -84,8 +84,8 @@
     <string name="example_cubes_subtitle">Tests the DistortedCubes render target.</string>
     <string name="example_quaternion">Quaternion</string>  
     <string name="example_quaternion_subtitle">Random rotations using quaternions.</string>
-    <string name="example_effects3d">Effects3D</string>  
-    <string name="example_effects3d_subtitle">Test results of all effects on a 3D object.</string>
+    <string name="example_matrix3d">3D Matrix Effects</string>
+    <string name="example_matrix3d_subtitle">Test results of Matrix effects on a 3D object.</string>
     <string name="example_plainmonalisa">PlainMonaLisa</string>  
     <string name="example_plainmonalisa_subtitle">MonaLisa rendered on a plain SurfaceView</string>
     <string name="example_save">Save to PNG</string>
