public void testCameraFusion() throws IOException {
    File dir = new File(outputdir, "test");
    dir.mkdir();

    Point3f[] vertices = smp.getSphere().getVertices();
    for (int ill = 0; ill < 2; ill++) {
      for (int cam = 0; cam < 2; cam++) {
        for (int a = 0; a < nAngles; a++) {
          File outf = new File(dir, getFile(0, a, angleInc, cam, ill, 0));
          if (outf.exists()) continue;
          short[] res = new short[vertices.length];
          for (int v = 0; v < vertices.length; v++) {
            Point3f vertex = new Point3f(vertices[v]);
            if (transforms[a] != null) transforms[a].transform(vertex);
            res[v] = (short) (100 * weights[cam][ill][a].getWeight(vertex.x, vertex.y, vertex.z));
          }
          SphericalMaxProjection.saveShortData(res, outf.getAbsolutePath());
        }
      }
    }
  }
  public void fuse(int tp) throws IOException {
    boolean done = true;
    for (int l = 0; l < nLayers; l++) {
      if (!new File(outputdir, String.format("tp%04d_%02d.vertices", tp, l)).exists()) {
        done = false;
        break;
      }
    }
    if (done) return;

    int nVertices = smp.getSphere().nVertices;

    short[][][][][] m = new short[2][2][nAngles][nLayers][];
    for (int a = 0; a < nAngles; a++) {
      for (int l = 0; l < nLayers; l++) {
        m[CAMERA1][LEFT][a][l] =
            SphericalMaxProjection.loadShortData(
                inputdir
                    .getFile(CAMERA1, getFile(tp, a, angleInc, CAMERA1, LEFT, l))
                    .getAbsolutePath(),
                nVertices);
        m[CAMERA1][RIGHT][a][l] =
            SphericalMaxProjection.loadShortData(
                inputdir
                    .getFile(CAMERA1, getFile(tp, a, angleInc, CAMERA1, RIGHT, l))
                    .getAbsolutePath(),
                nVertices);
        m[CAMERA2][LEFT][a][l] =
            SphericalMaxProjection.loadShortData(
                inputdir
                    .getFile(CAMERA2, getFile(tp, a, angleInc, CAMERA2, LEFT, l))
                    .getAbsolutePath(),
                nVertices);
        m[CAMERA2][RIGHT][a][l] =
            SphericalMaxProjection.loadShortData(
                inputdir
                    .getFile(CAMERA2, getFile(tp, a, angleInc, CAMERA2, RIGHT, l))
                    .getAbsolutePath(),
                nVertices);
      }
    }

    if (adjustModes) {
      float refmode = SphericalMaxProjection.getMode(m[CAMERA1][LEFT][0][0]);
      for (int a = 0; a < nAngles; a++) {
        short[] data = m[CAMERA1][LEFT][a][0];
        float mode = SphericalMaxProjection.getMode(data);
        SphericalMaxProjection.add(data, (short) (refmode - mode));

        data = m[CAMERA1][RIGHT][a][0];
        mode = SphericalMaxProjection.getMode(data);
        SphericalMaxProjection.add(data, (short) (refmode - mode));

        data = m[CAMERA2][LEFT][a][0];
        mode = SphericalMaxProjection.getMode(data);
        SphericalMaxProjection.add(data, (short) (refmode - mode));

        data = m[CAMERA2][RIGHT][a][0];
        mode = SphericalMaxProjection.getMode(data);
        SphericalMaxProjection.add(data, (short) (refmode - mode));
      }
    }

    for (int l = 0; l < nLayers; l++) {
      File out = new File(outputdir, String.format("tp%04d_%02d.vertices", tp, l));
      Point3f[] vertices = smp.getSphere().getVertices();
      float[] res = new float[vertices.length];
      for (int v = 0; v < vertices.length; v++) {
        Point3f vertex = vertices[v];
        float sum = 0;
        res[v] = 0;
        for (int a = 0; a < nAngles; a++) {
          Point3f xvtx = new Point3f(vertex);
          if (transforms[a] != null) transforms[a].transform(xvtx);
          float w1 = weights[CAMERA1][LEFT][a].getWeight(xvtx.x, xvtx.y, xvtx.z);
          float w2 = weights[CAMERA1][RIGHT][a].getWeight(xvtx.x, xvtx.y, xvtx.z);
          float w3 = weights[CAMERA2][LEFT][a].getWeight(xvtx.x, xvtx.y, xvtx.z);
          float w4 = weights[CAMERA2][RIGHT][a].getWeight(xvtx.x, xvtx.y, xvtx.z);
          float m1 = (m[CAMERA1][LEFT][a][l][v] & 0xffff);
          float m2 = (m[CAMERA1][RIGHT][a][l][v] & 0xffff);
          float m3 = (m[CAMERA2][LEFT][a][l][v] & 0xffff);
          float m4 = (m[CAMERA2][RIGHT][a][l][v] & 0xffff);
          sum += w1 + w2 + w3 + w4;
          res[v] += (w1 * m1 + w2 * m2 + w3 * m3 + w4 * m4);
        }
        res[v] = sum == 0 ? 0 : res[v] / sum;
      }
      short[] sData = new short[res.length];
      for (int v = 0; v < res.length; v++) sData[v] = (short) res[v];

      if (saveOutput) SphericalMaxProjection.saveShortData(sData, out.getAbsolutePath());
    }
  }