You are right in that it is the UV mapping. Since the origin of the umbrella is (0,0,0) then
Code:radius = sqrt(x*x + y*y + z*z)
and the value of x will go
0 -> 50 -> 0 -> -50 -> 0
since you take the absolute value then effectively the u coordinate will go
0 -> 1 -> 0 -> -1 -> 0
there is no simple way to change the mapping
Using floats in for loops is very unusual and probably not a good idea so I hope you don't mind I have modified your code so as to use ints in the for loops
Code:
import peasy.*;
PeasyCam pCamera;
float radius = 50.0;
float rho = radius;
float x, y, z, u, v;
float phi;
int phiSteps = 20;
float phiFactor = HALF_PI / phiSteps;
float theta;
int thetaSteps = 20;
float thetaFactor = TWO_PI / thetaSteps;
PVector[] sphereVertexPoints;
PImage skin;
void setup() {
size(320, 240, P3D);
pCamera = new PeasyCam(this, 150);
skin = loadImage("uv_texture.jpg");
textureMode(NORMALIZED);
noStroke();
}
void draw() {
background(50);
//noFill(); stroke(255);
fill(200, 130, 0);
// stage lighting
directionalLight(255, 255, 255, -100, 100, -100);
ambientLight(120, 120, 120);
phi = 0.0;
for(int p = 0; p < phiSteps; p++) {
beginShape(QUAD_STRIP);
texture(skin);
theta = 0.0;
for(int t = 0; t < thetaSteps + 1; t++) {
x = rho * sin(phi) * cos(theta);
z = rho * sin(phi) * sin(theta);
y = -rho * cos(phi);
u = (float)t / thetaSteps;
v = (float)p / phiSteps;
normal(x, y, z);
vertex(x, y, z, u, v);
x = rho * sin(phi + phiFactor) * cos(theta);
z = rho * sin(phi + phiFactor) * sin(theta);
y = -rho * cos(phi + phiFactor);
u = (float)t / thetaSteps;
v = (float)(p + 1) / phiSteps;
normal(x, y, z);
vertex(x, y, z, u, v);
theta += thetaFactor;
}
phi += phiFactor;
endShape(CLOSE);
}
}
It should be fairly self explanatory but there are now two variables to define the number of horizontal (phiSteps) and vertical strips (thetaSteps) that make up the umbrella.
P.S.
Quite a bit more can be done to make the code more efficient such as inside the inner loop pre-calculating the sin and cos functions before calculating the xyz coordinates...