#version 420 core
// UNIFORM BLOCK

#define USE_COLOR_PROP BOOL_COLOR_PROP

layout(vertices = 1) out;

in vec4 outpos_CS_in[];
in vec2 outAziIncl_CS_in[];

#if USE_COLOR_PROP
in float outProp_CS_in[];
out float outProp_ES_in[];
#endif

in vec3 outVecX_CS_in[];
in vec3 outVecY_CS_in[];
in vec3 outVecZ_CS_in[];


out vec4 outpos_ES_in[];
out vec2 outAziIncl_ES_in[];

out vec3 outVecX_ES_in[];
out vec3 outVecY_ES_in[];
out vec3 outVecZ_ES_in[];

uniform vec3 cSceneScale;
uniform vec4 cRadiusScale;
uniform float projInfoY;
uniform float proj1length;

float
CalcTessSizeHorizontal(vec4 cPosRadius, float rOuterRadius)
{
  // REPLACE VIEWDEPEDENT TESSELATION SIZE

  float
    rDist = gl_ModelViewProjectionMatrix[0][3] * cPosRadius.x +
            gl_ModelViewProjectionMatrix[1][3] * cPosRadius.y + 
            gl_ModelViewProjectionMatrix[2][3] * cPosRadius.z + 
            gl_ModelViewProjectionMatrix[3][3];

  float
    rPixelUnit = projInfoY * -rDist;

  float rPixels = rOuterRadius / rPixelUnit;
  rPixels *= 0.5;

  if (rPixels < 4.0) rPixels = 4.0;
  else if (rPixels > 512.0) rPixels = 512.0;

  return rPixels;
}

void main(void)
{
    if (gl_InvocationID == 0)
    {
      // horizontal tesselation
      float
        rRadius = length(outVecX_CS_in[gl_InvocationID]) + 
                  length(outVecY_CS_in[gl_InvocationID]) + 
                  length(outVecZ_CS_in[gl_InvocationID]);

      rRadius /= 3.0;
      
      float
        rTess = CalcTessSizeHorizontal(outpos_CS_in[0], rRadius);

      gl_TessLevelOuter[1] = 2.0 * rTess;
      gl_TessLevelOuter[3] = 2.0 * rTess;
      gl_TessLevelInner[0] = 2.0 * rTess;

      // vertical tesselation
      gl_TessLevelOuter[0] = rTess;
      gl_TessLevelOuter[2] = rTess;
      gl_TessLevelInner[1] = rTess;
    }

    outpos_ES_in[gl_InvocationID] = outpos_CS_in[gl_InvocationID];
    outAziIncl_ES_in[gl_InvocationID] = outAziIncl_CS_in[gl_InvocationID];
#if USE_COLOR_PROP
    outProp_ES_in[gl_InvocationID] = outProp_CS_in[gl_InvocationID];
#endif

    outVecX_ES_in[gl_InvocationID] = outVecX_CS_in[gl_InvocationID];
    outVecY_ES_in[gl_InvocationID] = outVecY_CS_in[gl_InvocationID];
    outVecZ_ES_in[gl_InvocationID] = outVecZ_CS_in[gl_InvocationID];
}
