// **************************************
// DOME PANO TO SPHERE for WINGS RX
// **************************************
// wraps equirectangular panorama image on dome
// (C) 2018 VIOSO GmbH
// version 1.0 (bf)
// date: 05.11.2018

// struct must have same name as this file
//@implements: sampler2D
struct DOME_pano2sphere2 {
  sampler2D sampler;
  //@ label: "Azimuth / Position", editor: range,  min: -360, max: 360, range_min: 0, range_max: 360, range_default: 90
  float azimuth;
  //@ label: "Elevation / Height", editor: range,  min: -179, max: 179, range_min: -179, range_max: 179, range_default: 50
  float elevation;
	//@ label: "Rotation / Roll ", editor: range,  min: 0, max: 90, range_min: 0, range_max: 90, range_default: 50
  float rotation;
  //@ label: "Field Of View in Y", editor: range,  min: 0, max: 360, range_min: 0, range_max: 360, range_default: 180
  float fovY;
};

vec4 texture(DOME_pano2sphere2 sa, vec2 tex_coords)
{
  float c2_PI   = 3.141592653589793238462643383279502884197169399375105820974944592308;
  float c2_2PI  = 2.0*c2_PI;
  float c2_G2R  = c2_PI/180.0;
  float c2_G2RH = c2_G2R*0.5;
  float c2_H_PI = c2_PI*0.5;
  vec3 angle = vec3(sa.elevation*c2_G2R, sa.azimuth*c2_G2R, sa.rotation*c2_G2R);
  
  vec3 v3D;
  vec2 v2D;
  float  c,s,l;
  vec2 pos = tex_coords;
  pos.x= 1.0 - pos.x;

  v2D.x=( 2.0*pos.x - 1.0 );
  v2D.y=( 1.0 - 2.0*pos.y );

  float in_azi = atan(v2D.y, v2D.x);
  float in_ele = (1.0 - length(v2D) * (sa.fovY / 180.0)) * c2_H_PI;

  float l_xz_3D = cos(in_ele);
  v3D.x = cos(in_azi) * l_xz_3D;
  v3D.z = sin(in_azi) * l_xz_3D;
  v3D.y = sin(in_ele);

  mat4 rotationX = mat4(1.0, 0, 0, 0, 0, cos(angle.x), -sin(angle.x), 0, 0, sin(angle.x), cos(angle.x), 0, 0, 0, 0, 1.0);
  mat4 rotationY = mat4(cos(angle.y), 0, sin(angle.y), 0, 0, 1.0, 0, 0, -sin(angle.y), 0, cos(angle.y), 0, 0, 0, 0, 1.0);
  mat4 rotationZ = mat4(cos(angle.z), -sin(angle.z), 0, 0, sin(angle.z), cos(angle.z),	0, 0, 0, 0, 1.0, 0, 0, 0, 0,1.0);

  v3D = (rotationY * rotationX * rotationZ * vec4(v3D, 1.0)).xyz;

  in_azi = atan(v3D.z, v3D.x);
  in_ele = atan(v3D.y, length(v3D.xz)); // ranges from 0 to PI
  in_ele /= c2_PI;
  return texture( sa.sampler, vec2( in_azi / c2_2PI + 0.5, in_ele + 0.5) );  
} 