¡Esta es una revisión vieja del documento!
Librería para la lectura de archivos 3D Studio con extensión .3ds en C\C++.
Como cualquier librería de C necesitarás linkarla e incluir los .h necesarios. Cada clase (más bien estructura, lib3ds está escrito en ANSI C) tiene su definición en su .h correspondiente.
El tipo básico sobre el que se trabaja es Lib3dsFile, para crear una variable de este sólo debemos pasarle el nombre del archivo a la función lib3ds_file_load la cual devolverá su correspondiente Lib3dsFile. Este estará estructurado como un archivo .3ds, como un árbol, con ramas correspondientes a los objetos, las luces, etc. En definitiva, tenemos la escena separada por bloques. Un ejemplo tonto, el de contar las meshes en el archivo:
#include "lib3ds\file.h" #include "lib3ds\mesh.h" int getNumMeshes (Lib3dsFile* f) { int tmp = 0; Lib3dsMesh* mesh = f->meshes; while (mesh != NULL) { tmp++; mesh = mesh->next; } return tmp; } void main () { Lib3dsFile* file = lib3ds_file_load("caja.3DS"); int i = getNumMeshes(file); lib3ds_file_free(file); }
lib3ds_file_free libera de memoria el Lib3dsFile pasado por parámetro.
Los modelos están guardados como una linked list en la variable meshes del Lib3dsFile del tipo Lib3dsMeshenlazadas por la variable next, que corresponde a la siguiente dentro del fichero.
Una mesh tiene un nombre\id (name) y un número de caras (faces). Una cara es un triangulo de tres vértices (o puntostodos los vértices de la mesh se encuentran en su variable pointL, que es un array de Lib3dsPoint. Para dibujar una cara debemos acceder al array de caras de la mesh (en faceL), escoger la cara deseada (tipo Lib3dsFace) y acceder a sus tres vertices que están en points, un array de tres integers correspondientes a los índices del array de vertices de la mesh. Cada Lib3dsPoint contiene una variable pos que es un array con tres números que son las tres coordenadas xyz de un vértice.
Lib3dsMesh* mesh = file->meshes; Lib3dsPoint ptmp; glBegin(GL_TRIANGLES); for (int i=0; i<mesh->faces; i++) { Lib3dsFace face = mesh->faceL[i]; for (int i=0; i<3; i++) { ptmp = mesh->pointL[face.points[i]]; glVertex3f(ptmp.pos[0], ptmp.pos[1], ptmp.pos[2]); } } glEnd();
Lib3ds dispone de una función llamada lib3ds_mesh_calculate_normals que calcula las normales para una mesh, se le pasa la mesh de la cual queremos calcular las normales y tantos arrays de 3 floats como normales tenga esta mesh (número de caras multiplicado por 3, que son los vértices). Para más comodidad podemos utilizar la estructura Lib3dsVector.
Lib3dsVector* normals = new Lib3dsVector[mesh->faces * 3]; lib3ds_mesh_calculate_normals(mesh, normals);
Ahora dentro del vector de normales tendremos las normales por cada vértice.
Las coordenadas de textura las tratamos desde la instancia a Lib3dsMesh. Esta contiene dos variables:
for (int i=0; i<mesh->faces; i++) { Lib3dsFace face = mesh->faceL[i]; for (int i=0; i<3; i++) { glTexCoord2f (mesh->texelL[face.points[i]][0], mesh->texelL[face.points[i]][1]); ...
Para saber qué textura tiene aplicada una cara accederemos a su variable material, esta contiene un string con el identificador.