#version 330 core

layout(location = 0) in vec3 Position_modelspace;
layout(location = 1) in uint Texture_model;
layout(location = 2) in vec3 Normal_modelspace;

out VertexData {
    vec3 Position_modelspace;
    flat uint Texture;
    vec3 FaceNormal_modelspace;
#ifdef PBR
    vec3 FaceNormal_worldspace;
    vec3 EyeDirection_cameraspace;
    vec3 LightDirection_cameraspace;
#endif
#ifdef FOG
    float Depth;
#endif
} vs;

#ifdef INSTANCED
layout(location = 6) in mat4 Model;
#else
uniform mat4 Model;
#endif
uniform mat4 View;
uniform mat4 Proj;

uniform vec4 SphereProj;
uniform float Curvature;

uniform vec3 LightInvDirection_worldspace;
uniform float FogDepth;

void main(){
    vs.Position_modelspace = Position_modelspace;

#ifdef CURVATURE
    if(Curvature > 0) {
        vec3 Position_areaspace = Position_modelspace + SphereProj.xyz;
        vec2 sph = vec2(acos(Position_areaspace.z / length(Position_areaspace.xyz)), atan(Position_areaspace.y, Position_areaspace.x));
#ifdef CURV_DEPTH
        float radius = max(max(abs(Position_areaspace.x), abs(Position_areaspace.y)), abs(Position_areaspace.z));
#else
        float radius = SphereProj.w;
#endif
        vs.Position_modelspace = mix(vs.Position_modelspace, vec3(sin(sph.x)*cos(sph.y), sin(sph.x)*sin(sph.y), cos(sph.x)) * radius - SphereProj.xyz, Curvature);
    }
#endif

    vec4 Position_cameraspace = View * Model * vec4(vs.Position_modelspace, 1);
    gl_Position = Proj * Position_cameraspace;

#ifdef FOG
    vs.Depth = length(Position_cameraspace.xyz) / FogDepth;
#endif

    vs.Texture = Texture_model;

    vs.FaceNormal_modelspace = normalize(Normal_modelspace);
#ifdef PBR
    // TODO: correct normal
    vs.FaceNormal_worldspace = normalize((Model * vec4(vs.FaceNormal_modelspace, 0)).xyz);

    // Vector that goes from the vertex to the camera, in camera space.
    // In camera space, the camera is at the origin (0,0,0).
    vs.EyeDirection_cameraspace = vec3(0,0,0) - Position_cameraspace.xyz;

    // Vector that goes from the vertex to the light, in camera space
    vs.LightDirection_cameraspace = (View * vec4(LightInvDirection_worldspace,0)).xyz;
#endif
}
