Jump to content
  • Advertisement
Sign in to follow this  
noaktree

Generate 3D Cone Primitive

This topic is 3995 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to programmatically generate 3d cones using only triangles, no quads. The cones do not have to come to a point - they can have both top and bottom caps. The generation function should take number of sides and height segments into consideration. Please someone point me towards a good resource, textboox, etc. that covers this particular algorithm? Pseudo code or c++ would be helpful. Examples of cones to generate:

Share this post


Link to post
Share on other sites
Advertisement
Both of these shapes can be created straightforwardly with a little trig and vector math. It's probably easiest to create them with a default position and orientation (e.g. centered at the origin and built around the z axis) and then transform them as desired. Alternatively, you can construct them manually 'in place' given a starting and ending point.

Let me know what exactly you need help with and I can give you some tips (or maybe just post an example - I have plenty of source code for this sort of thing lying around).

Share this post


Link to post
Share on other sites
I would like to build it centered at the origin and built around an axis.

jyk I am familiar with code you have posted on gamedev where your cone function:

template <class T> void Mesh<T>::MakeCone(T r, T l, const Vector3<T>& axis, unsigned int lod)

I have not compiled or tested this code but it seems to create a cone out of triangles with a single bottom cap and no height segments. If we could modify this function to support top caps, where r2 > 0, and add "height segments" then that's exactly what I need. How to do this mathematically is beyond me at the moment.

I would appreciate some examples and source, but I would also like to learn how this works so titles of papers written on these algorithms or books that cover this topic would be greatly appreciated.

Share this post


Link to post
Share on other sites
I can't think of any particular papers or references off the top of my head, but basically what you want is a GLUT-style 'make cylinder' function, with added support for specifying the top and bottom radii separately.

I have code for creating a cylinder mesh, but it's set up a little differently (for example, as you noted, there is no subdivision along the length). Rather than try to adapt that code for you, it'd probably be easier to just go over the algorithm here in this post.

To build your cone/cylinder, you first need to be able to generate the vertices of a unit circle, something like:
for (int i = 0; i < numRadialSubdivisions; ++i) {
float angle = TWO_PI * ((float)i / (float)numRadialSubdivisions);
float s = sin(angle);
float c = cos(angle);
verts[index++].set(c, s, 0.f);
}
For n vertical subdivisions, you'll want to generate n+1 of these circles, spaced appropriately along the z axis. Also, you'll want to scale the radius of each circle (the value by which to scale can be computed by interpolating between the values of the top and bottom radii, based on which 'step' you're at along the z axis).

Once you have the vertices in place, you can set the triangle indices. This is just bookkeeping, and involves nothing more than a little integer math.

Again, except for the differing radii this is essentially the algorithm used by GLUT to create a cylinder mesh, so if you can find some example code for that (Mesa?) you should be good to go.

Otherwise, just post back if you have any trouble implementing the algorithm I described above, and I'll try and help with the details.

Share this post


Link to post
Share on other sites
Thanks Jesse

I had very little trouble getting this to work. I just have vertices at the moment but rendering triangles should be a walk in the park. I had a look at the free glut geometry source. It will make an excellent reference.

_Neil

Share this post


Link to post
Share on other sites
Taken from my engine:

bool CreateCylinder( CMesh *Mesh,
int Size,
float Height,
float Radius,
float Radius1,
int Mode )
{

if ( Radius < 0 ) Radius = -Radius;
if ( Radius1 < 0 ) Radius1 = -Radius1;
if ( Size < 0 ) Size = -Size;
if ( Height < 0 ) Height=-Height;
if ( Size < 4 || Size==0 ||
Radius == 0.0f || Radius1==0.0f ||
Height ==0 ) return false;

float minorStep ;
float x[3],y[3];
float a,du;
int i;

////////////////////////////////////////

Mesh->Reset();

///////////////////////////////////////
// allocate vertex list

if ( Mesh->ReserveVertexBuffer( Size )==false )
return false;
// allocating proper sized texcoords list
if ( Mesh->ReserveTexCoordBuffer( Size )==false )
return false;

//////////////////////////////////////////
// allocating surfaces

if ( Mesh->ReserveSurfaceBuffer( Size )==false )
return false;

/////////////////////////////////////////
// adding vertices

du=(1.0f/(float)Size);

minorStep = 2.0F * __PI *du;

a=0.0f;

for (i=0; i<Size; i++)
{
y[0] = Radius * FastCos(a);
x[0] = Radius * FastSin(a);

Mesh->AddVertex( x[0],-Height,y[0]);

y[1] = Radius1 * FastCos(a);
x[1] = Radius1 * FastSin(a);

Mesh->AddVertex( x[1], Height,y[1]);

a+=minorStep;
}


for ( i=0; i<Size*2-2; i+=2 )
{
Mesh->AddSurface( i+1,i,i+2 );
Mesh->AddSurface( i+3,i+1,i+2 );
}

Mesh->AddSurface( Size*2-1,Size*2-2,0 );
Mesh->AddSurface( 1,Size*2-1,0 );


//////////////////////////////////////////////////////////
// capping

switch ( Mode )
{

case _VT_CAPBOTH_ :

Mesh->AddVertex( 0,-Height,0);

for ( i=0; i<Size*2-2; i+=2 )
Mesh->AddSurface( Size*2,i+2,i );
Mesh->AddSurface( Size*2,0,Size*2-2 );

Mesh->AddVertex( 0,Height,0);

for ( i=0; i<Size*2-2; i+=2 )
Mesh->AddSurface( Size*2+1,i+1,i+2+1 );
Mesh->AddSurface( Size*2+1,Size*2-1,1 );

break;

case _VT_CAPTOP_ :

Mesh->AddVertex( 0,Height,0);

for ( i=0; i<Size*2-2; i+=2 )
Mesh->AddSurface( Size*2,i+2,i );
Mesh->AddSurface( Size*2,0,Size*2-2 );

break;

case _VT_CAPBOTTOM_ :

Mesh->AddVertex( 0,-Height,0);

for ( i=0; i<Size*2-2; i+=2 )
Mesh->AddSurface( Size*2,i+2,i );

Mesh->AddSurface( Size*2,0,Size*2-2 );

break;

}

//////////////////////////////////////////////

//////////////////////////////////////////////

Mesh->Finalize();

return true;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!