|
-
Apr 27th, 2002, 11:26 AM
#1
Object Primitive Algorithms
I'm currently learning Direct3D in C++ and I was wondering if anyone could supply me with algorithms that create the vertices (positions and normals) for simple 3d objects like cubes, spheres, cylinders and such. It's very messy to create a cube by hand, and I don't get the normals right anyway.
I'd like C++ code best, but VB code or just an algorithm description is also ok.
Thanks in advance
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Apr 27th, 2002, 12:09 PM
#2
The easiest way to do a cube is to simply place the vertices by hand, unfortunatly. A cylinder is pretty simple. Simply use your standard sin/cos algorithm to add vertices as if you were drawing a 2D Circle, but do this in a for loop, and add to your up coordinate at each iteration of that loop (you need to generate the triangles, so it might be best to use indexed tri-lists for this).
Sphees are fun. You can do them in two ways; Latidue/Longitude spheres where triangles nearer the poles are smaller then those near the equator, and geo-spheres which have a VERY even triangle size spread. Lat/Long spheres are the easiest. Here is an algorithm (its for open GL, but the logic is there):
Code:
void CreateSphere(XYZ c,double r,int n)
{
int i,j;
double theta1,theta2,theta3;
XYZ e,p;
if (r < 0)
r = -r;
if (n < 0)
n = -n;
if (n < 4 || r <= 0) {
//glBegin(GL_POINTS);
//glVertex3f(c.x,c.y,c.z);
//glEnd();
return;
}
for (j=0;j<n/2;j++) {
theta1 = j * TWOPI / n - PID2;
theta2 = (j + 1) * TWOPI / n - PID2;
//glBegin(GL_QUAD_STRIP);
for (i=0;i<=n;i++) {
theta3 = i * TWOPI / n;
e.x = cos(theta2) * cos(theta3);
e.y = sin(theta2);
e.z = cos(theta2) * sin(theta3);
p.x = c.x + r * e.x;
p.y = c.y + r * e.y;
p.z = c.z + r * e.z;
// this is drawing stuff... you can ignore
//glNormal3f(e.x,e.y,e.z);
//glTexCoord2f(i/(double)n,2*(j+1)/(double)n);
//glVertex3f(p.x,p.y,p.z);
e.x = cos(theta1) * cos(theta3);
e.y = sin(theta1);
e.z = cos(theta1) * sin(theta3);
p.x = c.x + r * e.x;
p.y = c.y + r * e.y;
p.z = c.z + r * e.z;
//glNormal3f(e.x,e.y,e.z);
//glTexCoord2f(i/(double)n,2*j/(double)n);
//glVertex3f(p.x,p.y,p.z);
}
glEnd();
}
}
You should be able to figure out the constants. Texture coordinates are generated (the glTexCoord2f() calls), as well as normals.
Geo-spheres are more difficult. You take any platonic solid, and subdivide each triangle, and set the new vertices at r meters from the center of the object. Continue until you have the detail you want. The most common bases for a geo-sphere are tetrahedrons, cubes, and icosahedrons.
If you do a google search for platonic solids, you should be able to find algorithms to create them.
Z.
-
Apr 27th, 2002, 12:30 PM
#3
I also forgot to mention that the D3DX library has a set of functions for building primitives into ID3DXMesh objects that you can use for rendering. Unfortunatly, they dont create texture coordinates, and I am unsure of whether or not they generare vertex normals.
Z.
-
Apr 28th, 2002, 02:14 PM
#4
Thanks a lot. I think I can figure out a cone (I figure a triangle fan would be best).
I know what TWOPI means, but what is PID2?
Ok, here is the cube I always used, but there are some normal errors in there (it's a triangle strip, would an indexed triangle list be better?). Can you take a look at it?
The normals are a little bit complicated, since they are vertex normals(if you use one vertex for several triangles, the normal must be the average of the plane normals of all triangles, it's actually one of the few things I understand in all 3D math )
The cube is centered at (0,0,0), thanks to D3D architecture it's easy to move the object somewhere.
Code:
pVertices[0].position = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
pVertices[0].normal = D3DXVECTOR3(0.0f, -1.0f, -1.0f);
pVertices[1].position = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
pVertices[1].normal = D3DXVECTOR3(0.0f, -1.0f, -1.0f);
pVertices[2].position = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
pVertices[2].normal = D3DXVECTOR3(0.0f, 1.0f, -1.0f);
pVertices[3].position = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
pVertices[3].normal = D3DXVECTOR3(0.0f, 1.0f, -1.0f);
pVertices[4].position = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
pVertices[4].normal = D3DXVECTOR3(0.0f, 1.0f, 1.0f);
pVertices[5].position = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
pVertices[5].normal = D3DXVECTOR3(0.0f, 1.0f, 1.0f);
pVertices[6].position = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
pVertices[6].normal = D3DXVECTOR3(0.0f, -1.0f, 1.0f);
pVertices[7].position = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
pVertices[7].normal = D3DXVECTOR3(0.0f, -1.0f, 1.0f);
pVertices[8].position = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
pVertices[8].normal = D3DXVECTOR3(0.0f, -1.0f, -1.0f);
pVertices[9].position = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
pVertices[9].normal = D3DXVECTOR3(0.0f, -1.0f, -1.0f);
// remaining walls
pVertices[10].position = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
pVertices[10].normal = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
pVertices[11].position = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
pVertices[11].normal = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
pVertices[12].position = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
pVertices[12].normal = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
pVertices[13].position = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
pVertices[13].normal = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
pVertices[14].position = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
pVertices[14].normal = D3DXVECTOR3(-1.0f, 0.0f, 0.0f);
pVertices[15].position = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
pVertices[15].normal = D3DXVECTOR3(-1.0f, 0.0f, 0.0f);
pVertices[16].position = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
pVertices[16].normal = D3DXVECTOR3(-1.0f, 0.0f, 0.0f);
pVertices[17].position = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
pVertices[17].normal = D3DXVECTOR3(-1.0f, 0.0f, 0.0f);
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Apr 28th, 2002, 06:46 PM
#5
PID2 == 3.14159f / 2.0f
For cube normals, simply average the normals for the three adjacent faces, and normalize. The actual face normal sare easy:
Code:
Top: (0, 1, 0)
Bottom: (0, -1, 0)
Left: (1, 0, 0)
Right: (-1, 0, 0)
Front: (0, 0, 1)
Back (0, 0, -1)
Z.
-
Apr 29th, 2002, 05:49 AM
#6
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
May 2nd, 2002, 11:21 AM
#7
Fanatic Member
Shouldn't this have been placed in the C forums, instead of the VB?
-
May 2nd, 2002, 05:27 PM
#8
nope, it's mainly a graphics problem, not a C problem.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
May 2nd, 2002, 06:12 PM
#9
Fanatic Member
Here is where this thread is at:
VB Q and A > Visual Basic > Games and Graphics Programming > Object Primitive Algorithms
Notice the Visual Basic before the graphics part? Therefore this is a VB forum, not a graphics forum...
-
May 3rd, 2002, 09:33 AM
#10
The algorithms apply in both VB and C++.
It makes me angry to see this kind of response to a thread, when it is obvious that it does, in fact, belong here.
Z.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|