Here comes the essential part of the source code.
FMeshBuilder is an object that generated my mesh format.
The line commented out in fmesh_export_triangle_surface() is the line that causes bad normals for vertices..
- - clip - -
Code:
static void fmesh_export_triangle_surface(Surface* surface, FMeshBuilder& builder, int materialindex)
{
printf("exporting surface..\n");
int vertexindex = -1;
for(List* v = surface->vertlist; v != NULL; v = v->next)
{
SVertex* vertex = (SVertex*)v->data;
FMeshVector3 pos(vertex->v->x, vertex->v->y, vertex->v->z);
// FMeshVector3 n(vertex->v->normal.x, vertex->v->normal.y, vertex->v->normal.z);
FMeshVector3 n(surface->normal.x, surface->normal.y, surface->normal.z);
FMeshVector3 tc(vertex->tx, vertex->ty, 0);
vertexindex = builder.addVertex(pos, &n, &tc);
}
builder.addFace(materialindex, vertexindex - 2, vertexindex - 1, vertexindex);
}
static void fmesh_export_object(ACObject* obj, FMeshBuilder& builder)
{
if(ac_object_get_num_surfaces(obj) > 0)
{
object_calc_normals_force(obj);
printf("exporting object..\n");
int materialindex = -1;
char* data = ac_object_get_data(obj);
if(data[0])
materialindex = builder.addMaterial(data);
else
materialindex = builder.addMaterial("default");
printf("materialindex = %u\n", materialindex);
List* surfaces = ac_object_get_surfacelist(obj);
for (List* s = surfaces; s != NULL; s = s->next)
{
Surface *surface = (Surface *)s->data;
// if(surface->type == SURFACE_POLYGON)
{
if(surface->numvert == 3)
{
fmesh_export_triangle_surface(surface, builder, materialindex);
}
else if(surface->numvert > 3)
{
// Triangulate surface
List* triangles = surface_get_triangulations(surface);
for(List* t = triangles; t != NULL; t = t->next)
{
Surface* triangle = (Surface*)t->data;
fmesh_export_triangle_surface(triangle, builder, materialindex);
surface_free(triangle);
}
list_free(&triangles);
}
else
printf("skipping numvert = %d surface ..\n", (int)surface->numvert);
}
// else
// printf("skipping non-polygon surface %d..\n", (int)surface->type);
}
}
List* children = ac_object_get_childrenlist(obj);
for(List* c = children; c != NULL; c = c->next)
fmesh_export_object((ACObject *)c->data, builder);
}
static void fmesh_export()
{
char *filename;
FILE *file;
char *filter[] = {"fmesh files", ".fmesh", "All files", "*", NULL};
filename = ac_get_save_filename("Export fmesh file", filter);
if((filename == NULL) || (*filename =='\0'))
return;
FMeshBuilder builder;
builder.begin("exported", 1, 1, 0);
fmesh_export_object(ac_get_world(), builder);
builder.writeToFile(filename);
}
AC3D_PLUGIN_FUNC int AC3DPluginInit(AC3DPluginInitData *d)
{
double ver = ac_get_version_number();
ac_add_command("fmesh_export_plugin", fmesh_export);
ac_add_export_menu_item("fmesh...", "ac3d fmesh_export_plugin");
return(0);
}