// **************************************
// DOME FISHEYE for WINGS RX
// **************************************
// (C) 2020 Matthias Eichner
// version 0.1
// date: 19.02.2020

 const float PI = 3.141592653589793238462643383279502884197169399375105820974944592308;
 const vec4 c_BgColor = vec4( 0, 0, 0, 0);

//@implements: sampler2D
struct DOME_plane2fisheye
{
    
    sampler2D sampler;
    
    //@ label: "Image Width [px]", editor: range,  min: 0, max: 20000, range_min: 0, range_max: 20000, range_default: 1920
    float imageWidth;
    //@ label: "Image Height [px]", editor: range,  min: 0, max: 20000, range_min: 0, range_max: 20000, range_default: 1080
    float imageHeight;
    //@ label: "Azimuth [deg]", editor: range,  min: 0, max: 360, range_min: 0, range_max: 360, range_default: 0
    float azimuth;
    //@ label: "Altitude [deg]", editor: range,  min: 0, max: 90, range_min: 0, range_max: 90, range_default: 30
    float altitude;
    //@ label: "Zoom [%]", editor: range,  min: 0, max: 350, range_min: 0, range_max: 350, range_default: 100
    float zoom;
    //@ label: "Field Of View [deg]", editor: range,  min: 0, max: 360, range_min: 0, range_max: 360, range_default: 180
    float fov;
    //@ label: "Camera X", editor: range,  min: -100, max: 100, range_min: -100, range_max: 100, range_default: 0
    float cameraX;
    //@ label: "Camera Y", editor: range,  min: -100, max: 100, range_min: -100, range_max: 100, range_default: 0
    float cameraY;
    
};

mat2 rotate(float angle)
{
    return mat2(cos(angle),-sin(angle),sin(angle),cos(angle));
}

vec3 rotateX(vec3 p,float angle)
{
    vec3 q;
    q.x=p.x;
    q.y=p.y*cos(angle)+p.z*sin(angle);
    q.z=-p.y*sin(angle)+p.z*cos(angle);
    return q;
}

vec4 texture(DOME_plane2fisheye s,vec2 tex_coords)
{
    // CALC
    float aspect=s.imageHeight/s.imageWidth;
    float azimuthRad=-(s.azimuth*PI/180.);
    float fovRad=s.fov*PI/180.;
    float tilt=(90.-s.altitude)*PI/180.;
    
    // Vector p in fisheye view
    vec2 vPos=2.*tex_coords-1.;
    
    // Rotate view
    vPos=rotate(azimuthRad)*vPos;
    
    // Vector p in fisheye view
    float r=sqrt(vPos.x*vPos.x+vPos.y*vPos.y);// 0 to 1
    float theta=atan(vPos.y,vPos.x);// -pi to pi
    float phi=r*.5*fovRad;
    vec3 p=vec3(sin(phi)*cos(theta),sin(phi)*sin(theta),cos(phi));
    
    // move camera
    p.x+=s.cameraX/100.;
    p.y+=s.cameraY/100.;
    
    // Rotate plane, height above spring line
    p=rotateX(p,tilt);
    
    // Below horizon?
    if(p.z<0.||r>1.)
    {
        return c_BgColor;
    }
    else
    {
        // Pixel in perspective
        float z=200./s.zoom;
        vec2 uv=vec2((z*aspect*p.x/p.z+1.)/2.,(z*p.y/p.z+1.)/2.);
        // Clip and return colour
        if(uv.x<0.||uv.x>1.||uv.y<0.||uv.y>1.) // Outside image width
        {
            return c_BgColor;
        }
        else
        {
            return texture(s.sampler,uv);
        }
    }
}
