Skip to main content
gamedev.net
🔒 Locked

sphere generation algorithm

Started by psykr Aug 29, 2003 at 6:23 PM 8 replies 2.4k views
Original Post
psykr
psykr
Is there a particular algorithm for generating a sphere? I''d like to create a skydome, but I want to generate the vertices with an algorithm so I can change parameters, like the LOD, and its height. Plus, I read that there should be more triangles near the horizon, because it makes sunrise / sunset look better (with vertex colors, not texturing). So.. is there an algorithm? Or do I have to invent one?
Lord Hen
Lord Hen
I remember reading somewhere on the forums that you start with 6 points, 2 at the poles and 4 evenly spaced around the equator, each one''s distance from the center is the radius...from then, you loop through each triangle and get the average of each point, and now you have a new triangle, which splits the old one into 4...then for each of these points, you normalize their position and multiply by the radius.
For a higher LOD you loop through each triangle more times (3 or 4), for a lower, loop through 1 or 2 times, I guess...

Sorry I cant go into more detail, I dont have the code on this computer and am still looking for the old post, maybe someone else can elaborate?

Later,
Lord Hen
Lord Hen
Lord Hen
Ok, I went and got my code, and this is what I have:
create the 6 points
then:
v1,v2,v3 are vectors
tri refers to the current triangle
newtri1,newtri2,newtri3,newtri4 are the 4 new triangles
a triangle in this case is a struct with 3 vectors
psuedocode for each triangle:
v1 = tri.v1 + tri.v2
v2 = tri.v2 + tri.v3
v3 = tri.v3 + tri.v1
v1 = v1 * 0.5
v2 = v2 * 0.5
v3 = v3 * 0.5
normalize v1
normalize v2
normalize v3
v1 = v1 * radius
v2 = v2 * radius
v3 = v3 * radius
newtri1.v1 = tri.v1
newtri1.v2 = v1
newtri1.v3 = v3
newtri2.v1 = tri.v2
newtri2.v2 = v2
newtri2.v3 = v1
newtri3.v1 = tri.v3
newtri3.v2 = v3
newtri3.v3 = v2
newtri4.v1 = v3
newtri4.v2 = v1
newtri4.v3 = v2
delete tri
loop to next triangle

Sorta confusing, agh...maybe you can figure it out though...

So, for higher LOD, you do the full loop through all triangles more times...

Maybe someone can help clarify what my crap-code says...

Later,
Lord Hen
vember
vember
You could also take a decently tesselated cube and normalize all the vertices to the length 1 from the center of the cube.

The best method depends on how you would like the tesselation to look.

[edited by - vember on August 30, 2003 5:14:41 AM]
Lord Hen
Lord Hen
If you want a dome, I assume you could use my method above but change the 6 points to 5....so you have the top point and 4 around the equator, or something...


Later,
Lord Hen
WarAmp
WarAmp
My Skydome code:

SKY_NUM_LAYERS is how many rows of triangles between Horizon and Pole

SKY_NUM_WIDTH is how many triangles wide a layer is. This code generates an hemisphere that has the same number of triangles at every elevation.


float fYaw, fPitch;
float fHStep, fVStep, fLayers, fWidth;
fLayers = (float)SKY_NUM_LAYERS;
fWidth = (float)SKY_NUM_WIDTH;
fVStep = 90.0f / fLayers;
fHStep = 360.0f / fWidth;
m_nNumVertices = 0;

for (fPitch = 90.0f; fPitch >= 0.0f; fPitch -= fVStep)
{
for (fYaw = 0.0f; fYaw < 360.0f; fYaw += fHStep)
{
m_vVertex[m_nNumVertices++].Set(
sinf(DEGRAD(fPitch))*cosf(DEGRAD(fYaw)),
cosf(DEGRAD(fPitch)),
sinf(DEGRAD(fPitch))*sinf(DEGRAD(fYaw))
);
}
}


Then to render this mess:


for (j = 0; j < SKY_NUM_LAYERS; j ++)
{
k = l;
l += SKY_NUM_WIDTH;
glBegin(GL_TRIANGLE_STRIP);
for (i = 0; i < SKY_NUM_WIDTH; i++)
{
glVertex3fv(&m_vVertex[l + i].x);
glVertex3fv(&m_vVertex[k + i].x);
}

glVertex3fv(&m_vVertex[l].x);
glVertex3fv(&m_vVertex[k].x);
glEnd();
}


there ya go. don't laugh too hard at it. it was coded in about 20 minutes, and it worked the first time.

Edit: so. tired. cant. type.

[edited by - waramp on August 30, 2003 12:53:22 AM]
Waramp.Before you insult a man, walk a mile in his shoes.That way, when you do insult him, you'll be a mile away, and you'll have his shoes.
quasar3d
quasar3d
you could indeed use that tesselation method, that may be better for skydomes, but if you just want a globe like sphere (with horizontal edges, and polar edges), you can just rotate a 2D circle around an axis, and create polygons between the points you generate that way

My Site
Alan_Grey
Alan_Grey
Hi, sorry to resurrect an old thread, but I tried implementing waramp''s method with vertex arrays and it doesn''t seem to work. Here''s the code that corresponds to his first block...

	float yaw, pitch;    
float hStep, vStep, layers, width;
layers = (float)res;
width = (float)res;
vStep = PI / (2.0f * layers);
hStep = (2.0f * PI) / width;
int currentVertex=0;

for (pitch = PI / 2.0f; pitch >= 0.0f; pitch -= vStep)
{
for (yaw = 0.0f; yaw < 2.0f * PI; yaw += hStep)
{
// x co-ord
sphereVertices[currentVertex] = sinf(pitch)*cosf(yaw);
currentVertex++;
// y co-ord
sphereVertices[currentVertex] = cosf(pitch);
currentVertex++;
// z co-ord
sphereVertices[currentVertex] = sinf(pitch)*sinf(yaw);
currentVertex++;
}
}


Spherevertices being the vertex array.

This is meant to draw the spheres...

	glNewList(gluSphereList, GL_COMPILE);
//glEnable(GL_NORMALIZE);
glPushMatrix();
glScaled(size, size, size);
glVertexPointer(3, GL_FLOAT, 0, sphereVertices);
glNormalPointer(GL_FLOAT, 0, sphereVertices);

int k=0;
int l=0;

currentVertex=0;

for(int j=0; j < res; j++)
{
k=l;

l += res;

for(int i=0; i < res; i++)
{
sphereIndices[currentVertex] = l + i;
currentVertex++;
sphereIndices[currentVertex] = k + i;
currentVertex++;
}

sphereIndices[currentVertex] = l;
currentVertex++;
sphereIndices[currentVertex] = k;
currentVertex++;
}

for(int m=0; m < res; m++)
{
glDrawElements(GL_TRIANGLE_STRIP, 2*res + 2, GL_UNSIGNED_BYTE, sphereIndices); //&sphereIndices[m*(2*res+2)]);
}

glPopMatrix();
//glDisable(GL_NORMALIZE);
glEndList();


Any help would be greatly appreciated, I''ve run out of things to try.

-Simon
psykr
psykr
Not being an OpenGL user myself, I can''t test your code, so could you describe your problem? I implemented this successfully before, but all my previous code got lost in a fatal hard drive crash (no, I didn''t consider my code important enough to backup).

In case this is the problem.. be careful when you use radians in the vertex generation code. Make sure that the loop is iterating the correct number of times, i.e. not skipping the last one because of floating point precision errors or something.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.