Ejemplo n.º 1
0
void write_mesh(FILE *o, Lib3dsFile *f, Lib3dsMeshInstanceNode *node) {
    float (*orig_vertices)[3];
    int export_texcos;
    int export_normals;
    int i, j;
    Lib3dsMesh *mesh;
        
    mesh = lib3ds_file_mesh_for_node(f, (Lib3dsNode*)node);
    if (!mesh || !mesh->vertices) return;

    fprintf(o, "# object %s\n", node->base.name);
    fprintf(o, "g %s\n", node->instance_name[0]? node->instance_name : node->base.name);

    orig_vertices = (float(*)[3])malloc(sizeof(float) * 3 * mesh->nvertices);
    memcpy(orig_vertices, mesh->vertices, sizeof(float) * 3 * mesh->nvertices);
     {
         float inv_matrix[4][4], M[4][4];
         float tmp[3];
         int i;
 
         lib3ds_matrix_copy(M, node->base.matrix);
         lib3ds_matrix_translate(M, -node->pivot[0], -node->pivot[1], -node->pivot[2]);
         lib3ds_matrix_copy(inv_matrix, mesh->matrix);
         lib3ds_matrix_inv(inv_matrix);
         lib3ds_matrix_mult(M, M, inv_matrix);
 
         for (i = 0; i < mesh->nvertices; ++i) {
             lib3ds_vector_transform(tmp, M, mesh->vertices[i]);
             lib3ds_vector_copy(mesh->vertices[i], tmp);
         }
     }

    export_texcos = (mesh->texcos != 0);
    export_normals = (mesh->faces != 0);

    for (i = 0; i < mesh->nvertices; ++i) {
        fprintf(o, "v %f %f %f\n", mesh->vertices[i][0], 
                                   mesh->vertices[i][1], 
                                   mesh->vertices[i][2]);
    }
    fprintf(o, "# %d vertices\n", mesh->nvertices);

    if (export_texcos) {
        for (i = 0; i < mesh->nvertices; ++i) {
            fprintf(o, "vt %f %f\n", mesh->texcos[i][0], 
                                     mesh->texcos[i][1]);
        }
        fprintf(o, "# %d texture vertices\n", mesh->nvertices);
    }

    if (export_normals) {
        float (*normals)[3] = (float(*)[3])malloc(sizeof(float) * 9 * mesh->nfaces);
        lib3ds_mesh_calculate_vertex_normals(mesh, normals);
        for (i = 0; i < 3 * mesh->nfaces; ++i) {
            fprintf(o, "vn %f %f %f\n", normals[i][0],
                                        normals[i][1],
                                        normals[i][2]);
        }
        free(normals);  
        fprintf(o, "# %d normals\n", 3 * mesh->nfaces);
    }

    {
        int mat_index = -1;
        for (i = 0; i < mesh->nfaces; ++i) {
            if (mat_index != mesh->faces[i].material) {
                mat_index = mesh->faces[i].material;
                if (mat_index != -1) {
                    fprintf(o, "usemtl %s\n", f->materials[mat_index]->name);
                }
            }

            fprintf(o, "f ");
            for (j = 0; j < 3; ++j) {
                fprintf(o, "%d", mesh->faces[i].index[j] + max_vertices + 1);
                if (export_texcos) {
                    fprintf(o, "/%d", mesh->faces[i].index[j] + max_texcos + 1);
                } else if (export_normals) {
                    fprintf(o, "/");
                }
                if (export_normals) {
                    fprintf(o, "/%d", 3 * i + j + max_normals + 1);
                }
                if (j < 3) {
                    fprintf(o, " ");
                }
            }
            fprintf(o, "\n");
        }
    }

    max_vertices += mesh->nvertices;
    if (export_texcos) 
        max_texcos += mesh->nvertices;
    if (export_normals) 
        max_normals += 3 * mesh->nfaces;
    
    memcpy(mesh->vertices, orig_vertices, sizeof(float) * 3 * mesh->nvertices);
    free(orig_vertices);
}
Ejemplo n.º 2
0
std::vector<CL_Lib3dsMesh> CL_Lib3dsFile::export_meshes(Lib3dsNode *node)
{
	if (node == 0)
	{
		lib3ds_file_eval(file, 0.0f);
		node = file->nodes;
	}

	std::vector<CL_Lib3dsMesh> meshes;
	for (; node; node = node->next)
	{
		if (node->type == LIB3DS_NODE_MESH_INSTANCE)
		{
			Lib3dsMeshInstanceNode *instance_node = (Lib3dsMeshInstanceNode *) node;
			Lib3dsMesh *mesh = lib3ds_file_mesh_for_node(file, (Lib3dsNode*)node);
			if (mesh && mesh->vertices)
			{
				float inv_matrix[4][4], M[4][4];
				lib3ds_matrix_copy(M, instance_node->base.matrix);
				lib3ds_matrix_translate(M, -instance_node->pivot[0], -instance_node->pivot[1], -instance_node->pivot[2]);
				lib3ds_matrix_copy(inv_matrix, mesh->matrix);
				lib3ds_matrix_inv(inv_matrix);
				lib3ds_matrix_mult(M, M, inv_matrix);

				std::vector<CL_Vec3f> positions;
				for (int i = 0; i < mesh->nvertices; ++i)
				{
					float position[3];
					lib3ds_vector_transform(position, M, mesh->vertices[i]);
					positions.push_back(CL_Vec3f(position[0], position[1], position[2]));
				}

				std::vector<CL_Vec2f> texcoords;
				if (mesh->texcos)
				{
					for (int i = 0; i < mesh->nvertices; ++i)
					{
						float tx = mesh->texcos[i][0];
						float ty = mesh->texcos[i][1];
						texcoords.push_back(CL_Vec2f(tx, ty));
					}
				}

				std::vector<CL_Vec3f> normals;
				if (mesh->faces && mesh->nfaces > 0)
				{
			        float (*normals_array)[3] = (float(*)[3])malloc(sizeof(float) * 9 * mesh->nfaces);
					lib3ds_mesh_calculate_vertex_normals(mesh, normals_array);
					for (int i = 0; i < 3 * mesh->nfaces; ++i)
					{
						normals.push_back(CL_Vec3f(normals_array[i][0], normals_array[i][1], normals_array[i][2]));
					}
					free(normals_array);
				}

				CL_Lib3dsMesh mesh_object;
				for (int i = 0; i < mesh->nfaces; ++i)
				{
					int material_index = mesh->faces[i].material;
					mesh_object.face_materials.push_back(material_index);

					for (int j = 0; j < 3; ++j)
					{
						int vertex_index = mesh->faces[i].index[j];
						mesh_object.positions.push_back(positions[vertex_index]);
						if (!texcoords.empty())
							mesh_object.texcooords.push_back(texcoords[vertex_index]);
						if (!normals.empty())
							mesh_object.normals.push_back(normals[i*3+j]);
					}
				}

				meshes.push_back(mesh_object);
			}

			if (node->childs)
			{
				std::vector<CL_Lib3dsMesh> child_meshes = export_meshes(node->childs);
				meshes.insert(meshes.end(), child_meshes.begin(), child_meshes.end());
			}
		}
	}

	return meshes;
}