Flash CS4 Polar Cube (one-to-one mapping)

January 24, 2009

Intro

Mapping a sphere to a cube becomes a fundamental issue in CS4, where vertex to UV data is a one-to-one map. Typical UV data brought in from Blender or 3DSMax, which have multiple uv data points per vertex (or triangle fan), will not work with the drawTriangles method of CS4. There are work-a-rounds, but eventually it all boils down to creating some type of one-to-one mapping scheme.

An illustrative step in this process is the creation of a polar cube – a polar cube created completely from the polar parametric equations of an octagonal cubic (not pieced together with six planes (or 8 planes in this case) as is done in Papervision3D and other such software). Got a little ahead of myself here – the techniques described can be used to make any number of sides. I kept referring to a cube but created an octagonal as was pointed out by makc3d in the comments. The equations can be used to created a sculpty prim maker which will be posted soon.

Not 8 separate sides, all one structure.

Polar Cube

Polar Cube

Demo: Click Here

Source: Click Here

Polar Cube Derivation

The parametric mapping equations (for a polar cube) are simple, and for a 2D boil down to

x = r(θ)*cos(θ)
y = r(θ)*sin(θ)

and in 3D,

x = r(θ, Φ)*cos(θ)sin(Φ)
y = r(θ, Φ)*sin(θ)sin(Φ)
z = r(θ, Φ)*cos(Φ)

where r is function of angle (not constant as in the spherical case).

Solving for the 2D case, r(θ) is given by

θ: 0 to 90, r(θ) = 1/(sin(θ) + cos(θ))
θ: 90 to 180, r(θ) = 1/(sin(θ) – cos(θ))
θ: 180 to 270, r(θ) = -1/(sin(θ) + cos(θ))
θ: 270 to360, r(θ) = -1/(sin(θ) – cos(θ))

These solutions are easily obtained by substitution x = r(θ)*cos(θ), and y = r(θ)*sin(θ) into the linear equations shown in the figure below and solving for r(θ).

2D Polar Case

2D Polar Case

The generalized solution is

r(a, b, θ) = a/(sin(θ) + b*cos(θ))

where

θ: 0 to 90 (a=1, b=1), θ: 90 to 180 (a=1, b=-1), θ: 180 to 270 (a=-1, b=-1), θ: 270 to360 (a=-1, b=-1) Of interest, the values of the a, b parameters correspond to all possible combinations of 1 and -1, similar two coins which gives (HH, HT, TH, TT) where H=1, and T=-1.

3D Case

Following the approach above, for the 3D case (where 8 possible planes corresponding to the 8 sides of the polar cube), the general solution is given by

r(a, b, c, θ, Φ) = a/(cos(Φ)+b*sin(θ)sin(Φ)+c*cos(θ)sin(Φ))

where the parameters a, b, c correspond to flipping three coins at the same time with 8 possible outcomes (HHH, HHT, HTH, HTT, THH, THT, TTH, TTT or 111, 11-1, 1-11, 1-1-1, -111,- 11-1, -1-11, -1-1-1), corresponding to the 8 sides of our polar cube.

The eight possibilities used to map the vertices of the cube are given below:

θ: 0 to 90, Φ:0 to 90 (-1,-1,-1)
θ: 90 to 180, Φ:0 to 90 (-1,-1,1)
θ: 180 to 270, Φ:0 to 90 (-1,1,1)
θ: 270 to360, Φ:0 to 90 (-1,1,-1)

θ: 0 to 90, Φ:90 to 180 (1,1,1)
θ: 90 to 180, Φ:90 to 180 (1,1,-1)
θ: 180 to 270, Φ:90 to 180 (1,-1,-1)
θ: 270 to360, Φ:90 to 180 (1,-1,1)

Coding the Parametric Equations

The coding is straightforward. The cube’s vertices are derived from the parametric form given above and its indices are derived from a one-to-one mapping of a sphere onto a cube. That’s why the spherically mapped image, shown in the image above, lays on the cube without distortion.

for (var i:int = 0 ; i!=rows; i++) {
ix= i/(rows-1)*Math.PI*2.0;

for (var j:int = 0 ; j!=cols; j++) {
iy= (j/(cols-1)-0.5)*Math.PI;

// 8 planes 8case

if(ix>=0 && ix<2*Math.PI/4){

//θ: 0-90, Φ: 0-90, (-1,-1,-1)

if(iy>=-2*Math.PI/4 && iy<0){
varMyrIs=rFunc(-1,-1,-1,ix,iy);
}else{

//θ: 0-90, Φ: 90-180, (1,1,1)

varMyrIs=rFunc(1,1,1,ix,iy);}
}

if(ix>=2*Math.PI/4 && ix<2*Math.PI/2){

//θ: 90-180, Φ: 0-90, (-1,-1,1)

if(iy>=-2*Math.PI/4 && iy<0){
varMyrIs=rFunc(-1,-1,1,ix,iy);
}else{

//θ: 90-180, Φ: 90-180, (1,1,-1)

varMyrIs=rFunc(1,1,-1,ix,iy);}
}

if(ix>=2*Math.PI/2 && ix<6*Math.PI/4){

//θ: 180-270, Φ: 0-90, (1,-1,1)

if(iy>=-2*Math.PI/4 && iy<0){
varMyrIs=rFunc(-1,1,1,ix,iy);
}else{

//θ: 180-270, Φ: 90-180, (-1,-1,1)

varMyrIs=rFunc(1,-1,-1,ix,iy);}
}

if(ix>=6*Math.PI/4 && ix<=2*Math.PI){

//θ: 270-360, Φ: 0-90, (-1,1,-1)

if(iy>=-2*Math.PI/4 && iy<0){

varMyrIs=rFunc(-1,1,-1,ix,iy);
}else{

//θ: 270-360, Φ: 90-180, (1,-1,1)

varMyrIs=rFunc(1,-1,1,ix,iy);}
}

//Polar Cube
paraVec = new Vector3D(
varMyrIs*Math.cos(iy)*Math.cos(ix), varMyrIs*Math.sin(iy), varMyrIs*Math.cos(iy)*Math.sin(ix));

//Collect vetices in the verts Vector array
verts.push(radx*paraVec.x,rady*paraVec.y,radz*paraVec.z);

//Load uvt data
uvtData.push( i/(rows-1),j/(cols-1), 0.0);
//Initialize projected vertices
projectedVerts.push(0.0,0.0);
}
}

Now you’ll ready to start Knowledge Space. To see the entire code click the more link below:

Read the rest of this entry »


Flash CS4 Spherical Panorama (animating uvtData)

January 24, 2009

Intro

Creating a CS4 Panorama has a unique twist – literally! You actually don’t rotate the primitive but you animate its texture, using the code snippet below:

public function step(moveU:Number, moveV:Number=0.0):void {
for (var i=0; i<uvtData.length; i+=2) {
uvtData[i++] -= moveU;
uvtData[i] += moveV;
// each loop i increases by 3 because skiping over the t-coordinate
}
}

The uvtData is easily animated just by skipping through correct U or V values of the uvtData vector and adding a small increment. Click on the image below to see the web demo.

Panorama of NKU Bridge

Panorama of NKU Bridge

As in the previous Super Prim post, Petri Leskinen’s great work on Pixelero http://pixelero.wordpress.com/ was key to this creation. He demonstrates an animated tube which with a little work I was able to turn into this panorama.

Demo: Click Here

Source: Click Here

YouTube: Coming Soon!

Discussion

The encapsulated code very closely resembles the OOP regimentation of Papervision3D. The CS4PanoPrim wrapper class instantiates the SpherePano primitive. And the SpherePano constructor function has 5 input parameters: material, width, height, hSegments, and wSegments, as shown below:

spherePano = new SpherePano(bmp, 500.0, 500.0, 32, 32);

The SpherePanoPrim is set up very much like the Super Prim (previous post) with the addition of a new mask function, which gives you the ability to trim the look of your pano.

private function addMyMask():void {
// mask crops that to a rectangle
myMask = new Sprite();

myMask.graphics.lineStyle(0.0,0×00,1.0);
myMask.graphics.beginFill(0x00,1.0);
myMask.graphics.drawRect(-w/2,-h/2,w,h);

myMask.graphics.endFill();
addChild(myMask);
this.mask = myMask;
}

The mask is just a simple sprite that uses the “this.mask” method to mask your pano.

If you want to learn how to make spherical pano images check out the following YouTube links by Amanda Verrette (one of my graphic designers):

Part 1: http://www.youtube.com/watch?v=wfkLQ93Uey0
Part 2: http://www.youtube.com/watch?v=hhjuSIzLXCE
Part 3: http://www.youtube.com/watch?v=AKpVboahayg

Parts 4, 5, 6, 7, and 8 are still in production.

There’s still more work to do on this before release, but it’s great starter code. And harnesses the OOP structure of Papervision3D. To view both classes discussed above click the more link below:

Read the rest of this entry »


Follow

Get every new post delivered to your Inbox.