Equirectangular panorama

Post Reply
kerbal
Posts: 9
Joined: Sun Nov 22, 2015 9:06 pm

Equirectangular panorama

Post by kerbal »

Смастерил просмотрщик панорам.
https://yadi.sk/d/P0LzMsyVwt4xZ
Attachments
screen1.jpg
screen1.jpg (15.46 KiB) Viewed 7589 times
kerbal
Posts: 9
Joined: Sun Nov 22, 2015 9:06 pm

Re: Equirectangular panorama

Post by kerbal »

Допиленная версия - можно открывать любую панораму не перезапуская программу.
Меню выбора открывается по "F1"

Code: Select all

//pano_pixi

panosource_filename=file_dialog("Выбрать панораму","gif/png/jpg","3d layer_files")
panosource=load(panosource_filename)

scr = get_screen() //получаем контекст экрана

vpx = get_xsize( scr ) //получаем ширину экрана
vpy = get_ysize( scr ) //получаем высоту экрана

psx = get_xsize( panosource ) //получаем ширину панорамы - источника
psy = get_ysize( panosource ) //получаем высоту  панорамы - источника

panodest = new(vpx,vpy, PIXEL)

deg2rad = M_PI / 180

cam_heading = 60 //поворот
cam_pitch = 90 //наклон
cam_fov = 75 //угол зрения

theta_fac = psy / M_PI
phi_fac = (psx - 3) * 0.5 / M_PI

ratioUp = 2.0 * tan( cam_fov * deg2rad / 2.0)
ratioRight = ratioUp * 1.33

PosLastX = 0;
PosLastY = 0;

fn atan2( $x,$y)
{
_atan_t = 0.0
if $x == 0.0 && $y == 0.0
{
    _atan_t = 0.0
}
else
{
    if $x >= $y
    {
        if $x >= -$y
        {
            _atan_t = atan($y / $x) // правый квадрант 
        }
        else
        {
            _atan_t = (-M_PI / 2) - atan($x / $y) // нижний квадрант
        }
     }
     else
     {
     if $x >= - $y
	 {
         _atan_t = (M_PI / 2) - atan($x / $y) // верхний квадрант
      }
     else
	 {
     if $y >= 0.0
     {
      _atan_t = M_PI + atan($y / $x) // верхний октант в левом квадранте
	  }
     else
     {
      _atan_t = -M_PI + atan($y / $x) // нижний октант в левом квадранте
     }
   }
}
}
   ret ( _atan_t )
}

while( 1 )
{
while(get_event())
{
draw = 0
    if EVT[ EVT_TYPE ] == EVT_MOUSEMOVE { 
	x = EVT[ EVT_X ] + (vpx / 2)
	y = EVT[ EVT_Y ] + (vpy / 2)
	camDirX = sin(cam_pitch* deg2rad) * sin(cam_heading* deg2rad);
	camDirY = cos(cam_pitch* deg2rad);
	camDirZ = sin(cam_pitch* deg2rad) * cos(cam_heading* deg2rad);
	camUpX = ratioUp * sin((cam_pitch - 90.0)* deg2rad) * sin(cam_heading* deg2rad);
	camUpY = ratioUp * cos((cam_pitch - 90.0)* deg2rad);
	camUpZ = ratioUp * sin((cam_pitch - 90.0)* deg2rad) * cos(cam_heading* deg2rad);
	camRightX = ratioRight * sin((cam_heading - 90.0)* deg2rad);
	camRightY = 0.0 ;
	camRightZ = ratioRight * cos((cam_heading - 90.0)* deg2rad);
	camPlaneOriginX = camDirX + 0.5 * camUpX - 0.5 * camRightX;
	camPlaneOriginY = camDirY + 0.5 * camUpY - 0.5 * camRightY;
	camPlaneOriginZ = camDirZ + 0.5 * camUpZ - 0.5 * camRightZ;
	i= 0
	while (i < vpy)
	{
		fy = i / vpy
		j = 0
		while (j < vpx)
		{
			fx = j / vpx
			rayX = camPlaneOriginX + fx * camRightX - fy * camUpX;
			rayY = camPlaneOriginY + fx * camRightY - fy * camUpY;
			rayZ = camPlaneOriginZ + fx * camRightZ - fy * camUpZ;
			rayNorm = 1.0 / sqrt(pow(rayX,2) + pow(rayY,2) + pow(rayZ,2));
			theta = acos(rayY * rayNorm);
			phi = atan2(rayZ, rayX) + M_PI;
			phi_i = floor(phi_fac * phi);
			theta_i = floor(theta_fac * theta);
			panodest[j,i] = panosource[phi_i, theta_i]
		j + 1 // шаг копирования х - увеличение ускоряет отрисовку за счёт снижения качества
		}
	i + 1 // шаг копирования у - увеличение ускоряет отрисовку за счёт снижения качества
	}
	draw = 1
 }
  
	pixi(panodest,0,0)
	cam_heading = cam_heading - (x - PosLastX);
	cam_pitch = cam_pitch + 0.5 * (y - PosLastY);
	if cam_pitch < 0 {cam_pitch = 0}
	if cam_pitch > 180 { cam_pitch = 180}
	PosLastX = x;
	PosLastY = y;
	while( get_event() ) {
	if(EVT[ EVT_TYPE ] == EVT_BUTTONDOWN )
	{
		if(EVT[ EVT_KEY ]==KEY_F1)
		{
		panosource_filename=file_dialog("Выбрать панораму - F1","gif/png/jpg","3d layer_files")
		panosource=load(panosource_filename)
		}
	}
	if EVT[ EVT_TYPE ] == EVT_QUIT {halt}}
	frame()
	}
}
Post Reply