#version 430

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

out vec2 uv;

out float no;

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

uniform mat4 projectionMatrix;
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));

  if (id3<0.5) {
      vp = imageLoad(mesherVertPos, getTrip(tri.x));
      norm = imageLoad(mesherVertNorm, getTrip(tri.x)).xyz;
      //vp = imageLoad(mesherVertPos, getTrip(int(id)));
   //   vp.xyz = vec3(0.0, 0.0, 0.0);
  } else if (id3<1.5) {
      vp = imageLoad(mesherVertPos, getTrip(tri.y));
      norm = imageLoad(mesherVertNorm, getTrip(tri.y)).xyz;
      //vp.xyz = vec3(1.0, 0.0, 0.0);
  } else {
      vp = imageLoad(mesherVertPos, getTrip(tri.z));
      norm = imageLoad(mesherVertNorm, getTrip(tri.z)).xyz;
     // vp.xyz = vec3(1.0, 1.0, 0.0);
  }

  norm = imageLoad(mesherVertNorm, getTrip(idt)).xyz;

//  float dk = 4.0;
//   if (id > 6.0*dk*2.0) vp.xyz *= 0.0;

  vec4 vpo = vp;

  vp.w = 1.0;

  vp.xyz *= vec3(scaleX, scaleY, scaleZ);

  vp = modelViewMatrix*vp;
  vp = projectionMatrix*vp;

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

  no = -vpo.z;

  uv = vpo.xy;

  gl_Position = vp;
}
