Doom3 MD5 Meshes
Übersicht

DavidBetreff: Doom3 MD5 Meshes |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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. ![]() 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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
mach doch mal ein sample. inkl normalmapping. wäre mal ein interessanter vergleich *hust* ![]() |
||
David |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi!
Sicher, sieht dann genauso aus wie bei Doom3... ![]() grüße |
||
![]() |
FreakForFreedom |
![]() Antworten mit Zitat ![]() |
---|---|---|
@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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi!
Mal schauen was die Zeit so zulässt... ![]() grüße |
||
![]() |
FreakForFreedom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hrhr das kenne ich... wäre aber trotzdem cool von dir!^^ | ||
Mfg
F.F.F. "Try and ERROR!" |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group