#version 430

// layout (location=0) in vec3 vertexPosition;

out vec2 uv;

out float no;

out vec3 norm;
out vec3 tan;
out vec3 bit;

out vec4 posWorld;
out vec4 posView;

uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionInvMatrix;
uniform float g_windowWidth;
uniform float g_windowHeight;

uniform float g_time;

vec2 rot2(vec2 p, float a) {
  vec2 r = p;
  r.x = cos(a)*p.x - sin(a)*p.y;
  r.y = sin(a)*p.x + cos(a)*p.y;
  return r;
}

vec4 rotateXZ(vec4 p, float a) {
    vec4 r = p;
    r.x = cos(a)*p.x - sin(a)*p.z;
    r.z = sin(a)*p.x + cos(a)*p.z;
    return r;
}
vec4 rotateYZ(vec4 p, float a) {
    vec4 r = p;
    r.y = cos(a)*p.y - sin(a)*p.z;
    r.z = sin(a)*p.y + cos(a)*p.z;
    return r;
}



float zn = 0.0;
float zf = 1.0;

vec4 CalcEyeFromWindow(in vec3 windowSpace) {
    vec3 ndcPos;
    vec4 viewport = vec4(0.0, 0.0, g_windowWidth, g_windowHeight);
    ndcPos.xy = ((2.0 * windowSpace.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
    ndcPos.z = (2.0 * windowSpace.z - zn - zf) / (zf - zn);
    vec4 clipPos;
    clipPos.w = projectionMatrix[3][2]/(ndcPos.z-(projectionMatrix[2][2]/projectionMatrix[2][3]));
    clipPos.xyz = ndcPos * clipPos.w;
    return projectionInvMatrix * clipPos;
}



uniform float div = 4.0;
uniform float noiseAmp = 1.0;
uniform float noiseFreq = 1.0;


uniform float noisePos = 0.0;
uniform float noiseOfsX = 0.0;
uniform float noiseOfsY = 0.0;
uniform float noiseOfsZ = 0.0;

uniform float minLim = 0.02;
uniform float fadeArea = 0.20;
uniform float fadeAmp = 160.0;

uniform float explo = 0.0;

uniform float noiseExp = 1.0;
uniform float noiseSub = 0.0;

uniform float subFreq = 4.0;
uniform float subSinFreq = 1.0;
uniform float subAmp = 0.250;
uniform float subEps = 0.050;
uniform float subPos = 0.0;

uniform float subBaseNorm = 0.0;

uniform float uvScale = 2.0;


uniform float scaleX = 1.0;
uniform float scaleY = 1.0;
uniform float scaleZ = 1.0;



layout(binding=0, rgba32i) uniform iimage2D mesherTriangles;
layout(binding=1, rgba32f) uniform image2D mesherVertPos;
layout(binding=2, rgba32f) uniform image2D mesherVertNorm;


ivec2 getTrip(int idt) {
    ivec2 triBufSize = imageSize(mesherTriangles);
    ivec2 trip;
    trip.y = idt/triBufSize.x;
    trip.x = idt-trip.y*triBufSize.x;
   // trip.y = 0;
    return trip;
}

void main() {
  vec4 vp = vec4(0.0);
  float id = float(gl_VertexID);

  float id3 = (fract(id/3.0)*3.0); // index of the vertex in a triangle 0,1,2
  float idv = floor((id/3.0-fract(id/3.0))+0.50); // triangle index 0,1,2,3,...
  float idv2 = fract(idv/2.0)*2.0; // every second triangle 0 and 1
  float idq = floor((id/6.0-fract(id/6.0))+0.5); // quad index 0,1,2,3,...


  int idt = int(idv);

  idt = int(id)/3;

  ivec4 tri = imageLoad(mesherTriangles, getTrip(idt));

  int vi = 0;
  if (id3<0.5) {
      vi = tri.x;
      vp = imageLoad(mesherVertPos, getTrip(tri.x));
  } else if (id3<1.5) {
      vi = tri.y;
      vp = imageLoad(mesherVertPos, getTrip(tri.y));
  } else {
      vi = tri.z;
      vp = imageLoad(mesherVertPos, getTrip(tri.z));
  }

//  norm = imageLoad(mesherTriNorm, getTrip(idt)).xyz;

//  int idTri = idt;
//  ivec4 adj;

//  int i=0;

//  bool lookRight = false;

//  while (true) {
//    if (lookRight) {
//        adj = imageLoad(mesherTriAdjRight, getTrip(idTri));
//    } else {
//        adj = imageLoad(mesherTriAdjLeft, getTrip(idTri));
//    }
//    ivec4 triVerts = imageLoad(mesherTriangles, getTrip(idTri));
//    if (triVerts.x == vi) {
//        idTri = adj.x;
//    } else if (triVerts.y == vi) {
//        idTri = adj.y;
//    } else if (triVerts.z == vi) {
//        idTri = adj.z;
//    } else {
//        idTri = -1;
//        break;
//    }
//    i++;
//    if (idTri == -1 && !lookRight) {
//        lookRight = true;
//        idTri = idt;
//        continue;
//    }
//    if (i>16 || (idTri == idt) || (idTri == -1)) break;
//    norm += imageLoad(mesherTriNorm, getTrip(idTri)).xyz;
//  }
//  norm = (modelViewMatrix*vec4(norm, 0.0)).xyz;
//  norm = -normalize(norm);

  norm = imageLoad(mesherVertNorm, getTrip(vi)).xyz;
  norm = (viewMatrix*vec4(norm, 0.0)).xyz;
  norm = -normalize(norm);

  vec4 vpo = vp;

  vp.w = 1.0;

  posWorld = modelMatrix*vp;


  vp = modelViewMatrix*vp;

  posView = vp;

  vp = projectionMatrix*vp;

  tan = vec3(1.0, 0.0, 0.0);
  bit = vec3(0.0, 1.0, 0.0);

 // tan = (modelViewMatrix*vec4(tan, 0.0)).xyz;
 // bit = (modelViewMatrix*vec4(tan, 0.0)).xyz;

  tan = tan-dot(norm, tan)*norm;
  bit = bit-dot(norm, bit)*norm;

  no = -vpo.z;

  uv = vpo.xy/vec2(scaleX, scaleY);

  gl_Position = vp;
}
