Reputation: 2811
I'm writing a 3ds Max exporter and I need to get mesh normals computed by the application. I have a Mesh
instance and I can get vertex positions, UVs, colors, etc. but the normals seem to be not so easy... BTW: I know how to compute face/vertex normals, but I need the exact data from 3ds Max, with smoothing groups and material index taken into account.
For this case I've created a simple box and looked into resulting Mesh
instance after calling the buildNormals()
method. Here is what I've found after some debugging and digging into documentation, all mentioned data are inside of a Mesh
class:
I have simple vertex/face numbers:
int numVerts = 8;
int numFaces = 12;
And verices/faces data:
Point3* verts; // contains 8 vectors with positions (x,y,z)
Face* faces; // contains 12 faces, each with 3 indexes into *verts - [0-7]
So far so good... Now I have computed normals data:
int normalCount = 24; // 6 sides * 4 vertices each, no reuse of normal data
Point3* gfxNormals; // contains 24 normal vectors
At this point I have almost all the data I need but I can't assign one normal to one rendered vertex. There is one more interesting table:
Tab<ulong> norInd; // contains 8 indexes - {0,3,6,9,12,15,18,21}
It seems to be somehow connected to previous fields (I have 8 verts, each has 3 normals) but I have no idea how to use it in more complex situations.
I need an index of normal for particular vertex in particular face, or in other words - if I wanted to render 0'th face in OpenGl I could use:
glVertex3f( verts[ faces[0].v[0] ].x, verts[ faces[0].v[0] ].y, verts[ faces[0].v[0] ].z );
glVertex3f( verts[ faces[0].v[1] ].x, verts[ faces[0].v[1] ].y, verts[ faces[0].v[1] ].z );
glVertex3f( verts[ faces[0].v[2] ].x, verts[ faces[0].v[2] ].y, verts[ faces[0].v[2] ].z );
But what to pass to glNormal3f()
?
Upvotes: 0
Views: 698
Reputation: 1011
The way I get them is this:
for(int f = 0; f < mesh->numFaces; ++f)
{
Point3 normal;
Face* face = &mesh->faces[f];
for(int v = 0; v < 3; ++v)
{
DWORD vi = face->v[v];
Point3 normal;
if(mesh->getRVertPtr(vi))
normal = GetVertexNormal(mesh, f, mesh->getRVertPtr(vi));
else
normal = Point3(0, 0, 1);
fprintf(file, "\t\t\t<normal x=\"%f\" y=\"%f\" z=\"%f\" />\n", normal.x, normal.y, normal.z);
}
}
Upvotes: 1