commit 7ba3801197fe6e35af4d1971f66efcfd0a783d3c
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Fri Nov 11 01:03:17 2016 +0000

    New app: Around The World (beginnings)

diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index bd8a22f..5b97bb0 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -40,5 +40,6 @@
         <activity android:name=".save.SaveActivity"/>
         <activity android:name=".flag.FlagActivity"/>
         <activity android:name=".wind.WindActivity"/>
+        <activity android:name=".aroundtheworld.AroundTheWorldActivity"/>
     </application>
 </manifest>
diff --git a/src/main/java/org/distorted/examples/TableOfContents.java b/src/main/java/org/distorted/examples/TableOfContents.java
index 8485327..0ec3f10 100644
--- a/src/main/java/org/distorted/examples/TableOfContents.java
+++ b/src/main/java/org/distorted/examples/TableOfContents.java
@@ -34,6 +34,7 @@ import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.SimpleAdapter;
 
+import org.distorted.examples.aroundtheworld.AroundTheWorldActivity;
 import org.distorted.examples.monalisa.MonaLisaActivity;
 import org.distorted.examples.sink.SinkActivity;
 import org.distorted.examples.fov.FOVActivity;
@@ -59,6 +60,7 @@ import org.distorted.examples.plainmonalisa.PlainMonaLisaActivity;
 import org.distorted.examples.save.SaveActivity;
 import org.distorted.examples.flag.FlagActivity;
 import org.distorted.examples.wind.WindActivity;
+import org.distorted.examples.aroundtheworld.AroundTheWorldActivity;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -306,6 +308,15 @@ public class TableOfContents extends ListActivity
       activityMapping.put(i++, WindActivity.class);
    }
 
+   {
+      final Map<String, Object> item = new HashMap<>();
+      item.put(ITEM_IMAGE, R.drawable.icon_example_aroundtheworld);
+      item.put(ITEM_TITLE, (i+1)+". "+getText(R.string.example_aroundtheworld));
+      item.put(ITEM_SUBTITLE, getText(R.string.example_aroundtheworld_subtitle));
+      data.add(item);
+      activityMapping.put(i++, AroundTheWorldActivity.class);
+   }
+
    final SimpleAdapter dataAdapter = new SimpleAdapter(this, data, R.layout.toc_item, new String[] {ITEM_IMAGE, ITEM_TITLE, ITEM_SUBTITLE}, new int[] {R.id.Image, R.id.Title, R.id.SubTitle});
    setListAdapter(dataAdapter);  
       
diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldActivity.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldActivity.java
new file mode 100644
index 0000000..c28a84b
--- /dev/null
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldActivity.java
@@ -0,0 +1,71 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.aroundtheworld;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import org.distorted.examples.R;
+import org.distorted.library.Distorted;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class AroundTheWorldActivity extends Activity
+{
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onCreate(Bundle icicle) 
+      {
+      super.onCreate(icicle);
+      setContentView(R.layout.aroundtheworldlayout);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onPause() 
+      {
+      AroundTheWorldSurfaceView view = (AroundTheWorldSurfaceView) this.findViewById(R.id.aroundTheWorldSurfaceView);
+      view.onPause();
+
+      super.onPause();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onResume() 
+      {
+      super.onResume();
+
+      AroundTheWorldSurfaceView view = (AroundTheWorldSurfaceView) this.findViewById(R.id.aroundTheWorldSurfaceView);
+      view.onResume();
+      }
+ 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onDestroy() 
+      {
+      Distorted.onDestroy();  
+      super.onDestroy();
+      }
+}
diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldEffectsManager.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldEffectsManager.java
new file mode 100644
index 0000000..7930426
--- /dev/null
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldEffectsManager.java
@@ -0,0 +1,128 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.aroundtheworld;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+import org.distorted.library.DistortedObject;
+import org.distorted.library.type.Dynamic;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Dynamic5D;
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+import org.distorted.library.type.Static5D;
+
+class AroundTheWorldEffectsManager
+  {
+  private int mHeight, mWidth;
+
+  private Static3D  shearFactor;
+  private Dynamic3D shearDynamic;
+  private Static3D  scaleFactor;
+  private Dynamic3D scaleDynamic;
+  private Static3D  deformForce;
+  private Static5D  windFactor11, windFactor12;
+  private Dynamic5D windDynamic1;
+  private Static5D  windFactor21, windFactor22;
+  private Dynamic5D windDynamic2;
+  private Static5D  windFactor31, windFactor32;
+  private Dynamic5D windDynamic3;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  AroundTheWorldEffectsManager(DistortedObject obj)
+    {
+    mHeight = obj.getHeight();
+    mWidth  = obj.getWidth();
+
+    shearFactor = new Static3D(0,0,0);
+    shearDynamic= new Dynamic3D();
+    shearDynamic.add(shearFactor);
+
+    scaleFactor = new Static3D(1,1,1);
+    scaleDynamic= new Dynamic3D();
+    scaleDynamic.add(scaleFactor);
+
+    deformForce = new Static3D(mWidth/3,0,0);
+
+    windFactor11 = new Static5D(mHeight/10,mHeight/5, 180, 0, 90);
+    windFactor12 = new Static5D(mHeight/10,mHeight/5,-180, 0, 90);
+    windDynamic1 = new Dynamic5D(1000,0.0f);
+    windDynamic1.add(windFactor11);
+    windDynamic1.add(windFactor12);
+    windDynamic1.setMode(Dynamic.MODE_JUMP);
+    windDynamic1.setAccessMode(Dynamic.ACCESS_SEQUENTIAL);
+
+    windFactor21 = new Static5D(mHeight/10,mHeight/5,-180, 90, 10);
+    windFactor22 = new Static5D(mHeight/10,mHeight/5,+180, 90, 10);
+    windDynamic2 = new Dynamic5D(1000,0.0f);
+    windDynamic2.add(windFactor21);
+    windDynamic2.add(windFactor22);
+    windDynamic2.setMode(Dynamic.MODE_JUMP);
+    windDynamic2.setAccessMode(Dynamic.ACCESS_SEQUENTIAL);
+
+    windFactor31 = new Static5D(mHeight/10,mHeight/10,-180, 90, 90);
+    windFactor32 = new Static5D(mHeight/10,mHeight/10,+180, 90, 90);
+    windDynamic3 = new Dynamic5D(1000,0.0f);
+    windDynamic3.add(windFactor31);
+    windDynamic3.add(windFactor32);
+    windDynamic3.setMode(Dynamic.MODE_JUMP);
+    windDynamic3.setAccessMode(Dynamic.ACCESS_SEQUENTIAL);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  synchronized void apply(DistortedObject obj, int wind)
+    {
+    Static3D midLeft = new Static3D(0,mHeight/2,0);
+    Static3D midRight = new Static3D(mWidth,mHeight/2,0);
+    Static4D windRegion = new Static4D(0,0,mWidth,mHeight);
+
+    setWind(wind);
+
+    obj.shear(shearDynamic,midLeft);
+    obj.scale(scaleDynamic);
+    obj.deform(deformForce,midRight);
+    obj.wave(windDynamic1, midRight, windRegion);
+    obj.wave(windDynamic2, midRight, windRegion);
+    obj.wave(windDynamic3, midRight, windRegion);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  synchronized void setWind(int wind)
+    {
+    float tanAngle = (wind-50)/50.0f;
+
+    shearFactor.set2(tanAngle);
+    scaleFactor.set1(1/(float)Math.sqrt(1+tanAngle*tanAngle));
+    windDynamic1.setDuration( wind > 0 ? 100000/wind : Long.MAX_VALUE);
+    windDynamic2.setDuration( wind > 0 ?  80000/wind : Long.MAX_VALUE);
+    windDynamic3.setDuration( wind > 0 ? 100000/wind : Long.MAX_VALUE);
+
+    float waveA = (mHeight/(20.0f-0.15f*wind));
+    windFactor21.set1(waveA);
+    windFactor22.set1(waveA);
+
+    float waveB = (mHeight/(wind+5.0f));
+    windFactor31.set1(waveB);
+    windFactor32.set1(waveB);
+    }
+  }
diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
new file mode 100644
index 0000000..b9f3637
--- /dev/null
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
@@ -0,0 +1,130 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.aroundtheworld;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+
+import org.distorted.examples.R;
+import org.distorted.library.Distorted;
+import org.distorted.library.DistortedBitmap;
+import org.distorted.library.DistortedCubes;
+import org.distorted.library.DistortedObject;
+import org.distorted.library.EffectTypes;
+import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static3D;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class AroundTheWorldRenderer implements GLSurfaceView.Renderer
+{
+   private GLSurfaceView mView;
+   private DistortedObject mObject;
+   private AroundTheWorldEffectsManager mEffects;
+   private int mObjWidth, mObjHeight;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   AroundTheWorldRenderer(GLSurfaceView view)
+      {
+      mView = view;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+   
+   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);
+     
+      mObject.draw(System.currentTimeMillis());
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+   public void onSurfaceChanged(GL10 glUnused, int width, int height) 
+      {
+      mObject.abortEffects(EffectTypes.MATRIX);
+
+      if( mObjHeight/mObjWidth > height/width )
+        {
+        int w = (height*mObjWidth)/mObjHeight;
+        float factor = (float)height/mObjHeight;
+        mObject.move( new Static3D((width-w)/2,0,0) );
+        mObject.scale(factor);
+        }
+      else
+        {
+        int h = (width*mObjHeight)/mObjWidth;
+        float factor = (float)width/mObjWidth;
+        mObject.move( new Static3D(0,(height-h)/2,0) );
+        mObject.scale(factor);
+        }
+
+      Distorted.onSurfaceChanged(width, height);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+   public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
+      {  
+      InputStream is = mView.getContext().getResources().openRawResource(R.raw.face);
+      Bitmap bitmap;
+
+      try
+        {
+        bitmap = BitmapFactory.decodeStream(is);
+        }
+      finally
+        {
+        try
+          {
+          is.close();
+          }
+        catch(IOException e) { }
+        }
+
+
+      mObject = new DistortedBitmap(bitmap.getWidth(),bitmap.getHeight(),30);
+      mEffects = new AroundTheWorldEffectsManager(mObject);
+
+      mObjWidth = mObject.getWidth();
+      mObjHeight= mObject.getHeight();
+
+      mObject.setBitmap(bitmap);
+
+      try
+        {
+        Distorted.onSurfaceCreated(mView.getContext());
+        }
+      catch(Exception ex)
+        {
+        android.util.Log.e("AroundTheWorld", ex.getMessage() );
+        }
+      }
+}
diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldSurfaceView.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldSurfaceView.java
new file mode 100644
index 0000000..75a4f44
--- /dev/null
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldSurfaceView.java
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.aroundtheworld;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Build;
+import android.util.AttributeSet;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class AroundTheWorldSurfaceView extends GLSurfaceView
+{
+    private AroundTheWorldRenderer mRenderer;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public AroundTheWorldSurfaceView(Context c, AttributeSet attrs)
+      {
+      super(c, attrs);
+
+      if(!isInEditMode())
+        {
+        setEGLContextClientVersion(2);
+
+        if( Build.FINGERPRINT.startsWith("generic") )
+          {
+          setEGLConfigChooser(8, 8, 8, 8, 16, 0);
+          }
+
+        mRenderer = new AroundTheWorldRenderer(this);
+        setRenderer(mRenderer);
+        }
+      }
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public AroundTheWorldRenderer getRenderer()
+      {
+      return mRenderer;
+      }
+}
+
diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldSurfaceViewPicker.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldSurfaceViewPicker.java
new file mode 100644
index 0000000..ebd7f64
--- /dev/null
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldSurfaceViewPicker.java
@@ -0,0 +1,203 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.aroundtheworld;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class AroundTheWorldSurfaceViewPicker extends SurfaceView implements SurfaceHolder.Callback
+{
+    private static final int FRAME_INTERVAL = 70;
+
+    private boolean refreshScreen = true;
+    private boolean mFinishedBooting=false;
+    private int scrWidth, scrHeight;
+    private GraphicsThread mThread;
+    private int mX, mY;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private class GraphicsThread extends Thread
+      {
+      private SurfaceHolder mSurfaceHolder;
+      private AroundTheWorldSurfaceViewPicker mPicker;
+      private boolean mRun = false;
+
+      /////////////////////////////////////////////////////////////////////////////////////
+
+      GraphicsThread(SurfaceHolder surfaceHolder, AroundTheWorldSurfaceViewPicker p)
+        {
+        mSurfaceHolder = surfaceHolder;
+        mPicker = p;
+        }
+
+      /////////////////////////////////////////////////////////////////////////////////////
+
+      void setRunning(boolean run)
+        {
+        mRun = run;
+        }
+
+      /////////////////////////////////////////////////////////////////////////////////////
+
+      public void run()
+        {
+        Canvas c;
+        long time;
+
+        while (mRun)
+          {
+          c = null;
+          time = 0;
+
+          if( refreshScreen && mFinishedBooting )
+            {
+            refreshScreen=false;
+            time = System.currentTimeMillis();
+
+            try
+              {
+              c = mSurfaceHolder.lockCanvas(null);
+              synchronized (mSurfaceHolder) { mPicker.draw(c); }
+              }
+            finally
+              {
+              if (c != null)  mSurfaceHolder.unlockCanvasAndPost(c);
+              }
+
+            time = System.currentTimeMillis() -time;
+            }
+
+          if( time<FRAME_INTERVAL )
+            {
+            try { Thread.sleep(FRAME_INTERVAL-time); }
+            catch(InterruptedException ex) {}
+            }
+          }
+        }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public AroundTheWorldSurfaceViewPicker(Context c, AttributeSet attrs)
+      {
+      super(c, attrs);
+
+      mX = -100;
+      mY = -100;
+
+      getHolder().addCallback(this);
+      setFocusable(true);
+      setFocusableInTouchMode(true);
+
+      mFinishedBooting=true;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void surfaceCreated(SurfaceHolder holder)
+      {
+      android.util.Log.e( "Picker", "surfaceCreated");
+
+      mThread = new GraphicsThread(getHolder(), this);
+      mThread.setRunning(true);
+      mThread.start();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
+      {
+      android.util.Log.e( "Picker", "surfaceChanged: width="+w+" height="+h);
+
+      scrWidth = w;
+      scrHeight= h;
+      refreshScreen = true;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void surfaceDestroyed(SurfaceHolder holder)
+      {
+      android.util.Log.e( "Picker", "surfaceDestroyed");
+
+      stopThread();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void stopThread()
+      {
+      if( mThread!=null )
+        {
+        boolean retry = true;
+        mThread.setRunning(false);
+
+        while (retry)
+          {
+          try
+            {
+            mThread.join();
+            retry = false;
+            }
+          catch (InterruptedException e) { android.util.Log.e( "Picker", "Joining thread interrupted!"); }
+          }
+
+        mThread=null;
+        }
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void draw(Canvas c)
+      {
+      if( c!=null )
+        {
+
+        }
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public void setRepaint()
+      {
+      refreshScreen=true;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public boolean onTouchEvent(MotionEvent event)
+      {
+      mX = (int)event.getX();
+      mY = (int)event.getY();
+
+      android.util.Log.e( "Picker", "onTouchEvent: x="+mX+" y="+mY);
+
+      setRepaint();
+
+      return true;
+      }
+}
diff --git a/src/main/res/drawable-hdpi/icon_example_aroundtheworld.png b/src/main/res/drawable-hdpi/icon_example_aroundtheworld.png
new file mode 100644
index 0000000..ecd1a29
Binary files /dev/null and b/src/main/res/drawable-hdpi/icon_example_aroundtheworld.png differ
diff --git a/src/main/res/layout/aroundtheworldlayout.xml b/src/main/res/layout/aroundtheworldlayout.xml
new file mode 100644
index 0000000..b228579
--- /dev/null
+++ b/src/main/res/layout/aroundtheworldlayout.xml
@@ -0,0 +1,23 @@
+<?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.aroundtheworld.AroundTheWorldSurfaceView
+        android:id="@+id/aroundTheWorldSurfaceView"
+        android:layout_width="fill_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="5dp"/>
+
+    <org.distorted.examples.aroundtheworld.AroundTheWorldSurfaceViewPicker
+        android:id="@+id/aroundTheWorldSurfaceViewPicker"
+        android:layout_width="fill_parent"
+        android:layout_height="0dp"
+        android:layout_weight="0.6" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index f33bdbb..7171f8c 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -108,6 +108,8 @@
     <string name="example_flag_subtitle">See the WAVE effect.</string>
     <string name="example_wind">Variable wind</string>
     <string name="example_wind_subtitle">A couple of effects put together to create an effect of a waving flag.</string>
+    <string name="example_aroundtheworld">Around the World</string>
+    <string name="example_aroundtheworld_subtitle">Combine several effects to change facial features.</string>
 
     <string name="example_movingeffects_toast">Click on \'RESET\' and define your path by touching the screen. Then click on one of the effects and see it move along your path.</string>
     <string name="example_rotate_toast">Rotate the scene by swiping the screen</string>
