Article     Discussion     Modifier     Historique     Forums     Salon IRC

3dsloader:ObjetBlocChunk

Un article de Games Creators Network.

suite du tuto sur le loader 3ds : OpenGL:3dsloader

Sommaire

[modifier] les opcodes

nous allons voir maintenant les opcodes suivants :

0x4100 : opcode pour créer un mesh triangulaire
 0x4110 : opcode qui contient la liste des vertex
 0x4120 : opcode qui contient la liste des faces
  0x4130 : opcode qui donne les infos sur le material a appliquer
 0x4140 : opcode qui contient la liste des coordonées de texture

[modifier] les fonctions supplémentaires

une fonction pour initialiser les vectrices(mesh->num_vectrices est le nombre de vectrices)

void initvectrice(mesh3ds *mesh){
mesh->vectrices = (vectrice3ds*)malloc(sizeof(vectrice3ds)*mesh->num_vectrices);
}

une fonction pour initialiser les faces(mesh->num_faces est le nombre de faces) :

void initface(mesh3ds *mesh){
mesh->faces = (face3ds*)malloc(sizeof(face3ds)*mesh->num_faces);
}

[modifier] la fonction ObjetBlocChunk()

on commence la fonction :

int ObjetBlockChunk(object3ds *objet3d, FILE *fichier, unsigned int lenght)
{
    int start = ftell(fichier);
    unsigned short chunk_id;
    unsigned int chunk_lenght;
    while (ftell(fichier) < start + lenght){
      fread (&chunk_id, 2, 1, fichier);
      fread (&chunk_lenght, 4, 1, fichier); 
      switch(chunk_id){

si on a 0x4100, on ouvre la fonction pour les mesh triangulaires :

case 0x4100:{
  TriangularMeshChunk(objet3d, fichier, chunk_lenght-6);
  break;
}

sinon,

default:{  
 fseek(fichier, chunk_lenght-6, SEEK_CUR);
}

et on ferme la fonction :

}
   }
   fseek(fichier, start+lenght, SEEK_SET);
   return 1;
}

[modifier] la fonction TriangularMeshChunk()

on commence la fonction :

int TriangularMeshChunk(object3ds *objet3d, FILE *fichier, unsigned int lenght)
{
    int start = ftell(fichier);
    unsigned short chunk_id;
    unsigned int chunk_lenght;
    while (ftell(fichier) < start + lenght){
      fread (&chunk_id, 2, 1, fichier);
      fread (&chunk_lenght, 4, 1, fichier); 
      switch(chunk_id){
  • on va gérer le opcode 0x4110(liste de vertex) :
case 0x4110:{
int i;
int num=objet3d->num_mesh-1;

on recupère le nombre de vectrices

fread (&objet3d->mesh[num].num_vectrices, sizeof (unsigned short), 1, fichier);

on initialise ensuite les vectrices du mesh :

initvectrice(&objet3d->mesh[num]);

on va ensuite lire tous les vertex :

for (i=0; i<objet3d->mesh[num].num_vectrices; i++)
{
   fread (&objet3d->mesh[num].vectrices[i].x, sizeof(float), 1, fichier);
   fread (&objet3d->mesh[num].vectrices[i].y, sizeof(float), 1, fichier);
   fread (&objet3d->mesh[num].vectrices[i].z, sizeof(float), 1, fichier);
}

et on ferme :

break;
}

voila, vous avez obtenu la liste des vertex d'un objet .3ds

  • on va gerer le opcode 0x4120(liste des faces) :
case 0x4120:{
int i;
int num=objet3d->num_mesh-1;

on lit le nombre de faces :

fread (&objet3d->mesh[num].num_faces, sizeof (unsigned short), 1, fichier);

on initialise les faces :

initface(&objet3d->mesh[num]);

on lit les faces :

unsigned short flag;
          for (i=0; i<objet3d->mesh[num].num_faces; i++)
          {
             fread (&objet3d->mesh[num].faces[i].a, sizeof (unsigned short), 1, fichier);
             fread (&objet3d->mesh[num].faces[i].b, sizeof (unsigned short), 1, fichier);
             fread (&objet3d->mesh[num].faces[i].c, sizeof (unsigned short), 1, fichier);
             fread (&flag, sizeof (unsigned short), 1, fichier);
          }

ensuite, il y a une sous fonction a appeler :

FaceDescriptionChunk(objet3d,fichier,chunk_lenght-6-8*objet3d->mesh[num].num_faces-2);

et on ferme :

break;
 }
  • on va lire le opcode 0x4140(coordonnées de texure) :

d'abord, il faut ajouter une nouvelle structure :

typedef struct mapping_face3ds{
   float u,v;
}mapping_face3ds;

il faut aussi rajouter

unsigned short num_mapping_face;
mapping_face3ds *mapping_faces;

dans la structure mesh3ds

et creer une fonction pour les initialiser :

void init_mapping_face(mesh3ds *mesh){
  mesh->mapping_faces = (mapping_face3ds*)malloc(sizeof(mapping_face3ds)*mesh->num_mapping_face);
}

ensuite, on peux revenir a la fonction Triangular Mesh et ajouter :

case 0x4140:{
int i;
int num=objet3d->num_mesh-1;

on récupère le nombre de coordonnées de textures :

fread (&objet3d->mesh[num].num_mapping_face, sizeof (unsigned short), 1, fichier);

puis initialiser les coordonées de texture :

init_mapping_face(&objet3d->mesh[num]);

ensuite lire la liste de coordonnées de texture :

for (i=0; i<objet3d->mesh[num].num_mapping_face; i++)
{
fread (&objet3d->mesh[num].mapping_faces[i].u, sizeof (float), 1, fichier);
fread (&objet3d->mesh[num].mapping_faces[i].v, sizeof (float), 1, fichier);
}

et fermer :

break;
}

et finir la fonction Triangular Mesh

default:
        {  
          fseek(fichier, chunk_lenght-6, SEEK_CUR);
        }
      }
   }
   fseek(fichier, start+lenght, SEEK_SET);
   return 1;
}

[modifier] la sous fonction FaceDescriptionChunk

  • on gère le opcode 0x4130 :

nous allons recevoir le nom du material à appliquer ainsi que les faces sur lesquels ils faut les appliquer(en general, sur toutes les faces)

il faut donc rajouter de quoi stocker le nom et les faces: on ajoute

char material_name[20];
unsigned short num_material_face;
unsigned short *material_face;

dans la structure mesh3ds

ensuite, on code la fonction :

on commence comme d'habitude :

int FaceDescriptionChunk(object3ds *objet3d, FILE *fichier, unsigned int lenght)
{
    int start = ftell(fichier);
    unsigned short chunk_id;
    unsigned int chunk_lenght;
    while (ftell(fichier) < start + lenght){
      fread (&chunk_id, 2, 1, fichier);
      fread (&chunk_lenght, 4, 1, fichier); 
      switch(chunk_id){

on lit le opcode 0x4130 :

case 0x4130 :{    
  int num=objet3d->num_mesh-1;
  char temp;
  int i = 0;

on lit le nom du material :

do
  {
     fread (&temp, 1, 1, fichier);
     objet3d->mesh[num].material_name[i] = temp;
     i++;
  }while(temp != '\0');

on lit le nombres de faces où il faut appliquer le material:

fread (&objet3d->mesh[num].num_material_face, 2, 1, fichier);

on initialise les material_faces :

objet3d->mesh[num].material_face = (unsigned short*)malloc(sizeof(unsigned short)*objet3d->mesh[num].num_material_face);

et on lit les material_faces :

for(i=0;i<objet3d->mesh[num].num_material_face;i++){
fread (&objet3d->mesh[num].material_face[i], sizeof (unsigned short), 1, fichier);

on ferme :

}
break;
}

et on ferme la fonction :

default:
       { 
          fseek(fichier, chunk_lenght-6, SEEK_CUR);
       }
     }
   }
   fseek(fichier, start+lenght, SEEK_SET);
 }

 

Rechercher
Installer l'extension de recherche Plus d'informations

 

Comprendre
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. - Benjamin Franklin

 

Partager
La connaissance est la seule chose qui s'accroit lorsqu'on la partage. - Sacha Boudjema

 

Créer
L'imagination est plus importante que la connaissance. - Albert Einstein

 

 

Le wiki en images Le wiki en images Image du mois: «Snowball: un prototype de jeu développé avec NeL.