Playing around with texture mapping.
Can render “polar” or “skybox” type videos.
Move the mouse to look around.
If your video has a different mapping, I have not run across it.
/**
* Based on "Texture Sphere" example by Gillian Ramsay
*
*/
import processing.video.*;
Movie movie;
boolean doSphere = false;
float SPH_RAD = 300;
int ptsW, ptsH;
PImage img;
int numPointsW;
int numPointsH_2pi;
int numPointsH;
float[] coorX;
float[] coorY;
float[] coorZ;
float[] multXZ;
void setup() {
size(1280, 900, P3D);
background(0);
noStroke();
ptsW=48;
ptsH=48;
initializeSphere(ptsW, ptsH);
movie = new Movie(this, "video360.mp4");
movie.loop();
movie.volume(0.1);
}
void movieEvent(Movie m) {
m.read();
}
void keyPressed() {
if (key == ' ') doSphere = !doSphere; // toggle sphere/skybox rendering
}
void draw() {
background(0);
float rota = TWO_PI * mouseX / width + PI/2;
float rotx = cos(rota)*SPH_RAD;
float rotz = sin(rota)*SPH_RAD;
camera(0, 0, 0,
rotx, 2*(mouseY-height/2), rotz,
0, 1, 0);
if (doSphere)
{
textureSphere(SPH_RAD, SPH_RAD, SPH_RAD, movie);
}
else
{
skybox(SPH_RAD, movie);
}
}
void skybox(float sz, PImage t) {
float B = sz;
beginShape(QUADS);
texture(t);
//front
vertex(-B,-B,-B, t.width*1.0/3, 0.0);
vertex( B,-B,-B, t.width*2.0/3, 0.0);
vertex( B, B,-B, t.width*2.0/3, t.height*0.5);
vertex(-B, B,-B, t.width*1.0/3, t.height*0.5);
// left
vertex(-B,-B,-B, t.width*1.0/3, 0.0);
vertex(-B, B,-B, t.width*1.0/3, t.height*0.5);
vertex(-B, B, B, 0.0, t.height*0.5);
vertex(-B,-B, B, 0.0, 0.0);
// right
vertex( B,-B,-B, t.width*2.0/3, 0.0);
vertex( B,-B, B, t.width, 0.0);
vertex( B, B, B, t.width, t.height*0.5);
vertex( B, B,-B, t.width*2.0/3, t.height*0.5);
// back
vertex( B, B, B, t.width*1.0/3, t.height*0.5);
vertex(-B, B, B, t.width*1.0/3, t.height);
vertex(-B,-B, B, t.width*2.0/3, t.height);
vertex( B,-B, B, t.width*2.0/3, t.height*0.5);
// top
vertex(-B,-B, B, t.width*2.0/3, t.height);
vertex(-B,-B,-B, t.width, t.height);
vertex( B,-B,-B, t.width, t.height*0.5);
vertex( B,-B, B, t.width*2.0/3, t.height*0.5);
// bottom
vertex(-B, B, B, t.width*1.0/3, t.height);
vertex(-B, B,-B, 0.0, t.height);
vertex( B, B,-B, 0.0, t.height*0.5);
vertex( B, B, B, t.width*1.0/3, t.height*0.5);
endShape();
}
void initializeSphere(int numPtsW, int numPtsH_2pi) {
// The number of points around the width and height
numPointsW=numPtsW+1;
numPointsH_2pi=numPtsH_2pi; // How many actual pts around the sphere (not just from top to bottom)
numPointsH=ceil((float)numPointsH_2pi/2)+1; // How many pts from top to bottom (abs(....) b/c of the possibility of an odd numPointsH_2pi)
coorX=new float[numPointsW]; // All the x-coor in a horizontal circle radius 1
coorY=new float[numPointsH]; // All the y-coor in a vertical circle radius 1
coorZ=new float[numPointsW]; // All the z-coor in a horizontal circle radius 1
multXZ=new float[numPointsH]; // The radius of each horizontal circle (that you will multiply with coorX and coorZ)
for (int i=0; i<numPointsW ;i++) { // For all the points around the width
float thetaW=i*2*PI/(numPointsW-1);
coorX[i]=sin(thetaW);
coorZ[i]=cos(thetaW);
}
for (int i=0; i<numPointsH; i++) { // For all points from top to bottom
if (int(numPointsH_2pi/2) != (float)numPointsH_2pi/2 && i==numPointsH-1) { // If the numPointsH_2pi is odd and it is at the last pt
float thetaH=(i-1)*2*PI/(numPointsH_2pi);
coorY[i]=cos(PI+thetaH);
multXZ[i]=0;
}
else {
//The numPointsH_2pi and 2 below allows there to be a flat bottom if the numPointsH is odd
float thetaH=i*2*PI/(numPointsH_2pi);
//PI+ below makes the top always the point instead of the bottom.
coorY[i]=cos(PI+thetaH);
multXZ[i]=sin(thetaH);
}
}
}
void textureSphere(float rx, float ry, float rz, PImage t) {
// These are so we can map certain parts of the image on to the shape
float changeU=t.width/(float)(numPointsW-1);
float changeV=t.height/(float)(numPointsH-1);
float u=0; // Width variable for the texture
float v=0; // Height variable for the texture
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i=0; i<(numPointsH-1); i++) { // For all the rings but top and bottom
// Goes into the array here instead of loop to save time
float coory=coorY[i];
float cooryPlus=coorY[i+1];
float multxz=multXZ[i];
float multxzPlus=multXZ[i+1];
for (int j=0; j<numPointsW; j++) { // For all the pts in the ring
normal(-coorX[j]*multxz, -coory, coorZ[j]*multxz);
vertex(coorX[j]*multxz*rx, coory*ry, -coorZ[j]*multxz*rz, u, v);
normal(-coorX[j]*multxzPlus, -cooryPlus, -coorZ[j]*multxzPlus);
vertex(coorX[j]*multxzPlus*rx, cooryPlus*ry, -coorZ[j]*multxzPlus*rz, u, v+changeV);
u+=changeU;
}
v+=changeV;
u=0;
}
endShape();
}