commit 4d883a926fa41e31ddac23347fe163f476a2129c
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Apr 12 15:46:19 2021 +0200

    Cubit creation: bugfixes. Cube, Tetrahedron, Dino cubits - all work.

diff --git a/src/main/java/org/distorted/examples/meshfile/FactoryCubit.java b/src/main/java/org/distorted/examples/meshfile/FactoryCubit.java
index 431d652..55c39de 100644
--- a/src/main/java/org/distorted/examples/meshfile/FactoryCubit.java
+++ b/src/main/java/org/distorted/examples/meshfile/FactoryCubit.java
@@ -38,10 +38,10 @@ import java.util.ArrayList;
 
 class FactoryCubit
   {
-  private static final float[] mBuffer = new float[3];
-  private static final float[] mQuat1  = new float[4];
-  private static final float[] mQuat2  = new float[4];
-  private static final float[] mQuat3  = new float[4];
+  private static final double[] mBuffer = new double[3];
+  private static final double[] mQuat1  = new double[4];
+  private static final double[] mQuat2  = new double[4];
+  private static final double[] mQuat3  = new double[4];
 
   private static final Static1D RADIUS = new Static1D(1);
 
@@ -49,15 +49,15 @@ class FactoryCubit
 
   private static class StickerInfo
     {
-    float[] vertices;
+    double[] vertices;
     }
 
   private static class FaceInfo
     {
     int sticker;
-    float vx,vy,vz;
-    float scale;
-    float qx,qy,qz,qw;
+    double vx,vy,vz;
+    double scale;
+    double qx,qy,qz,qw;
     boolean flip;
     }
 
@@ -211,57 +211,57 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private boolean areColinear(float[][] vertices, int index1, int index2, int index3)
+  private boolean areColinear(double[][] vertices, int index1, int index2, int index3)
     {
-    float x1 = vertices[index1][0];
-    float y1 = vertices[index1][1];
-    float z1 = vertices[index1][2];
-    float x2 = vertices[index2][0];
-    float y2 = vertices[index2][1];
-    float z2 = vertices[index2][2];
-    float x3 = vertices[index3][0];
-    float y3 = vertices[index3][1];
-    float z3 = vertices[index3][2];
-
-    float v1x = x2-x1;
-    float v1y = y2-y1;
-    float v1z = z2-z1;
-    float v2x = x3-x1;
-    float v2y = y3-y1;
-    float v2z = z3-z1;
-
-    float A = (float)Math.sqrt( (v1x*v1x+v1y*v1y+v1z*v1z) / (v2x*v2x+v2y*v2y+v2z*v2z) );
+    double x1 = vertices[index1][0];
+    double y1 = vertices[index1][1];
+    double z1 = vertices[index1][2];
+    double x2 = vertices[index2][0];
+    double y2 = vertices[index2][1];
+    double z2 = vertices[index2][2];
+    double x3 = vertices[index3][0];
+    double y3 = vertices[index3][1];
+    double z3 = vertices[index3][2];
+
+    double v1x = x2-x1;
+    double v1y = y2-y1;
+    double v1z = z2-z1;
+    double v2x = x3-x1;
+    double v2y = y3-y1;
+    double v2z = z3-z1;
+
+    double A = Math.sqrt( (v1x*v1x+v1y*v1y+v1z*v1z) / (v2x*v2x+v2y*v2y+v2z*v2z) );
 
     return (v1x==A*v2x && v1y==A*v2y && v1z==A*v2z);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void computeNormalVector(float[][] vertices, int index1, int index2, int index3)
+  private void computeNormalVector(double[][] vertices, int index1, int index2, int index3)
     {
-    float x1 = vertices[index1][0];
-    float y1 = vertices[index1][1];
-    float z1 = vertices[index1][2];
-    float x2 = vertices[index2][0];
-    float y2 = vertices[index2][1];
-    float z2 = vertices[index2][2];
-    float x3 = vertices[index3][0];
-    float y3 = vertices[index3][1];
-    float z3 = vertices[index3][2];
-
-    float v1x = x2-x1;
-    float v1y = y2-y1;
-    float v1z = z2-z1;
-    float v2x = x3-x1;
-    float v2y = y3-y1;
-    float v2z = z3-z1;
+    double x1 = vertices[index1][0];
+    double y1 = vertices[index1][1];
+    double z1 = vertices[index1][2];
+    double x2 = vertices[index2][0];
+    double y2 = vertices[index2][1];
+    double z2 = vertices[index2][2];
+    double x3 = vertices[index3][0];
+    double y3 = vertices[index3][1];
+    double z3 = vertices[index3][2];
+
+    double v1x = x2-x1;
+    double v1y = y2-y1;
+    double v1z = z2-z1;
+    double v2x = x3-x1;
+    double v2y = y3-y1;
+    double v2z = z3-z1;
 
     mBuffer[0] = v1y*v2z - v2y*v1z;
     mBuffer[1] = v1z*v2x - v2z*v1x;
     mBuffer[2] = v1x*v2y - v2x*v1y;
 
-    float len = mBuffer[0]*mBuffer[0] + mBuffer[1]*mBuffer[1] + mBuffer[2]*mBuffer[2];
-    len = (float)Math.sqrt(len);
+    double len = mBuffer[0]*mBuffer[0] + mBuffer[1]*mBuffer[1] + mBuffer[2]*mBuffer[2];
+    len = Math.sqrt(len);
     mBuffer[0] /= len;
     mBuffer[1] /= len;
     mBuffer[2] /= len;
@@ -270,17 +270,17 @@ class FactoryCubit
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // return quat1*quat2
 
-  private static void quatMultiply( float[] quat1, float[] quat2, float[] result )
+  private static void quatMultiply( double[] quat1, double[] quat2, double[] result )
     {
-    float qx = quat1[0];
-    float qy = quat1[1];
-    float qz = quat1[2];
-    float qw = quat1[3];
+    double qx = quat1[0];
+    double qy = quat1[1];
+    double qz = quat1[2];
+    double qw = quat1[3];
 
-    float rx = quat2[0];
-    float ry = quat2[1];
-    float rz = quat2[2];
-    float rw = quat2[3];
+    double rx = quat2[0];
+    double ry = quat2[1];
+    double rz = quat2[2];
+    double rw = quat2[3];
 
     result[0] = rw*qx - rz*qy + ry*qz + rx*qw;
     result[1] = rw*qy + rz*qx + ry*qw - rx*qz;
@@ -290,17 +290,17 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void fitInSquare(FaceInfo info, float[][] vert3D)
+  private void fitInSquare(FaceInfo info, double[][] vert3D)
     {
-    float minX = Float.MAX_VALUE;
-    float maxX =-Float.MAX_VALUE;
-    float minY = Float.MAX_VALUE;
-    float maxY =-Float.MAX_VALUE;
+    double minX = Double.MAX_VALUE;
+    double maxX =-Double.MAX_VALUE;
+    double minY = Double.MAX_VALUE;
+    double maxY =-Double.MAX_VALUE;
 
-    for (float[] vert : vert3D)
+    for (double[] vert : vert3D)
       {
-      float x = vert[0];
-      float y = vert[1];
+      double x = vert[0];
+      double y = vert[1];
 
       if (x > maxX) maxX = x;
       if (x < minX) minX = x;
@@ -312,7 +312,7 @@ class FactoryCubit
 
     int len = vert3D.length;
     StickerInfo sInfo = new StickerInfo();
-    sInfo.vertices = new float[2*len];
+    sInfo.vertices = new double[2*len];
 
     for( int vertex=0; vertex<len; vertex++ )
       {
@@ -328,7 +328,7 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void constructNew(FaceInfo info, final float[][] vert3D)
+  private void constructNew(FaceInfo info, final double[][] vert3D)
     {
     // compute center of gravity
     info.vx = 0.0f;
@@ -336,7 +336,7 @@ class FactoryCubit
     info.vz = 0.0f;
     int len = vert3D.length;
 
-    for (float[] vert : vert3D)
+    for (double[] vert : vert3D)
       {
       info.vx += vert[0];
       info.vy += vert[1];
@@ -376,7 +376,7 @@ class FactoryCubit
     computeNormalVector(vert3D,0,1,foundIndex);
 
     // rotate so that the normal vector becomes (0,0,1)
-    float axisX, axisY, axisZ;
+    double axisX, axisY, axisZ;
 
     if( mBuffer[0]!=0.0f || mBuffer[1]!=0.0f )
       {
@@ -384,8 +384,8 @@ class FactoryCubit
       axisY =  mBuffer[0];
       axisZ = 0.0f;
 
-      float axiLen = axisX*axisX + axisY*axisY;
-      axiLen = (float)Math.sqrt(axiLen);
+      double axiLen = axisX*axisX + axisY*axisY;
+      axiLen = Math.sqrt(axiLen);
       axisX /= axiLen;
       axisY /= axiLen;
       axisZ /= axiLen;
@@ -397,9 +397,10 @@ class FactoryCubit
       axisZ = 0.0f;
       }
 
-    float cosTheta = mBuffer[2];
-    float sinHalfTheta = (float)Math.sqrt(0.5f*(1-cosTheta));
-    float cosHalfTheta = (float)Math.sqrt(0.5f*(1+cosTheta));
+    double cosTheta = mBuffer[2];
+    double sinTheta = Math.sqrt(1-cosTheta*cosTheta);
+    double sinHalfTheta = computeSinHalf(cosTheta);
+    double cosHalfTheta = computeCosHalf(sinTheta,cosTheta);
 
     mQuat1[0] = axisX*sinHalfTheta;
     mQuat1[1] = axisY*sinHalfTheta;
@@ -410,7 +411,7 @@ class FactoryCubit
     mQuat2[2] =-axisZ*sinHalfTheta;
     mQuat2[3] = cosHalfTheta;
 
-    for (float[] vert : vert3D)
+    for (double[] vert : vert3D)
       {
       quatMultiply(mQuat1, vert  , mQuat3);
       quatMultiply(mQuat3, mQuat2, vert  );
@@ -428,32 +429,32 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private float computeCos(float x1, float y1, float x2, float y2, float len1, float len2)
+  private double computeCos(double oldX, double oldY, double newX, double newY, double len1, double len2)
     {
-    float ret =  (x1*x2+y1*y2) / (len1*len2);
+    double ret =  (oldX*newX+oldY*newY) / (len1*len2);
 
-    if( ret> 1.0f ) return  1.0f;
-    if( ret<-1.0f ) return -1.0f;
+    if( ret> 1.0f ) return  1.0;
+    if( ret<-1.0f ) return -1.0;
 
     return ret;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// sin of (signed!) angle between vectors (x1,y1) and (x2,y2), counterclockwise!
+// sin of (signed!) angle between vectors 'old' and 'new', counterclockwise!
 
-  private float computeSin(float x1, float y1, float x2, float y2, float len1, float len2)
+  private double computeSin(double oldX, double oldY, double newX, double newY, double len1, double len2)
     {
-    float ret = (x2*y1-x1*y2) / (len1*len2);
+    double ret = (newX*oldY-oldX*newY) / (len1*len2);
 
-    if( ret> 1.0f ) return  1.0f;
-    if( ret<-1.0f ) return -1.0f;
+    if( ret> 1.0f ) return  1.0;
+    if( ret<-1.0f ) return -1.0;
 
     return ret;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void rotateAllVertices(float[] result, int len, float[] vertices, float sin, float cos)
+  private void rotateAllVertices(double[] result, int len, double[] vertices, double sin, double cos)
     {
     for(int i=0; i<len; i++)
       {
@@ -464,15 +465,40 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private boolean isScaledVersionOf(float[] v1, float[] v2, int len)
+  private double computeScale(double[] v1, double[] v2)
     {
-    float EPSILON = 0.001f;
-    float scale = v1[0]!=0.0f ? v2[0]/v1[0] : v2[1]/v1[1];
+    double lenSq1 = v1[0]*v1[0] + v1[1]*v1[1];
+    double lenSq2 = v2[0]*v2[0] + v2[1]*v2[1];
+
+    return Math.sqrt(lenSq2/lenSq1);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private double computeSinHalf(double cos)
+    {
+    return Math.sqrt((1-cos)/2);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private double computeCosHalf(double sin, double cos)
+    {
+    double cosHalf = Math.sqrt((1+cos)/2);
+    return sin<0 ? -cosHalf : cosHalf;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean isScaledVersionOf(double[] newVert, double[] oldVert, int len)
+    {
+    double EPSILON = 0.001;
+    double scale = computeScale(newVert,oldVert);
 
     for(int i=1; i<len; i++)
       {
-      float horz = v2[2*i  ] - scale*v1[2*i  ];
-      float vert = v2[2*i+1] - scale*v1[2*i+1];
+      double horz = oldVert[2*i  ] - scale*newVert[2*i  ];
+      double vert = oldVert[2*i+1] - scale*newVert[2*i+1];
 
       if( horz>EPSILON || horz<-EPSILON || vert>EPSILON || vert<-EPSILON ) return false;
       }
@@ -482,7 +508,7 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void mirrorAllVertices(float[] output, int len, float[] input)
+  private void mirrorAllVertices(double[] output, int len, double[] input)
     {
     for(int vertex=0; vertex<len; vertex++)
       {
@@ -493,7 +519,7 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void correctInfo(FaceInfo info, float scale, float cos, int oldSticker, boolean flip)
+  private void correctInfo(FaceInfo info, double scale, double sin, double cos, int oldSticker, boolean flip)
     {
     mStickerInfo.remove(info.sticker);
 
@@ -506,8 +532,8 @@ class FactoryCubit
     mQuat1[2] = info.qz;
     mQuat1[3] = info.qw;
 
-    float sinHalf = (float)Math.sqrt(0.5f*(1-cos));
-    float cosHalf = (float)Math.sqrt(0.5f*(1+cos));
+    double sinHalf = computeSinHalf(cos);
+    double cosHalf = computeCosHalf(sin,cos);
 
     mQuat2[0] = 0.0f;
     mQuat2[1] = 0.0f;
@@ -524,23 +550,23 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private boolean foundVertex(FaceInfo info, float[] buffer, int len, float[] preVert,
-                              float[] newVert, float lenVert, int oldSticker, boolean inverted)
+  private boolean foundVertex(FaceInfo info, double[] buffer, int len, double[] newVert,
+                              double[] oldVert, double lenFirstOld, int oldSticker, boolean inverted)
     {
     for(int vertex=0; vertex<len; vertex++)
       {
-      float xR = preVert[2*vertex  ];
-      float yR = preVert[2*vertex+1];
-      float lenRotV = (float)Math.sqrt(xR*xR+yR*yR);
-      float cos = computeCos(xR,yR,newVert[0],newVert[1], lenRotV, lenVert);
-      float sin = computeSin(xR,yR,newVert[0],newVert[1], lenRotV, lenVert);
+      double newX = newVert[2*vertex  ];
+      double newY = newVert[2*vertex+1];
+      double lenIthNew = Math.sqrt(newX*newX + newY*newY);
+      double cos = computeCos( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
+      double sin = computeSin( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
 
       rotateAllVertices(buffer,len,newVert,sin,cos);
 
-      if( isScaledVersionOf(buffer,preVert,len) )
+      if( isScaledVersionOf(buffer,oldVert,len) )
         {
-        float scale = preVert[0]!=0.0f ? buffer[0]/preVert[0] : buffer[1]/preVert[1];
-        correctInfo(info,scale,cos,oldSticker,inverted);
+        double scale = computeScale(oldVert,newVert);
+        correctInfo(info,scale,sin,cos,oldSticker,inverted);
         return true;
         }
       }
@@ -550,22 +576,24 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private boolean successfullyCollapsedStickers(final FaceInfo newInfo, final FaceInfo preInfo)
+  private boolean successfullyCollapsedStickers(final FaceInfo newInfo, final FaceInfo oldInfo)
     {
     StickerInfo sNewInfo = mStickerInfo.get(newInfo.sticker);
-    StickerInfo sPreInfo = mStickerInfo.get(preInfo.sticker);
-    int len = sPreInfo.vertices.length;
-    float[] newVert = sNewInfo.vertices;
+    StickerInfo sOldInfo = mStickerInfo.get(oldInfo.sticker);
+    double[] newVert = sNewInfo.vertices;
+    double[] oldVert = sOldInfo.vertices;
+    int oldLen = oldVert.length;
+    int newLen = newVert.length;
 
-    if( len == newVert.length )
+    if( oldLen == newLen )
       {
-      int oldSticker = preInfo.sticker;
-      float[] tmp1 = new float[len];
-      float lenVert = (float)Math.sqrt(newVert[0]*newVert[0] + newVert[1]*newVert[1]);
-      if( foundVertex(newInfo, tmp1, len/2, sPreInfo.vertices, newVert, lenVert, oldSticker, false) ) return true;
-      float[] tmp2 = new float[len];
-      mirrorAllVertices(tmp2,len/2,sPreInfo.vertices);
-      if( foundVertex(newInfo, tmp1, len/2, tmp2             , newVert, lenVert, oldSticker, true ) ) return true;
+      int oldSticker = oldInfo.sticker;
+      double[] buffer1 = new double[oldLen];
+      double lenFirstOld = Math.sqrt(newVert[0]*newVert[0] + newVert[1]*newVert[1]);
+      if( foundVertex(newInfo, buffer1, oldLen/2, newVert, oldVert, lenFirstOld, oldSticker, false) ) return true;
+      double[] buffer2 = new double[oldLen];
+      mirrorAllVertices(buffer2, newLen/2, newVert);
+      if( foundVertex(newInfo, buffer1, oldLen/2, buffer2, oldVert, lenFirstOld, oldSticker, true ) ) return true;
       }
 
     return false;
@@ -573,10 +601,10 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private float[][] constructVert(float[][] vertices, int[] index)
+  private double[][] constructVert(double[][] vertices, int[] index)
     {
     int len = index.length;
-    float[][] ret = new float[len][4];
+    double[][] ret = new double[len][4];
 
     for(int i=0; i<len; i++)
       {
@@ -591,25 +619,25 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void prepareFaceInfo( final float[][] vertices, final int[][] indexes)
+  private void prepareFaceInfo( final double[][] vertices, final int[][] indexes)
     {
     mFaceInfo.clear();
     mStickerInfo.clear();
 
     int numFaces = indexes.length;
-    FaceInfo preInfo;
+    FaceInfo oldInfo;
 
     for(int face=0; face<numFaces; face++)
       {
       FaceInfo newInfo = new FaceInfo();
       int[] index = indexes[face];
-      float[][] vert = constructVert(vertices,index);
+      double[][] vert = constructVert(vertices,index);
       constructNew(newInfo,vert);
 
       for(int previous=0; previous<face; previous++)
         {
-        preInfo = mFaceInfo.get(previous);
-        if( successfullyCollapsedStickers(newInfo,preInfo) ) break;
+        oldInfo = mFaceInfo.get(previous);
+        if( successfullyCollapsedStickers(newInfo,oldInfo) ) break;
         }
 
       mFaceInfo.add(newInfo);
@@ -618,7 +646,7 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void prepareAndRoundCorners(MeshBase mesh, float[][] vertices, int[][] vertIndexes,
+  private void prepareAndRoundCorners(MeshBase mesh, double[][] vertices, int[][] vertIndexes,
                                       float[][] corners, int[] cornerIndexes )
     {
     int numNeig, lenFV;
@@ -626,8 +654,8 @@ class FactoryCubit
     int[] verts = new int[2*(lenV-1)];
     Static3D[] staticVert = new Static3D[1];
     Static3D center = new Static3D(0,0,0);
-    float cx, cy, cz;
-    float[] singleV;
+    double cx, cy, cz;
+    double[] singleV;
 
     for(int v=0; v<lenV; v++)
       {
@@ -660,10 +688,12 @@ class FactoryCubit
         cy += singleV[1];
         cz += singleV[2];
         }
-      center.set(cx/numNeig - vertices[v][0],cy/numNeig - vertices[v][1],cz/numNeig - vertices[v][2]);
+      center.set( (float)(cx/numNeig - vertices[v][0]),
+                  (float)(cy/numNeig - vertices[v][1]),
+                  (float)(cz/numNeig - vertices[v][2]));
 
       // round Corners
-      staticVert[0] = new Static3D(vertices[v][0], vertices[v][1], vertices[v][2]);
+      staticVert[0] = new Static3D( (float)vertices[v][0], (float)vertices[v][1], (float)vertices[v][2]);
 
       int corn = cornerIndexes[v];
       float strength = corners[corn][0];
@@ -712,9 +742,9 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createRoundedSolid(final float[][] vertices, final int[][] vertIndexes,
-                              final float[][] bands   , final int[]   bandIndexes,
-                              final float[][] corners , final int[]   cornerIndexes)
+  MeshBase createRoundedSolid(final double[][] vertices, final int[][] vertIndexes,
+                              final float[][] bands    , final int[]   bandIndexes,
+                              final float[][] corners  , final int[]   cornerIndexes)
     {
     int EFFECTS_PER_FACE = 3;
 
@@ -733,9 +763,14 @@ class FactoryCubit
       fInfo = mFaceInfo.get(face);
       sInfo = mStickerInfo.get(fInfo.sticker);
 
+      double[] verts = sInfo.vertices;
+      int lenVerts = verts.length;
+      float[] vertsFloat = new float[lenVerts];
+      for(int i=0; i<lenVerts; i++) vertsFloat[i] = (float)verts[i];
+
       band = bands[bandIndexes[face]];
       bandsComputed = computeBands( band[0], (int)band[1], band[2], band[3], (int)band[4]);
-      meshes[face] = new MeshPolygon(sInfo.vertices,bandsComputed,(int)band[5],(int)band[6]);
+      meshes[face] = new MeshPolygon(vertsFloat,bandsComputed,(int)band[5],(int)band[6]);
       meshes[face].setEffectAssociation(0,(1<<face),0);
       }
 
@@ -748,9 +783,18 @@ class FactoryCubit
       int assoc = (1<<face);
       fInfo = mFaceInfo.get(face);
 
-      Static3D move3D= new Static3D(fInfo.vx,fInfo.vy,fInfo.vz);
-      Static3D scale = new Static3D(fInfo.scale,fInfo.scale, fInfo.flip ? -fInfo.scale : fInfo.scale);
-      Static4D quat  = new Static4D(fInfo.qx,fInfo.qy,fInfo.qz,fInfo.qw);
+      float vx = (float)fInfo.vx;
+      float vy = (float)fInfo.vy;
+      float vz = (float)fInfo.vz;
+      float sc = (float)fInfo.scale;
+      float qx = (float)fInfo.qx;
+      float qy = (float)fInfo.qy;
+      float qz = (float)fInfo.qz;
+      float qw = (float)fInfo.qw;
+
+      Static3D move3D= new Static3D(vx,vy,vz);
+      Static3D scale = new Static3D(sc,sc, fInfo.flip ? -sc : sc);
+      Static4D quat  = new Static4D(qx,qy,qz,qw);
 
       effects[EFFECTS_PER_FACE*face  ] = new MatrixEffectScale(scale);
       effects[EFFECTS_PER_FACE*face+1] = new MatrixEffectQuaternion(quat,center);
diff --git a/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java b/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
index fc8f0a3..141641c 100644
--- a/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
+++ b/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
@@ -38,7 +38,6 @@ import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.mesh.MeshFile;
-import org.distorted.library.mesh.MeshPolygon;
 import org.distorted.library.type.DynamicQuat;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
@@ -249,68 +248,32 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
       return bitmap;
       }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private MeshBase createStaticMesh()
-    {
-    final float IVY_D = 0.10f;
-    final int   IVY_N = 8;
-
-    final float angle = (float)Math.PI/(2*IVY_N);
-    final float CORR  = 1.0f - IVY_D*SQ2;
-    final float DIST  = 0.4f;
-    final float CORR2 = 0.5f;
-    float[] vertices = new float[2*(IVY_N+1)+6];
-
-    vertices[0] = ( 0.5f      -DIST)*CORR2;
-    vertices[1] = (-0.5f+IVY_D-DIST)*CORR2;
-    vertices[2] = ( 0.5f      -DIST)*CORR2;
-    vertices[3] = ( 0.5f      -DIST)*CORR2;
-    vertices[4] = (-0.5f+IVY_D-DIST)*CORR2;
-    vertices[5] = ( 0.5f      -DIST)*CORR2;
-
-    for(int i=0; i<=IVY_N; i++)
-      {
-      float ang = (IVY_N-i)*angle;
-      float sin = (float)Math.sin(ang);
-      float cos = (float)Math.cos(ang);
-
-      vertices[2*i+6] = (CORR*(cos-0.5f)-DIST)*CORR2;
-      vertices[2*i+7] = (CORR*(sin-0.5f)-DIST)*CORR2;
-      }
-
-    float[] bands = new float[] {1.0f, 0.0f, 0.5f, 0.03f, 0.0f, 0.05f};
-
-    MeshBase mesh = new MeshPolygon(vertices,bands,0,0);
-    mesh.setShowNormals(true);
-
-    return mesh;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     private void createMesh()
       {
       int mode = 2;
-      float[][] vertices  = null;
+      double[][] vertices = null;
       int[][] vertIndexes = null;
       float[][] bands     = null;
       int[] bandIndexes   = null;
       float[][] corners   = null;
       int[] cornerIndexes = null;
 
-      if( mode==0 ) // CUBE
+      ///// CUBE ////////////////////////////////////////////////////////////////////////////////
+
+      if( mode==0 )
         {
-        vertices = new float[][]
+        vertices = new double[][]
           {
-              { 0.5f, 0.5f, 0.5f },
-              { 0.5f, 0.5f,-0.5f },
-              { 0.5f,-0.5f, 0.5f },
-              { 0.5f,-0.5f,-0.5f },
-              {-0.5f, 0.5f, 0.5f },
-              {-0.5f, 0.5f,-0.5f },
-              {-0.5f,-0.5f, 0.5f },
-              {-0.5f,-0.5f,-0.5f },
+              { 0.5, 0.5, 0.5 },
+              { 0.5, 0.5,-0.5 },
+              { 0.5,-0.5, 0.5 },
+              { 0.5,-0.5,-0.5 },
+              {-0.5, 0.5, 0.5 },
+              {-0.5, 0.5,-0.5 },
+              {-0.5,-0.5, 0.5 },
+              {-0.5,-0.5,-0.5 },
           };
 
         vertIndexes = new int[][]
@@ -337,14 +300,17 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
 
         cornerIndexes = new int[] { 0,0,0,0,0,0,0,0 };
         }
-      else if( mode==1 ) // TETRAHEDRON
+
+      ///// TETRAHEDRON //////////////////////////////////////////////////////////////////////////
+
+      else if( mode==1 )
         {
-        vertices = new float[][]
+        vertices = new double[][]
           {
-              {-0.5f, SQ2/4, 0.0f},
-              { 0.5f, SQ2/4, 0.0f},
-              { 0.0f,-SQ2/4, 0.5f},
-              { 0.0f,-SQ2/4,-0.5f}
+              {-0.5, SQ2/4, 0.0},
+              { 0.5, SQ2/4, 0.0},
+              { 0.0,-SQ2/4, 0.5},
+              { 0.0,-SQ2/4,-0.5}
           };
 
         vertIndexes = new int[][]
@@ -369,14 +335,17 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
 
         cornerIndexes = new int[] { 0,0,0,0 };
         }
-      else if( mode==2 )  // DINO
+
+      ///// DINO ////////////////////////////////////////////////////////////////////////////////
+
+      else if( mode==2 )
         {
-        vertices = new float[][]
+        vertices = new double[][]
           {
-              {-0.5f, 0.0f, 0.0f},
-              { 0.5f, 0.0f, 0.0f},
-              { 0.0f,-0.5f, 0.0f},
-              { 0.0f, 0.0f,-0.5f}
+              {-0.5, 0.0, 0.0},
+              { 0.5, 0.0, 0.0},
+              { 0.0,-0.5, 0.0},
+              { 0.0, 0.0,-0.5}
           };
 
         vertIndexes = new int[][]
