Creating the Hyperspace Tunnel Webpage

In the simplest terms, the hyperspace tunnel was created by creating a circle and projecting it down the positive Z axis in order to map out a cylinder in 3D virtual space. The tunnel was not created as a polygonal model. A circle is created by using the mathematical sin() and cos() functions. The sin() and cos() functions both produce a same sinusoidal waveform except that the two functional waveforms are 90 degrees out of phase with each other. We can take advantage of this phase difference to create a circle for ourselves. Now remember that we previously said that our texture map's width, 5026 pixels, must be the distance around the tunnel. If we take the distance around a unit circle, which is 2*PI radians, and divide that by the width of our texture map, then we have just determined how much around the unit circle we need to go for each pixel. In other words, we have just divided the circle into 5026 pieces or slices. This amount is 0.001250136 radians and this is the amount we add to go from one pixel along the circle to the next pixel.

To form the unit circle, we just need to keep a running tab of which slice of the circle we are currently looking at and then feed these radian values into both the sin() and cos() functions. The results of each function are then plotted on an X-Y coordinate system graph with the X axis plotting out the sin() function value and the Y axis plotting out the cos() function. To go to the next pixel around the circle, we just add the 0.001250136 increment amount to our previous amount and calculate the sin() and cos() function values again. See the diagram below.

(Diagram)


Now, we need the circle to be larger than the unit circle size, which is a circle with a radius of 1 inch. We actually need a circle with a radius of 2 inches. To get a two inch circle we just multiply the results of the sin() and cos() function values by two. Also, each slice of the circle must intersect the pixel somewhere within its area so we will just decide that the center of each pixel is where we want each slice of the circle to intersect the pixel. That means that for the first pixel on the circle, we can't feed the 0.001250136 value into the sin() and cos() functions since this value is used to get us from the center of one pixel to the center of the next pixel along the circle. The center of the first pixel on the circle is halfway through the pixel so for the first pixel we define on the circle, we must feed 0.001250136 / 2.0 or 0.000625068 into the sin() and cos() functions.

Now, we have defined where all the 5026 pixels are going to go along the edge of a circle that is four inches in diameter. Next we need to create a tunnel. To do that, all we need to know is how many inches there are per pixel. That is just 1.0/400 or 0.0025. We get the 400 from the fact that the virtual camera's viewport is two inches wide, with 800 pixels squeezed in that distance so 800/2=400.

We can now make our tunnel. Remember that we have already determined the X and Y coordinates for every pixel along the four inch diameter circle. If we move this tunnel circle and all the pixels attached to it down the positive Z axis by a distance of one pixel or 0.0025 inch, then we have just defined a cylinder and each pixel now has an X, Y and Z coordinate in virtual space. If we keep moving the circle down the Z axis by a distance of 0.0025 inch each time, after 56580 moves, which is the number of rows in our texture map, then we have just created the tunnel we want. See the below diagram.

(Diagram), the first circle of pixels is actually located in the Z=0 plane so they must be offset a half pixel distance down the Z axis since we want all the center points for each pixel to be on the positive side of the Z axis. I should say again that each time we go down the Z axis in order to create another ring of pixels, we are also going another row down in texture map.

So to recap, to create our tunnel, which is really just the pixels of our texture map placed out in virtual space in the shape of a cylinder, all we need to do is repeatedly create a new tunnel circle out in virtual space at a distance of one more pixel than the circle before it, and then just run around the circumference of this new circle mapping out each pixel along the edge. So what we're really doing is completely mapping our texture map to the tunnel's inner surface. Below is the essence of these thoughts.

// Start function -----------------------------------------------------------

for (each Z distance going from the near end of the tunnel to the far end of the tunnel,
        Also keep track of texture map row_coord)
   {
   for (each rotational distance along the tunnel circle,
           Also keep track of texture map column_coord)
      {
      Calculate a new X coordinate with sin(Rotational Distance) function.
      Calculate a new Y coordinate with cos(Rotational Distance) function.
      Call function Translate_pixel(X, Y, Z)
      Call function Add_pixel_to_viewport_accumulator(X, Y, Z, row_coord, column_coord)
      }
   }

// End function -----------------------------------------------------------

Now, my hyperspace tunnel is only physically about 12 feet long, and four inches wide. But even with that length of tunnel you will be able to see out the far end. And beyond the far end of the tunnel is the infinite black space of the twilight zone. I would prefer the people viewing the tunnel not see that. To make that black circle go away, what I have decided to do is mathematically mold the last two inches worth of the tunnel into the shape of a half sphere. By doing this, I can effectively make the hole disappear and now all the user will see is an infinitely long hyperspace tunnel. I'm not going to go into any more detail about this point. I just wanted you to be aware of this.

Now, I should note that as we go along and create our hyperspace tunnel one ring of pixels at a time, I'm constantly keeping track of both the X, Y, and Z virtual 3D space coordinates of each texture map pixel as well as the row and column coordinates of where each pixel is in the texture map. This information is necessary to both determine where each tunnel pixel projects into the viewport, but it also helps me create the Viewport Accumulator Array. This array is used to prevent the program from having to go through the above tunnel definition procedure for every frame of animation that must be created. This saves the computer from doing tens of billions of unnecessary calculations per frame. The cost of using this array is an additional 218MB of memory. Click the link in the above pseudo code to learn more about the Viewport Accumulator Array.


Last Updated: May 3, 2002
HTML URL: http://geocities.datacellar.net/~special_effect/ht_create_tunnel.html
E-Mail: special_effect.geo@yahoo.com or click here
1