#version 430

layout (location=0) in vec3 vertexPosition;
layout (location=1) in vec3 vertexNormal;
layout (location=2) in vec2 vertexUV;
layout (location=3) in vec3 vertexTangent;
layout (location=4) in float vertexBright;
layout (location=5) in vec3 vertexOrigCenter;
layout (location=6) in vec4 vertexBranchInfo; // x: age, y: 0.0 = main branch, > 1.0 side branch, z: number of replicas done, w: branch counter

out vec3 position;
out vec3 normal;
out vec2 uv;
out vec3 tangent;
out float bright;
out vec3 origCenter;
out vec4 branchInfo;

uniform float g_time;
uniform float g_timeStep=0.0;
uniform float g_emit = 1.0;
uniform float g_uvScale = 1.0;
uniform float g_bright = 1.0;

uniform float g_zoomAmount = 1.03;

uniform mat4 modelMatrix;

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;
}

vec3 rotateXZ3(vec3 p, float a) {
  return rotateXZ(vec4(p, 0.0), a).xyz;
}

vec3 movePos(vec3 p, vec3 oc, vec4 bi) {
  //  float d = dot(oc, oc);
  //  return p*pow(1.03, g_timeStep/0.05)+vec3(0.0, 1.0*sin(sqrt(d)*0.5), 0.0);
   // return p*pow(g_zoomAmount, g_timeStep/0.05); // +vec3(0.0, 1.0*sin(sqrt(d)*0.5), 0.0);

  //  p-=oc;
  //  p.z+=1.01*pow(0.1, g_timeStep/0.05);
   // p+=oc;

  //  return p*pow(g_zoomAmount, g_timeStep/0.05)+(g_zoomAmount-1.0)/0.07*vec3(0.0, 1.0*(1.0+sqrt(d)*0.001)*sin(log(d)*2.0), 0.0);

    return p*pow(g_zoomAmount, g_timeStep/0.05);
}

vec3 doRot(vec3 p, vec3 oc, vec4 bi) {
//    float d = sqrt(dot(p, p));
    //d = abs(oc.x)*10.0;
  //  p-=oc;


//    p.x*=pow(1.0+0.05*(g_zoomAmount-1.0)/0.07, g_timeStep/0.05);
//    p.y*=pow(1.0-0.01*(g_zoomAmount-1.0)/0.07, g_timeStep/0.05);
//    p.z*=pow(1.0-0.01*(g_zoomAmount-1.0)/0.07, g_timeStep/0.05);
//  //  p+=oc;
//    p = rotateXZ3(p.xzy, (g_zoomAmount-1.0)/0.07*g_timeStep*15.50*sin(d*0.01)).xzy;
   // p = rotateXZ3(p.xyz, g_timeStep*0.250*sin(d*0.15)).xyz;

  //  p = rotateXZ3(p, bi.x);

    return p;
}


void main() {
  gl_Position = vec4(vertexPosition, 1.0);

  float emit = g_emit;

  normal = vertexNormal;
  tangent = vertexTangent;
  bright = vertexBright;
  origCenter = vertexOrigCenter;
  branchInfo = vertexBranchInfo;
  if (emit < 0.5) {
    position = movePos(vertexPosition, vertexOrigCenter, branchInfo);
    origCenter = movePos(vertexOrigCenter, vertexOrigCenter, branchInfo);
    uv = vertexUV;
  //  position += 0.001*normal*sin(sqrt(d*1.1));
    position -= origCenter;
    position = doRot(position, origCenter, branchInfo);
    normal = doRot(normal, origCenter, branchInfo);
    tangent = doRot(tangent, origCenter, branchInfo);
    position += origCenter;

   // branchInfo.x += g_timeStep;
   // position.y = abs(position.y);
  } else {
    // emit a new
    //  position = vertexPosition+vec3(0.1, 0.0, 0.0);
    position = (modelMatrix*vec4(vertexPosition, 1.0)).xyz;
    origCenter = (modelMatrix*vec4(0.0, 0.0, 0.0, 1.0)).xyz;
    //uv = vertexUV;
    bright = g_bright;
    uv = vec2(position.x*1.1+position.z*0.05, position.x*0.1+position.z*1.07+position.y*0.23)*g_uvScale;

    branchInfo.x = g_time; // age
    branchInfo.y = 0.0; // mark as main branch
    branchInfo.z = 0.0; // number of replicas done
    branchInfo.w = 0.0; // branch counter
   // uv.x = bright;
   // uv.y = 0.0;
  }


}

