commit a3a05347dec371a5e85bac2a2f5bfde83900f79b
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu Mar 5 11:40:33 2020 +0000

    Improve setTextureMap.

diff --git a/src/main/java/org/distorted/library/mesh/MeshBase.java b/src/main/java/org/distorted/library/mesh/MeshBase.java
index 31901fa..c7bda8b 100644
--- a/src/main/java/org/distorted/library/mesh/MeshBase.java
+++ b/src/main/java/org/distorted/library/mesh/MeshBase.java
@@ -26,6 +26,7 @@ import org.distorted.library.effect.MatrixEffect;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.InternalBuffer;
 import org.distorted.library.program.DistortedProgram;
+import org.distorted.library.type.Static4D;
 
 import java.util.ArrayList;
 
@@ -71,28 +72,27 @@ public abstract class MeshBase
    private class Component
      {
      private int mEndIndex;
-     private float[] mTextureMap;
+     private Static4D mTextureMap;
 
      Component(int end)
        {
-       mEndIndex = end;
-
-       mTextureMap    = new float[4];
-       mTextureMap[0] = 0.0f;  // LowerLeft_X
-       mTextureMap[1] = 0.0f;  // LowerLeft_Y
-       mTextureMap[2] = 1.0f;  // Width
-       mTextureMap[3] = 1.0f;  // Height
+       mEndIndex  = end;
+       mTextureMap= new Static4D(0,0,1,1);
        }
      Component(Component original)
        {
        mEndIndex = original.mEndIndex;
-       mTextureMap = new float[4];
-       System.arraycopy(original.mTextureMap,0,mTextureMap,0,4);
+
+       float x = original.mTextureMap.get0();
+       float y = original.mTextureMap.get1();
+       float z = original.mTextureMap.get2();
+       float w = original.mTextureMap.get3();
+       mTextureMap = new Static4D(x,y,z,w);
        }
 
-     void setMap(float[] newMap)
+     void setMap(Static4D map)
        {
-       System.arraycopy(newMap,0,mTextureMap,0,4);
+       mTextureMap.set(map.get0(),map.get1(),map.get2(),map.get3());
        }
      }
 
@@ -452,40 +452,60 @@ public abstract class MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Sets texture maps for all components of this mesh.
+ * Sets texture maps for (some of) the components of this mesh.
  * <p>
- * Please note that calling this once with the complete list of Maps will be much faster than
- * calling it repeatedly with one Maps at a time, as we have to reallocate the array of vertices
- * each time.
- * 'maps' needs to be maps[NumComponentsInThisMesh][4]. [0] is the lower-left corner's X, [1]- its Y,
- * [2] - width, [3] - height of the map.
- * For example map[0] = new float { 0.0, 0.5, 0.5, 0.5 } sets the 0th component texture map to the
+ * Format: ( x of lower-left corner, y of lower-left corner, width, height ).
+ * For example maps[0] = new Static4D( 0.0, 0.5, 0.5, 0.5 ) sets the 0th component texture map to the
  * upper-left quadrant of the texture.
+ * <p>
+ * Probably the most common user case would be sending as many maps as there are components in this
+ * Mesh. One can also send less, or more (the extraneous ones will be ignored) and set some of them
+ * to null (those will be ignored as well). So if there are 5 components, and we want to set the map
+ * of the 2nd and 4rd one, call this with
+ * maps = new Static4D[4]
+ * maps[0] = null
+ * maps[1] = the map for the 2nd component
+ * maps[2] = null
+ * maps[3] = the map for the 4th component
+ *
+ * A map's width and height have to be non-zero (but can be negative!)
  */
-   public void setTextureMap(float[][] maps)
+   public void setTextureMap(Static4D[] maps)
      {
      int num_comp = mComponent.size();
      int num_maps = maps.length;
      int min = num_comp<num_maps ? num_comp : num_maps;
      int vertex = 0;
      int index  = TEX_ATTRIB;
-     float[] newMap, oldMap;
+     Static4D newMap, oldMap;
      Component comp;
+     float newW, newH, ratW, ratH, movX, movY;
 
      for(int i=0; i<min; i++)
        {
-       if( maps[i]!=null && maps[i][2]!=0.0f && maps[i][3]!=0.0f )
+       newMap = maps[i];
+
+       if( newMap!=null )
          {
-         comp = mComponent.get(i);
-         newMap = maps[i];
-         oldMap = comp.mTextureMap;
+         newW = newMap.get2();
+         newH = newMap.get3();
 
-         for( ; vertex<=comp.mEndIndex; vertex++, index+=VERT_ATTRIBS)
+         if( newW!=0.0f && newH!=0.0f )
            {
-           mVertAttribs[index  ] = (newMap[2]/oldMap[2])*(mVertAttribs[index  ]-oldMap[0]) + newMap[0];
-           mVertAttribs[index+1] = (newMap[3]/oldMap[3])*(mVertAttribs[index+1]-oldMap[1]) + newMap[1];
+           comp = mComponent.get(i);
+           oldMap = comp.mTextureMap;
+           ratW = newW/oldMap.get2();
+           ratH = newH/oldMap.get3();
+           movX = newMap.get0() - ratW*oldMap.get0();
+           movY = newMap.get1() - ratH*oldMap.get1();
+
+           for( ; vertex<=comp.mEndIndex; vertex++, index+=VERT_ATTRIBS)
+             {
+             mVertAttribs[index  ] = ratW*mVertAttribs[index  ] + movX;
+             mVertAttribs[index+1] = ratH*mVertAttribs[index+1] + movY;
+             }
+           comp.setMap(newMap);
            }
-         comp.setMap(newMap);
          }
        }
 
