Jump to content
  • Advertisement
Sign in to follow this  
brekehan

Programatically create sphere

This topic is 3404 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

Does anyone have an algorithm for creating the vertices for a sphere with a given a radius and another variable controlling how many triangles it is made of? How about texture coordinates to go along with those? My Google search is fairing well on this one. I can go in circles with sin and cos, but I'm not really sure how to actually make triangles with them, or how to get texture coords since I've never really understood spherical texture mapping.

Share this post


Link to post
Share on other sites
Advertisement
Moving to Graphics Programming and Theory.

Have you tried Google? There seems to be a lot of reasonable results there - in particular, this and this (OpenGL, but the theory is the same as D3D).

Share this post


Link to post
Share on other sites
My code to generate sphere, everything is obvious nevertheless there are some my structs.


static void R_CreateSphere(lightShape_t *shape, float radius, int slices, int stacks) {
float sinI[MAX_SHAPE_SEGMENTS], cosI[MAX_SHAPE_SEGMENTS];
float sinJ[MAX_SHAPE_SEGMENTS], cosJ[MAX_SHAPE_SEGMENTS];
vec3_t normal;
shadowVert_t *vertex;
index_t *index;
index_t rowA, rowB;
int i, j;

// validate parameters
radius = max(radius, 0.f);
slices = Q_clamp(slices, 2, MAX_SHAPE_SEGMENTS);
stacks = Q_clamp(stacks, 2, MAX_SHAPE_SEGMENTS);

// setup the shape
shape->numIndices = 6 * (stacks - 1) * slices;
shape->indices = R_StaticAlloc(shape->numIndices * sizeof(index_t));

shape->numVertices = (stacks - 1) * slices + 2;
shape->vertexBuffer = R_VB_Alloc(VBT_STATIC, shape->numVertices * sizeof(shadowVert_t));

// create sin/cos cache
for (i = 0; i < slices; i++)
Q_sincos(2.f * Q_PI * (float)i / (float)slices, &sinI, &cosI);
for (j = 0; j < stacks; j++)
Q_sincos(Q_PI * (float)j / (float)stacks, &sinJ[j], &cosJ[j]);

// generate vertices
vertex = R_VB_Map(shape->vertexBuffer, VBA_WRITE_ONLY);

// positive Z pole
vertex->xyz[0] = 0.f;
vertex->xyz[1] = 0.f;
vertex->xyz[2] = radius;
vertex++;

// stacks
for (j = 1; j < stacks; j++) {
for (i = 0; i < slices; i++) {
normal[0] = sinI * sinJ[j];
normal[1] = cosI * sinJ[j];
normal[2] = cosJ[j];

vertex->xyz[0] = normal[0] * radius;
vertex->xyz[1] = normal[1] * radius;
vertex->xyz[2] = normal[2] * radius;
vertex++;
}
}

// negative Z pole
vertex->xyz[0] = 0.f;
vertex->xyz[1] = 0.f;
vertex->xyz[2] = -radius;
vertex++;

R_VB_Unmap(shape->vertexBuffer);
GL_BindVB(NULL);

// generate indices
index = shape->indices;

// positive Z pole
rowA = 0;
rowB = 1;

for(i = 0; i < slices - 1; i++) {
index[0] = rowA;
index[1] = rowB + i + 1;
index[2] = rowB + i;
index += 3;
}

index[0] = rowA;
index[1] = rowB;
index[2] = rowB + i;
index += 3;

// interior stacks
for (j = 1; j < stacks - 1; j++) {
rowA = 1 + (j - 1) * slices;
rowB = rowA + slices;

for (i = 0; i < slices - 1; i++) {
index[0] = rowA + i;
index[1] = rowA + i + 1;
index[2] = rowB + i;
index += 3;

index[0] = rowA + i + 1;
index[1] = rowB + i + 1;
index[2] = rowB + i;
index += 3;
}

index[0] = rowA + i;
index[1] = rowA;
index[2] = rowB + i;
index += 3;

index[0] = rowA;
index[1] = rowB;
index[2] = rowB + i;
index += 3;
}

// negative Z pole
rowA = 1 + (stacks - 2) * slices;
rowB = rowA + slices;

for (i = 0; i < slices - 1; i++) {
index[0] = rowA + i;
index[1] = rowA + i + 1;
index[2] = rowB;
index += 3;
}

index[0] = rowA + i;
index[1] = rowA;
index[2] = rowB;
}

Share this post


Link to post
Share on other sites
I created four video tutorials that show how you can create a sphere programatically and also how to apply a texture over it. You can get the video's here: http://www.marek-knows.com/downloadSection.php?Topic=Physics&pg=1#Physics4

Share this post


Link to post
Share on other sites
it's probably not what you're after,
but i have a simple demo showing non-realtime generation of a sphere with exactly N vertices here: http://elenzil.com/progs/separate
(essentially using a simple electrostatic repulsion method to relax an initial random distribution)
and a demo of efficiently uniformly distributing random points on a sphere here: http://elenzil.com/progs/randompoints

both include DirectX 9 source.

(sorry, new to the forum, not sure how to markup links yet)

Share this post


Link to post
Share on other sites
Quote:
Original post by mmakrzem
I created four video tutorials that show how you can create a sphere programatically and also how to apply a texture over it. You can get the video's here: http://www.marek-knows.com/downloadSection.php?Topic=Physics&pg=1#Physics4


Site will not send an email to allow me to register in order to watch the video.

EDIT:
I finally got an email and logged in. Your website is so set up to make money.
The user is forced to watch videos in sequence and is only given a few free downloads. Before I am even able to get to the sphere video, which is the only one that interests me, I am told I need to purchase download slots.

Everyone has to make a buck, but I am not going to contribute to something that leaves such a sour taste in my mouth.

Maybe I'll try again in 4 days when I am allowed another free download from your site.




[Edited by - brekehan on May 28, 2009 2:56:38 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by KRIGSSVIN
My code to generate sphere, everything is obvious nevertheless there are some my structs.


It isn't so obvious :(

I tired drawing on paper what is going on and I am failing to visualize it.
I tried stepping through the code and my first vertex ends up being (0, very close to 0, very close to 0)... like e-19 close.

I used a radius of 1, 4 stacks, 4 slices, in order to know what the trig valus should be.

I can't visualize the iteration of the vertices. Where is the first point supposed to be after you do a pole?




Share this post


Link to post
Share on other sites
An easy algorithm with great results and without singularities at the poles is to create 6 planes, with normals to the left, right, top, bottom, front, back. You triangulate those planes, and then normalise all vertex positions, and finally multiply them by some radius. While still not a perfect mapping, it is also easy to texture that sphere with a cubemap.

Share this post


Link to post
Share on other sites
Quote:
Original post by phresnel
An easy algorithm with better results and without singularities at the poles is to create 6 planes, with normals to the left, right, top, bottom, front, back. You triangulate those planes, and then normalise all vertex positions, and finally multiply them by some radius. While still not a perfect mapping, it is also easy to texture that sphere with a cubemap.


That sounds like a good idea.

I can probably use that for some spheres, but I have a special case where I need to generate my sphere to have particular triangles for proper texture mapping.

I want to end up with a sphere as I would if I created it in 3ds max.


This is built of rectangles, except for the stack next to the poles.
I imagine I can just split those rectangles into triangles if I can get an algorithm to get this far.

The reason I like this is that it makes texture mapping so easy. I can visualize the way the texture fits as if I took a knife and cut down the sphere from pole to pole on one side. It then unwraps to look like this:



So I can predict what my texture is going to look like as if I took a sheet of paper and wrapped it around a drinking glass. Of course there is some distortion near the poles because it is spherical, but I can still visualize it.

I am in fact trying to generate spheres in my engine in order to replace spheres that were exported from max as models for things like background, star field, planets, and moons. Each of those has multiple layers that are also spheres, so loading all these models from files seems silly, when I know my engine could do it instead.

EDIT:
I can easily see that sin and cos can be taken around the unit circle in the xz plane and the same for the yz plane. It is just a matter of using that to make the actual vertices. It's been a long time since trig class. I'll eventually get it if I draw enough pictures :P


Share this post


Link to post
Share on other sites
brekehan

This function gives you a sphere identical to 3DSMax one.
It consists of three parts: top cap, central part, and bottom cap.

Output is a triangle mesh, there are 3 indices per triangle.

Anyway, this is a sample from DXSDK adapted to my engine. They have normals there too.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!