PDA

View Full Version : Generating tris from a set og spherical coordinates???



Pete Bassett
01-08-2001, 05:33 AM
Hi all.

I've been messing around with the "Do your own lighting" tutorial which I found on Flipcode. I decided that I would like to see a nice sphere lit with my own routines so I set about building a class to handle building spherical coordinates and then assigning triangles using these vertexes. Ok.

The class below is very nearly working purfectly, except for making the triangles fool proof. As you can see, the Build function takes the Radius, stacks and slices for the sphere, just like gluSphere.

Each triangle in the m_vTris vector holds three indexes into the m_vVert vector. Each vector has a position and a color and some other stuff, blah blah.

The roblem is that assigning the triangles is not 100 correct, I get a missing triangle at the end of the last strip of triangles by the "North Pole" of the sphere.

Also, I'm not sure what this line should read



long iVerts = m_vVert.size()-2;


The minus 2 was needed when I was using 16 stacks to take into consideration the pole regions, but at 32 it doesn't work, I had to set it to 1. Any ideas.

Can anyone see where I'm going wrong with this code.

Thanks a lot.

Pete Bassett




typedef vector<CVertex> VertexCol;
typedef vector<Triangle> TriangleCol;

typedef struct tagTri
{
long m_lVertIndex[3];
} Triangle;

long CSphere::Build(float fRadius, int iSlices, int iStacks)
{
long lTris = 0; // The Number of triangles in this here sphere
float offset = 0.0f;
float dtheta = PI / iSlices;
float fRotFactor = 360.0f / (float)iStacks;
float fRot = 0.0f;
float theta = 0.0f;
vec3_t vDest;
long i = 0;

// clear out the vertex array
m_vVert.clear();
m_vTris.clear();
// save the build info for posterity
m_fRadius = fRadius;
m_iStacks = iStacks;
m_iSlices = iSlices;

// add the north pole to the sphere
m_vVert.push_back(CVertex( offset, -fRadius, 0));

// generate points of latitude.
for(theta = -PI / 2 + dtheta; theta < PI / 2 - dtheta + 0.1; theta += dtheta)
{
fRot = fRotFactor;

vec3_t v(offset + fRadius * cos(theta), fRadius * sin(theta), 0);

m_vVert.push_back(CVertex(v));
// rotate this point around 360 degrees on the Y axis
while(fRot < 359.0f)
{
v.RotateY(fRot, vDest);
m_vVert.push_back(CVertex(vDest));
fRot += fRotFactor;
}
}

// add the south pole to the sphere
m_vVert.push_back(CVertex( offset, fRadius, 0));

// now generate triangles for these points //

// first build a triangle fan for the north pole

Triangle cTri;
for(i = 1; i < iSlices; i++)
{
// generate triangles who all have a vertex at the north pol
cTri.m_lVertIndex[0] = 0;
cTri.m_lVertIndex[1] = i + 1;
cTri.m_lVertIndex[2] = i ;
m_vTris.push_back(cTri);
}

cTri.m_lVertIndex[0] = 0;
cTri.m_lVertIndex[1] = 1;
cTri.m_lVertIndex[2] = iSlices;
m_vTris.push_back(cTri);

// now generate iStack triangle strips for the main body of the sphere
long iStack = 0;
while(iStack < iStacks-1)
{
for(i = iStack * iSlices; i < iStack * iSlices + iSlices; i++)
{
// generate triangles who all have a vertex at the north pol
cTri.m_lVertIndex[0] = i;
cTri.m_lVertIndex[1] = i + 1;
cTri.m_lVertIndex[2] = i + iStacks;
m_vTris.push_back(cTri);

cTri.m_lVertIndex[0] = i + 1;
cTri.m_lVertIndex[1] = i + iStacks + 1;
cTri.m_lVertIndex[2] = i + iStacks;
m_vTris.push_back(cTri);
}
iStack++;
}

// now generate a triangle fan for the south pole
long iVerts = m_vVert.size()-1;
for(i = 1; i < iSlices; i++)
{
// generate triangles who all have a vertex at the north pol
cTri.m_lVertIndex[0] = iVerts;
cTri.m_lVertIndex[1] = iVerts - i - 1;
cTri.m_lVertIndex[2] = iVerts - i ;
m_vTris.push_back(cTri);
}

cTri.m_lVertIndex[0] = iVerts;
cTri.m_lVertIndex[1] = iVerts - 1;
cTri.m_lVertIndex[2] = iVerts - iSlices;
m_vTris.push_back(cTri);

return lTris; // return the number of triangles we have put in here
}

long CSphere: http://www.opengl.org/discussion_boards/ubb/biggrin.gifraw(float fParam)
{
TriangleCol::iterator iIter;

glBegin(GL_TRIANGLES);
for(iIter = m_vTris.begin();iIter != m_vTris.end();iIter++)
{
CColour c;

c = m_vVert[(*iIter).m_lVertIndex[0]].Colour();
glColor4f(c.Red(),c.Green(),c.Blue(),c.Alpha());

glVertex3fv((float*)m_vVert[(*iIter).m_lVertIndex[0]].Pos());

c = m_vVert[(*iIter).m_lVertIndex[1]].Colour();
glColor4f(c.Red(),c.Green(),c.Blue(),c.Alpha());

glVertex3fv((float*)m_vVert[(*iIter).m_lVertIndex[1]].Pos());

c = m_vVert[(*iIter).m_lVertIndex[2]].Colour();
glColor4f(c.Red(),c.Green(),c.Blue(),c.Alpha());

glVertex3fv((float*)m_vVert[(*iIter).m_lVertIndex[2]].Pos());
}
glEnd();

/*VertexCol::iterator iIter;

glBegin(GL_POINTS);
for(iIter = m_vVert.begin();iIter != m_vVert.end();iIter++)
{
CColour c = (*iIter).Colour();
glColor4f(c.Red(),c.Green(),c.Blue(),c.Alpha());
glVertex3fv((float*)(*iIter).Pos());
}
glEnd();*/

return 0;
}