uniform sampler2D colorMap;
uniform sampler2D distortMap;
in vec2 texCoord;
uniform float testvalue;
uniform float rotbounce;
uniform float x_rotation;

vec2 bulge(vec2 v)
{
 
 float factor=0.07*0.4;
 float rf=0.2*0.7;
 vec2 cen = vec2(0.0,0.0) - v;
 vec2 mcen = - 
      factor*log(length(cen))*normalize(cen);
 if (length(cen)<rf) mcen=mix(vec2(0,0),mcen,length(cen)/rf); 
 if (length(cen)<0.001*12.0) mcen=vec2(0,0); 
 return v.xy+mcen;
}

mat3 getrot(vec3 r)
{
    float cx = cos(radians(r.x));
    float sx = sin(radians(r.x));
    float cy = cos(radians(r.y));
    float sy = sin(radians(r.y));
    float cz = cos(radians(r.z));
    float sz = sin(radians(r.z));

    float m1 = cy * cz;
    float m2= cx * sz + sx * sy * cz;
    float m3= sx * sz - cx * sy * cz;
    float m4= -cy * sz;
    float m5= cx * cz - sx * sy * sz;
    float m6= sx * cz + cx * sy * sz;
    float m7= sy;
    float m8= -sx * cy;
    float m9= cx * cy;

    return mat3
    (
        m1,m2,m3,
        m4,m5,m6,
        m7,m8,m9
    );
};

const float PI=3.1415926535897932384626433832795;



vec3 getRot2(float zangle, vec3 v){
float ct=cos(zangle); float st=sin(zangle);
	mat4 rotm=mat4( ct, -st, 0.0,  0.0,
	              st,  ct, 0.0,  0.0,
	             0.0, 0.0, 1.0,  0.0,
	             0.0, 0.0, 0.0,  1.0);
    vec4 v2=vec4(v,1.0)*rotm;
    return v2.xyz;
}

vec3 getRot3(float xangle, vec3 v){
float ct=cos(xangle); float st=sin(xangle);

	mat4 rotm=mat4(1.0, 0.0, 0.0,  0.0,
	         0.0,  ct, -st,  0.0,
	         0.0,  st,  ct,  0.0,
	         0.0, 0.0, 0.0,  1.0);
             

    vec4 v2=vec4(v,1.0)*rotm;
    return v2.xyz;
}


vec3 rotateXY(vec3 p, vec2 angle) {
    vec2 c = cos(angle), s = sin(angle);
    p = vec3(p.x, c.x*p.y + s.x*p.z, -s.x*p.y + c.x*p.z);
    return vec3(c.y*p.x + s.y*p.z, p.y, -s.y*p.x + c.y*p.z);
}

vec4 TinyPlanet()
{
    float ar = 1.0 * 2048.0 / 1024.0;
    float ar2 = 1.0 * 1920.0 / 1080.0;
    
    
    ar=ar/ar2*0.5;

    
    float z_rotation=3.14+rotbounce;
    
    

    vec2 rads = vec2(PI * 2.0 , PI);
    
    

    
    
    
    
    vec2 offset = vec2(0.0,-0.5);
    float scale = 4.5*1.6 /(1.0+1.0)/1.35;
    if (testvalue<0.0) offset*=vec2(0.0,pow(1.0+testvalue,3.0)); 
    if (testvalue<0.0) scale*=1.0+pow(abs(testvalue),5.2); 
    vec2 pnt = (texCoord - 0.5 - offset).xy * vec2(scale, scale*ar);
    

    
    float x2y2 = pnt.x * pnt.x + pnt.y * pnt.y;
    vec3 sphere_pnt = vec3(2.0 * pnt, x2y2 - 1.0) / (x2y2 + 1.0);
    
    sphere_pnt=getRot2(z_rotation,sphere_pnt);

    float fader=x_rotation/6.28;
    if (fader>0.5) fader=1.0-fader;
    fader*=2.0;

fader=testvalue;

    float x_rot;
    if (x_rotation>0) x_rot=x_rotation+texture2D(distortMap, gl_FragCoord/vec2(1920.0,1080.0)).x*fader; else x_rot=0;
x_rot=0;
    sphere_pnt=getRot3(x_rot,sphere_pnt);

    
    float r2=length(sphere_pnt.xy); 
    float r = length(sphere_pnt);

    

    

    float lon = atan(sphere_pnt.x,sphere_pnt.y);
    
    
    
    float lat = acos(sphere_pnt.z / r);
    
    

    vec2 coos=vec2(lon, lat) / rads;

    


    const float hfovDegrees=90.0;
    const float vfovDegrees=90.0/(1920.0/1080.0);
    vec2 uv = texCoord.xy * 2.- 1.;
    
#define DEG2RAD 0.01745329251994329576923690768489
    vec3 camDir = normalize(vec3(uv.xy * vec2(tan(0.5 * hfovDegrees * DEG2RAD), tan(0.5 * vfovDegrees * DEG2RAD)), 1.0));



    
    
    
    
    vec3 camRot=vec3((90.0)*DEG2RAD,0,0);
    
    vec3 rd = normalize(rotateXY(camDir, camRot.yx));
    
    vec2 coos2 = vec2(atan(rd.z, rd.x) + PI, acos(-rd.y)) / vec2(2.0 * PI, PI);
    coos2.y*=-1.0;


    coos2=mod(coos2,1.0);
    coos=mod(coos,1.0);

    
    vec2 coosr;

    
    float mixvalue=clamp(testvalue,0.0,1.0);
    coosr.x=coos2.x*(mixvalue)+(-coos.x+1.0)*(1.0-mixvalue);
    coosr.y=coos2.y*(mixvalue)+(coos.y)*(1.0-mixvalue);

coosr.x=-coosr.x;
    
    

    return texture2D(colorMap, coosr);
    
}










void main()
{
    gl_FragColor = TinyPlanet();
}
