Bonsoir à tous, Je me suis lancé dans la lecture de modèles au format PKMDL. Je mettrais à jour ce post prochainement en fonction de l'avancement et des résultats obtenus (descriptif du format, rendu 3D, etc).
Le format PKDML Le format PKMDL est utilisé dans le jeu pc Painkiller (FPS) sorti en 2004. Les modèles sont illisibles par un éditeur de texte. Les données sont stockées en brut. Voici un aperçu des modèles présents dans le jeu:
Descriptif du format PKDML Un fichier au format PKMDL est composé de 2 sections: - le Header (taille variable) - les Données (taille variable)
Afin de simplifier l'écriture, on appelera un type Chaine, la suite de données suivante: { int taillechaine //nb de caractères de la chaine char tab[taillechaine] // les taillechaine caractères de la chaine } Ainsi, lorsque dans la description, il est indiqué Chaine ...., il faudra lire un int + les taillechaine caractères de la chaine. Pensez à vous munir d'un éditeur héxadécimal pour contrôler et suivre les données que vous lisez (ça peut toujours être utile). Important: le fichier PKMDL provient d'un jeu PC (Little Endian). La Wii travaille en Big Endian. Pensez à convertir les données lues
1- Le Header Le Header est constitué des données suivantes:
int identifiant // apparemment = 3 Chaine nomfichier // le nom du fichier Chaine chemin // le chemin Chaine animtext // apparemment = "AnimatedMesh" pour les pkmdl animés int tabentier[4] // apparemment = 1,0,2,1 à chaque fois int taillerestefic // taille totale du fichier - offset int offset // taille totale du fichier - taillerestefic Chaine chemin2 // un 2nd chemin short nbskel // le nombre de squelette, apparement = 1
2- Les Données Juste après le Header, on trouve les données relatives au squelette
int nbbones // nombre de bones Bone tabbones[nbbones] // tableau de Bone
Citation:
Détail d'un Bone struct Bone { Chaine nombone // nom du bone float matricelocale[16] // la matrice de transformation unsigned char numfils // le nombre de bone fils du bone courant }
Puis les groupes (un groupe est un ensemble de triangles)
int nbpolygroupe // le nombre de groupe PolyGroupe tabpolygroupe[nbpolygroupe] // les groupes de triangles
Citation:
Détail d'un PolyGroupe struct PolyGroupe { Chaine nom // nom du groupe int tabint[3] // apparemment toujours = 0, 0, 0 int nbtexture // nombre de texture Texture tabtextures[nbtexture] //les textures int nbvertindice //nombre d'indices de vertex short tabtriangles[3*nbvertindice] //tableau d'indices de vertex. Un triangle est dessiné avec les index J,J+1,J+2 int tmpint // apparemment = 0 int nbvertex //nombre de vertex Vertex tabvertex[nbvertex] //tableau de vertex int tmpint[2] //apparemment = 0,0 int nbvertex //nombre de vertex SkinInfos[nbvertex] // }
Un ensemble PolyGroupe contient des sous-ensembles dont voici le détail
Citation:
Détail d'un Texture struct Texture { Chaine texturename // nom de la texture int 1erindvertex // 1er indice du vertex int nbtriangles // nombre de triangles utilisant la texture }
Citation:
Détail d'un Vertex struct Vertex { float position[3] // position x,y,z float normal[3] // vecteur de la normale float uvcoord[2] // coordonnées u,v pour application de la texture }
Citation:
Détail d'un SkinInfos struct SkinInfos { int nbbonesaffectepar // nombre de bones qui vont affecter le vertex Boneinfos [nbbonesaffectepar] // tableau de Boneinfos }
Citation:
Détail d'un Boneinfos struct { unsigned short boneind // n° du Bone float poids // poids du bone sur le vertex }
Complément de commentaires sur les données prochainement
Algorithme de rendu statique
Citation:
pseudo code Pour chaque PolyGroupe(i) Pour chaque Texture(k) Si nombre de triangles de Texture(k) > 0 Appliquer la texture de Texture GX_Begin(.....) Pour j allant de 0 à PolyGroupe(i).Texture(k).numtriangles Dessiner les vertex du triangle // position + normale + color + uv //PolyGroupe(i).Vertex[ PolyGroupe(i).tabtriangles[3*j+1erindvertex] ].... //PolyGroupe(i).Vertex[ PolyGroupe(i).tabtriangles[3*j+1+1erindvertex] ].... //PolyGroupe(i).Vertex[ PolyGroupe(i).tabtriangles[3*j+2+1erindvertex] ].... FinPour GX_End(.....) FinSi FinPour FinPour
Descriptif du format ANI : Squelettes et Animations Chaque animmation est stockée dans un fichier ".ani". Par exemple, si votre modèle est "zombie.pkmdl" et qu'il dispose de 5 animations différentes, vous aurez "zombie.atak1.ani", zombie.atak2.ani", "zombie.atak3.ani", "zombie.walk.ani", "zombie.run.ani". Chaque fichier .ANI contient les matrices de transformation à appliquer sur chaque vertex à un instant T de l'animation.
Citation:
Détail d'une Animation struct Animation { Chaine char skel[4] // chaine = "skel" float animlength // durée de l'animation int numboneanims // nombre de BoneAnime BoneAnime tab[numboneanims] // tableau de BoneAnime }
Citation:
Détail d'un BoneAnime struct BoneAnime { Chaine nombone // le nom du bone int nbframes // le nombre de frames pour ce BoneAnime Frame tab[nbframes] // tableau de Frame }
Citation:
Détail d'une Frame struct Frame { float timestamp // le timestamp de la frame (l'instant T) float matrix[16] // la matrice de transformation liée à cet instant T }
Screen de rendu statique
Screen de rendu animation
Vidéo de rendu animation
Dernière édition par tchagui le 01 Oct 2012 20:38, édité 23 fois.
Ajout d'un second rendu texturé + début des données. Pour l'instant, il s'agit d'un rendu statique. Je n'ai pas commencé les animations qui sont stockées dans des fichiers séparés. J'ai remarqué des erreurs dans le second modèle (épée trouée). Je reposterai le descriptif des données quand j'aurais corrigé tout ça. ... les joies du WIP....
Mise à jour des données J'ajoute un rendu d'ici quelques jours et l'épée ne sera plus trouée J'en profiterai pour détailler le rendu statique.
Hello Owen, The framerate on Dolphin isn't good (between 15-25fps). But my first test on the Wii (with texture) the framerate is 50fps. Each model has ~3000 triangles.
Up pour mise à jour avec une petite vidéo. C'est très loin d'être de la bonne qualité ... le logiciel CamStudio avec la fenêtre Dolphin... ça rame. J'ai pris un modèle avec peu de triangles pour cette vidéo afin que celle-ci ne soit pas trop saccadée. Sur la Wii, c'est 50fps
Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité
Vous ne pouvez pas poster de nouveaux sujets Vous ne pouvez pas répondre aux sujets Vous ne pouvez pas éditer vos messages Vous ne pouvez pas supprimer vos messages