OK here's a 360 viewer, it ended up quite a bit longer than I anticipated, but maybe someone better at math can simplify it/improve:
Code:
//equirectangular 360 panner
//@param1:fov_ang 'fov' 90 20 170 45 1
//@param2:x_ang 'x' 0 -180 180 0.5 1
//@param3:y_ang 'y' 0 -90 90 0.5 1
//@param4:div 'div' 100 20 150 40 1
//@param5:filter 'filter' 0 0 1 0 1
project_w<1 ? project_w=1920;
project_h<1 ? project_h=1080;
gfx_img_resize(-1,project_w,project_h);
input_info(0,srcw,srch);
function matrix_make_rotate(matrix, m, d) global() local(m2)
(
memset(matrix,0,16);
matrix[m*5-5] = matrix[15] = 1.0;
m2 = m==2 ? 0 : (m+1);
matrix[m2*5]=matrix[m*5]=cos(d);
matrix[m2*4+m]=-(matrix[m*4+m2]=sin(d));
);
function matrix_multiply(dest,src) global() local(s0,s1,s2,s3)
(
loop(4,
s0=dest[0]; s1=dest[1]; s2=dest[2]; s3=dest[3];
dest[0] = s0*src[(0<<2)+0]+s1*src[(1<<2)+0]+s2*src[(2<<2)+0]+s3*src[(3<<2)+0];
dest[1] = s0*src[(0<<2)+1]+s1*src[(1<<2)+1]+s2*src[(2<<2)+1]+s3*src[(3<<2)+1];
dest[2] = s0*src[(0<<2)+2]+s1*src[(1<<2)+2]+s2*src[(2<<2)+2]+s3*src[(3<<2)+2];
dest[3] = s0*src[(0<<2)+3]+s1*src[(1<<2)+3]+s2*src[(2<<2)+3]+s3*src[(3<<2)+3];
dest+=4;
);
);
function matrix_apply(x,y,z, m, vec*) global()
(
vec.x = x*m[0] + y*m[1] + z*m[2] + m[3];
vec.y = x*m[4] + y*m[5] + z*m[6] + m[7];
vec.z = x*m[8] + y*m[9] + z*m[10] + m[11];
);
matrix1 = 0;
matrix2 = matrix1 + 16;
tab=matrix2 + 16;
xdiv=ydiv=div|0;
screen_z = 1/tan(fov_ang * 0.5 * $pi / 180);
y = -0.5 * (project_h/project_w);
dx = 1.0 / (xdiv-1);
dy = (project_h/project_w) / (ydiv-1);
matrix_make_rotate(matrix1,2,-x_ang * $pi / 180);
matrix_make_rotate(matrix2,1,y_ang * $pi / 180);
matrix_multiply(matrix1,matrix2);
ptr = tab;
loop(ydiv,
x=-0.5;
loop(xdiv,
matrix_apply(x,y,screen_z,matrix1,vv);
sy = 0.5 + asin(vv.y / sqrt(vv.x*vv.x+vv.y*vv.y+vv.z*vv.z)) / $pi;
sx = 0.5 + (atan2(vv.x,vv.z)) / (2*$pi);
sy < 0 ? (
sy = -sy;
sx += 0.5;
) : sy>= 1 ? (
sy=2-sy;
sx+=0.5;
);
ptr[0]=sx*srcw;
ptr[1]=sy*srch;
x+=dx;
ptr+=2;
);
y+=dy;
);
gfx_mode=filter > 0 ? 0x100 : 0;
gfx_xformblit(0, 0,0, project_w,project_h,xdiv,ydiv, tab,0);
In the next 5.22 pre, I'm going to improve video processors in the monitoring FX chain -- particularly, it will apply them after the main (cached) video rendering pipeline, so you can look around and it won't need to reprocess any project video. Right now (in 5.21) this viewer pretty useless unless you're automating it (e.g. if you have some 360deg 4k video, and you tweak the x/y parameters, it takes forever to update). So try in the next 5.22pre, I suppose...
Preview: