Doom3 MD5 Meshes

Übersicht BlitzBasic FAQ und Tutorials

Neue Antwort erstellen

 

David

Betreff: Doom3 MD5 Meshes

BeitragDi, Dez 07, 2004 19:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi!

Screenshot: hier

Doom3 Mesh Format (.md5mesh)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Einleitung:

Doom3 Models bestehen aus mehreren Dateien. Zum einem einer .md5mesh Datei, welche
Vertexinformationen u.ä. speichert, zum anderen aus diversen .md5anim Dateien.

Hier sollen vorerst nur die .md5mesh Dateien berücksichtig werden, welche ausreichen
um ein Doom3 Model zu laden und in der "Initial-Pose" anzuzeigen.


Format:

Im groben ist eine Doom3 .md5mesh Datei folgendermaßen aufgebaut:

Code: [AUSKLAPPEN]

MD5Version 10
commandline "mesh" ...

numJoints %i
numMeshes %i

Joints-Block mit {numJoints} Einträgen

{numMeshes} Mesh-Blöcke



Der Joints-Block:

Jeder Eintrag in diesem Block stellt einen "Knochen" dar, jeder einzelne Bone hat diverse
Parameter:

Code: [AUSKLAPPEN]

name       -> Name des Bones
parent index   -> Index zum Parent-Bone falls vorhanden, ansonsten -1
Position   -> 3 Dimensionaler Vektor
Quaternion   -> 3 Dimensionaler Vektor



Der Mesh-Block:

Für jedes Mesh gibt es in der .md5mesh Datei einen Meshblock, also anders wie bei den Bones
welche alle in einem Block stehen.
Jeder Meshblock ist folgendermaßen aufgebaut:

Code: [AUSKLAPPEN]

shader         -> Pfad zum Shader

numverts %i      -> Anzahl der Vertices in diesem Mesh
numverts mal vert   -> Doom3 Vertex

numtris %i      -> Anzahl der Triangles in diesem Mesh
numtris mal tri      -> Doom3 Triangle

numweights %i      -> Anzahl der "Weights" in diesem Mesh
numweights mal weight   -> Doom3 Weight (Vertex im lokalen Koordinatensystem des Models)



Doom3 Vertices:

Ein "Doom3-Vertex" enthält (wie alles sonst) auch mehrere Parameter:

Code: [AUSKLAPPEN]

index         -> Index des Vertex
Texture Coordinaten   -> 2 Dimensionaler Vektor
Weight Index      -> Index zum ersten Weight
Weight Count      -> Anzahl der Weights, aufgezählt beginnend von "Weight Index"



Doom3 Triangles:

Ein Triangle ist in der Datei folgendermaßen aufgebaut:

Code: [AUSKLAPPEN]

Index         -> Index des Triangles
Vertex 1      -> Index zum ersten Vertex
Vertex 2      -> Index zum zweiten Vertex
Vertex 3      -> Index zum dritten Vertex



Doom3 Weights:

Und so sieht ein "Weight" in der .md5mesh Datei aus

Code: [AUSKLAPPEN]

Index         -> Index des Weights
Bone Index      -> Index zum zugehörigen Knochen
Bias         -> "Gewicht" des Weights
Position      -> 3 Dimensionaler Vektor. X, Y, Z Werte des Vertex



Zusammenhänge:

So, nachdem die "Formalitäten" geklärt sind, geht’s los mit den Zusammenhängen.
Grob gesagt besitzt ein Model eine bestimmte Anzahl von Meshes und eine bestimmte Anzahl Bones.
Jedes Mesh besteht aus einer Liste Triangles welche auf jeweils drei verschiedene Vertices
verweisen, welche wiederum mit 'n' verschiedenen Weights "verknüpft" sind und jedes dieser
Weights ist einem Bone zugeordnet.

Easy oder?


Laden des Models:

Jetzt muss man nur noch die ganzen Daten einlesen und diverse Listen erstellen und schon hat man
Doom3 Model geladen, toll nicht???

Aber halt... Beim Versuch das Model zu rendern wird man schnell bemerken, dass die Models in Doom3
doch etwas 'formabler' aussehen.

Das Problem ist das Bone-System, welches die Doom3 Models verwenden, jeder Vertex muss vor dem
Darstellen, im Verhältnis zum Zugehörigen Knochen, in Position gebracht werden.


Skinnen des Models:

Code: [AUSKLAPPEN]

void CDoom3Mesh::ConvertVectorToQuat( CVec3 &v, CQuaternion &q )
{
   q = v;

   float l_fVal = 1.f - v.SqrLength();
   float l_fQuatW = l_fVal < .0f ? .0f : sqrtf( l_fVal );

   q.W( -l_fQuatW );
   q.Normalize();
}


Das ganze läuft in etwa so ab:

Code: [AUSKLAPPEN]

void CDoom3Mesh::BindModel()
{
    for ( int i = 0; i < m_nNumMeshes; i++ )
    {
        Mesh_t    *l_pMesh = &m_pMeshes[ i ];
        CVec3    l_vPos;

        for ( int j = 0; j < l_pMesh->m_nNumVerts; j++ )
        {
            TVertex    *v = &l_pMesh->m_pVertexes[ j ];
           
            v->m_vPos.Set( 0, 0, 0 );
            for ( int k = 0; k < v->m_nNumVertexes; k++ )
            {
                TWeight *w = &l_pMesh->m_pWeights[ v->m_nWeightIndex + k ];
                TJoint  *j = &m_pJoints[ w->m_nBoneIndex ];

                CQuaternion l_pQuat;

                ConvertVectorToQuat( j->m_vQuaternion, l_pQuat );
                j->m_mBindMatrix = l_pQuat.ToMat4();

                j->m_mBindMatrix.Set( 0, 3, j->m_vPos.X() );
                j->m_mBindMatrix.Set( 1, 3, j->m_vPos.Y() );
                j->m_mBindMatrix.Set( 2, 3, j->m_vPos.Z() );

                j->m_mBindMatrix.Multiply( w->m_vVertex, l_vPos );

                v->m_vPos += ( l_vPos + j->m_vPos ) * w->m_fBias;
            }
        }
    }
}


Aha, ganz klar!
Man wandelt den 3 Dimensionalen Vektor in ein Quaternion um. (heist es "ein" Quaternion) ???
Dann erstellt man eine 4x4 Matrix aus dem Quaternion und multiplziert die Matrix mit dem
Vertex was im aktuellen Weight steht, das Ergebniss wird in "Pos" zwischengespeichert.

Danach addiert man den Vektor "Pos" mit dem Vektor Position, welcher im aktuellen Joint steht und
skaliert das Ergebnis mit dem Bias des aktuellen Weights... klar?

Den daraus resultieren Vektor addiert man zu der Vertexposition des aktuellen Vertices.

Alles ganz easy oder?
Wem meine grauenhafte Erklärung nicht eingeleuchtet hat, der sollte sich über Quatenions, Vektoren
und Matrizen informieren. Mit etwas Glück kommt man dann weiter. Smile


grüße

Und es klappt doch:


http://mitglied.lycos.de/David...c00004.JPG
http://mitglied.lycos.de/David...c00007.JPG

grüße
  • Zuletzt bearbeitet von David am Do, Dez 09, 2004 19:29, insgesamt 5-mal bearbeitet
 

OJay

BeitragDi, Dez 07, 2004 19:54
Antworten mit Zitat
Benutzer-Profile anzeigen
mach doch mal ein sample. inkl normalmapping. wäre mal ein interessanter vergleich *hust* Wink
 

David

BeitragDi, Dez 07, 2004 20:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi!

Sicher, sieht dann genauso aus wie bei Doom3... Smile

grüße

FreakForFreedom

BeitragMo, Jan 10, 2005 17:26
Antworten mit Zitat
Benutzer-Profile anzeigen
@David... sieht ja ganz cool aus! Würde es dir was ausmachen, ein sample (code und vieleicht model(ka ob das erlaubt ist)) zu machen und den link hier zu posten?
Wäre cool!


Mfg,
F.F.F.
Mfg
F.F.F.
"Try and ERROR!"
 

David

BeitragMo, Jan 10, 2005 23:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi!

Mal schauen was die Zeit so zulässt... Smile

grüße

FreakForFreedom

BeitragDi, Jan 11, 2005 17:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Hrhr das kenne ich... wäre aber trotzdem cool von dir!^^
Mfg
F.F.F.
"Try and ERROR!"

Neue Antwort erstellen


Übersicht BlitzBasic FAQ und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group