#include "stdafx.h" #include "Private Klassen\Kl_DX\Kl_3D_Objekt\Kl_3D_Objekt.h" // Standart-Konstruktor Kl_3D_Objekt::Kl_3D_Objekt() { // NULLungen m_DateiInput_3D_Objekt=NULL; m_akt_Datei_Zeile=NULL; m_VertexBuffer_3D_Objekt=NULL; m_Indexbuffer_3D_Objekt=NULL; m_3D_Objekt_Indices=NULL; m_3D_Objekt_Textur=NULL; m_3D_Objekt_Material=NULL; m_DateiPfad_XFile=NULL; m_DateiPfad_DatName_XFile=NULL; m_Anz_Vertices_MeshNr=NULL; m_Anz_Faces_MeshNr=NULL; m_Anz_NormalenVekt_MeshNr=NULL; m_Anz_Texturkoordin_MeshNr=NULL; m_3D_Obj_Vertice_AddWert_Mesh=NULL; m_3D_Obj_IndexbufferPos_Mesh=NULL; m_KollisionsObj=NULL; /* m_z_Kl_2D_Bild=NULL; */ // m_Art_aktDatZeile=0; // m_Anz_Meshes_3D_Obj=0; m_Anz_Vertices_3D_Objekt=0; m_Anz_Faces_3D_Objekt=0; m_Anz_Indices_3D_Objekt=0; m_Nr_akt_Mesh=-1; // -1, weil m_Nr_akt_Mesh bei Mesh Nr.1=0 ist, usw m_Anz_Materialien_3D_Objekt=0; m_Anz_Texturen_3D_Objekt=0; // m_XFile_istOK=false; m_XFile_hatTextur=false; m_XFile_hatNormalen=false; m_XFile_hatTexturkoordinaten=false; m_TexturAnzeigen_erlaubt=false; m_XFile_hatTransparenz=false; m_3D_Objekt_Matrix_gesetzt=false; // m_3D_Objekt_xPos=0.0f; m_3D_Objekt_yPos=0.0f; m_3D_Objekt_zPos=0.0f; m_3D_Objekt_yDrehung=0.0f; // Falls X-File Eintrag hierfür fehlen sollte, // dann Matrix des gesammten 3D-Objekts vorsorglich schonmal mit Werten füllen. // Grund: Damit 3D-Objekt trotzdem richtig angezeigt wird, usw (Z.B. an richtiger Position) // // D3DXMatrixIdentity() Erzeugt eine Identitätsmatrix // die so aussieht: // // 1.000000, 0.000000, 0.000000, 0.000000, // 0.000000, 1.000000, 0.000000, 0.000000, // 0.000000, 0.000000, 1.000000, 0.000000, // 0.000000, 0.000000, 0.000000, 1.000000;; // D3DXMatrixIdentity(&m_3D_Objekt_Matrix); // m_DateiPfad_XFile=new char[255]; m_DateiPfad_DatName_XFile=new char[255]; m_akt_Datei_Zeile=new char[255]; // m_DateiPfad_XFile[0]='\0'; m_DateiPfad_DatName_XFile[0]='\0'; m_akt_Datei_Zeile[0]='\0'; } // Statisches Kl_2D_Bild *Kl_3D_Objekt::m_z_Kl_2D_Bild=NULL; /**/ // ** Zuweisungsoperator (Bei Verwendung von =) ** // ACHTUNG: "Kl_3D_Objekt& Kl_3D_Objekt::operator=(const Kl_3D_Objekt& source)" // ergab sich durch mein Experiment. Könnte also falsch geschrieben sein! // (Siehe auch Headerdatei) // Im gelben Dummies Buch S.152 (Der Zuweisungsoperator) stehts so: // "const KlasseA& Operator=(const KlasseA& source)" // "{ " // "... " // "} // // Beispiel für Aufruf des Zuweisungsoperators ('='): // --> m_3D_Obj_Gitterstaebe_WgRecht[1]=m_3D_Obj_Gitterstaebe_WgRecht[0]; // " Kl_3D_Objekt& Kl_3D_Objekt::operator=(const Kl_3D_Objekt& Quellklasse) { //Beep(500,100); // Prüfung auf Selbstzuweisung (self-assignment) if (this == &Quellklasse) { return (*this); } // Ansonsten else { // *** // m_XFile_istOK=Quellklasse.m_XFile_istOK; // 3D-Objekt nur kopieren, wenn erlaubt (Fehler & PRG-Absturz Vermeidung) if (m_XFile_istOK == true) { // *** 1. einfache Datentypen kopieren *** m_Art_aktDatZeile=Quellklasse.m_Art_aktDatZeile; m_Anz_Meshes_3D_Obj=Quellklasse.m_Anz_Meshes_3D_Obj; m_Anz_Vertices_3D_Objekt=Quellklasse.m_Anz_Vertices_3D_Objekt; m_Anz_Indices_3D_Objekt=Quellklasse.m_Anz_Indices_3D_Objekt; m_Anz_Faces_3D_Objekt=Quellklasse.m_Anz_Faces_3D_Objekt; m_Anz_Materialien_3D_Objekt=Quellklasse.m_Anz_Materialien_3D_Objekt; m_Anz_Texturen_3D_Objekt=Quellklasse.m_Anz_Texturen_3D_Objekt; m_Nr_akt_Mesh=Quellklasse.m_Nr_akt_Mesh; m_DatGroesse_3D_Objekt_Vertices=Quellklasse.m_DatGroesse_3D_Objekt_Vertices; m_XFile_hatTextur=Quellklasse.m_XFile_hatTextur; m_XFile_hatNormalen=Quellklasse.m_XFile_hatNormalen; m_XFile_hatTexturkoordinaten=Quellklasse.m_XFile_hatTexturkoordinaten; m_TexturAnzeigen_erlaubt=Quellklasse.m_TexturAnzeigen_erlaubt; m_XFile_hatTransparenz=Quellklasse.m_XFile_hatTransparenz; m_3D_Objekt_xPos=Quellklasse.m_3D_Objekt_xPos; m_3D_Objekt_yPos=Quellklasse.m_3D_Objekt_yPos; m_3D_Objekt_zPos=Quellklasse.m_3D_Objekt_zPos; m_3D_Objekt_yDrehung=Quellklasse.m_3D_Objekt_yDrehung; // *** 2. Matrix(en) kopieren *** m_3D_Objekt_Matrix=Quellklasse.m_3D_Objekt_Matrix; // Laut Debug ist es so ok // *** 3. eindimensionale Zeiger kopieren *** m_DateiInput_3D_Objekt=Quellklasse.m_DateiInput_3D_Objekt; // m_DateiInput_3D_Objekt=NULL; // ??? // *** 4. Mehrdimensionale Zeiger/Speicherbereiche kopieren // //m_akt_Datei_Zeile=new char[254]; strcpy(m_akt_Datei_Zeile, Quellklasse.m_akt_Datei_Zeile); //m_DateiPfad_XFile=new char[255]; strcpy(m_DateiPfad_XFile, Quellklasse.m_DateiPfad_XFile); //(m_DateiPfad_DatName_XFile=new char[255]; strcpy(m_DateiPfad_DatName_XFile, Quellklasse.m_DateiPfad_DatName_XFile); // m_3D_Objekt_Vertices // m_3D_Objekt_Vertices=NULL; // m_3D_Objekt_Vertices= new CUSTOMVERTEX_3D_Objekt_1[Quellklasse.m_Anz_Vertices_3D_Objekt]; for (unsigned short int VerNr=0; VerNrerzeuge_Vertexbuffer(&m_VertexBuffer_3D_Objekt, m_DatGroesse_3D_Objekt_Vertices); // Daten des 3D-Objekts in den 3D-Objekt-Vertexbuffer kopieren: m_z_Kl_3D->kopiere_Vertices_in_Vertexbuffer(m_VertexBuffer_3D_Objekt, m_3D_Objekt_Vertices, m_DatGroesse_3D_Objekt_Vertices); // m_Indexbuffer_3D_Objekt // m_Indexbuffer_3D_Objekt=NULL; // Erzeuget Indexbuffer m_z_Kl_3D->erzeuge_Indexbuffer(&m_Indexbuffer_3D_Objekt, m_Anz_Indices_3D_Objekt); // Kopiert Indizes eines 3D-Objekts in den Indexbuffer m_z_Kl_3D->kopiere_Indizes_in_Indexbuffer(m_Indexbuffer_3D_Objekt, m_3D_Objekt_Indices, m_Anz_Indices_3D_Objekt); // m_KollisionsObj m_KollisionsObj=NULL; m_KollisionsObj=new Kl_DX_KollisionsObj(); m_KollisionsObj->init_KollisionsObj(2, m_Anz_Vertices_3D_Objekt, m_3D_Objekt_Vertices); // m_3D_Objekt_Textur m_3D_Objekt_Textur=NULL; m_3D_Objekt_Textur=new LPDIRECT3DTEXTURE9[m_Anz_Texturen_3D_Objekt]; /* // for (unsigned char TexturNr=0; TexturNrreset_Material(&m_3D_Objekt_Material[MatNr]); // m_3D_Objekt_Material[MatNr].Diffuse.r=Quellklasse.m_3D_Objekt_Material[MatNr].Diffuse.r; m_3D_Objekt_Material[MatNr].Diffuse.g=Quellklasse.m_3D_Objekt_Material[MatNr].Diffuse.g; m_3D_Objekt_Material[MatNr].Diffuse.b=Quellklasse.m_3D_Objekt_Material[MatNr].Diffuse.b; m_3D_Objekt_Material[MatNr].Diffuse.a=Quellklasse.m_3D_Objekt_Material[MatNr].Diffuse.a; m_3D_Objekt_Material[MatNr].Power=Quellklasse.m_3D_Objekt_Material[MatNr].Power; m_3D_Objekt_Material[MatNr].Specular.r=Quellklasse.m_3D_Objekt_Material[MatNr].Specular.r; m_3D_Objekt_Material[MatNr].Specular.g=Quellklasse.m_3D_Objekt_Material[MatNr].Specular.g; m_3D_Objekt_Material[MatNr].Specular.b=Quellklasse.m_3D_Objekt_Material[MatNr].Specular.b; m_3D_Objekt_Material[MatNr].Emissive.r=Quellklasse.m_3D_Objekt_Material[MatNr].Emissive.r; m_3D_Objekt_Material[MatNr].Emissive.g=Quellklasse.m_3D_Objekt_Material[MatNr].Emissive.g; m_3D_Objekt_Material[MatNr].Emissive.b=Quellklasse.m_3D_Objekt_Material[MatNr].Emissive.b; m_3D_Objekt_Material[MatNr].Ambient.r=Quellklasse.m_3D_Objekt_Material[MatNr].Ambient.r; m_3D_Objekt_Material[MatNr].Ambient.g=Quellklasse.m_3D_Objekt_Material[MatNr].Ambient.g; m_3D_Objekt_Material[MatNr].Ambient.b=Quellklasse.m_3D_Objekt_Material[MatNr].Ambient.b; m_3D_Objekt_Material[MatNr].Ambient.a=Quellklasse.m_3D_Objekt_Material[MatNr].Ambient.a; } //&m_3D_Objekt_Material[m_Nr_akt_Mesh].Diffuse.r // m_Anz_Vertices_MeshNr und // m_Anz_Faces_MeshNr und // m_Anz_NormalenVekt_MeshNr und // m_Anz_Texturkoordin_MeshNr // m_z3DObj_Vertice_AddWert_Mesh // m_z3DObj_IndexbufferPos_Mesh m_Anz_Vertices_MeshNr=NULL; m_Anz_Vertices_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; m_Anz_Faces_MeshNr=NULL; m_Anz_Faces_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; m_Anz_NormalenVekt_MeshNr=NULL; m_Anz_NormalenVekt_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; m_Anz_Texturkoordin_MeshNr=NULL; m_Anz_Texturkoordin_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; m_3D_Obj_Vertice_AddWert_Mesh=NULL; m_3D_Obj_Vertice_AddWert_Mesh=new unsigned int[m_Anz_Meshes_3D_Obj]; m_3D_Obj_IndexbufferPos_Mesh=NULL; m_3D_Obj_IndexbufferPos_Mesh=new unsigned int[m_Anz_Meshes_3D_Obj]; // for (unsigned short int MeNr=0; MeNrAddRef(); } } // *** return (*this); } } // ** Copy-Konstruktor (Kopier-Konstruktor, auch Copy-Ctor genannt) ** // // Info: Ohne selbstdefinierten Copykonstruktor wird beim kopieren // von Objekten automatisch einer angelegt. // Problem: der automatische Copy-Ctor macht // eine memberweise Kopie aller Attribute eines Objekts. // Skalare Typen wie z.B. int, float, werden bitweise kopiert // ABER: // Bei einen Zeiger wird NUR der Inhalt des Zeigers kopiert, // aber NICHT der gesammte Speicherbereich, auf den er zeigt! // Es wird also nur die Adresse, auf die der Zeiger zeigt, kopiert. // // Siehe ab S.107 im Buch "Objektorientierte Programmierung für Dummies" // // Beispiel für Aufruf des Copykonstruktors: // --> m_3D_Obj_Gitterstaebe_WgRecht[1]=Kl_3D_Objekt(m_3D_Obj_Gitterstaebe_WgRecht[0]); // /* Kl_3D_Objekt::Kl_3D_Objekt(const Kl_3D_Objekt& Quellklasse) { // **************************************************** // * // * Der folgende Quellcode ist genau der gleiche, // * wie der im Zuweisungsoperator. Stand: 24.03.2013 // * // **************************************************** //Beep(999,100); // ***** ALLE zu kopierenden Klassenelemente ***** } */ // *** Methoden *** // ** Init-Methoden ** // Initialisiert Kl_3D_Objekt (Statische Membervariablen) // // ACHTUNG: Brauch nur 1 x im gesammten Programm aufgerufen zu werden! void Kl_3D_Objekt::init_Kl_3D_Objekt(Kl_2D_Bild *z_Kl_2D_Bild, Kl_Debug *z_Kl_Debug) { //m_z_m_Grafikkarte=z_m_Grafikkarte; //m_z_Kl_3D=z_Kl_3D; m_z_Kl_2D_Bild=z_Kl_2D_Bild; m_z_Kl_Debug=z_Kl_Debug; //m_z_Kl_DX->get_Farbe_AmbientenLicht(); // D3DCOLORVALUE } /* EINSCHRÄNKUNGEN/Hinweis zur Benutzung von Kl_3D_Objekt (Stand: 01.04.2015: ACHTUNG: -1.) Kann nur X-Dateien im Text-Format laden (die auch Zeilenumbruchsmäßig mit den Windows Editor ansehbar sind! (Ansonsten Text kurz nach MS Word kopieren, und dann wieder ins X-File) X-Dateien im Binärformat u.a. werden derzeitig nicht unterstützt. -2.) Im Dateinamen der Textur darf momentan kein Leerzeichen sein! -3.) Wenn mit Texturangabe, sollte bestenfalls auch Texturdatei(en) (Grafik) vorhanden sein, damit Textur beim anzeigen des 3D-Objekts auch sichtbar ist. -4.) Verwendet nur die Texturen, die im Materialmesh sind! Stehen diese woanders, dann keine Unterstützung. -5.) Referenzen auf Materialien werden derzeitig nicht unterstützt! -6.) Transparente Objekte werden momentan nicht unterstützt??? -7.) Jede Face/Indizes-Zeile darf momentan nur 3 Indizes haben (=Triangles statt Quads). Mehr als 3 oder z.B. mal 4, dann mal 10 Indizes, werden nicht unterstützt. (Abhilfe: Truespace kann x-Dateien Triangulieren. Blender kann per Strg-T im Edit Modus alle markierten Faces (Quads) eines 3D-Models triangulieren) (Programmiertechnische Problemlösung/Triangulierung: S.158 im braunen Zerbst II Buch) -8.) Wenn X-File mehr normalen als Face/Indizes-Zeilen hat, wird dies noch NICHT unterstützt! -9.) Animation: -X-Files mit mehreren Meshes & Texturen werden noch nicht unterstützt. Aber es ist auch effizienter, X-Files mit nur einer Textur statt mehreren (=Textur Atlas) zu verwenden. Nachteil: ?Mip Map Probleme?, etc -?Es werden derzeitig nur Matrix-Keys, aber keine Rotation- usw Keys unterstützt? -X-Files mit Matrix-Keys (z.B. von Milkshape 3D) funktionieren 100%ig -X-Files mit SRT-Keys (z.B. von Blender) funktionieren nur fast 100%ig (SRT=Scale, Rotation, Translation Keys statt Matrixkeys) -Es dürfen z.B. keine Matrix Keys "fehlen" (Wenn z.B. nicht bei jedem Animationsschritt (außer der 1.) ein Matrix Key vorhanden ist) -10.) Kompatiblität mit von 3D-Modellierungsprogrammen erzeugten X-Files: -Milkshape 3D 1.8.4 und "DirectX 8.0 File"-Exporter von Matthew Scott: unanimierte 3D-Modelle funktionieren (auch mit mehreren Meshes & Texturen). Animierte 3D-Modelle funktionieren (Wenn max 1 Mesh & 1 Textur usw) -Blender 2.73a und "DirectX (.x)" 3.1.0-Exporter von Chris Foster (Nur kurz getestet): X-Files müssen vorm X-File Export Trianguliert werden. Danach als Right-Handed, eventuell ohne Normalen, usw als X-File exportieren unanimiertes 3D-Modell funktionierte. Animiertes 3D-Modell (Robotermensch) funktionierte (Wenn max 1 Mesh & 1 Textur usw) fast 100%, wird in GW3D aber liegend usw statt stehend angezeigt... -Blender X-File Tipp: Falls bei einen animierten Mensch z.B. am anderen Bein Vertices unerlaubt mitgezogen werden, lag das oft daran, daß in Blender die Vertices nicht so ordentlich den Bones zugewiesen wurden (Z.B. wg Parenting ...with automatic Weights) -11.) Derzeitig wird nur Software-Skinning unterstützt, aber kein Hardware-Skinning (per Grafikkarte) -12.) Das aktuelle Software-Skinning von Kl_3D_Objekt kann programmiertechnisch noch verschnellert werden: Statt per verketteter Liste per zuvor erzeugtes Array auf Bones zugreifen. */ // Lädt ein 3D-Objekt (auch Mesh genannt) aus einem XFile. // // Parameter: 1.=Pfad incl Dateiname der X-Datei, Z.B. // "3D Modelle\\Geist\\Geist.x" // 2.=Ist in einer der Texturen Transparenz, // dann brauch Wert nur dann auf true gesetzt werden, // Wenn in mind. 1 Material kein Diffuse.a (alpha) < 1.000000f ist // (damit Transparenz trotzdem angezeigt wird) void Kl_3D_Objekt::lade_3D_Obj_aus_XFile(char *DatPfad_XDatei, bool verwendet_TexturMitTransparenz) { // Dafür sorgen, daß Transparentes angezeigt wird // (Falls Diffuse.a==1 ist, und dadurch später keine Transparenz aktiviert wird) // // (Zukünftig könnte dieser Prg-Teil komfortabler gemacht werden, // indem geladene Texturen auf Alphawerte < 255 überprüft werden, // und m_XFile_hatTransparenz entsprechend gesetzt wird) if (verwendet_TexturMitTransparenz==true) { m_XFile_hatTransparenz=true; } // *** 1. Dateipfad incl Name der X-Datei speichern m_DateiPfad_DatName_XFile[0]='\0'; strcpy(m_DateiPfad_DatName_XFile, DatPfad_XDatei); // *** 2. Pfad für Textur ermitteln *** // INFO: In *DatPfad_XDatei wurde z.B."3D Modelle\\Spielfeld\\Kanone.x" übergeben. // Daraus soll dann "3D Modelle\\Spielfeld\\" gemacht werden. // (Damit später der Dateiname der Textur des X-Files drangehängt werden kann) // strcpy(m_DateiPfad_XFile, DatPfad_XDatei); // INFO: m_DateiPfad_XFile enthält jetzt "3D Modelle\\Spielfeld\\Kanone.x" // Dateiname aus Pfad entfernen // (Aus "3D Modelle\\Spielfeld\\Kanone.x" das machen: "3D Modelle\\Spielfeld\\") // char *pdest; int Pos_VomZeichen; // 1.Position des letzten "\" ermitteln // strrchr scan a string for the last occurrence of a character. pdest = strrchr( m_DateiPfad_XFile, '\\' ); Pos_VomZeichen = pdest - m_DateiPfad_XFile + 1; // 2.Durch Kürzung des Strings den Dateinamen aus Pfad entfernen. // Anschließend enthält m_DateiPfad_XFile="3D Modelle\\Spielfeld\\" m_DateiPfad_XFile[Pos_VomZeichen]='\0'; // *** 3. X-File laden usw *** // ** 3a. X-File öffnen usw ** // Text-Datei zum Lesen öffnen m_DateiInput_3D_Objekt = fopen(DatPfad_XDatei,"rt"); // prüft, ob // -m_DateiInput_3D_Objekt == NULL ist, und ob // -Datei ein X-File ist. // Rückgabewert: False, falls m_DateiInput_3D_Objekt==NULL, // oder wenn Datei kein X-File ist m_XFile_istOK=pruefe_XFile_Datei(); // if (m_XFile_istOK==false) { // Muß hier AUSNAHMSWEISE außerhalb einer X-File Animationsdaten-Ladefunktion false sein, // weil jetzt keine dieser Funktionen mehr aufgerufen wird, und es dort nicht mehr auf // false gesetzt werden kann. // (Um Prg-Absturz wg. Aufruf von "animiere_3D_Obj()" zu vermeiden) m_Animationsdaten_sindOK=false; // Funktion "lade_3D_Obj_aus_XFile()" vorzeitig beenden return; } // ** 3b. XFile analysieren ** // sieht im XFile nach, wie viel vom folgenden enthalten ist: // -Materialien // -Texturen // -Meshes // // Ergebnisse werden in // m_AnzMaterialien_3D_Objekt, m_AnzTexturen_3D_Objekt und // m_Anz_Meshes_3D_Obj gespeichert analysiere_XFile(); // Setzt Datei (Filepointer) wieder zum Anfang der Datei // Repositions the file pointer to the beginning of a file. rewind(m_DateiInput_3D_Objekt); // ** 3c. Speicher anfordern usw ** // Speicher entsprechend der X-File Analyse anfordern m_3D_Objekt_Material=new D3DMATERIAL9[m_Anz_Materialien_3D_Objekt]; m_3D_Objekt_Textur=new LPDIRECT3DTEXTURE9[m_Anz_Texturen_3D_Objekt]; m_Anz_Vertices_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; m_Anz_Faces_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; m_Anz_NormalenVekt_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; m_Anz_Texturkoordin_MeshNr=new unsigned int[m_Anz_Meshes_3D_Obj]; // sieht in den Meshes des XFiles nach, // wie viel vom folgenden enthalten ist: // -Anzahl Vertices je Mesh, Anzahl Faces je Mesh // -Anzahl der Normalenvektoren je Mesh // -Anzahl der Texturkoordinaten je Mesh // -Anzahl Vertices des gesammten 3D-Objekts (Alle Meshes zusammen) // -Anzahl Faces des gesammten 3D-Objekts (Alle Meshes zusammen) // // Ergebnisse werden in // m_Anz_Vertices_MeshNr[], m_Anz_Faces_MeshNr[], // m_Anz_NormalenVekt_MeshNr[], // m_Anz_Texturkoordin_MeshNr[], // m_Anz_Vertices_3D_Objekt, m_Anz_Faces_3D_Objekt // gespeichert analysiere_XFile_Meshes(); // Setzt Datei (Filepointer) wieder zum Anfang der Datei rewind(m_DateiInput_3D_Objekt); // *** Daten für Vertex-Buffer *** // Speicher für Vertices anfordern m_3D_Objekt_Vertices= new CUSTOMVERTEX_3D_Objekt_1[m_Anz_Vertices_3D_Objekt]; // Alle Inhalte der Vertices Nullen for (unsigned int Nr=0; Nr < m_Anz_Vertices_3D_Objekt; Nr++) { m_3D_Objekt_Vertices[Nr].x=0; m_3D_Objekt_Vertices[Nr].y=0; m_3D_Objekt_Vertices[Nr].z=0; m_3D_Objekt_Vertices[Nr].nx=0.000000f; m_3D_Objekt_Vertices[Nr].ny=0.000000f; m_3D_Objekt_Vertices[Nr].nz=0.000000f; m_3D_Objekt_Vertices[Nr].tu=0.000000f; m_3D_Objekt_Vertices[Nr].tv=0.000000f; } // Daten-Größe ermitteln & speichern // (Sollte bei z.B 5 Vertices/einer Pyramide=160 sein!) m_DatGroesse_3D_Objekt_Vertices= m_Anz_Vertices_3D_Objekt * sizeof(m_3D_Objekt_Vertices[0]); // *** Daten für Index-Buffer *** // Jedes Face hat 3 Indices m_Anz_Indices_3D_Objekt=m_Anz_Faces_3D_Objekt * 3; // Speicher für Indices anfordern m_3D_Objekt_Indices=new short int[m_Anz_Indices_3D_Objekt + 1]; // Alle Inhalte der Indices Nullen ZeroMemory(m_3D_Objekt_Indices, m_Anz_Indices_3D_Objekt * sizeof (unsigned short int) ); // ** 3d. Sonstiges ** // zunächst alles Nullen. // (Wenn Material später nicht mit Werten gefüllt wird, // ist 3D-Objekt schwarz!...) for (unsigned int Nr_Material=0; Nr_Material < m_Anz_Materialien_3D_Objekt; Nr_Material++) { m_z_Kl_3D->reset_Material(&m_3D_Objekt_Material[Nr_Material]); } // if (m_Anz_Texturen_3D_Objekt > 0) { // muß Anfangs true sein m_TexturAnzeigen_erlaubt=true; } // ** 3e. XFile-Animationsdaten analysieren ** // sieht im XFile nach, // wie viel vom folgenden enthalten ist: // -Anzahl der Meshes mit Bones (Joints) // -Anzahl der AnimationKey-Dateiblöcke // -Anzahl der Joints/Gelenke des 3D-Objekts // // Ergebnisse werden in // m_anz_MeshesMitJoints // m_anz_AnimationKeys und // m_anz_Joints // gespeichert analysiere_XFile_Animationsdaten(); // Setzt Datei (Filepointer) wieder zum Anfang der Datei rewind(m_DateiInput_3D_Objekt); // Prüfen, ob X-File Animation hat if (m_anz_Joints > 0) { m_XFile_hat_Animation=true; } // ** 3f. Weitere XFile-Animationsdaten analysieren ** // Darf nur ausgeführt werden, wenn X-File auch Animationsdaten enthält if (m_XFile_hat_Animation==true) { // sieht im XFile nach, // -ob X-File Matrix Keys (oder SRT Keys) nutzt // -Wie hoch die höchste Anzahl der Matrix Keys eines AnimationKey Dateiblocks ist // // Ergebnisse werden in // m_XFile_nutzt_MatrixKeys und // m_max_anz_Mtr_Keys // gespeichert analysiere_XFile_Animationsdaten2(); rewind(m_DateiInput_3D_Objekt); // unsigned short int MtrKey_Nr; // Speicher für m_Tmp_MatrixKey nur dann bereitstellen, // wenn X-File auch Matrix-Keys hat if (m_XFile_nutzt_MatrixKeys==true) { m_Tmp_MatrixKey=new D3DXMATRIX[m_max_anz_Mtr_Keys]; for (MtrKey_Nr=0; MtrKey_Nr < m_max_anz_Mtr_Keys; MtrKey_Nr++) { D3DXMatrixIdentity(&m_Tmp_MatrixKey[MtrKey_Nr]); } } // Anonsten else { // m_Tmp_RotationKey=new D3DXQUATERNION[m_max_anz_Mtr_Keys]; m_Tmp_ScaleKey=new D3DXVECTOR3[m_max_anz_Mtr_Keys]; m_Tmp_PositionKey=new D3DXVECTOR3[m_max_anz_Mtr_Keys]; for (MtrKey_Nr=0; MtrKey_Nr < m_max_anz_Mtr_Keys; MtrKey_Nr++) { // D3DXQuaternionIdentity(&m_Tmp_RotationKey[MtrKey_Nr]); // m_Tmp_ScaleKey[MtrKey_Nr].x=0.0f; m_Tmp_ScaleKey[MtrKey_Nr].y=0.0f; m_Tmp_ScaleKey[MtrKey_Nr].z=0.0f; // m_Tmp_PositionKey[MtrKey_Nr].x=0.0f; m_Tmp_PositionKey[MtrKey_Nr].y=0.0f; m_Tmp_PositionKey[MtrKey_Nr].z=0.0f; } } } // ** 3g. XFile-Daten laden usw ** // Lese solange aus der Datei, // bis das Dateiende erreicht wurde while (feof(m_DateiInput_3D_Objekt) == NULL) { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); // Inhalt der aktuellen Datei-Zeile (=m_akt_Datei_Zeile) prüfen, // und bei Fund in m_Art_aktDatZeile speichern pruefInhalt_DatZeile(); // Behandelt den Datei-Zeilen-Inhalt, // der in m_Art_aktDatZeile steht behandleInhalt_DatZeile(); /* // Für Debug-Überprüfungszwecke: inDz_XSkinMeshHeader inDz_SkinWeights inDz_AnimationKey if (m_Art_aktDatZeile==inDz_AnimationKey) { m_Animationsdaten_sindOK; //=1 m_akt_Datei_Zeile; //=" " m_Art_aktDatZeile; //=72=inDz_SkinWeights char b=0; } */ } // Datei darf vermutlich nur dann geschlossen werden, // falls sie erfolgreich geöffnet wurde fclose (m_DateiInput_3D_Objekt); // *** 4. Kl_3D_Objekt mit X-File initialisieren *** // Initialisiert das 3D-Objekt mit den geladenen Daten des X-Files. // (Vertexbuffer erzeugen & füllen, usw). // Bereitet außerdem beim Einsatz mehrerer Meshes Werte für // zeig_3D_Objekt() vor // (m_z3DObj_Vertice_AddWert_Mesh & m_z3DObj_IndexbufferPos_Mesh) init_3D_Obj_aus_XFile(); } // sieht im XFile nach, wie viel vom folgenden enthalten ist: // -Materialien // -Texturen // -Meshes // // Ergebnisse werden in // m_AnzMaterialien_3D_Objekt, m_AnzTexturen_3D_Objekt und // m_Anz_Meshes_3D_Obj gespeichert void Kl_3D_Objekt::analysiere_XFile(void) { // m_Anz_Materialien_3D_Objekt=0; m_Anz_Texturen_3D_Objekt=0; m_Anz_Meshes_3D_Obj=0; // Lese solange aus der Datei, // bis das Dateiende erreicht wurde while (feof(m_DateiInput_3D_Objekt) == NULL) { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); // Ist Dateizeile eine... // ..."template "-Zeile? // // z.B. wg. "Material <" (Ist in template MeshMaterialList {) if (pruefeAuf_Zeichenfolge("template ") == true) { // Überspringt Einträge des aktuellen Templates des X-Files, // damit Dateizeiger auf der Zeile nach dem Ende des Templates gelangt ueberspringe_Template_XFile(); } else { // ..."Material "-Zeile? if (pruefeAuf_Zeichenfolge("Material ") == true) // Prüfung=-ok- { // Es wurde ein Material gefunden. Deswegen um 1 erhöhen m_Anz_Materialien_3D_Objekt++; } // ..."TextureFilename {" oder "template TextureFilename {" -Zeile? if (pruefeAuf_Zeichenfolge("TextureFilename {") == true) // Prüfung=-- { // ACHTUNG: der Eintrag "template TextureFilename {" enthält auch "TextureFilename {"! if (pruefeAuf_Zeichenfolge("template TextureFilename {")==true) { ueberspringe_Template_XFile(); } else { // Es wurde ein Textureintrag gefunden. Deswegen um 1 erhöhen m_Anz_Texturen_3D_Objekt++; } } // ..."Mesh " oder "template Mesh {"-Zeile? // // Zeile kann nur "Mesh {", aber auch variable Namen wie z.B. // "Mesh mesh-guard {" oder "Mesh mesh-stab {" u.v.m. enthalten! if (pruefeAuf_Zeichenfolge("Mesh ")==true) // Prüfung=-ok- { // ACHTUNG: der Eintrag "template Mesh {" enthält auch "Mesh "! if (pruefeAuf_Zeichenfolge("template Mesh {")==true) { ueberspringe_Template_XFile(); } else { // Es wurde ein Mesh gefunden. Deswegen um 1 erhöhen m_Anz_Meshes_3D_Obj++; } } } } } // sieht in den Meshes des XFiles nach, // wie viel vom folgenden enthalten ist: // -Anzahl Vertices je Mesh, Anzahl Faces je Mesh // -Anzahl der Normalenvektoren je Mesh // -Anzahl der Texturkoordinaten je Mesh // -Anzahl Vertices des gesammten 3D-Objekts (Alle Meshes zusammen) // -Anzahl Faces des gesammten 3D-Objekts (Alle Meshes zusammen) // // Ergebnisse werden in // m_Anz_Vertices_MeshNr[], m_Anz_Faces_MeshNr[], // m_Anz_NormalenVekt_MeshNr[], // m_Anz_Texturkoordin_MeshNr[], // m_Anz_Vertices_3D_Objekt, m_Anz_Faces_3D_Objekt // gespeichert void Kl_3D_Objekt::analysiere_XFile_Meshes(void) { // m_Nr_akt_Mesh=-1; // m_Anz_Vertices_3D_Objekt=0; m_Anz_Faces_3D_Objekt=0; // Lese solange aus der Datei, // bis das Dateiende erreicht wurde while (feof(m_DateiInput_3D_Objekt) == NULL) { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); // Ist Dateizeile eine... // ..."template "-Zeile? // // z.B. wg. "Material <" (Ist in template MeshMaterialList {) if (pruefeAuf_Zeichenfolge("template ") == true) { // Überspringt Einträge des aktuellen Templates des X-Files, // damit Dateizeiger auf der Zeile nach dem Ende des Templates gelangt ueberspringe_Template_XFile(); } // Oder ist Dateizeile eine... else { // ..."Mesh " oder "template Mesh {"-Zeile? // // Zeile kann nur "Mesh {", aber auch variable Namen wie z.B. // "Mesh mesh-guard {" oder "Mesh mesh-stab {" u.v.m. enthalten! if (pruefeAuf_Zeichenfolge("Mesh ")==true) // Prüfung=-- { // ACHTUNG: der Eintrag "template Mesh {" enthält auch "Mesh "! // // um zu verhindern, das bei diesen Eintrag inDz_Mesh_X statt // inDz_TemplateMesh aktiviert wird, folgendes prüfen: if (pruefeAuf_Zeichenfolge("template Mesh {")==true) { ueberspringe_Template_XFile(); } else { // Es wurde ein Mesh gefunden. Deswegen um 1 erhöhen m_Nr_akt_Mesh++; // sieht im XFile-Mesh nach, wieviel Vertices & Faces es enthält. // Ergebnisse werden in m_Anz_Vertices_MeshNr[m_Nr_akt_Mesh] und // m_Anz_Faces_MeshNr[m_Nr_akt_Mesh] gespeichert lese_Mesh__Mengen(); } } // Ende von ..."Mesh " oder "template Mesh {"-Zeile? // ..."MeshNormals {" oder "template MeshNormals {"-Zeile? if (pruefeAuf_Zeichenfolge("MeshNormals {")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("template MeshNormals {")==true) { ueberspringe_Template_XFile(); } else { // Ließt im XFile den Eintrag für Anzahl der Normalenvektoren, // der im aktuellen "MeshNormals" Dateiblock steht. // Ergebnis wird in m_Anz_NormalenVekt_MeshNr[m_Nr_akt_Mesh] // gespeichert lese_MeshNormals__Mengen(); } } // ..."MeshTextureCoords {" oder "template MeshTextureCoords {" -Zeile? if (pruefeAuf_Zeichenfolge("MeshTextureCoords {")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("template MeshTextureCoords {")==true) // Prüfung=-- { ueberspringe_Template_XFile(); } else { // Ließt im XFile den Eintrag für Anzahl der Texturkoordinaten, // der im aktuellen "MeshTextureCoords" Dateiblock steht. // Ergebnis wird in m_Anz_Texturkoordin_MeshNr[m_Nr_akt_Mesh] // gespeichert lese_MeshTextureCoords__Mengen(); } } } } // Gesammtmengen (Summen) ausrechnen for (unsigned short int Nr_Mesh=0; Nr_Mesh < m_Anz_Meshes_3D_Obj; Nr_Mesh++) { m_Anz_Vertices_3D_Objekt=m_Anz_Vertices_3D_Objekt + m_Anz_Vertices_MeshNr[Nr_Mesh]; m_Anz_Faces_3D_Objekt=m_Anz_Faces_3D_Objekt + m_Anz_Faces_MeshNr[Nr_Mesh]; } // Muß jetzt wieder auf -1 gesetzt werden m_Nr_akt_Mesh=-1; } // sieht im XFile-Mesh nach, wieviel Vertices & Faces es enthält. // Ergebnisse werden in m_Anz_Vertices_MeshNr[m_Nr_akt_Mesh] und // m_Anz_Faces_MeshNr[m_Nr_akt_Mesh] gespeichert void Kl_3D_Objekt::lese_Mesh__Mengen(void) { // Erstmal auf 0 setzen, falls nichts aus Datei geladen wird m_Anz_Vertices_MeshNr[m_Nr_akt_Mesh]=0; m_Anz_Faces_MeshNr[m_Nr_akt_Mesh]=0; // bool Fehler; unsigned int Anzahl; // *** Anzahl der Vertices dieses Meshs einlesen *** // // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Liest z.B. den Dateieintrag" 5;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück // // Rückgabewerte: // false=Fehler beim lesen/Dateieinträge fehlen // *Menge: Z.B. Menge/Anzahl der Vertices, die zurückgegeben wird Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lese_Mesh__Mengen(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_Vertices_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // m_Anz_Vertices_MeshNr[m_Nr_akt_Mesh]=Anzahl; int Ergebnis; // Fehler=false; // *** Vertices dieses Meshs überspringen *** // float Dummy; char Zeichen; // je 3 float-Werte lesen, z.B. von Dateizeile: // 0.000000;0.000000;1.000000;, for (unsigned int Nr_DateiZeile=0; Nr_DateiZeileset_Meldung("in Kl_3D_Objekt::lese_Mesh__Mengen(...)", 6); m_z_Kl_Debug->set_Meldung("fscanf(...&Dummy, &Zeichen,...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_XFile_istOK=false; return; } // *** Anzahl der Faces dieses Meshs einlesen *** // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Liest z.B. den Dateieintrag" 6;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lese_Mesh__Mengen(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_Faces_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // m_Anz_Faces_MeshNr[m_Nr_akt_Mesh]=Anzahl; } // Ließt im XFile den Eintrag für Anzahl der Normalenvektoren, // der im aktuellen "MeshNormals" Dateiblock steht. // Ergebnis wird in m_Anz_NormalenVekt_MeshNr[m_Nr_akt_Mesh] // gespeichert void Kl_3D_Objekt::lese_MeshNormals__Mengen(void) { // Erstmal auf 0 setzen, falls nichts aus Datei geladen wird m_Anz_NormalenVekt_MeshNr[m_Nr_akt_Mesh]=0; // Info: Dateizeiger ist in Zeile " MeshNormals {" // *** 1. Anzahl der Normalenvektoren dieses Mesh lesen *** // (=Nächste Dateizeile " 5;" lesen.) // Dabei eventuell vorhandene Leer- oder Kommentarzeilen überspringen // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Jetzt sollte aber die Dateizeile wie Z.B. " 5;" // in m_akt_Datei_Zeile enthalten sein // unsigned int Anzahl; bool Fehler; // Liest z.B. den Dateieintrag" 5;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lese_MeshNormals__Mengen(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_NormalenVekt_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // Info: Dateizeiger ist in Zeile " 5;" // m_Anz_NormalenVekt_MeshNr[m_Nr_akt_Mesh]=Anzahl; } // Ließt im XFile den Eintrag für Anzahl der Texturkoordinaten, // der im aktuellen "MeshTextureCoords" Dateiblock steht. // Ergebnis wird in m_Anz_Texturkoordin_MeshNr[m_Nr_akt_Mesh] // gespeichert void Kl_3D_Objekt::lese_MeshTextureCoords__Mengen(void) { // Erstmal auf 0 setzen, falls nichts aus Datei geladen wird m_Anz_Texturkoordin_MeshNr[m_Nr_akt_Mesh]=0; // Info: Dateizeiger ist in Zeile " MeshTextureCoords {" // *** 1. Anzahl der Texturkoordinaten dieses Mesh lesen *** // (=Nächste Dateizeile " 71;" lesen.) // Dabei eventuell vorhandene Leer- oder Kommentarzeilen überspringen // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Jetzt sollte aber die Dateizeile wie Z.B. " 71;" // in m_akt_Datei_Zeile enthalten sein // unsigned int Anzahl; bool Fehler; // Liest z.B. den Dateieintrag" 71;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lese_MeshTextureCoords__Mengen(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_Texturkoordin_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // Info: Dateizeiger ist in Zeile " 71;" // m_Anz_Texturkoordin_MeshNr[m_Nr_akt_Mesh]=Anzahl; } // Initialisiert das 3D-Objekt mit den geladenen Daten des X-Files. // (Vertexbuffer erzeugen & füllen, usw). // Bereitet außerdem beim Einsatz mehrerer Meshes Werte für // zeig_3D_Objekt() vor // (m_z3DObj_Vertice_AddWert_Mesh & m_z3DObj_IndexbufferPos_Mesh) void Kl_3D_Objekt::init_3D_Obj_aus_XFile(void) { // Wenns Probleme beim laden des X-Files gab, Funktion sofort verlassen if (m_XFile_istOK==false) { return; } // *** Vorbereitungen & Vorberechnungen für zeig_3D_Objekt() *** // m_3D_Obj_Vertice_AddWert_Mesh=new unsigned int[m_Anz_Meshes_3D_Obj]; m_3D_Obj_IndexbufferPos_Mesh=new unsigned int[m_Anz_Meshes_3D_Obj]; // Werte für den 1.Mesh (=Nr.0) speichern. Prüfung: -ok- m_3D_Obj_Vertice_AddWert_Mesh[0]=0; m_3D_Obj_IndexbufferPos_Mesh[0]=0; // Werte für weitere Meshes erzeugen, falls mehr als 1 Mesh vorhanden ist // Prüfung: -- for (unsigned short int Nr_Mesh=1; Nr_Mesh < m_Anz_Meshes_3D_Obj; Nr_Mesh++) { // m_3D_Obj_Vertice_AddWert_Mesh[Nr_Mesh]=m_3D_Obj_Vertice_AddWert_Mesh[Nr_Mesh - 1]; // m_3D_Obj_Vertice_AddWert_Mesh[Nr_Mesh]+=m_Anz_Vertices_MeshNr[Nr_Mesh - 1]; // m_3D_Obj_IndexbufferPos_Mesh[Nr_Mesh]=m_3D_Obj_IndexbufferPos_Mesh[Nr_Mesh - 1]; // m_3D_Obj_IndexbufferPos_Mesh[Nr_Mesh]+=3 * m_Anz_Faces_MeshNr[Nr_Mesh - 1]; } // *** Eventuell Meldungen ausgeben *** // if (m_XFile_hatNormalen==false) { m_z_Kl_Debug->set_Meldung("Kl_3D_Objekt::init_3D_Obj_aus_XFile(...) meldet...", 5); m_z_Kl_Debug->set_Meldung("...Geladene *.X-Datei enthält keine Normalenvektoren:", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_z_Kl_Debug->set_Meldung("...Normalenvektoren werden ersatzweise berechnet", 5); // In Vorbereitung, funktioniert größtenteils schon: // // Berechnet Normalenvektoren für die Vertices // // ACHTUNG: Jeder Vertex (3 Vertices) MUß ein Dreieck ergeben, // damit Berechnung durchgeführt werden kann! // Siehe S.76 im roten Scherfgen Buch I berechne_Normalenvektoren(); } // if (m_XFile_hatTexturkoordinaten==false) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::init_3D_Obj_aus_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("Ursache: Geladene *.X-Datei enthält keine Texturkoordinaten:", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); } // *** Vertex & Index Buffer für das 3D-Objekt des X-Files*** // // (Damit die Daten direkt in der Grafikkarte gespeichert werden, und der zugriff // wesentlich schneller erfolgt) // Erzeugt Vertexbuffer fürs 3D-Objekt // (verwendet D3D_CUSTOMVERTEX_3D_Objekt_1) m_z_Kl_3D->erzeuge_Vertexbuffer(&m_VertexBuffer_3D_Objekt, m_DatGroesse_3D_Objekt_Vertices); // Daten des 3D-Objekts in den 3D-Objekt-Vertexbuffer kopieren: m_z_Kl_3D->kopiere_Vertices_in_Vertexbuffer(m_VertexBuffer_3D_Objekt, m_3D_Objekt_Vertices, m_DatGroesse_3D_Objekt_Vertices); // Erzeuget Indexbuffer // // ACHTUNG: // (Soll laut Buch direkt nach Vertexbuffererzeugung aufgerufen werden) m_z_Kl_3D->erzeuge_Indexbuffer(&m_Indexbuffer_3D_Objekt, m_Anz_Indices_3D_Objekt); // Kopiert Indizes eines 3D-Objekts in den Indexbuffer m_z_Kl_3D->kopiere_Indizes_in_Indexbuffer(m_Indexbuffer_3D_Objekt, m_3D_Objekt_Indices, m_Anz_Indices_3D_Objekt); // *** Bounding Box *** // m_KollisionsObj=new Kl_DX_KollisionsObj(); // m_KollisionsObj->init_KollisionsObj(1, m_Anz_Vertices_3D_Objekt, m_3D_Objekt_Vertices); // *** Animationsdaten *** // Funktion nur weiter ausführen, wenn erlaubt // (Um Programmabstürze bei X-File Problemen zu vermeiden, // und eventuelle Prg-Meldungen trotzdem lesen zu können) if (m_Animationsdaten_sindOK==false) { return; } // Darf nur ausgeführt werden, wenn X-File auch Animationsdaten enthält if (m_XFile_hat_Animation==true) { // Berechnet für alle Gelenke alle Animationspositionen der Gelenke (Joints) // Ergebnisse werden in m_absolute_Matrix_Gelenk[][] gespeichert. berechne_Matrixen_Gelenkpositionen(); // ** Für jeden Vertex den zugehörigen Joint ermitteln ** // unsigned short int VertexNr; // VertexNr=0; // ** Vertices & Vertexbuffer für Animation erstmalig füllen ** // m_3D_Obj_Vertices_Animation= new CUSTOMVERTEX_3D_Objekt_1[m_Anz_Vertices_3D_Objekt]; // Original-Vertice des XFiles in den Vertices für // die 3D-Objekt Animation kopieren for (unsigned int Nr=0; Nrerzeuge_Vertexbuffer(&m_VertexBuffer_Animiertes_3D_Objekt, m_DatGroesse_3D_Objekt_Vertices); // Animations-Vertices in den 2. 3D-Objekt-Vertexbuffer kopieren: m_z_Kl_3D->kopiere_Vertices_in_Vertexbuffer(m_VertexBuffer_Animiertes_3D_Objekt, m_3D_Obj_Vertices_Animation, m_DatGroesse_3D_Objekt_Vertices); } } // In Vorbereitung, funktioniert größtenteils schon: // // Berechnet Normalenvektoren für die Vertices // // ACHTUNG: Jeder Vertex (3 Vertices) MUß ein Dreieck ergeben, // damit Berechnung durchgeführt werden kann! // Siehe S.76 im roten Scherfgen Buch I void Kl_3D_Objekt::berechne_Normalenvektoren(void) { // *** 1.Variante zum Berechnen *** // Erklärung aus Buch: // // Gegebene Punkte=A (-5,-1,7), B (1,2,8), C (7,-4,9) // // 1. Berechnen der 2 Verbindungsvektoren AB und AC // // AB=B - A=(1,2,8) -(-5,-1,7)=(6, 3, 1) // AC=C - A=(7,-4,9) -(-5,-1,7)=(12,-3, 2) // 2. Das Kreuzprodukt bilden und 3.das Ergebnis normalisieren // // N(a,b,c)=AB x AC ~ (0.164, 0, -0.986) // D3DXVECTOR3 Verbindungsvektor_AB; D3DXVECTOR3 Verbindungsvektor_AC; D3DXVECTOR3 Kreuzprodukt; D3DXVECTOR3 Normalenvektor; unsigned int Nr_1ter_Indice; // Muß anfangs 0 sein Nr_1ter_Indice=0; // for ( unsigned int Nr_Vertex=0; Nr_Vertexx=m_3D_Objekt_Vertices[Nr_1ter_Indice].x; p0->y=m_3D_Objekt_Vertices[Nr_1ter_Indice].y; p0->z=m_3D_Objekt_Vertices[Nr_1ter_Indice].z; p1->x=m_3D_Objekt_Vertices[Nr_1ter_Indice+1].x; p1->y=m_3D_Objekt_Vertices[Nr_1ter_Indice+1].y; p1->z=m_3D_Objekt_Vertices[Nr_1ter_Indice+1].z; p2->x=m_3D_Objekt_Vertices[Nr_1ter_Indice+2].x; p2->y=m_3D_Objekt_Vertices[Nr_1ter_Indice+2].y; p2->z=m_3D_Objekt_Vertices[Nr_1ter_Indice+2].z; D3DXVECTOR3 u = *p1 - *p0; D3DXVECTOR3 v = *p2 - *p0; D3DXVec3Cross(out, &u, &v); D3DXVec3Normalize(out, out); m_3D_Objekt_Vertices[Nr_Vertex].nx=out->x; m_3D_Objekt_Vertices[Nr_Vertex].ny=out->y; m_3D_Objekt_Vertices[Nr_Vertex].nz=out->z; Nr_1ter_Indice+=3; } */ } // Setzt den grafischen Datenstrom auf den Vertexbuffer des 3D-Objekts void Kl_3D_Objekt::set_Datenstrom_3D_Objekt_VB(void) { // DX mitteilen,von welchem Vertexbuffer die zu zeichnenden Daten entommen werden sollen: m_z_m_Grafikkarte->SetStreamSource( 0, // Nr. des Datenstroms. "0"=es wird nur // 1 Datenstrom verwendet m_VertexBuffer_3D_Objekt, // Zeiger auf den Vertexbuffer 0, // Abstand vom Vertexbuffer-Anfang (Wenn // nicht alle VB-Daten verwendet werden // sollen) m_z_Kl_3D->m_DatGrsse_CustomVertex_3D_Objekt_1 // Die Größe des verwendeten Vertex-Formats ); } // Lädt den Header (die 1.Zeile) einer geöffneten X-Datei // Bsp für Header: "xof 0303txt 0032" // // Rückgabewert: false, wenn Datei kein "xof" enthält (Datei Kein X-File ist) // ("xof"=Erkennungsmerkmal für XFile) bool Kl_3D_Objekt::lade_Header_XFile(void) { // Infos zum Header: // // Der Header einer X-Datei ist 16 Byte lang. Er muß ganz oben am Anfang der // Datei stehen! // // Bsp-Header: xof 0303txt 0032 // // Bytes 1-4: xof // Identifiziert Datei als X-File // (=Magic Number) // Bytes 5-6: 03 // Major-Number (03=Major version 3) // Bytes 7-8: 03 // Minor-Number (03=Minor version 3) // Bytes 9-12: txt // Formattyp // (txt=Textdatei, // bin=Binärdatei, // tzip=komprimierte Textdatei, // bzip=kompr. Binärdatei) // Bytes 13-16:0032 // Bitbreite der verwendeten float-Variablen // (32 oder 64 Bit floats) /* // String für 1.Zeile des X-Files char XFile_Header[254]; // 1.Zeile der Datei lesen (Soll bis incl '\n' lesen!) // Lädt String ab aktueller Dateiposition bis zum newline character, // oder bis max Anzahl zu lesender Zeichen erreicht wurde. // Das Stringende enthält entweder '\0' oder '\n', falls '\n' gelesen wurde // // Get a string from a stream. // Reads a string from the input stream argument and stores it in string. // Reads characters from the current stream position to and // including the first newline character, to the end of the stream, // or until the number of characters read is equal to n - 1, whichever comes first. // The result stored in string is appended with a null character. // The newline character, if read, is included in the string. fgets( XFile_Header, // Storage location for data (String) 254, // Maximum number of characters to read m_DateiInput_3D_Objekt // Pointer to FILE structure ); // Prüfen, ob die Zeichenfolge "xof" enthalten ist // unsigned char Zaehler; Zaehler=0; // if (XFile_Header[0] == 'x') { Zaehler++; } if (XFile_Header[1] == 'o') { Zaehler++; } if (XFile_Header[2] == 'f') { Zaehler++; } // if (Zaehler == 3) { return(true); } else { return(false); } */ // EXPERIMENT // Ließt eine Dateizeile in m_akt_Datei_Zeile ein. // sollte aktuelle Dateizeile eine Leer- oder Kommentarzeile sein, // werden solange weitere Dateizeilen eingelesen, wie // Leer- oder Kommentarzeilen vorhanden sind. // // Wurden mehrere Dateizeilen gelesen, dann wird // auch die danach folgende Zeile, z.B. " 5;", // eingelesen und in m_akt_Datei_Zeile gespeichert. // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Prüfen, ob die Zeichenfolge "xof" enthalten ist /* // unsigned char Zaehler; Zaehler=0; // if (m_akt_Datei_Zeile[0] == 'x') { Zaehler++; } if (m_akt_Datei_Zeile[1] == 'o') { Zaehler++; } if (m_akt_Datei_Zeile[2] == 'f') { Zaehler++; } // if (Zaehler == 3) { return(true); } else { return(false); } */ // bool xof_gefunden; // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält (Z.B. "template ") xof_gefunden=pruefeAuf_Zeichenfolge("xof"); // return (xof_gefunden); } // Derzeitiger Stand: Überspringt Einträge des aktuellen Templates // des X-Files, damit Dateizeiger auf der Zeile nach dem Ende des // Templates gelangt void Kl_3D_Objekt::lade_Template_XFile(void) { // Beispiel Datei-Einträge: /* xof 0303txt 0032 template XSkinMeshHeader { <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> WORD nMaxSkinWeightsPerVertex; WORD nMaxSkinWeightsPerFace; WORD nBones; } template VertexDuplicationIndices { DWORD nIndices; DWORD nOriginalVertices; array DWORD indices[nIndices]; } template Mesh { <3d82ab44-62da-11cf-ab39-0020af71e433> DWORD nVertices; array Vector vertices[nVertices]; DWORD nFaces; array MeshFace faces[nFaces]; [...] } template MeshMaterialList { DWORD nMaterials; DWORD nFaceIndexes; array DWORD faceIndexes[nFaceIndexes]; [Material <3d82ab4d-62da-11cf-ab39-0020af71e433>] } */ // Die 1.Zeile des Templates wurde ja schon geladen! // Beispiel-Zeile: "template XSkinMeshHeader {" // Alle Zeilen des Templates laden, bis zum "}" (Template-Ende) do { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); }while ( strchr(m_akt_Datei_Zeile, '}') == NULL); // Dateizeiger steht nun auf der Zeile mit "}" } // Überspringt Einträge des aktuellen Templates des X-Files, // damit Dateizeiger auf der Zeile nach dem Ende des Templates gelangt void Kl_3D_Objekt::ueberspringe_Template_XFile(void) { // Funktion Wird z.B. wg. // template MeshMaterialList { // // DWORD nMaterials; // DWORD nFaceIndexes; // array DWORD faceIndexes[nFaceIndexes]; // [Material <3d82ab4d-62da-11cf-ab39-0020af71e433>] // gebraucht (wg. --> [Material <3d82ab4d-6 ...) // Alle Zeilen des Templates laden, bis zum "}" (Template-Ende) do { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); }while ( strchr(m_akt_Datei_Zeile, '}') == NULL); // Dateizeiger steht nun auf der Zeile mit "}" } // Ließt das Material & eine eventuell vorhandene // Textur & Dateinamen dafür ein. // // ACHTUNG: Im Dateinamen der Textur darf momentan kein // Leerzeichen sein! // void Kl_3D_Objekt::lade_Material_XFile(void) { /* Material PyramTextur { 0.800000;0.800000;0.800000;1.000000;; // ?Diffuse? Farbe RGBA 0.000000; // Spec. Exponent 0.000000;0.000000;0.000000;; // Specular (RGB) 0.000000;0.000000;0.000000;; // Emmisive (RGB) TextureFilename { // "Pyramiden Textur.bmp"; // } // oder Material Testmat { 0.800000;0.800000;0.800000;1.000000;; // ACHTUNG: Texturen 0.000000; // können, müßen aber 0.000000;0.000000;0.000000;; // nicht im XFile ent- 0.000000;0.000000;0.000000;; // halten sein! } // oder Material { 1.000000;1.000000;0.000000;1.000000;; 0.000000; 1.000000;1.000000;1.000000;; 0.000000;0.000000;0.000000;; TextureFilename { "Kanone.bmp"; } // oder (Blender) Material Material_Wuerfel { 0.999970; 1.000000; 1.000000; 1.000000;; 0.000000; 0.000000; 0.000000; 0.000000;; 0.000000; 0.000000; 0.000000;; TextureFilename {"Metall.PNG";} } 0, 0, 0;; Material Material_1 { 0.800000; 0.800000; 0.800000; 1.000000;; 96.078431; 0.500000; 0.500000; 0.500000;; 0.000000; 0.000000; 0.000000;; TextureFilename {"Haut.PNG";} } } // End of Mesh_Roboter material list */ // 1. Materialien laden. // Die 1.Zeile des Material-Blocks wurde ja schon geladen! // Beispiel-Zeile: " Material {" // Vorbereitungen // char Zeichen; char *Dt_String; Dt_String=NULL; Dt_String=new char[255]; // Da in X-File Materialien keine Ambiente Farbe gespeichert wird, // wird sie vorab schonmal hier gesetzt m_3D_Objekt_Material[m_Nr_akt_Mesh].Ambient.r=m_z_Kl_3D->m_Material_Ambient_Tmp.r; m_3D_Objekt_Material[m_Nr_akt_Mesh].Ambient.g=m_z_Kl_3D->m_Material_Ambient_Tmp.g; m_3D_Objekt_Material[m_Nr_akt_Mesh].Ambient.b=m_z_Kl_3D->m_Material_Ambient_Tmp.b; m_3D_Objekt_Material[m_Nr_akt_Mesh].Ambient.a=m_z_Kl_3D->m_Material_Ambient_Tmp.a; // Diffuse Farbe RGBA laden (Z.B. aus 0.800000;0.800000;0.800000;1.000000;;) // hole 4 float-Werte der aktuellen Dateizeile, // LeseNaechste_DatZeile_NEU(); int Ergebnis; // Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%s", &m_3D_Objekt_Material[m_Nr_akt_Mesh].Diffuse.r, &Zeichen, &m_3D_Objekt_Material[m_Nr_akt_Mesh].Diffuse.g, &Zeichen, &m_3D_Objekt_Material[m_Nr_akt_Mesh].Diffuse.b, &Zeichen, &m_3D_Objekt_Material[m_Nr_akt_Mesh].Diffuse.a, &Dt_String ); // Falls Probleme oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Material_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_3D_Objekt_Material[...].Diffuse...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // Spec. Exponent laden (Z.B. aus 0.000000;) LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%s", &m_3D_Objekt_Material[m_Nr_akt_Mesh].Power, &Dt_String ); // Falls Probleme oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Material_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_3D_Objekt_Material[...].Power...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_XFile_istOK=false; return; } // Specular Farbe RGB laden (Z.B. aus 0.000000;0.000000;0.000000;;) LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%s", &m_3D_Objekt_Material[m_Nr_akt_Mesh].Specular.r, &Zeichen, &m_3D_Objekt_Material[m_Nr_akt_Mesh].Specular.g, &Zeichen, &m_3D_Objekt_Material[m_Nr_akt_Mesh].Specular.b, &Dt_String ); // Falls Probleme oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Material_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_3D_Objekt_Material[...].Specular...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_XFile_istOK=false; return; } // Emissive Farbe RGB laden (Z.B. aus 0.000000;0.000000;0.000000;;) LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%s", &m_3D_Objekt_Material[m_Nr_akt_Mesh].Emissive.r, &Zeichen, &m_3D_Objekt_Material[m_Nr_akt_Mesh].Emissive.g, &Zeichen, &m_3D_Objekt_Material[m_Nr_akt_Mesh].Emissive.b, &Dt_String ); // Falls Probleme oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Material_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_3D_Objekt_Material[...].Emissive...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_XFile_istOK=false; return; } // m_akt_Datei_Zeile ist momentan " 0.000000;0.000000;0.000000;;" LeseNaechste_DatZeile_NEU(); // 2. Prüfen, ob X-File Transparenz verwendet if (m_3D_Objekt_Material[m_Nr_akt_Mesh].Diffuse.a < 1.000000f) { m_XFile_hatTransparenz=true; } // 3. Textur laden, falls Eintrag vorhanden // Dateizeiger steht nun auf der Zeile mit " TextureFilename {" // (Falls X-File einen Textureintrag enthält), // oder auf // " }" (Falls X-File KEIN Textureintrag enthält) // m_XFile_hatTextur= pruefeAuf_Zeichenfolge("TextureFilename {"); // if (m_XFile_hatTextur==true) { // ...für Dateiname der Textur char Dateiname_Textur[255]; // ...für Dateipfad incl. Dateiname der Textur char Datei_PfadUndName_Textur[255]; // bool Texturname_inSelberDatZeile; Texturname_inSelberDatZeile=false; // prüfen, ob bereits in der aktuellen Dateizeile ein Texturname vorhanden ist // (Ist z.B. bei X-Files von Blender 2.73 der Fall. Dort steht dann z.B. // " TextureFilename {"Haut.PNG";}" statt nur " TextureFilename {") char Nr; Nr=0; char Ergebnis; Ergebnis=0; // sind 2 x --> " und 1 x --> . vorhanden? while (m_akt_Datei_Zeile[Nr] != '\0') { // if (m_akt_Datei_Zeile[Nr] == '"') { Ergebnis++; } if (m_akt_Datei_Zeile[Nr] == '.') { Ergebnis++; } // Nr++; } if (Ergebnis==3) { Texturname_inSelberDatZeile=true; } // Der Texturname kann nur dann in der nächsten Dateizeile stehen, // wenn er nicht in der jetzigen Dateizeile steht // (Bei X-Files von Milkshape 3D steht er z.B. in der nächsten Dateizeile) if (Texturname_inSelberDatZeile==false) { // Zeile mit dem Dateinamen für die Textur laden LeseNaechste_DatZeile_NEU(); } // m_akt_Datei_Zeile enthält jetzt z.B. " "Kanone.bmp";" // Verwandelt z.B. m_akt_Datei_Zeile " "Kanone.bmp" in den Dateinamen "Kanone.bmp" // oder auch z.B. m_akt_Datei_Zeile " TextureFilename {"Haut.PNG";}" in den Dateinamen "Haut.PNG" // // Scheint außerdem auch für "joint1_LinksGelenk"; zu funktionieren // // Rückgabewert: Z.B. Kanone.bmp, oder z.B. Haut.PNG verwandle_inName(Dateiname_Textur); // Zeile mit der geschweiften Endklammer "}" überspringen LeseNaechste_DatZeile(); // Zeile mit der geschweiften Endklammer "}" überspringen LeseNaechste_DatZeile(); // Textur für X-File laden // INFO: m_DateiPfad_XFile enthält z.B. "3D Modelle\\Spielfeld\\" strcpy(Datei_PfadUndName_Textur, m_DateiPfad_XFile); // Textur-Dateiname an Pfad dranhängen strcat(Datei_PfadUndName_Textur, Dateiname_Textur); // INFO: Datei_PfadUndName_Textur enthält nun z.B. "3D Modelle\\Spielfeld\\Kanone.bmp" // bool Textur_laden_erfolgreich; Textur_laden_erfolgreich= m_z_Kl_2D_Bild->lade_Textur_ohneTransparenz( Datei_PfadUndName_Textur, &m_3D_Objekt_Textur[m_Nr_akt_Mesh]); // Prg-Absturz bei eventuell fehlender Texturdatei vermeiden if (Textur_laden_erfolgreich==false) { // m_z_Kl_Debug->set_Meldung( "Kl_3D_Objekt::lade_Material_XFile(...) meldet...", 5); m_z_Kl_Debug->set_Meldung( "Texturen werden nicht angezeigt, weil mind. eine fehlt.", 5); // verhindern, daß nicht geladene Textur beim Rendern gesetzt wird m_TexturAnzeigen_erlaubt=false; } // m_akt_Datei_Zeile ist momentan "" LeseNaechste_DatZeile(); } // FEHLER // delete []Dt_String; // Dt_String=NULL; } // Verwandelt z.B. m_akt_Datei_Zeile " "Kanone.bmp" in den Dateinamen "Kanone.bmp" // oder auch z.B. m_akt_Datei_Zeile " TextureFilename {"Haut.PNG";}" in den Dateinamen "Haut.PNG" // // Scheint außerdem auch für "joint1_LinksGelenk"; zu funktionieren // // Rückgabewert: Z.B. Kanone.bmp, oder z.B. Haut.PNG void Kl_3D_Objekt::verwandle_inName(char *Dateiname) { // Neue Methode (auch mit Texturnamen von Blender X-Files) // m_akt_Datei_Zeile enthält jetzt z.B. " "Kanone.bmp";" // oder " TextureFilename {"Haut.PNG";}" // unsigned char Nr; Nr=0; int Nr_Anfuehrungszeichen; Nr_Anfuehrungszeichen=0; unsigned char StartPos; StartPos=0; unsigned char EndPos; EndPos=0; // 1.) Positionen der Anführungszeichen ermitteln // solange Stringende noch nicht erreicht wurde while (m_akt_Datei_Zeile[Nr] != '\0') { // if (m_akt_Datei_Zeile[Nr] == '"') { // Nr_Anfuehrungszeichen++; // switch (Nr_Anfuehrungszeichen) { case 1: { StartPos=unsigned char (Nr+1); }break; case 2: { EndPos=unsigned char (Nr); }break; } } // Nr++; } // 2.) Text (=Dateiname) zwischen den 2 Anführungszeichen holen und speichern // Für Nr des Zeichens in Dateiname[] unsigned char Nr2; Nr2=0; // for (Nr=StartPos; Nr < EndPos; Nr++) { // Dateiname[Nr2]=m_akt_Datei_Zeile[Nr]; // Nr2++; } // Dateiname[Nr2]='\0'; /* Dateiname; StartPos; // 29 EndPos; // 38 m_akt_Datei_Zeile; char b=0; */ // Alte Methode (ohne Texturnamen von Blender X-Files) /* // m_akt_Datei_Zeile enthält jetzt z.B. " "Kanone.bmp";" // Aus z.B. " "Kanone.bmp";" das machen: "Kanone.bmp" sscanf( m_akt_Datei_Zeile, "%s", Dateiname ); // Dateiname_Textur ist jetzt z.B. ""Kanone.bmp";" // Dateiname_Textur um 2 Stellen kürzen unsigned int Stringlaenge; Stringlaenge=strlen(Dateiname); Dateiname[Stringlaenge-2]='\0'; // Dateiname_Textur ist jetzt z.B. ""Kanone.bmp" Dateiname[0]=' '; // Dateiname_Textur ist jetzt z.B. " Kanone.bmp" sscanf( Dateiname, "%s", Dateiname ); // Dateiname_Textur ist jetzt z.B. "Kanone.bmp" */ } // Verwandelt m_akt_Datei_Zeile " { Scene_Root }" oder " {Scene_Root}" // in den Frame-Referenznamen "Scene_Root" // // Rückgabewert: Z.B. Scene_Root void Kl_3D_Objekt::verwandle_inFrame_Referenzname(char *Frame_Referenzname) { // int Nr=0; int Nr2=0; // Aus " { Scene_Root }" oder " {Scene_Root}" das machen: "Scene_Root" // (Alle Zeichen einlesen usw, bis "}" erreicht wurde) do { // Nur Zeichen einlesen & zuweisen, die keine Leerzeichen oder "{" enthalten if ( (m_akt_Datei_Zeile[Nr] !='{') && (m_akt_Datei_Zeile[Nr] !=' ') ) { // Frame_Referenzname[Nr2]=m_akt_Datei_Zeile[Nr]; // Nr2++; } // Nr++; }while (m_akt_Datei_Zeile[Nr] != '}'); // Stringende setzen Frame_Referenzname[Nr2]='\0'; } // Derzeitiger Stand: // // Ließt aus dem jew. "Frame "-Block den Frame-Name // und die Startjoint-Matrix (Frame-Transformations-Matrix) // void Kl_3D_Objekt::lade_Frame_XFile(void) { // Beispiel Datei-Einträge: /* xof 0303txt 0032 template XSkinMeshHeader { <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> WORD nMaxSkinWeightsPerVertex; WORD nMaxSkinWeightsPerFace; WORD nBones; } ... Frame Scene_Root { FrameTransformMatrix { 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;; } Frame Koerper { FrameTransformMatrix { 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;; } Mesh { 71; 0.281231;0.005685;-0.000502;, 0.281231;0.284635;-0.000502;, 0.243140;0.284635;-0.142688;, ... // *** ACHTUNG: "Tiny.x" enthält z.B. einen namenlosen Frame: ... Frame { FrameTransformMatrix { 1.000000,-0.000000,-0.000000,0.000000, -0.000000,1.000000,0.000000,0.000000, -0.000000,0.000000,1.000000,0.000000, -0.142114,0.000023,-49.556850,1.000000;; } ... // Template-Infos: template Frame { < 3D82AB46-62DA-11cf-AB39-0020AF71E433 > FrameTransformMatrix frameTransformMatrix; Mesh mesh; } Description Defines a coordinate frame, or "frame of reference." The Frame template is open and can contain any object. The Direct3D extensions (D3DX) mesh-loading functions recognize Mesh, FrameTransformMatrix, and Frame template instances as child objects when loading a Frame instance. Template Name: FrameTransformMatrix UUID Member Name Type Optional Array Size Optional Data Objects frameMatrix Matrix4x4 None Description This template defines a local transform for a frame (and all its child objects). // Vom Buch (PDF) "Beginning Direct3D Game Programming" (Band 2), S.242: // // Transformation Matrices // To transform parts of an object independently from each other, you have to divide the // model into different frames. For example, a tank could turn its cannon up and down and // to the left or right. Its chains and wheels will turn when it drives through the wild enemy // terrain. Therefore, there is a frame for the hull, turret, cannon, chains, and wheels. // Every frame will hold the matrix for the specified part of the tank. // A Frame data object is expected to take the following structure: // // Frame Hull { // // FrameTransformMatrix { // 1.000000, 0.000000, 0.000000, 0.000000, // 0.000000, 1.000000, 0.000000, 0.000000, // 0.000000, -0.000000, 1.000000, 0.000000, // 206.093353, -6.400993, -31.132195, 1.000000;; // } // // Mesh Hull { // 2470; // 41.310013; -26.219450; -113.602348;, // ... */ /* // Matrix-Infos: D3DXMATRIX m_3D_Objekt_Matrix D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); // INFO: Translation (verschieben) usw ist auch Manuel möglich, // per setzen der entsprechenden Matrix-Werte. // // Matrix-Elemente für Skalierung & Translation: // // | Sx (X-Skal.) 0 0 0 | mat._11, mat._12, mat._13, mat._14 // | 0 Sy (Y-Skal.)0 0 | mat._21, mat._22, mat._23, mat._24 // | 0 0 Sz (Z-Skal.)0 | mat._31, mat._32, mat._33, mat._34 // | Tx (=Xpos) Ty (=Ypos) Tz (=Zpos) 1 | mat._41, mat._42, mat._43, mat._44 // Sx=X-Skalierung (Größenänderung). Sy, Sz=dasselbe, aber für Y & Z-Skalierung // Tx=X-Translation (Positionsänderung). Ty, Tz=dasselbe, aber für Y & Z-Translation // // (Siehe ab S. 90 im weißen Buch "Inside Microsoft DirectX 9 - Spiele-programmierung" */ // *** 1.) Name des Frames laden *** // int Ergebnis; char *Dummy; // Für den Text "Frame" char Leerz; // Fürs Leerzeichen char *FrameName; // Für Name des Frames // Dummy=NULL; FrameName=NULL; Dummy=new char [255]; FrameName=new char [255]; // Die 1.Zeile "Frame Scene_Root {" wurde ja schon geladen! // (und in m_akt_Datei_Zeile gespeichert) // Aus "Frame Scene_Root {" den Name des Frames, also "Scene_Root", holen Ergebnis=sscanf(m_akt_Datei_Zeile, "%s%c%s", Dummy, &Leerz, FrameName); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Frame_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("beim holen des Frame-Namens wegen", 5); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_Datei_Zeile...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } else { // Falls Frame keinen Namen hat (Z.B. "Frame {" statt "Frame Scene_Root {") if (FrameName[0]=='{') { strcpy(FrameName, "-"); } } // *** 2.) FrameTransformMatrix laden *** // INFO: // // Die Frametransformationsmatrix wurde von mir "Start-Joint Matrix" genannt, // weil Milkshape 3D sie beim 1. zeichnen eines Joints (Gelenks) erzeugt // (Also diese Matrix an dieser Stelle (Frame) im X-File speichert). // Dateizeiger ist bei "Frame Scene_Root {" // // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Enthält m_akt_Datei_Zeile = "FrameTransformMatrix {" ? // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält (Z.B. "template ") if (pruefeAuf_Zeichenfolge("FrameTransformMatrix {")==false) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Frame_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("Zeichenfolge FrameTransformMatrix {", 5); m_z_Kl_Debug->set_Meldung("nicht im aktuellen Frame gefunden", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // else { // *** Daten laden *** // Die 1.Zeile "FrameTransformMatrix {" wurde ja schon geladen! // Vorbereitungen // char Zeichen; char *Dt_String; Dt_String=NULL; Dt_String=new char[255]; // D3DXMATRIX Tmp_Matrix; // Matrix für Dateneinlesevorgang D3DXMatrixIdentity(&Tmp_Matrix); // 1.Zeile laden (Z.B. 1.000000, 0.000000, 0.000000, 0.000000, ) // hole 4 float-Werte der aktuellen Dateizeile, // LeseNaechste_DatZeile_NEU(); int Ergebnis; // Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%c", &Tmp_Matrix._11, &Zeichen, &Tmp_Matrix._12, &Zeichen, &Tmp_Matrix._13, &Zeichen, &Tmp_Matrix._14, &Zeichen ); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("Kl_3D_Objekt::lade_Frame_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("beim laden der 1.Matrixzeile wegen", 5); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_Datei_Zeile...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // 2.Zeile laden (Z.B. 0.000000, 1.000000, 0.000000, 0.000000, ) LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%c", &Tmp_Matrix._21, &Zeichen, &Tmp_Matrix._22, &Zeichen, &Tmp_Matrix._23, &Zeichen, &Tmp_Matrix._24, &Zeichen ); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("Kl_3D_Objekt::lade_Frame_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("beim laden der 2.Matrixzeile wegen", 5); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_Datei_Zeile...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_Animationsdaten_sindOK=false; return; } // 3.Zeile laden (Z.B. 0.000000, 0.000000, 1.000000, 0.000000, ) LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%c", &Tmp_Matrix._31, &Zeichen, &Tmp_Matrix._32, &Zeichen, &Tmp_Matrix._33, &Zeichen, &Tmp_Matrix._34, &Zeichen ); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("Kl_3D_Objekt::lade_Frame_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("beim laden der 3.Matrixzeile wegen", 5); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_Datei_Zeile...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_Animationsdaten_sindOK=false; return; } // 4.Zeile laden (Z.B. 0.000000, 0.000000, 0.000000, 1.000000;; ) LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%s", &Tmp_Matrix._41, &Zeichen, &Tmp_Matrix._42, &Zeichen, &Tmp_Matrix._43, &Zeichen, &Tmp_Matrix._44, &Dt_String ); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("Kl_3D_Objekt::lade_Frame_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("beim laden der 4.Matrixzeile wegen", 5); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_Datei_Zeile...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_Animationsdaten_sindOK=false; return; } // m_akt_Datei_Zeile ist momentan " 0.000000, 0.000000, 0.000000, 1.000000;;" // Zeile mit " }" laden LeseNaechste_DatZeile(); // Dateizeiger steht nun auf der Zeile mit " }" // *** Daten entsprechend speichern *** // Ist dies die 1.Matrix des X-Files? if (m_3D_Objekt_Matrix_gesetzt==false) { // Der erste FrameTransformMatrix-Dateiblock enthält z.B. // die Matrix für das gesammte 3D-Objekt. m_3D_Objekt_Matrix=Tmp_Matrix; // Muß jetzt true sein m_3D_Objekt_Matrix_gesetzt=true; } // Bone(s) für Animationsskelett nur dann erzeugen, wenn X-File auch Animation hat if (m_XFile_hat_Animation==true) { // Erzeugt den jeweils aktuellen Bone für das Animationsskelett (Frame-Hierarchie) // und speichert ihn incl. des Frame-Namens und der F.T.Matrix in m_str_akt_Bone. // Außerdem wird in m_str_root_Bone ein Zeiger auf den Root-Bone (=1.Bone) gespeichert. // // Parameter: 1=Name des Frames aus dem X-File // 2=Frame Transform Matrix aus dem entsprechenden X-File Frame erzeuge_Bone(FrameName, &Tmp_Matrix); } // delete [] Dummy; delete [] FrameName; }// Ende von "Enthält m_akt_Datei_Zeile = "FrameTransformMatrix {" ?" } /* // Derzeitiger Stand: // Liest Einträge des jew. "FrameTransformMatrix {"-Blocks, // und speichert sie VORERST in m_3D_Objekt_Matrix void Kl_3D_Objekt::lade_FrameTransformMatrix_XFile(void) { } */ // Ließt die Inhalte des Mesh-Blocks // (Anzahl der Vertices, alle Vertex-Daten (X,Y,Z-Pos), // Anzahl der Faces & alle Index-Daten(Für Indexbuffer) ) void Kl_3D_Objekt::lade_Mesh_XFile(void) { /* // *** INFOS *** // // ACHTUNG: 1.Zeile dieses BSPs kann nur // "Mesh {", aber auch variable Namen wie z.B. // "Mesh mesh-guard {" oder "Mesh mesh-stab {" u.v.m. enthalten! // (Festgestellt durch meine Betrachtung von 3 X-Files) xof 0303txt 0032 ... Mesh { 5; // =Anzahl der Vertices dieses Mesh 0.000000;0.000000;1.000000;, // =Vertex 0 1.000000;0.000000;1.000000;, // =Vertex 1 1.000000;0.000000;0.000000;, // =Vertex 2 0.000000;0.000000;0.000000;, // =Vertex 3 0.500000;0.500000;0.500000;; // =Vertex 4 6; // =Anzahl der Faces dieses Mesh 3;0,2,1;, // =Face 0 aus Vertices 0,2,1. 1.Zahl(3)=Anzahl 3;3,2,0;, // Vertices im Face 3;4,0,1;, // =Face 2 aus Vertices 4,0,1 3;2,3,4;, // =Face 3 aus Vertices 2,3,4 3;3,0,4;, // =Face 4 aus Vertices 3,0,4 3;1,2,4;; // =Face 5 aus Vertices 1,2,4 */ // Dateizeiger ist in Zeile " Mesh {" // *** 1. Anzahl der Vertices dieses Mesh lesen *** // (=Nächste Dateizeile " 5;" lesen.) // Dabei eventuell vorhandene Leer- oder Kommentarzeilen überspringen // Ließt eine Dateizeile in m_akt_Datei_Zeile ein. // sollte aktuelle Dateizeile eine Leer- oder Kommentarzeile sein, // werden solange weitere Dateizeilen eingelesen, wie // Leer- oder Kommentarzeilen vorhanden sind. // // Wurden mehrere Dateizeilen gelesen, dann wird // auch die danach folgende Zeile, z.B. " 5;", // eingelesen und in m_akt_Datei_Zeile gespeichert. // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Jetzt sollte aber die Dateizeile wie Z.B. " 5;" // in m_akt_Datei_Zeile enthalten sein // unsigned int Anzahl; bool Fehler; // Liest z.B. den Dateieintrag" 5;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück // // Rückgabewerte: // // false=Fehler beim lesen/Dateieinträge fehlen // *Menge: Z.B. Menge/Anzahl der Vertices, die zurückgegeben wird Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Mesh_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_Vertices_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // m_Anz_Vertices_MeshNr[m_Nr_akt_Mesh]=Anzahl; // *** 2. Nächste Dateizeilen lesen, z.B. *** // 0.000000;0.000000;1.000000;, // =Vertex 0 // 1.000000;0.000000;1.000000;, // =Vertex 1 // 1.000000;0.000000;0.000000;, // =Vertex 2 // 0.000000;0.000000;0.000000;, // =Vertex 3 // 0.500000;0.500000;0.500000;; // =Vertex 4 // Ließt alle Vertices aus dem Mesh-Block, // und speichert sie in m_3D_Objekt_Vertices. Lese_Vertices_Mesh(); // *** 3. Anzahl der Faces dieses Mesh lesen *** // (=Nächste Dateizeile " 6;" lesen.) // Dabei eventuell vorhandene Leer- oder Kommentarzeilen überspringen // Ließt eine Dateizeile in m_akt_Datei_Zeile ein. // sollte aktuelle Dateizeile eine Leer- oder Kommentarzeile sein, // werden solange weitere Dateizeilen eingelesen, wie // Leer- oder Kommentarzeilen vorhanden sind. // // Wurden mehrere Dateizeilen gelesen, dann wird // auch die danach folgende Zeile, z.B. " 5;", // eingelesen und in m_akt_Datei_Zeile gespeichert. // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Liest z.B. den Dateieintrag" 6;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Mesh_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_Faces_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // m_Anz_Faces_MeshNr[m_Nr_akt_Mesh]=Anzahl; // *** 6. Nächste Dateizeilen lesen, z.B. *** // 3;0,2,1;, // =Face 0 aus Vertices 0,2,1. 1.Zahl(3)=Anzahl // 3;3,2,0;, // Vertices im Face // 3;4,0,1;, // =Face 2 aus Vertices 4,0,1 // 3;2,3,4;, // =Face 3 aus Vertices 2,3,4 // 3;3,0,4;, // =Face 4 aus Vertices 3,0,4 // 3;1,2,4;; // =Face 5 aus Vertices 1,2,4 // Ließt alle Faces aus dem Mesh-Block, // und speichert sie in m_3D_Objekt_Indices // (Jedes Face hat je 3 Indices) Lese_Faces_Mesh(); } // Ließt die Inhalte des MeshNormals-Blocks // (Anzahl der Normalen, alle Normalenvektor-Daten (nx,ny,nz). // Der Rest des Blocks wird NICHT gelesen!) // // Wenn X-File keine Normalenvektoren hat, // dann wird laut Experiment nur ein schwarzes 3D-Objekt angezeigt. void Kl_3D_Objekt::lade_MeshNormals_XFile(void) { /* // *** Infos: *** xof 0303txt 0032 ... Mesh { 5; // =Anzahl der Vertices dieses Mesh 0.000000;0.000000;1.000000;, // =Vertex 0 1.000000;0.000000;1.000000;, // =Vertex 1 1.000000;0.000000;0.000000;, // =Vertex 2 0.000000;0.000000;0.000000;, // =Vertex 3 0.500000;0.500000;0.500000;; // =Vertex 4 6; // =Anzahl der Faces dieses Mesh 3;0,2,1;, // =Face 0 aus Vertices 0,2,1. 1.Zahl(3)=Anzahl 3;3,2,0;, // Vertices im Face 3;4,0,1;, // =Face 2 aus Vertices 4,0,1 3;2,3,4;, // =Face 3 aus Vertices 2,3,4 3;3,0,4;, // =Face 4 aus Vertices 3,0,4 3;1,2,4;; // =Face 5 aus Vertices 1,2,4 MeshNormals { 5; // 5 Normale. Eine pro Vertex 0.610132;0.505449;0.610132;, // Normale 1 -0.653282;-0.382683;0.653282;, // Normale 2 -0.610132;0.505449;-0.610132;, // usw 0.653282;-0.382683;-0.653282;, 0.000000;-1.000000;0.000000;; 6; // 6 ?Faces? mit Normalen 3;0,2,1;, // ?Oberfläche 0 verwendet Normale 0? (=Fehler im Buch???) 3;3,2,0;, 3;4,0,1;, 3;2,3,4;, 3;3,0,4;, 3;1,2,4;; } MeshTextureCoords { 5; // Anzahl der Texturkoordinaten 0.000000;0.000000;, // Texturkoordinaten für Vertex 0 (tu, tv) 1.000000;0.000000;, // Texturkoordinaten für Vertex 1 (tu, tv) 1.000000;1.000000;, // Texturkoordinaten für Vertex 2 (tu, tv) 0.000000;1.000000;, // Texturkoordinaten für Vertex 3 (tu, tv) 0.500000;0.500000;; // Texturkoordinaten für Vertex 4 (tu, tv) } */ // Dateizeiger ist in Zeile " MeshNormals {" // *** 1. Anzahl der Normalenvektoren dieses Mesh lesen *** // (=Nächste Dateizeile " 5;" lesen.) // Dabei eventuell vorhandene Leer- oder Kommentarzeilen überspringen // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Jetzt sollte aber die Dateizeile wie Z.B. " 5;" // in m_akt_Datei_Zeile enthalten sein // unsigned int Anzahl; bool Fehler; // Liest z.B. den Dateieintrag" 5;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_MeshNormals_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_NormalenVekt_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // Info: Dateizeiger ist in Zeile " 5;" // m_Anz_NormalenVekt_MeshNr[m_Nr_akt_Mesh]=Anzahl; // Nr. des ersten Vertice des aktuellen Meshes // unsigned int StartNr1te_Normale; // Muß erst 0 sein. Z.B.,falls X-File nur 1 Mesh enthält, // und die folgende For-Schleife deswegen nicht ausgeführt werden sollte StartNr1te_Normale=0; // Nr. des ersten Vertice für den aktuellen Mesh ermitteln for (unsigned short int Nr_Mesh=0; Nr_Mesh < m_Nr_akt_Mesh; Nr_Mesh++) { StartNr1te_Normale=StartNr1te_Normale + m_Anz_NormalenVekt_MeshNr[Nr_Mesh]; } // Alle Normalen einlesen // Die 3 float-Werte holen, z.B. von Dateizeile: // 0.610132;0.505449;0.610132;, // char Zeichen; unsigned int Nr_Normalen; // Nr_Normalen=StartNr1te_Normale; int Ergebnis; Fehler=false; // Die 3 float-Werte der jeweiligen Dateizeile holen // // Prüfung: -ok- for (unsigned int Nr_DateiZeile=0; Nr_DateiZeile < Anzahl; Nr_DateiZeile++) { // hole 3 float-Werte der aktuellen Dateizeile Ergebnis=fscanf( m_DateiInput_3D_Objekt, "%f%c %f%c %f%c%c", &m_3D_Objekt_Vertices[Nr_Normalen].nx, &Zeichen, &m_3D_Objekt_Vertices[Nr_Normalen].ny, &Zeichen, &m_3D_Objekt_Vertices[Nr_Normalen].nz, &Zeichen, &Zeichen ); // Falls Probleme oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } Nr_Normalen++; } // Falls Problem oder Fehler if (Fehler==true) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_MeshNormals_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("fscanf(...m_3D_Objekt_Vertices[Nr_Normalen]...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // Am 19.01.2015 eingefügt: // // Den nach den float-Werten folgenden Dateiblock überspringen, incl "}" // // (Alle weiteren Zeilen laden, bis zum "}" (Block-Ende) ) do { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); }while ( strchr(m_akt_Datei_Zeile, '}') == NULL); // Dateizeiger müßte nun auf der Zeile mit "}" stehen } // Ließt die Inhalte des MeshTextureCoords-Blocks // (Anzahl der Texturkoordinaten? und alle // Texturkoordinaten-Daten (tu, tv) ) // // Wenn X-File keine Texturkoordinaten hat, // dann wird laut Experiment keine Textur angezeigt. // Objekt ist dann trotzdem sichtbar, mit Material. void Kl_3D_Objekt::lade_MeshTextureCoords_XFile(void) { /* // *** Infos: *** xof 0303txt 0032 ... Mesh { 5; // =Anzahl der Vertices dieses Mesh 0.000000;0.000000;1.000000;, // =Vertex 0 1.000000;0.000000;1.000000;, // =Vertex 1 1.000000;0.000000;0.000000;, // =Vertex 2 0.000000;0.000000;0.000000;, // =Vertex 3 0.500000;0.500000;0.500000;; // =Vertex 4 6; // =Anzahl der Faces dieses Mesh 3;0,2,1;, // =Face 0 aus Vertices 0,2,1. 1.Zahl(3)=Anzahl 3;3,2,0;, // Vertices im Face 3;4,0,1;, // =Face 2 aus Vertices 4,0,1 3;2,3,4;, // =Face 3 aus Vertices 2,3,4 3;3,0,4;, // =Face 4 aus Vertices 3,0,4 3;1,2,4;; // =Face 5 aus Vertices 1,2,4 MeshNormals { 5; // 5 Normale. Eine pro Vertex 0.610132;0.505449;0.610132;, // Normale 1 -0.653282;-0.382683;0.653282;, // Normale 2 -0.610132;0.505449;-0.610132;, // usw 0.653282;-0.382683;-0.653282;, 0.000000;-1.000000;0.000000;; 6; // 6 ?Faces? mit Normalen 3;0,2,1;, // ?Oberfläche 0 verwendet Normale 0? (=Fehler im Buch???) 3;3,2,0;, 3;4,0,1;, 3;2,3,4;, 3;3,0,4;, 3;1,2,4;; } MeshTextureCoords { 5; // Anzahl der Texturkoordinaten 0.000000;0.000000;, // Texturkoordinaten für Vertex 0 (tu, tv) 1.000000;0.000000;, // Texturkoordinaten für Vertex 1 (tu, tv) 1.000000;1.000000;, // Texturkoordinaten für Vertex 2 (tu, tv) 0.000000;1.000000;, // Texturkoordinaten für Vertex 3 (tu, tv) 0.500000;0.500000;; // Texturkoordinaten für Vertex 4 (tu, tv) } */ // Dateizeiger ist in Zeile " MeshTextureCoords {" // *** 1. Anzahl der ?Texturkoordinaten? dieses Mesh lesen *** // (=Nächste Dateizeile " 5;" lesen.) // Dabei eventuell vorhandene Leer- oder Kommentarzeilen überspringen // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); // Jetzt sollte aber die Dateizeile wie Z.B. " 5;" // in m_akt_Datei_Zeile enthalten sein // unsigned int Anzahl; bool Fehler; // Liest z.B. den Dateieintrag" 5;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück Fehler=Lese_MengenEintrag_DatZeile(&Anzahl); if (Fehler==false) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_MeshTextureCoords_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("Lese_MengenEintrag_DatZeile(...)...)", 5); m_z_Kl_Debug->set_Meldung("(m_Anz_Vertices_MeshNr[])", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } // Dateizeiger ist in Zeile " 5;" // Nr. der ersten Texturkoordinate des aktuellen Meshes // unsigned int StartNr1te_Texturkoordinate; // Muß erst 0 sein. Z.B.,falls X-File nur 1 Mesh enthält, // und die folgende For-Schleife deswegen nicht ausgeführt werden sollte StartNr1te_Texturkoordinate=0; // Nr. der ersten Texturkoordinate für den aktuellen Mesh ermitteln for (unsigned short int Nr_Mesh=0; Nr_Mesh < m_Nr_akt_Mesh; Nr_Mesh++) { StartNr1te_Texturkoordinate=StartNr1te_Texturkoordinate + m_Anz_Texturkoordin_MeshNr[Nr_Mesh]; } // char Zeichen; unsigned int Nr_Texturkoordinate; // Nr_Texturkoordinate=StartNr1te_Texturkoordinate; int Ergebnis; Fehler=false; // Die 2 float-Werte der jeweiligen Dateizeile holen, // z.B. von Dateizeile: // 0.000000;0.000000;, // // Prüfung: -ok- for (unsigned int Nr_DateiZeile=0; Nr_DateiZeile < Anzahl; Nr_DateiZeile++) { // hole 2 float-Werte der aktuellen Dateizeile Ergebnis=fscanf( m_DateiInput_3D_Objekt, "%f%c %f%c%c", &m_3D_Objekt_Vertices[Nr_Texturkoordinate].tu, &Zeichen, &m_3D_Objekt_Vertices[Nr_Texturkoordinate].tv, &Zeichen, &Zeichen ); // Nr_Texturkoordinate++; // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } } // Falls Problem oder Fehler if (Fehler==true) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_MeshTextureCoords_XFile(...)", 6); m_z_Kl_Debug->set_Meldung("fscanf(...m_3D_Objekt_Vertices[Nr_Texturkoordinate]...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; return; } LeseNaechste_DatZeile(); // Zeile mit der geschweiften Endklammer "}" überspringen LeseNaechste_DatZeile(); } // void Kl_3D_Objekt::lade_VertexDuplicationIndices(void) { /* // *** Infos: *** xof 0303txt 0032 ... VertexDuplicationIndices { 306; // 282; 0, 1, 2, 3, 4, ... 175, 165, 171, 173, 277, 271; } */ // Die 1.Zeile dieses Dateiblocks wurde ja schon geladen! // Beispiel-Zeile: "VertexDuplicationIndices {" // Alle Zeilen des Dateiblocks laden, bis zum "}" (Dateiblock-Ende) do { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); }while ( strchr(m_akt_Datei_Zeile, '}') == NULL); } // void Kl_3D_Objekt::lade_MeshMaterialList(void) { /* // *** Infos: *** xof 0303txt 0032 ... MeshMaterialList { 1; // Anzahl der genutzten Materialien 6; // Jedes Face erhält 1 Material 0, // Materialien an Faces zuweisen 0, 0, 0, 0, 0; Material PyramTextur { 0.800000;0.800000;0.800000;1.000000;; 0.000000; 0.000000;0.000000;0.000000;; 0.000000;0.000000;0.000000;; TextureFilename { "Pyramiden Textur.bmp"; } } // oder MeshMaterialList { 5; 26; 0, 0, 0, ... 0, 1, ... 1, 2, ... 3, . ... 4;; { Material0 } // Referenzen zu den Materialien { Material1 } { Material2 } { Material3 } { Material4 } } */ } // sieht im XFile nach, // wie viel vom folgenden enthalten ist: // -Anzahl der Meshes mit Bones (Joints) // -Anzahl der AnimationKey-Dateiblöcke // -Anzahl der Joints/Gelenke des 3D-Objekts // // Ergebnisse werden in // m_anz_MeshesMitJoints // m_anz_AnimationKeys und // m_anz_Joints // gespeichert void Kl_3D_Objekt::analysiere_XFile_Animationsdaten(void) { // erstmal 0 m_anz_MeshesMitJoints=0; m_anz_AnimationKeys=0; m_anz_Joints=0; // Lese solange aus der Datei, // bis das Dateiende erreicht wurde while (feof(m_DateiInput_3D_Objekt) == NULL) { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); // Ist Dateizeile eine... // ..."template "-Zeile? // // z.B. wg. "Material <" (Ist in template MeshMaterialList {) if (pruefeAuf_Zeichenfolge("template ") == true) { // Überspringt Einträge des aktuellen Templates des X-Files, // damit Dateizeiger auf der Zeile nach dem Ende des Templates gelangt ueberspringe_Template_XFile(); } else { // ..."XSkinMeshHeader {" oder "template XSkinMeshHeader" -Zeile? if (pruefeAuf_Zeichenfolge("XSkinMeshHeader {") == true) // Prüfung=-- { // ACHTUNG: der Eintrag "template XSkinMeshHeader" enthält auch "XSkinMeshHeader {"! if (pruefeAuf_Zeichenfolge("template XSkinMeshHeader")==true) { ueberspringe_Template_XFile(); } // Es wurde ein XSkinMeshHeader-Eintrag gefunden. Deswegen... else { // Ließt Anzahl der Bones aus dem XSkinMeshHeader-Block ein. unsigned short int anz_Bones_Mesh; anz_Bones_Mesh=lade_Anz_Bones_anim_XSkinMeshHeader(); // Wenn aktueller Mesh Bones enthält... if (anz_Bones_Mesh > 0) { // ...um 1 erhöhen und m_anz_MeshesMitJoints++; } } } // ..."AnimationKey" oder "template AnimationKey" -Zeile? if (pruefeAuf_Zeichenfolge("AnimationKey") == true) // Prüfung=-- { // ACHTUNG: der Eintrag "template AnimationKey" enthält auch "AnimationKey"! if (pruefeAuf_Zeichenfolge("template AnimationKey")==true) { ueberspringe_Template_XFile(); } // Es wurde ein AnimationKey-Eintrag gefunden. Deswegen... else { // m_anz_AnimationKeys++; } } // ..."SkinWeights {" oder "template SkinWeights {"-Zeile? if (pruefeAuf_Zeichenfolge("SkinWeights {")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("template SkinWeights {")==true) { m_Art_aktDatZeile=inDz_Template; } else { // m_anz_Joints++; } } } } } // Ließt Anzahl der Bones aus dem XSkinMeshHeader-Block ein // // Rückgabewert: Anzahl Bones oder 0 bei Problemen unsigned short int Kl_3D_Objekt::lade_Anz_Bones_anim_XSkinMeshHeader(void) { // Info: Folgendes wird insgesammt eingelesen: // // XSkinMeshHeader { // 1; // max Anzahl von Transforms, die ein Vertex im Mesh beeinflussen // 3; // max Anzahl von einzelnen/besonderen Transforms, // // die 3 Vertices jedes Faces beeinflussen // 0; // Anzahl der Bones, die Vertices in diesem Mesh beeinflussen // } // Funktion nur ausführen, wenn erlaubt // (Um Programmabstürze bei X-File Problemen zu vermeiden, // und eventuelle Prg-Meldungen trotzdem lesen zu können) if (m_Animationsdaten_sindOK==false) { return (0); } // Info: Dateizeiger ist in Zeile "XSkinMeshHeader {" // lese 3 Zeilen mit je 1 int-Wert ein // Z.B.: 1; // 3; // 2; // char Zeichen; unsigned short int Dummy_1; unsigned short int Dummy_2; unsigned short int Anz_Bones; int Ergebnis; // 0, falls Werte nicht geladen werden Zeichen='0'; Dummy_1=0; Dummy_2=0; Anz_Bones=0; Ergebnis=0; // LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Dummy_1, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Anz_Bones_anim_XSkinMeshHeader(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Dummy_1...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return (0); } // LeseNaechste_DatZeile_NEU(); // Nicht ausführen, falls es zuvor Probleme gab. // Grund: Um Prg-Absturz zu vermeiden. if (m_Animationsdaten_sindOK==true) { Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Dummy_2, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Anz_Bones_anim_XSkinMeshHeader(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Dummy_2...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return (0); } } // Anzahl der Bones/Knochen des aktuellen Meshes speichern LeseNaechste_DatZeile_NEU(); if (m_Animationsdaten_sindOK==true) { Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Anz_Bones, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_Anz_Bones_anim_XSkinMeshHeader(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Anz_Bones...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return (0); } } // Zeile mit "}" lesen LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile "}" // return (Anz_Bones); } // sieht im XFile nach, // -ob X-File Matrix Keys (oder SRT Keys) nutzt // -Wie hoch die höchste Anzahl der Matrix Keys eines AnimationKey Dateiblocks ist // // Ergebnisse werden in // m_XFile_nutzt_MatrixKeys und // m_max_anz_Mtr_Keys // gespeichert void Kl_3D_Objekt::analysiere_XFile_Animationsdaten2(void) { // Für "SkinWeights {" unsigned short int akt_Bone_Nr; // Nr des aktiven AnimationKey X-File Dateiblocks unsigned short int akt_AnimKey_Nr; int Ergebnis; // erstmal 0 akt_Bone_Nr=0; akt_AnimKey_Nr=0; m_max_anz_Mtr_Keys=0; Ergebnis=0; // m_XFile_nutzt_MatrixKeys=false; // Lese solange aus der Datei, // bis das Dateiende erreicht wurde while (feof(m_DateiInput_3D_Objekt) == NULL) { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); // Ist Dateizeile eine... // ..."template "-Zeile? // // z.B. wg. "Material <" (Ist in template MeshMaterialList {) if (pruefeAuf_Zeichenfolge("template ") == true) { // Überspringt Einträge des aktuellen Templates des X-Files, // damit Dateizeiger auf der Zeile nach dem Ende des Templates gelangt ueberspringe_Template_XFile(); } else { // ..."SkinWeights {" oder "template SkinWeights {" -Zeile? if (pruefeAuf_Zeichenfolge("SkinWeights {") == true) // Prüfung=-- { // ACHTUNG: der Eintrag "template SkinWeights {" enthält auch "SkinWeights {"! if (pruefeAuf_Zeichenfolge("template SkinWeights {")==true) { ueberspringe_Template_XFile(); } // Es wurde ein SkinWeights-Eintrag gefunden. Deswegen... else { // ** Wert einlesen ** // Info: Dateizeiger ist in Zeile " SkinWeights {" // Dateizeile mit Namen des Bones überspringen (Z.B.: "joint1_LinksGelenk";) LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " "joint1_LinksGelenk";" // char Zeichen; unsigned long int anz_Vertices_Bone; // 0, falls Werte nicht geladen werden Zeichen='0'; anz_Vertices_Bone=0; // Vertice Anzahl einlesen, z.B. // "12;" LeseNaechste_DatZeile(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &anz_Vertices_Bone, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::analysiere_XFile_Animationsdaten2(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...anz_Vertices_Bone...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } else { // Kann jetzt um 1 erhöht werden akt_Bone_Nr++; } // Restliche Dateieinträge können erstmal ignoriert werden } } // ..."AnimationKey" oder "template AnimationKey" -Zeile? if (pruefeAuf_Zeichenfolge("AnimationKey") == true) // Prüfung=-- { // ACHTUNG: der Eintrag "template AnimationKey" enthält auch "AnimationKey"! if (pruefeAuf_Zeichenfolge("template AnimationKey")==true) { ueberspringe_Template_XFile(); } // Es wurde ein AnimationKey-Eintrag gefunden. Deswegen... else { // Info: Folgendes wird insgesammt eingelesen: // // AnimationKey { // 4; // 4=Matrix-Keys // 10; // 10=10 Keys // // Unten folgen 10 Keys // 0;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.019833,-0.016415,0.100000,1.000000;;, // 33;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000242,0.430010,0.100000,1.000000;;, // 66;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.019360,0.876666,0.100000,1.000000;;, // 100;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.038968,1.323488,0.100000,1.000000;;, // 133;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.058581,1.770409,0.100000,1.000000;;, // 166;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.077851,2.209522,0.100000,1.000000;;, // 200;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.097464,2.656443,0.100000,1.000000;;, // 233;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.117072,3.103265,0.100000,1.000000;;, // 266;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.136673,3.549921,0.100000,1.000000;;, // 300;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.156265,3.996346,0.100000,1.000000;;; // } // { Wuerfel1 } // /* // Info: Dateizeiger ist in Zeile " AnimationKey" // Zeile mit " {" überspringen LeseNaechste_DatZeile(); */ // Info: Dateizeiger ist in Zeile " AnimationKey" oder " AnimationKey {" // Bis zur nächsten Startklammer "{" lesen // Falls m_akt_Datei_Zeile keine Endklammer "}" enthält, // werden weitere Zeile(n) bis incl. der nächsten Endklammer in m_akt_Datei_Zeile eingelesen. Lese_bis_StartKlammer(); // char Zeichen; unsigned short int Art_Keys; unsigned short int anz_Mtr_Keys; // 0, falls Werte nicht geladen werden Zeichen='0'; Art_Keys=0; anz_Mtr_Keys=0; m_max_anz_Mtr_Keys=0; // lese 2 Zeilen mit je 1 int-Wert ein // Z.B.: 4; // 10; // LeseNaechste_DatZeile(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Art_Keys, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::analysiere_XFile_Animationsdaten2(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Art_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // if (Art_Keys==4) { m_XFile_nutzt_MatrixKeys=true; } // LeseNaechste_DatZeile(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &anz_Mtr_Keys, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::analysiere_XFile_Animationsdaten2(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_anz_Mtr_Keys[akt_AnimKey_Nr]...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } else { // Kann jetzt um 1 erhöht werden akt_AnimKey_Nr++; // Höchste Anzahl Matrix Keys ermitteln // (Beispiel Roboterarm: Der 1.AnimationKey Eintrag im X-File hat z.B. nur // 2 Matrix-Keys, aber AnimationKey Eintrag 2-4 haben je 8) if (m_max_anz_Mtr_Keys < anz_Mtr_Keys) { m_max_anz_Mtr_Keys=anz_Mtr_Keys; } } // Info: Dateizeiger ist in Zeile "10;" } } } } } // Ließt die Inhalte des XSkinMeshHeader-Blocks ein, // und speichert aktuell nur den 3.Eintrag des Blocks // in "m_Anz_Bones_MeshNr[m_Nr_akt_Mesh]" void Kl_3D_Objekt::lade_anim_XSkinMeshHeader(void) { /* // *** Template "XSkinMeshHeader" Infos: *** ...XSkinMeshHeader sagt, wie viele Bones/Knochen wir ?in diesem Mesh? finden können. This template is instantiated on a per-mesh basis only in meshes that contain exported skinning information. The purpose of this template is to provide information about the nature of the skinning information that was exported. template XSkinMeshHeader { < 3CF169CE-FF7C-44ab-93C0-F78F62D172E2 > WORD nMaxSkinWeightsPerVertex; WORD nMaxSkinWeightsPerFace; WORD nBones; } Where: nMaxSkinWeightsPerVertex - Maximum number of transforms that affect a vertex in the mesh. nMaxSkinWeightsPerFace - Maximum number of unique transforms that affect the three vertices of any face. nBones - Number of bones that affect vertices in this mesh. // *** X-File Infos: *** ... Frame Unterteil { ... MeshMaterialList { 1; 12; ... 0, 0; Material MatEisen { 0.800000;0.800000;0.800000;1.000000;; 0.000000; 0.000000;0.000000;0.000000;; 0.000000;0.000000;0.000000;; TextureFilename { "Eisen.bmp"; } } } XSkinMeshHeader { 1; // max Anzahl von Transforms, die ein Vertex im Mesh beeinflussen 3; // max Anzahl von einzelnen/besonderen Transforms, die 3 Vertices jedes Faces beeinflussen 0; // Anzahl der Bones, die Vertices in diesem Mesh beeinflussen } ... Frame Oberteil { ... Material MatEisen { 0.800000;0.800000;0.800000;1.000000;; 0.000000; 0.000000;0.000000;0.000000;; 0.000000;0.000000;0.000000;; TextureFilename { "Eisen.bmp"; } } } XSkinMeshHeader { 1; 3; 2; } SkinWeights { "joint1OberseiteLinks"; 12; ... */ // Info: Folgendes wird insgesammt eingelesen: /* XSkinMeshHeader { 1; // max Anzahl von Transforms, die ein Vertex im Mesh beeinflussen 3; // max Anzahl von einzelnen/besonderen Transforms, // die 3 Vertices jedes Faces beeinflussen 0; // Anzahl der Bones, die Vertices in diesem Mesh beeinflussen } */ // Info: Dateizeiger ist in Zeile "XSkinMeshHeader {" // lese 3 Zeilen mit je 1 int-Wert ein // Z.B.: 1; // 3; // 2; // char Zeichen; unsigned short int VertexBeeinfl_AnzTransforms; unsigned short int FaceVerticesBeeinfl_AnzTransf; unsigned short int Anz_Bones; int Ergebnis; // 0, falls Werte nicht geladen werden Zeichen='0'; VertexBeeinfl_AnzTransforms=0; FaceVerticesBeeinfl_AnzTransf=0; Anz_Bones=0; Ergebnis=0; // // LeseNaechste_DatZeile(); // Ließt eine Dateizeile in m_akt_Datei_Zeile ein. // sollte aktuelle Dateizeile eine Leer- oder Kommentarzeile sein, // werden solange weitere Dateizeilen eingelesen, wie // Leer- oder Kommentarzeilen vorhanden sind. // // Wurden mehrere Dateizeilen gelesen, dann wird // auch die danach folgende Zeile, z.B. " 5;", // eingelesen und in m_akt_Datei_Zeile gespeichert. // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &VertexBeeinfl_AnzTransforms, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_XSkinMeshHeader(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...VertexBeeinfl_AnzTransforms...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &FaceVerticesBeeinfl_AnzTransf, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_XSkinMeshHeader(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...FaceVerticesBeeinfl_AnzTransf...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // Anzahl der Bones/Knochen des aktuellen Meshes speichern LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Anz_Bones, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_XSkinMeshHeader(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Anz_Bones...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // Zeile mit "}" lesen LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile "}" } // Speichert Daten in m_anz_Vertices_Bone, m_vBoneBeeinfltrIndice[], // m_BoneWeight[], und in m_BoneSpace_Matrix. void Kl_3D_Objekt::lade_anim_SkinWeights(void) { /* // *** Template "SkinWeights" Infos: *** This template is instantiated on a per-mesh basis. Within a mesh, a sequence of n instances of this template will appear, where n is the number of bones (X file frames) that influence the vertices in the mesh. Each instance of the template basically defines the influence of a particular bone on the mesh. There is a list of vertex indices, and a corresponding list of weights. template SkinWeights { < 6F0D123B-BAD2-4167-A0D0-80224F25FABB > STRING transformNodeName; DWORD nWeights; array DWORD vertexIndices[nWeights]; array float weights[nWeights]; Matrix4x4 matrixOffset; } // *** X-File Infos: *** ... XSkinMeshHeader { 1; 3; 2; } SkinWeights { "joint1OberseiteLinks"; // The name of the bone whose influence (Bone=?Knochen?) 12; // number of vertices affected by this bone 2, // The vertices influenced by this bone are contained 3, // here (=in vertexIndices). 4, // 5, 6, 7, 8, 9, 17, 19, 21, 23; 1.000000, // the weights for each of the vertices influenced by 1.000000, // this bone are contained here (=in weights) 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; 0.000066, -0.001264, 0.999999, 0.000000, // The matrix matrixOffset 0.000000, -0.999999, -0.001264, 0.000000, // transforms the mesh vertices to the 1.000000, 0.000000, -0.000066, 0.000000, // space of the bone. -0.000047, 0.297482, -0.715358, 1.000000;; } SkinWeights { "joint2OberseiteRechts"; 12; 0, 1, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22; 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; 0.000066, -0.001264, 0.999999, 0.000000, 0.000000, -0.999999, -0.001264, 0.000000, 1.000000, 0.000000, -0.000066, 0.000000, -0.000047, 0.297482, 0.602505, 1.000000;; } */ // Info: Folgendes wird insgesammt eingelesen: /* SkinWeights { "joint1_LinksGelenk"; 12; 2, 3, 4, 5, 6, 7, 8, 9, 17, 19, 21, 23; 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; 0.000033, 0.000346, 1.000000, 0.000000, 0.000000, -1.000000, 0.000346, 0.000000, 1.000000, -0.000000, -0.000033, 0.000000, 0.014937, 0.119100, -0.604162, 1.000000;; } */ // Info: Dateizeiger ist in Zeile " SkinWeights {" // *** 1.) Namen des Bones laden (Z.B.: "joint1_LinksGelenk"; ) *** LeseNaechste_DatZeile_NEU(); // Info: Dateizeiger ist in Zeile " "joint1_LinksGelenk";" // Aus z.B. "joint1_LinksGelenk"; das machen: joint1_LinksGelenk char *Name_SkinWeight; Name_SkinWeight=new char[255]; verwandle_inName(Name_SkinWeight); // Falls der 1. SkinWeight-Block geladen wird, Verbindungs-Bones resetten if (m_1tenSkinWeight_geladen==false) { // Verbindungs-Bones resetten, damit die gesammte Bonehierarchie // wieder von vorne durchsucht werden kann. // Ohne Reset ist erneutes Durchsuchen NICHT möglich! // (Die Child-Ebene aller Verbindungsbones wieder auf 0 setzen) Reset_Verbindungs_Bones(); // muß jetzt true sein m_1tenSkinWeight_geladen=true; } // Den zum SkinWeight-Namen passenden Bone ermitteln str_Bones *Gefundener_Bone; // Durchsucht die Bonehierarchie nach den gesuchten Bone // // Parameter: 1.=Name des gesuchten Bones // Rückgabewert: Entweder Adresse des gefundenen Bones, // oder NULL, wenn Bone nicht gefunden wurde Gefundener_Bone=suche_Bone(Name_SkinWeight); // Zuvor Speicher wieder freigeben delete [] Name_SkinWeight; Name_SkinWeight=NULL; if (Gefundener_Bone == NULL) { // Wegen Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } else { m_str_akt_Bone=Gefundener_Bone; } // char Zeichen; int Ergebnis; // 0, falls Werte nicht geladen werden Zeichen='0'; Ergebnis=0; // *** 2.) Vertice Anzahl einlesen (Z.B.: 12) *** // 2.) Vertice Anzahl einlesen, z.B. // "12;" LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &m_str_akt_Bone->anz_Vertices, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_SkinWeights(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...&m_str_akt_Bone->anz_Vertices...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // Die folgende leere Dateizeile überspringen // LeseNaechste_DatZeile(); bool Fehler; // *** 3.) Alle Indices einlesen *** // Nur ausführen, falls erlaubt if (m_Animationsdaten_sindOK==true) { // erstmal false Fehler=false; // Zuerst den Speicher bereitstellen m_str_akt_Bone->vBoneBeeinfltrIndice=new unsigned long int [m_str_akt_Bone->anz_Vertices]; for (unsigned long int aktNr=0; aktNr < m_str_akt_Bone->anz_Vertices; aktNr++) { LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &m_str_akt_Bone->vBoneBeeinfltrIndice[aktNr], &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; break; // break=hier wird mit break die Schleife verlassen } } if (Fehler==true) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_SkinWeights(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...&m_str_akt_Bone->vBoneBeeinfltrIndice[aktNr]...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } } // Info: Dateizeiger ist in Zeile " 23;" // Die folgende leere Dateizeile überspringen // LeseNaechste_DatZeile(); // *** 4.) Alle Weights einlesen *** if (m_Animationsdaten_sindOK==true) { Fehler=false; // Zuerst den Speicher bereitstellen m_str_akt_Bone->BoneWeight=new float [m_str_akt_Bone->anz_Vertices]; for (unsigned long int aktNr=0; aktNranz_Vertices; aktNr++) { LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%f%c", &m_str_akt_Bone->BoneWeight[aktNr], &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; break; } } if (Fehler==true) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_SkinWeights(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...&m_str_akt_Bone->BoneWeight[aktNr]...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } } // Info: Dateizeiger ist in Zeile " 1.000900;" (12.Weight) // 5.) Matrix einlesen if (m_Animationsdaten_sindOK==true) { Fehler=false; // hole je 4 float-Werte der aktuellen Dateizeile, // (Z.B. aus 0.000033, 0.000346, 1.000000, 0.000000,) LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%c", &m_str_akt_Bone->Offset_Matrix._11, &Zeichen, &m_str_akt_Bone->Offset_Matrix._12, &Zeichen, &m_str_akt_Bone->Offset_Matrix._13, &Zeichen, &m_str_akt_Bone->Offset_Matrix._14, &Zeichen ); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } if (Fehler==false) { LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%c", &m_str_akt_Bone->Offset_Matrix._21, &Zeichen, &m_str_akt_Bone->Offset_Matrix._22, &Zeichen, &m_str_akt_Bone->Offset_Matrix._23, &Zeichen, &m_str_akt_Bone->Offset_Matrix._24, &Zeichen ); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } } if (Fehler==false) { LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%c", &m_str_akt_Bone->Offset_Matrix._31, &Zeichen, &m_str_akt_Bone->Offset_Matrix._32, &Zeichen, &m_str_akt_Bone->Offset_Matrix._33, &Zeichen, &m_str_akt_Bone->Offset_Matrix._34, &Zeichen ); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } } if (Fehler==false) { LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf( m_akt_Datei_Zeile, "%f%c %f%c %f%c %f%c", &m_str_akt_Bone->Offset_Matrix._41, &Zeichen, &m_str_akt_Bone->Offset_Matrix._42, &Zeichen, &m_str_akt_Bone->Offset_Matrix._43, &Zeichen, &m_str_akt_Bone->Offset_Matrix._44, &Zeichen ); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } } if (Fehler==true) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_SkinWeights(...)", 6); m_z_Kl_Debug->set_Meldung("zwischen sscanf(...m_BoneSpace_Matrix[Nr]._11...)", 5); m_z_Kl_Debug->set_Meldung("und sscanf(...m_BoneSpace_Matrix[Nr]._44...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } } // Info: Dateizeiger ist in Zeile // " 0.014937, 0.119100, -0.604162, 1.000000;;" (4.Matrix-Zeile) LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " }" } // Lädt momentan nur den "AnimationSet"-Eintrag, // und die darunter folgende "}" ein void Kl_3D_Objekt::lade_anim_AnimationSet(void) { /* // *** Template "AnimationSet" Infos: *** Contains one or more Animation objects. Each animation within an animation set has the same time at any given point. Increasing the animation set's time increases the time for all the animations it contains. template AnimationSet { < 3D82AB50-62DA-11cf-AB39-0020AF71E433 > [ Animation ] } Where: [ Animation ] - Optional animation template. // *** X-File Infos: *** ... AnimationSet AnimationSet0 // { Animation // { AnimationKey { 4; 2; 0; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;;, 2; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;;; } { Scene_Root } } Animation joint1OberseiteLinksAnimation { AnimationKey { 4; 1; 0; 16; 0.000066, 0.000000, 1.000000, 0.000000, -0.001264, -0.999999, 0.000000, 0.000000, 0.999999, -0.001264, -0.000066, 0.000000, 0.715733, 0.296578, 0.000000, 1.000000;;; } AnimationOptions { 0; 0; } { joint1OberseiteLinks } } Animation joint2OberseiteRechtsAnimation { AnimationKey { 4; 3; 0; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, -1.317863, 1.000000;;, 1; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, -0.252252, -1.318182, 1.000000;;, 2; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000001, -0.612635, -1.300620, 1.000000;;; } AnimationOptions { 0; 0; } { joint2OberseiteRechts } } } */ /* // Achtung: Bei Tiny.x folgt die Klammer "}" nicht UNTER, sondern HINTER AnimationKey... AnimationKey { 4; 3; ... } */ // NICHT vergessen, einzubauen: /* Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Art_Keys, &Zeichen); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // false, weil Probleme beim laden m_Animationsdaten_sindOK=false; // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Art_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); } */ // Info: Folgendes wird insgesammt eingelesen: /* AnimationSet AnimationSet0 { */ // Info: Dateizeiger ist in Zeile "AnimationSet AnimationSet0" /* // Zeile mit " {" überspringen Ueberspr_LeereOderKommentar_Zeile(); // Info: Dateizeiger ist in Zeile "{" */ // Falls m_akt_Datei_Zeile keine Endklammer "}" enthält, // werden weitere Zeile(n) bis incl. der nächsten Endklammer in m_akt_Datei_Zeile eingelesen. Lese_bis_StartKlammer(); } // Liest alle Matrix-Keys aus einen AnimationKey-Dateiblock void Kl_3D_Objekt::lade_anim_AnimationKey_4(void) { //Beep(900,900); //if (m_akt_AnimKey_Nr==0) {Beep(900,900); } /* // *** Template "AnimationKey" Infos: *** Defines a set of animation keys. A matrix key is useful for sets of animation data that need to be represented as transformation matrices. template AnimationKey { < 10DD46A8-775B-11cf-8F52-0040333594A3 > DWORD keyType; DWORD nKeys; DWORD keys; } Where: keyType - Specifies whether the keys are rotation, scale position, or matrix keys (using the integers 0, 1, 2, or 3 respectively). nKeys - Number of keys. keys - See TimedFloatKeys. // *** X-File Infos: *** ... AnimationSet AnimationSet0 { Animation { AnimationKey { 4; // Position keys? 2; // 2 Keys 0; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;;, // 2; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;;; // } { Scene_Root } } Animation joint1OberseiteLinksAnimation { AnimationKey { 4; 1; 0; 16; 0.000066, 0.000000, 1.000000, 0.000000, -0.001264, -0.999999, 0.000000, 0.000000, 0.999999, -0.001264, -0.000066, 0.000000, 0.715733, 0.296578, 0.000000, 1.000000;;; } AnimationOptions { 0; 0; } { joint1OberseiteLinks } } Animation joint2OberseiteRechtsAnimation { AnimationKey { 4; 3; // 3 Keys 0; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, -1.317863, 1.000000;;, 1; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, -0.252252, -1.318182, 1.000000;;, 2; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000001, -0.612635, -1.300620, 1.000000;;; } AnimationOptions { 0; 0; } { joint2OberseiteRechts } } } */ /* // Achtung: Bei Tiny.x folgt die Klammer "}" nicht UNTER, sondern HINTER AnimationKey... AnimationKey { 4; 3; ... } */ // Info: Folgendes wird insgesammt eingelesen: /* AnimationKey { 4; // 4=Matrix-Keys 10; // 10=10 Keys // Unten folgen 10 Keys 0;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.019833,-0.016415,0.100000,1.000000;;, 33;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000242,0.430010,0.100000,1.000000;;, 66;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.019360,0.876666,0.100000,1.000000;;, 100;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.038968,1.323488,0.100000,1.000000;;, 133;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.058581,1.770409,0.100000,1.000000;;, 166;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.077851,2.209522,0.100000,1.000000;;, 200;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.097464,2.656443,0.100000,1.000000;;, 233;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.117072,3.103265,0.100000,1.000000;;, 266;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.136673,3.549921,0.100000,1.000000;;, 300;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,-0.156265,3.996346,0.100000,1.000000;;; } */ // Info: Dateizeiger ist in Zeile " AnimationKey" /* // Zeile mit " {" überspringen Ueberspr_LeereOderKommentar_Zeile(); */ // Bis zur nächsten Startklammer "{" lesen // Falls m_akt_Datei_Zeile keine Endklammer "}" enthält, // werden weitere Zeile(n) bis incl. der nächsten Endklammer in m_akt_Datei_Zeile eingelesen. Lese_bis_StartKlammer(); /* m_akt_Datei_Zeile; char b=0; */ // char Zeichen; unsigned short int Art_Keys; int Ergebnis; // 0, falls Werte nicht geladen werden Zeichen='0'; Art_Keys=0; m_akt_anz_Mtr_Keys=0; // lese 2 Zeilen mit je 1 int-Wert ein // Z.B.: 4; // 10; // 1.Dateizeile lesen // Ließt eine Dateizeile in m_akt_Datei_Zeile ein. // sollte aktuelle Dateizeile eine Leer- oder Kommentarzeile sein, // werden solange weitere Dateizeilen eingelesen, wie // Leer- oder Kommentarzeilen vorhanden sind. // // Wurden mehrere Dateizeilen gelesen, dann wird // auch die danach folgende Zeile, z.B. " 5;", // eingelesen und in m_akt_Datei_Zeile gespeichert. // Ueberspr_LeereOderKommentar_Zeile(); LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Art_Keys, &Zeichen); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Art_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // 2.Dateizeile lesen LeseNaechste_DatZeile_NEU(); // Wurde bereits hier schon eingelesen: // "void Kl_3D_Objekt::analysiere_XFile_Animationsdaten2(void)" // sscanf(m_akt_Datei_Zeile, "%i%c", &m_anz_Mtr_Keys[m_akt_AnimKey_Nr], &Zeichen); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &m_akt_anz_Mtr_Keys, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_anz_Mtr_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // Info: Dateizeiger ist in Zeile "10;" // Entweder Rotation-, Scale-, Position- oder Matrixkeys laden lade_anim_Matrix_Keys(); // Info: Dateizeiger ist in Zeile "300;16;0.500000,0.000000,0.000000,0.000000,..." // (=In der letzten Zahlenreihe) // if (m_Animationsdaten_sindOK==false) { // Wegen Lade-Probleme Funktion sofort beenden return; } // Zeile mit " }" lesen LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " }" } // Liest alle Rotation-Keys aus einen AnimationKey-Dateiblock void Kl_3D_Objekt::lade_anim_AnimationKey_0(void) { /* // *** Template "AnimationKey" Infos: *** Defines a set of animation keys. A matrix key is useful for sets of animation data that need to be represented as transformation matrices. template AnimationKey { < 10DD46A8-775B-11cf-8F52-0040333594A3 > DWORD keyType; DWORD nKeys; DWORD keys; } Where: keyType - Specifies whether the keys are rotation, scale position, or matrix keys (using the integers 0, 1, 2, or 3 respectively). nKeys - Number of keys. keys - See TimedFloatKeys. // *** X-File Infos: *** ... AnimationSet Global { Animation { {Armature} AnimationKey { // Rotation 0; 5; 0;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 1;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 2;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 3;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 4;4;-0.709744,-0.704459,-0.000000, 0.000000;;; } AnimationKey { // Scale 1; 5; 0;3; 1.000000, 1.000000, 1.000000;;, 1;3; 1.000000, 1.000000, 1.000000;;, 2;3; 1.000000, 1.000000, 1.000000;;, 3;3; 1.000000, 1.000000, 1.000000;;, 4;3; 1.000000, 1.000000, 1.000000;;; } AnimationKey { // Position 2; 5; 0;3;-0.033988,-1.476499, 1.327704;;, 1;3;-0.033988,-1.476499, 1.327704;;, 2;3;-0.033988,-1.476499, 1.327704;;, 3;3;-0.033988,-1.476499, 1.327704;;, 4;3;-0.033988,-1.476499, 1.327704;;; } } Animation { {Armature_Root} AnimationKey { // Rotation 0; 5; 0;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 1;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 2;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 3;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 4;4;-0.702050, 0.712064,-0.006782, 0.006686;;; } AnimationKey { // Scale 1; 5; 0;3; 1.000000, 1.000000, 1.000000;;, 1;3; 1.000000, 1.000000, 1.000000;;, 2;3; 1.000000, 1.000000, 1.000000;;, 3;3; 1.000000, 1.000000, 1.000000;;, 4;3; 1.000000, 1.000000, 1.000000;;; } AnimationKey { // Position 2; 5; 0;3; 0.036323, 0.007397, 0.997875;;, 1;3; 0.036323, 0.007397, 0.997875;;, 2;3; 0.036323, 0.007397, 0.997875;;, 3;3; 0.036323, 0.007397, 0.997875;;, 4;3; 0.036323, 0.007397, 0.997875;;; } } */ /* // Achtung: Bei Tiny.x folgt die Klammer "}" nicht UNTER, sondern HINTER AnimationKey... AnimationKey { 4; 3; ... } */ // Info: Folgendes wird insgesammt eingelesen: /* AnimationKey { // Rotation 0; // 0=Rotation-Keys 5; // 5=es folgen 5 Keys 0;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 1;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 2;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 3;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 4;4;-0.709744,-0.704459,-0.000000, 0.000000;;; } */ // Bis zur nächsten Startklammer "{" lesen // Falls m_akt_Datei_Zeile keine Endklammer "}" enthält, // werden weitere Zeile(n) bis incl. der nächsten Endklammer in m_akt_Datei_Zeile eingelesen. Lese_bis_StartKlammer(); // Info: Dateizeiger ist in Zeile "AnimationKey { // Rotation" // char Zeichen; unsigned short int Art_Keys; int Ergebnis; // 0, falls Werte nicht geladen werden Zeichen='0'; Art_Keys=0; m_akt_anz_Mtr_Keys=0; // lese 2 Zeilen mit je 1 int-Wert ein // Z.B.: 4; // 10; // 1.Dateizeile lesen // Ließt eine Dateizeile in m_akt_Datei_Zeile ein. // sollte aktuelle Dateizeile eine Leer- oder Kommentarzeile sein, // werden solange weitere Dateizeilen eingelesen, wie // Leer- oder Kommentarzeilen vorhanden sind. // // Wurden mehrere Dateizeilen gelesen, dann wird // auch die danach folgende Zeile, z.B. " 5;", // eingelesen und in m_akt_Datei_Zeile gespeichert. LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Art_Keys, &Zeichen); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey_0(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Art_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // 2.Dateizeile lesen LeseNaechste_DatZeile_NEU(); // Wurde bereits hier schon eingelesen: // "void Kl_3D_Objekt::analysiere_XFile_Animationsdaten2(void)" // sscanf(m_akt_Datei_Zeile, "%i%c", &m_anz_Mtr_Keys[m_akt_AnimKey_Nr], &Zeichen); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &m_akt_anz_Mtr_Keys, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey_0(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_anz_Mtr_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // Rotations-Keys einlesen // Info: Dateizeiger ist in Zeile "10;" // lade_anim_Rotation_Keys(); // Info: Dateizeiger ist in Zeile "4;4;-0.709744,-0.704459,-0.000000, 0.000000;;;" // (=In der letzten Zahlenreihe) // Zeile mit " }" lesen LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " }" // if (m_Animationsdaten_sindOK==false) { // Wegen Lade-Probleme Funktion sofort beenden return; } } // Liest alle Scale-Keys aus einen AnimationKey-Dateiblock void Kl_3D_Objekt::lade_anim_AnimationKey_1(void) { /* // *** Template "AnimationKey" Infos: *** Defines a set of animation keys. A matrix key is useful for sets of animation data that need to be represented as transformation matrices. template AnimationKey { < 10DD46A8-775B-11cf-8F52-0040333594A3 > DWORD keyType; DWORD nKeys; DWORD keys; } Where: keyType - Specifies whether the keys are rotation, scale position, or matrix keys (using the integers 0, 1, 2, or 3 respectively). nKeys - Number of keys. keys - See TimedFloatKeys. // *** X-File Infos: *** ... AnimationSet Global { Animation { {Armature} AnimationKey { // Rotation 0; 5; 0;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 1;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 2;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 3;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 4;4;-0.709744,-0.704459,-0.000000, 0.000000;;; } AnimationKey { // Scale 1; 5; 0;3; 1.000000, 1.000000, 1.000000;;, 1;3; 1.000000, 1.000000, 1.000000;;, 2;3; 1.000000, 1.000000, 1.000000;;, 3;3; 1.000000, 1.000000, 1.000000;;, 4;3; 1.000000, 1.000000, 1.000000;;; } AnimationKey { // Position 2; 5; 0;3;-0.033988,-1.476499, 1.327704;;, 1;3;-0.033988,-1.476499, 1.327704;;, 2;3;-0.033988,-1.476499, 1.327704;;, 3;3;-0.033988,-1.476499, 1.327704;;, 4;3;-0.033988,-1.476499, 1.327704;;; } } Animation { {Armature_Root} AnimationKey { // Rotation 0; 5; 0;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 1;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 2;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 3;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 4;4;-0.702050, 0.712064,-0.006782, 0.006686;;; } AnimationKey { // Scale 1; 5; 0;3; 1.000000, 1.000000, 1.000000;;, 1;3; 1.000000, 1.000000, 1.000000;;, 2;3; 1.000000, 1.000000, 1.000000;;, 3;3; 1.000000, 1.000000, 1.000000;;, 4;3; 1.000000, 1.000000, 1.000000;;; } AnimationKey { // Position 2; 5; 0;3; 0.036323, 0.007397, 0.997875;;, 1;3; 0.036323, 0.007397, 0.997875;;, 2;3; 0.036323, 0.007397, 0.997875;;, 3;3; 0.036323, 0.007397, 0.997875;;, 4;3; 0.036323, 0.007397, 0.997875;;; } } */ /* // Achtung: Bei Tiny.x folgt die Klammer "}" nicht UNTER, sondern HINTER AnimationKey... AnimationKey { 4; 3; ... } */ // Info: Folgendes wird insgesammt eingelesen: /* AnimationKey { // Scale 1; // 0=Scale-Keys 5; // 5=es folgen 5 Keys 0;3; 1.000000, 1.000000, 1.000000;;, 1;3; 1.000000, 1.000000, 1.000000;;, 2;3; 1.000000, 1.000000, 1.000000;;, 3;3; 1.000000, 1.000000, 1.000000;;, 4;3; 1.000000, 1.000000, 1.000000;;; } */ // Bis zur nächsten Startklammer "{" lesen // Falls m_akt_Datei_Zeile keine Endklammer "}" enthält, // werden weitere Zeile(n) bis incl. der nächsten Endklammer in m_akt_Datei_Zeile eingelesen. Lese_bis_StartKlammer(); // Info: Dateizeiger ist in Zeile "AnimationKey { // Scale" // char Zeichen; unsigned short int Art_Keys; int Ergebnis; // 0, falls Werte nicht geladen werden Zeichen='0'; Art_Keys=0; m_akt_anz_Mtr_Keys=0; // lese 2 Zeilen mit je 1 int-Wert ein // Z.B.: 4; // 10; // 1.Dateizeile lesen LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Art_Keys, &Zeichen); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey_1(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Art_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // 2.Dateizeile lesen LeseNaechste_DatZeile_NEU(); // Wurde bereits hier schon eingelesen: // "void Kl_3D_Objekt::analysiere_XFile_Animationsdaten2(void)" // sscanf(m_akt_Datei_Zeile, "%i%c", &m_anz_Mtr_Keys[m_akt_AnimKey_Nr], &Zeichen); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &m_akt_anz_Mtr_Keys, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey_1(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_anz_Mtr_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // Scale-Keys einlesen // Info: Dateizeiger ist in Zeile "10;" // lade_anim_Scale_Keys(); // Info: Dateizeiger ist in Zeile "4;3; 1.000000, 1.000000, 1.000000;;;" // (=In der letzten Zahlenreihe) // Zeile mit " }" lesen LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " }" // if (m_Animationsdaten_sindOK==false) { // Wegen Lade-Probleme Funktion sofort beenden return; } } // Liest alle Position-Keys aus einen AnimationKey-Dateiblock void Kl_3D_Objekt::lade_anim_AnimationKey_2(void) { /* // *** Template "AnimationKey" Infos: *** Defines a set of animation keys. A matrix key is useful for sets of animation data that need to be represented as transformation matrices. template AnimationKey { < 10DD46A8-775B-11cf-8F52-0040333594A3 > DWORD keyType; DWORD nKeys; DWORD keys; } Where: keyType - Specifies whether the keys are rotation, scale position, or matrix keys (using the integers 0, 1, 2, or 3 respectively). nKeys - Number of keys. keys - See TimedFloatKeys. // *** X-File Infos: *** ... AnimationSet Global { Animation { {Armature} AnimationKey { // Rotation 0; 5; 0;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 1;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 2;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 3;4;-0.709744,-0.704459,-0.000000, 0.000000;;, 4;4;-0.709744,-0.704459,-0.000000, 0.000000;;; } AnimationKey { // Scale 1; 5; 0;3; 1.000000, 1.000000, 1.000000;;, 1;3; 1.000000, 1.000000, 1.000000;;, 2;3; 1.000000, 1.000000, 1.000000;;, 3;3; 1.000000, 1.000000, 1.000000;;, 4;3; 1.000000, 1.000000, 1.000000;;; } AnimationKey { // Position 2; 5; 0;3;-0.033988,-1.476499, 1.327704;;, 1;3;-0.033988,-1.476499, 1.327704;;, 2;3;-0.033988,-1.476499, 1.327704;;, 3;3;-0.033988,-1.476499, 1.327704;;, 4;3;-0.033988,-1.476499, 1.327704;;; } } Animation { {Armature_Root} AnimationKey { // Rotation 0; 5; 0;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 1;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 2;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 3;4;-0.702050, 0.712064,-0.006782, 0.006686;;, 4;4;-0.702050, 0.712064,-0.006782, 0.006686;;; } AnimationKey { // Scale 1; 5; 0;3; 1.000000, 1.000000, 1.000000;;, 1;3; 1.000000, 1.000000, 1.000000;;, 2;3; 1.000000, 1.000000, 1.000000;;, 3;3; 1.000000, 1.000000, 1.000000;;, 4;3; 1.000000, 1.000000, 1.000000;;; } AnimationKey { // Position 2; 5; 0;3; 0.036323, 0.007397, 0.997875;;, 1;3; 0.036323, 0.007397, 0.997875;;, 2;3; 0.036323, 0.007397, 0.997875;;, 3;3; 0.036323, 0.007397, 0.997875;;, 4;3; 0.036323, 0.007397, 0.997875;;; } } */ /* // Achtung: Bei Tiny.x folgt die Klammer "}" nicht UNTER, sondern HINTER AnimationKey... AnimationKey { 4; 3; ... } */ // Info: Folgendes wird insgesammt eingelesen: /* AnimationKey { // Position 2; // 0=Position-Keys 5; // 5=es folgen 5 Keys 0;3;-0.033988,-1.476499, 1.327704;;, 1;3;-0.033988,-1.476499, 1.327704;;, 2;3;-0.033988,-1.476499, 1.327704;;, 3;3;-0.033988,-1.476499, 1.327704;;, 4;3;-0.033988,-1.476499, 1.327704;;; } */ // Bis zur nächsten Startklammer "{" lesen // Falls m_akt_Datei_Zeile keine Endklammer "}" enthält, // werden weitere Zeile(n) bis incl. der nächsten Endklammer in m_akt_Datei_Zeile eingelesen. Lese_bis_StartKlammer(); // Info: Dateizeiger ist in Zeile " AnimationKey { // Position" // char Zeichen; unsigned short int Art_Keys; int Ergebnis; // 0, falls Werte nicht geladen werden Zeichen='0'; Art_Keys=0; m_akt_anz_Mtr_Keys=0; // lese 2 Zeilen mit je 1 int-Wert ein // Z.B.: 4; // 10; // 1.Dateizeile lesen LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &Art_Keys, &Zeichen); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey_2(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...Art_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // 2.Dateizeile lesen LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &m_akt_anz_Mtr_Keys, &Zeichen); if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationKey_2(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...m_akt_anz_Mtr_Keys...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // Position-Keys einlesen // Info: Dateizeiger ist in Zeile "5;" // lade_anim_Position_Keys(); // Info: Dateizeiger ist in Zeile "4;3;-0.033988,-1.476499, 1.327704;;;" // (=In der letzten Zahlenreihe) // Zeile mit " }" lesen LeseNaechste_DatZeile(); // if (m_Animationsdaten_sindOK==false) { // Wegen Lade-Probleme Funktion sofort beenden return; } } // void Kl_3D_Objekt::lade_anim_Matrix_Keys(void) { // unsigned short int Zahl; char Zeichen; int Ergebnis; // Zahl=0; // 0, falls Werte nicht geladen werden Zeichen='0'; // Je eine Dateizeile einlesen, wie z.B.: // 0;16;0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.000000,0.000000,0.000000,0.500000,0.000000,0.019833,-0.016415,0.100000,1.000000;;, // // HINWEIS: Die letzten 2 Zeichen am jew. Zeilenende werden ignoriert (Zeichen=";,") for (unsigned short int DatZle=0; DatZle < m_akt_anz_Mtr_Keys; DatZle++) { // LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c%i%c" "%f%c%f%c%f%c%f%c" "%f%c%f%c%f%c%f%c" "%f%c%f%c%f%c%f%c" "%f%c%f%c%f%c%f%c", &Zahl, &Zeichen, &Zahl, &Zeichen, &m_Tmp_MatrixKey[DatZle]._11, &Zeichen, &m_Tmp_MatrixKey[DatZle]._12, &Zeichen, &m_Tmp_MatrixKey[DatZle]._13, &Zeichen, &m_Tmp_MatrixKey[DatZle]._14, &Zeichen, &m_Tmp_MatrixKey[DatZle]._21, &Zeichen, &m_Tmp_MatrixKey[DatZle]._22, &Zeichen, &m_Tmp_MatrixKey[DatZle]._23, &Zeichen, &m_Tmp_MatrixKey[DatZle]._24, &Zeichen, &m_Tmp_MatrixKey[DatZle]._31, &Zeichen, &m_Tmp_MatrixKey[DatZle]._32, &Zeichen, &m_Tmp_MatrixKey[DatZle]._33, &Zeichen, &m_Tmp_MatrixKey[DatZle]._34, &Zeichen, &m_Tmp_MatrixKey[DatZle]._41, &Zeichen, &m_Tmp_MatrixKey[DatZle]._42, &Zeichen, &m_Tmp_MatrixKey[DatZle]._43, &Zeichen, &m_Tmp_MatrixKey[DatZle]._44, &Zeichen); // if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_Matrix_Keys(...)", 6); m_z_Kl_Debug->set_Meldung("zwischen sscanf(...m_Tmp_MatrixKey[DatZle]._11...)", 5); m_z_Kl_Debug->set_Meldung("und sscanf(...m_Tmp_MatrixKey[DatZle]._44...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_Animationsdaten_sindOK=false; break; } } } // void Kl_3D_Objekt::lade_anim_Rotation_Keys(void) { // unsigned short int Zahl; char Zeichen; int Ergebnis; // Zahl=0; // 0, falls Werte nicht geladen werden Zeichen='0'; // Je eine Dateizeile einlesen, wie z.B.: // 0;4;-0.709744,-0.704459,-0.000000, 0.000000;;, // // HINWEIS: Die letzten 3 Zeichen am jew. Zeilenende werden ignoriert (Zeichen=";;,") for (unsigned short int DatZle=0; DatZle < m_akt_anz_Mtr_Keys; DatZle++) { // INFO: // Quaternions are stored inside X files with their components in WXYZ order, // not the more typical XYZW format of 4D vectors // LeseNaechste_DatZeile_NEU(); // Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c%i%c" "%f%c%f%c%f%c%f%c", &Zahl, &Zeichen, &Zahl, &Zeichen, &m_Tmp_RotationKey[DatZle].w, &Zeichen, &m_Tmp_RotationKey[DatZle].x, &Zeichen, &m_Tmp_RotationKey[DatZle].y, &Zeichen, &m_Tmp_RotationKey[DatZle].z, &Zeichen); // if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_Rotation_Keys(...)", 6); m_z_Kl_Debug->set_Meldung("zwischen sscanf(...m_Tmp_RotationKey[DatZle].x...)", 5); m_z_Kl_Debug->set_Meldung("und sscanf(...m_Tmp_RotationKey[DatZle].w...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_Animationsdaten_sindOK=false; break; } } } // void Kl_3D_Objekt::lade_anim_Scale_Keys(void) { // unsigned short int Zahl; char Zeichen; int Ergebnis; // Zahl=0; // 0, falls Werte nicht geladen werden Zeichen='0'; // Je eine Dateizeile einlesen, wie z.B.: // 0;3; 1.000000, 1.000000, 1.000000;;, // // HINWEIS: Die letzten 3 Zeichen am jew. Zeilenende werden ignoriert (Zeichen=";;,") for (unsigned short int DatZle=0; DatZle < m_akt_anz_Mtr_Keys; DatZle++) { // LeseNaechste_DatZeile_NEU(); // Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c%i%c" "%f%c%f%c%f%c", &Zahl, &Zeichen, &Zahl, &Zeichen, &m_Tmp_ScaleKey[DatZle].x, &Zeichen, &m_Tmp_ScaleKey[DatZle].y, &Zeichen, &m_Tmp_ScaleKey[DatZle].z, &Zeichen); // if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_Scale_Keys(...)", 6); m_z_Kl_Debug->set_Meldung("zwischen sscanf(...m_Tmp_ScaleKey[DatZle].x...)", 5); m_z_Kl_Debug->set_Meldung("und sscanf(...m_Tmp_ScaleKey[DatZle].z...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_Animationsdaten_sindOK=false; break; } } } // void Kl_3D_Objekt::lade_anim_Position_Keys(void) { // unsigned short int Zahl; char Zeichen; int Ergebnis; // Zahl=0; // 0, falls Werte nicht geladen werden Zeichen='0'; // Je eine Dateizeile einlesen, wie z.B.: // 0;3;-0.033988,-1.476499, 1.327704;;, // // HINWEIS: Die letzten 3 Zeichen am jew. Zeilenende werden ignoriert (Zeichen=";;,") for (unsigned short int DatZle=0; DatZle < m_akt_anz_Mtr_Keys; DatZle++) { // LeseNaechste_DatZeile_NEU(); // Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c%i%c" "%f%c%f%c%f%c", &Zahl, &Zeichen, &Zahl, &Zeichen, &m_Tmp_PositionKey[DatZle].x, &Zeichen, &m_Tmp_PositionKey[DatZle].y, &Zeichen, &m_Tmp_PositionKey[DatZle].z, &Zeichen); // if ( (Ergebnis==0) || (Ergebnis==EOF) ) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_Position_Keys(...)", 6); m_z_Kl_Debug->set_Meldung("zwischen sscanf(...m_Tmp_PositionKey[DatZle].x...)", 5); m_z_Kl_Debug->set_Meldung("und sscanf(...m_Tmp_PositionKey[DatZle].z...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); m_Animationsdaten_sindOK=false; break; } } } // Liest einen Animation-Dateiblock incl Animation Key-Dateiblock und // einen eventuell vorhandenen AnimationOptions-Dateiblock. // Außerdem wird der Name der Frame-?Referenz? gelesen void Kl_3D_Objekt::lade_anim_Animation(void) { /* // *** X-File Infos: *** ... AnimationSet AnimationSet0 { Animation { AnimationKey { 4; 2; 0; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;;, 1998; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000;;; } { Scene_Root } } Animation Joint_RootAnimation { AnimationKey { 4; 2; 0; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.622646, 1.171117, 0.000000, 1.000000;;, 999; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.622646, 1.171117, 0.000000, 1.000000;;; } AnimationOptions { 0; 0; } { Joint_Root } } Animation Joint_Huefte_RAnimation { AnimationKey { 4; 3; 0; 16; 0.769430, -0.017472, 0.638492, 0.000000, 0.624063, 0.233555, -0.745652, 0.000000, -0.136095, 0.972187, 0.190608, 0.000000, 0.120585, -0.003060, 0.000000, 1.000000;;, 999; 16; 0.747064, -0.340025, 0.571208, 0.000000, 0.654591, 0.226620, -0.721217, 0.000000, 0.115785, 0.912703, 0.391878, 0.000000, 0.120585, -0.003060, 0.000000, 1.000000;;, 1998; 16; 0.767857, -0.000552, 0.640621, 0.000000, 0.624609, 0.222823, -0.748474, 0.000000, -0.142332, 0.974859, 0.171441, 0.000000, 0.120585, -0.003060, 0.000000, 1.000000;;; } AnimationOptions { 0; 0; } { Joint_Huefte_R } } */ /* // Achtung: Bei Tiny.x folgt die Klammer "}" nicht UNTER, sondern HINTER AnimationKey... AnimationKey { 4; 3; ... } */ // Info: Folgendes wird insgesammt eingelesen: /* ENTWEDER ( "{ Joint_Huefte_R }" folgt erst nach "AnimationOptions") Animation Joint_Huefte_RAnimation { AnimationKey { 4; 3; 0; 16; 0.769430, -0.017472, 0.638492, 0.000000, 0.624063, 0.233555, -0.745652, 0.000000, -0.136095, 0.972187, 0.190608, 0.000000, 0.120585, -0.003060, 0.000000, 1.000000;;, 999; 16; 0.747064, -0.340025, 0.571208, 0.000000, 0.654591, 0.226620, -0.721217, 0.000000, 0.115785, 0.912703, 0.391878, 0.000000, 0.120585, -0.003060, 0.000000, 1.000000;;, 1998; 16; 0.767857, -0.000552, 0.640621, 0.000000, 0.624609, 0.222823, -0.748474, 0.000000, -0.142332, 0.974859, 0.171441, 0.000000, 0.120585, -0.003060, 0.000000, 1.000000;;; } AnimationOptions { 0; 0; } { Joint_Huefte_R } } ODER ( "{Joint_Huefte_R}" folgt nach "Animation Joint_Huefte_RAnimation") Animation Joint_Huefte_RAnimation { {Joint_Huefte_R} AnimationKey { 4; 3; 0;16; 0.769430,-0.017472,-0.638492,0.000000, 0.624063,0.233555,0.745652,0.000000, 0.136095,-0.972187,0.190608,0.000000, 0.012059,-0.000306,-0.000000,1.000000;;, 999;16; 0.747064,-0.340025,-0.571208,0.000000, 0.654591,0.226620,0.721217,0.000000, -0.115785,-0.912703,0.391878,0.000000, 0.012059,-0.000306,-0.000000,1.000000;;, 1998;16; 0.767857,-0.000552,-0.640621,0.000000, 0.624609,0.222823,0.748474,0.000000, 0.142332,-0.974859,0.171441,0.000000, 0.012059,-0.000306,-0.000000,1.000000;;; } AnimationOptions { 0; 1; } } */ // *** Animation lesen (incl darunter folgender "{" *** /* // Info: Dateizeiger ist in Zeile " Animation" // Zeile mit " {" überspringen Ueberspr_LeereOderKommentar_Zeile(); // Info: Dateizeiger ist in Zeile " {" */ // Info: Dateizeiger ist in Zeile " Animation" oder "Animation {" // Falls m_akt_Datei_Zeile keine Startklammer "{" enthält, // werden weitere Zeile(n) bis incl. der nächsten "{" in m_akt_Datei_Zeile eingelesen. Lese_bis_StartKlammer(); // *** Eventuell Name der Frame-Referenz lesen (incl darunter folgender '{" *** // ACHTUNG: Lt. DX9-Doku sollte als nächstes z.B. "{Scene_Root}" kommen (=?Referenz? auf // entsprechenden Frame. // In einigen X-Files war es jedoch so, daß dies stattdessen erst nach dem // "AnimationOptions"-Block folgte. // Folgt als nächstes statt einer "AnimationKey"-Zeile z.B. eine "{Scene_Root}" Zeile? // LeseNaechste_DatZeile_NEU(); // char *Name_FrameReferenz; Name_FrameReferenz=NULL; Name_FrameReferenz=new char [255]; Name_FrameReferenz[0]='\0'; // bool AnimationKey; // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält AnimationKey=pruefeAuf_Zeichenfolge("AnimationKey"); // Falls jetzt noch kein AnimationKey-Block folgt, // könnte es eine Frame-Referenz sein (z.B. "{ Scene_Root }" oder "{Scene_Root}". // Deswegen: Name der Frame-Referenz ermitteln if (AnimationKey==false) { // Verwandelt m_akt_Datei_Zeile " { Scene_Root }" oder " {Scene_Root}" // in den Frame-Referenznamen "Scene_Root" // // Rückgabewert: Z.B. Scene_Root verwandle_inFrame_Referenzname(Name_FrameReferenz); } // *** AnimationKey-Block lesen (incl darunter folgender "{" *** // Dateizeiger zur nächsten Zeile "AnimationKey" bringen // (Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein) // LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " AnimationKey" // if (m_XFile_nutzt_MatrixKeys==true) { lade_anim_AnimationKey_4(); LeseNaechste_DatZeile_NEU(); } // else { // LeseNaechste_DatZeile_NEU(); // Liest alle Rotation-Keys aus einen AnimationKey-Dateiblock lade_anim_AnimationKey_0(); // LeseNaechste_DatZeile_NEU(); // Liest alle Scale-Keys aus einen AnimationKey-Dateiblock lade_anim_AnimationKey_1(); // LeseNaechste_DatZeile_NEU(); // Liest alle Position-Keys aus einen AnimationKey-Dateiblock lade_anim_AnimationKey_2(); // LeseNaechste_DatZeile_NEU(); } // *** Eventuell AnimationOptions-Block lesen (incl darunter folgender "{" *** // Funktion nur weiter ausführen, wenn erlaubt // (Um Programmabstürze bei X-File Problemen zu vermeiden, // und eventuelle Prg-Meldungen trotzdem lesen zu können) if (m_Animationsdaten_sindOK==false) { return; } // Info: Dateizeiger ist in Zeile "{ Scene_Root }" oder "AnimationOptions" bool AnimationOptions; // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält AnimationOptions=pruefeAuf_Zeichenfolge("AnimationOptions"); // if (AnimationOptions==true) { lade_anim_AnimationOptions(); LeseNaechste_DatZeile_NEU(); } // *** Eventuell Name der Frame-Referenz lesen (incl darunter folgender '{" *** // Info: Dateizeiger ist in Zeile // Falls Name für Frame-Referenz zuvor noch nicht vorkam // könnte jetzt eine Frame-Referenz vorkommen (z.B. "{ Scene_Root }" oder "{Scene_Root}". // Deswegen: Name der Frame-Referenz ermitteln if (Name_FrameReferenz[0] == '\0') { // Verwandelt m_akt_Datei_Zeile " { Scene_Root }" oder " {Scene_Root}" // in den Frame-Referenznamen "Scene_Root" // // Rückgabewert: Z.B. Scene_Root verwandle_inFrame_Referenzname(Name_FrameReferenz); } // letzte "}" vom Dateiblock Animation lesen // LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " }" // *** Daten im Bone speichern *** if (m_Animationsdaten_sindOK==false) { return; } // entsprechenden Bone suchen m_str_akt_Bone=suche_Bone(Name_FrameReferenz); // Zuvor Speicher wieder freigeben delete [] Name_FrameReferenz; Name_FrameReferenz=NULL; if (m_str_akt_Bone == NULL) { // Wegen Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // und anz_Mtr_Keys speichern m_str_akt_Bone->anz_Mtr_Keys=m_akt_anz_Mtr_Keys; // m_str_akt_Bone->animKey_Matrix=new D3DXMATRIX [m_str_akt_Bone->anz_Mtr_Keys]; m_str_akt_Bone->abs_Matrix_Gelenk=new D3DXMATRIX [m_str_akt_Bone->anz_Mtr_Keys]; // for (unsigned short int MtrKey_Nr=0; MtrKey_Nr < m_str_akt_Bone->anz_Mtr_Keys; MtrKey_Nr++) { D3DXMatrixIdentity(&m_str_akt_Bone->animKey_Matrix[MtrKey_Nr]); D3DXMatrixIdentity(&m_str_akt_Bone->abs_Matrix_Gelenk[MtrKey_Nr]); } // ENTWEDER nur die Matrix-Key Werte kopieren, if (m_XFile_nutzt_MatrixKeys==true) { for (unsigned short int MtrKey_Nr=0; MtrKey_Nr < m_str_akt_Bone->anz_Mtr_Keys; MtrKey_Nr++) { m_str_akt_Bone->animKey_Matrix[MtrKey_Nr]=m_Tmp_MatrixKey[MtrKey_Nr]; // Matrix-Key in SRT-Keys umwandeln (SRT=Scale Rotation Translation) // =lt. www mit D3DXMatrixDecompose(), aber DX 9 hat diese Funktion nicht. Neueres DX? } } // ODER die Rotation-, Scale- & Position-Keys behandeln else { // m_str_akt_Bone->animKey__Rotation=new D3DXQUATERNION[m_str_akt_Bone->anz_Mtr_Keys]; m_str_akt_Bone->animKey__Scale=new D3DXVECTOR3[m_str_akt_Bone->anz_Mtr_Keys]; m_str_akt_Bone->animKey__Position=new D3DXVECTOR3[m_str_akt_Bone->anz_Mtr_Keys]; // for (unsigned short int MtrKey_Nr=0; MtrKey_Nr < m_str_akt_Bone->anz_Mtr_Keys; MtrKey_Nr++) { // Rotation-, Scale- & Position-Key Werte kopieren m_str_akt_Bone->animKey__Rotation[MtrKey_Nr].w=m_Tmp_RotationKey[MtrKey_Nr].w; m_str_akt_Bone->animKey__Rotation[MtrKey_Nr].x=m_Tmp_RotationKey[MtrKey_Nr].x; m_str_akt_Bone->animKey__Rotation[MtrKey_Nr].y=m_Tmp_RotationKey[MtrKey_Nr].y; m_str_akt_Bone->animKey__Rotation[MtrKey_Nr].z=m_Tmp_RotationKey[MtrKey_Nr].z; m_str_akt_Bone->animKey__Scale[MtrKey_Nr].x=m_Tmp_ScaleKey[MtrKey_Nr].x; m_str_akt_Bone->animKey__Scale[MtrKey_Nr].y=m_Tmp_ScaleKey[MtrKey_Nr].y; m_str_akt_Bone->animKey__Scale[MtrKey_Nr].z=m_Tmp_ScaleKey[MtrKey_Nr].z; m_str_akt_Bone->animKey__Position[MtrKey_Nr].x=m_Tmp_PositionKey[MtrKey_Nr].x; m_str_akt_Bone->animKey__Position[MtrKey_Nr].y=m_Tmp_PositionKey[MtrKey_Nr].y; m_str_akt_Bone->animKey__Position[MtrKey_Nr].z=m_Tmp_PositionKey[MtrKey_Nr].z; // Matrix-Keys berechnen // Berechnet aus dem Scale-, Rotation- & Translation- Key einen Matrix-Key // (Wandelt m_str_akt_Bone->animKey__Scale[], m_str_akt_Bone->animKey__Rotation[] und // m_str_akt_Bone->animKey__Position[] in m_str_akt_Bone->animKey_Matrix[] um) // // Parameter: 1.=Nr des aktuellen Matrix Keys berechne_Matrix_Keys(MtrKey_Nr); } } } // Liest einen AnimationOptions-Dateiblock void Kl_3D_Objekt::lade_anim_AnimationOptions(void) { /* // *** Template "AnimationOptions" Infos: *** Enables you to set animation options. template AnimationOptions { < E2BF56C0-840F-11cf-8F52-0040333594A3 > DWORD openclosed; DWORD positionquality; } Where: openclosed - Use 0 for a closed animation, or 1 for an open animation. By default, an animation is closed. positionquality - Set the position quality for any position keys specified. Use 0 for spline positions or 1 for linear positions. // *** X-File Infos: *** ... Animation joint1OberseiteLinksAnimation { AnimationKey { 4; 1; 0; 16; 0.000066, 0.000000, 1.000000, 0.000000, -0.001264, -0.999999, 0.000000, 0.000000, 0.999999, -0.001264, -0.000066, 0.000000, 0.715733, 0.296578, 0.000000, 1.000000;;; } AnimationOptions { 0; // 0=geschlossene Animation, 1=offene Animation // (0=Animation wird ständig wiederholt. // 1=Animation wird nur 1 mal abgespielt, und stoppt dann) 0; // 0 bei Positionierung mit Splines, 1 bei linearer Positionierung } // { joint1OberseiteLinks } // } Animation joint2OberseiteRechtsAnimation { AnimationKey { 4; 3; 0; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, -1.317863, 1.000000;;, 1; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, -0.252252, -1.318182, 1.000000;;, 2; 16; 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000001, -0.612635, -1.300620, 1.000000;;; } AnimationOptions { 0; // 0; // } { joint2OberseiteRechts } // */ // Info: Folgendes wird insgesammt eingelesen: /* AnimationOptions { 0; // 0; // } */ // Info: Dateizeiger ist in Zeile " AnimationOptions" // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " {" int OpenClosed; int PositionQuality; // 0, falls Werte nicht geladen werden OpenClosed=0; PositionQuality=0; // int Ergebnis; char Zeichen; // 1.) einlesen, ob es eine offene oder geschlossene Animation ist // "0;" // LeseNaechste_DatZeile(); LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &OpenClosed, &Zeichen); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationOptions(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...OpenClosed...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // 2.) einlesen, ob es eine spline- oder linear positions ist (positionquality) // "0;" // LeseNaechste_DatZeile(); LeseNaechste_DatZeile_NEU(); Ergebnis=sscanf(m_akt_Datei_Zeile, "%i%c", &PositionQuality, &Zeichen); // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { // false, weil Probleme beim laden // m_Animationsdaten_sindOK=false; // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::lade_anim_AnimationOptions(...)", 6); m_z_Kl_Debug->set_Meldung("sscanf(...PositionQuality...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_Animationsdaten_sindOK=false; return; } // LeseNaechste_DatZeile(); // Info: Dateizeiger ist in Zeile " {" } // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein void Kl_3D_Objekt::LeseNaechste_DatZeile(void) { // Lädt String ab aktueller Dateiposition bis zum newline character, // oder bis max Anzahl zu lesender Zeichen erreicht wurde. // Das Stringende enthält entweder '\0' oder '\n', falls '\n' gelesen wurde fgets( m_akt_Datei_Zeile, // Storage location for data (String) 254, // Maximum number of characters to read m_DateiInput_3D_Objekt // Pointer to FILE structure ); } // Liest nächste Zeile(n) des XFiles in m_akt_Datei_Zeile ein, // und überspringt dabei alle Leer- oder alle ganzen Kommentarzeilen void Kl_3D_Objekt::LeseNaechste_DatZeile_NEU(void) { // Zur Überprüfung, ob leere Dateizeile oder Kommentarzeile // vorhanden ist bool LeereOderKommentar_Zeile; // Solange alle Leer- & Kommentarzeilen überspringen, // bis eine andere Zeile gefunden wird do { // Muß anfangs false sein! LeereOderKommentar_Zeile=false; // 1.) Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein // // (Lädt String ab aktueller Dateiposition bis zum newline character, // oder bis max Anzahl zu lesender Zeichen erreicht wurde. // Das Stringende enthält entweder '\0' oder '\n', falls '\n' gelesen wurde) fgets( m_akt_Datei_Zeile, // Storage location for data (String) 254, // Maximum number of characters to read m_DateiInput_3D_Objekt // Pointer to FILE structure ); // 2.) Prüft, ob m_akt_Datei_Zeile eine Leere Zeile ist // (Ob das Zeichen '\n' (=Zeilenvorschub) am ZeilenANFANG steht) if (m_akt_Datei_Zeile[0]=='\n') // Prüfung=-- { LeereOderKommentar_Zeile=true; } // 3.) Prüft, ob m_akt_Datei_Zeile eine Kommentarzeile ist // (Ob die Zeichen "//" oder "#" am ZeilenANFANG stehen) // Infos zu Kommentaren in X-Files // // ACHTUNG: Kommentare können überall im X-File vorkommen! // // Comments are only applicable in X-File text files. Comments can occur // anywhere in the data stream. A comment begins with either // C++ style double-slashes "//", or a number sign "#". // The comment runs to the next new line. // // Steht am Zeilenanfang "//"? if (m_akt_Datei_Zeile[0]=='/') { if (m_akt_Datei_Zeile[1]=='/') { // Prüfung=-- LeereOderKommentar_Zeile=true; } } // Steht am Zeilenanfang "#"? if (m_akt_Datei_Zeile[0]=='#') { LeereOderKommentar_Zeile=true; } // Prüfung=-- // 4.) // if (feof(m_DateiInput_3D_Objekt) != NULL) // { LeereOderKommentar_Zeile=true; } }while ( LeereOderKommentar_Zeile == true); } // Falls m_akt_Datei_Zeile keine Startklammer "{" enthält, // werden weitere Zeile(n) bis incl. der nächsten "{" in m_akt_Datei_Zeile eingelesen. // Dies ist notwendig, weil manche X-Files z.B. so aufgebaut sind ("{"=in nächster Zeile): // AnimationSet AnimationSet0 // { // Animation // { // AnimationKey // { // ... // Und manche anderen X-Files so ("{"=hinter Name): // AnimationSet Global { // Animation { // {Armature} // AnimationKey { // Rotation // 0; // 5; // ... void Kl_3D_Objekt::Lese_bis_StartKlammer(void) { // bool Endklammer; // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält (Z.B. "template ") Endklammer=pruefeAuf_Zeichenfolge("{"); // Falls m_akt_Datei_Zeile keine "}" enthält, // solange weitere Zeilen lesen, bis eine mit einer "}" folgt while (Endklammer==false) { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); Endklammer=pruefeAuf_Zeichenfolge("{"); } /* if (Endklammer==false) { // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); } */ } // Ließt eine Dateizeile in m_akt_Datei_Zeile ein. // sollte aktuelle Dateizeile eine Leer- oder Kommentarzeile sein, // werden solange weitere Dateizeilen eingelesen, wie // Leer- oder Kommentarzeilen vorhanden sind. // // Wurden mehrere Dateizeilen gelesen, dann wird // auch die danach folgende Zeile, z.B. " 5;", // eingelesen und in m_akt_Datei_Zeile gespeichert. void Kl_3D_Objekt::Ueberspr_LeereOderKommentar_Zeile(void) { // Zur Überprüfung, ob leere Dateizeile oder Kommentarzeile // vorhanden ist bool LeereOderKommentar_Zeile; // alle Leeren & Kommentarzeilen überspringen do { // Muß anfangs false sein! LeereOderKommentar_Zeile=false; // Liest nächste Zeile des XFiles in m_akt_Datei_Zeile ein LeseNaechste_DatZeile(); // Prüft, ob m_akt_Datei_Zeile eine Leere Zeile ist // (Ob das Zeichen '\n' (=Zeilenvorschub) am ZeilenANFANG steht) if (pruefeAuf_LeereZeile() == true) { LeereOderKommentar_Zeile=true; } // Prüft, ob m_akt_Datei_Zeile eine Kommentarzeile ist // (Ob die Zeichen "//" oder "#" am ZeilenANFANG stehen) if (pruefeAuf_Kommentarzeile() == true) { LeereOderKommentar_Zeile=true; } }while ( LeereOderKommentar_Zeile == true); } // Liest z.B. den Dateieintrag" 5;" aus m_akt_Datei_Zeile, // und gibt Zahl zurück // // Rückgabewerte: // // false=Fehler beim lesen/Dateieinträge fehlen // *Menge: Z.B. Menge/Anzahl der Vertices, die zurückgegeben wird bool Kl_3D_Objekt::Lese_MengenEintrag_DatZeile(unsigned int *Menge) { int Ergebnis_sscanf; char Zeichen; // Zeile wie z.B." 5;" lesen // // sscanf read formatted data from a string. // // Each of these functions returns the number of fields successfully converted and assigned; // the return value does not include fields that were read but not assigned. // A return value of 0 indicates that no fields were assigned. // The return value is EOF for an error or if the end of the string is reached // before the first conversion. Ergebnis_sscanf= sscanf( m_akt_Datei_Zeile, "%d %c", Menge, &Zeichen); // 0=Kein Eintrag gefunden, der %d oder %c entspricht // und verwertbar ist if (Ergebnis_sscanf==0) { // Menge auf 0 setzen *Menge=0; // Fehler return (false); } // EOF=Ende der Datei oder Fehler if (Ergebnis_sscanf==EOF) { *Menge=0; return (false); } // Da alles OK ist, true zurückgeben return (true); // Zahl und ";" aus String der Dateizeile holen // // Tests -OK- (getested mit: 5; und 599991; und 5;; // sscanf read formatted data from a string. // sscanf( m_akt_Datei_Zeile, "%d %c", &i, &Zeichen ); // Funktionierte alles nicht: //Read formatted data from the standard input stream. //wscanf( L"%d", &i); //Gets an integer from a stream //i=_getw(m_DateiInput_3D_Objekt); //i=fgetc(m_DateiInput_3D_Objekt); } // Ließt alle Vertices aus dem Mesh-Block, // und speichert sie in m_3D_Objekt_Vertices void Kl_3D_Objekt::Lese_Vertices_Mesh(void) { /* xof 0303txt 0032 ... Mesh { 5; // =Anzahl der Vertices dieses Mesh 0.000000;0.000000;1.000000;, // =Vertex 0 1.000000;0.000000;1.000000;, // =Vertex 1 1.000000;0.000000;0.000000;, // =Vertex 2 0.000000;0.000000;0.000000;, // =Vertex 3 0.500000;0.500000;0.500000;; // =Vertex 4 6; // =Anzahl der Faces dieses Mesh 3;0,2,1;, // =Face 0 aus Vertices 0,2,1. 1.Zahl(3)=Anzahl 3;3,2,0;, // Vertices im Face 3;4,0,1;, // =Face 2 aus Vertices 4,0,1 3;2,3,4;, // =Face 3 aus Vertices 2,3,4 3;3,0,4;, // =Face 4 aus Vertices 3,0,4 3;1,2,4;; // =Face 5 aus Vertices 1,2,4 */ // * Vertices für den aktuellen Mesh lesen * // Nr. des ersten Vertice des aktuellen Meshes // unsigned int StartNr1ter_Vertice; // Muß erst 0 sein. Z.B.,falls X-File nur 1 Mesh enthält, // und die folgende For-Schleife deswegen nicht ausgeführt werden sollte StartNr1ter_Vertice=0; // Nr. des ersten Vertice für den aktuellen Mesh ermitteln for (unsigned short int Nr_Mesh=0; Nr_Mesh < m_Nr_akt_Mesh; Nr_Mesh++) { StartNr1ter_Vertice=StartNr1ter_Vertice + m_Anz_Vertices_MeshNr[Nr_Mesh]; } // Zeilen einlesen // char Zeichen; unsigned int VerticeNr; VerticeNr=StartNr1ter_Vertice; int Ergebnis; bool Fehler; Fehler=false; // Die 3 float-Werte der jeweiligen Dateizeile holen // // Prüfung: -- for (unsigned int Nr_DateiZeile=0; Nr_DateiZeile < m_Anz_Vertices_MeshNr[m_Nr_akt_Mesh]; Nr_DateiZeile++) { // Nr des aktuellen Vertice ermitteln VerticeNr=StartNr1ter_Vertice + Nr_DateiZeile; // hole 3 float-Werte der aktuellen Dateizeile // Z.B.: 0.000000;0.000000;1.000000;, Ergebnis=fscanf( m_DateiInput_3D_Objekt, "%f%c %f%c %f%c%c", &m_3D_Objekt_Vertices[VerticeNr].x, &Zeichen, &m_3D_Objekt_Vertices[VerticeNr].y, &Zeichen, &m_3D_Objekt_Vertices[VerticeNr].z, &Zeichen, &Zeichen ); //VerticeNr++; // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } } // Falls Problem oder Fehler if (Fehler==true) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::Lese_Vertices_Mesh(...)", 6); m_z_Kl_Debug->set_Meldung("fscanf(...m_3D_Objekt_Vertices[VerticeNr]...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; } /* char b=0; if (m_Nr_akt_Mesh==1) { //VerticeNr; //StartNr1ter_Vertice; m_3D_Objekt_Vertices[70]; m_3D_Objekt_Vertices[71]; m_3D_Objekt_Vertices[72]; b=1; } */ } // Ließt alle Faces aus dem Mesh-Block, // und speichert sie in m_3D_Objekt_Indices // (Jedes Face hat je 3 Indices) void Kl_3D_Objekt::Lese_Faces_Mesh(void) { /* xof 0303txt 0032 ... Mesh { 5; // =Anzahl der Vertices dieses Mesh 0.000000;0.000000;1.000000;, // =Vertex 0 1.000000;0.000000;1.000000;, // =Vertex 1 1.000000;0.000000;0.000000;, // =Vertex 2 0.000000;0.000000;0.000000;, // =Vertex 3 0.500000;0.500000;0.500000;; // =Vertex 4 6; // =Anzahl der Faces dieses Mesh 3;0,2,1;, // =Face 0 aus Vertices 0,2,1. 1.Zahl(3)=Anzahl 3;3,2,0;, // Vertices im Face 3;4,0,1;, // =Face 2 aus Vertices 4,0,1 3;2,3,4;, // =Face 3 aus Vertices 2,3,4 3;3,0,4;, // =Face 4 aus Vertices 3,0,4 3;1,2,4;; // =Face 5 aus Vertices 1,2,4 */ // NEU: Für mehrere Meshes // Nr. des ersten Indices des aktuellen Meshes // unsigned int StartNr1ter_Indice; // Muß erst 0 sein. Z.B.,falls X-File nur 1 Mesh enthält, // und die folgende For-Schleife deswegen nicht ausgeführt werden sollte StartNr1ter_Indice=0; // Nr. des ersten Indices für den aktuellen Mesh ermitteln // unsigned int anz_Indices_akt_Mesh; for (unsigned short int Nr_Mesh=0; Nr_Mesh < m_Nr_akt_Mesh; Nr_Mesh++) { // Weil jedes Face je 3 Indices hat anz_Indices_akt_Mesh=3 * m_Anz_Faces_MeshNr[Nr_Mesh]; // StartNr1ter_Indice=StartNr1ter_Indice + anz_Indices_akt_Mesh; } // Fehler am 23.03.2013 gefunden: Indices des 3.Mesh werden nicht gelesen... // So wars falsch: /* // Nr. des ersten Vertice für den aktuellen Mesh ermitteln for (unsigned short int Nr_Mesh=0; Nr_Mesh < m_Nr_akt_Mesh; Nr_Mesh++) { StartNr1ter_Indice=StartNr1ter_Indice + m_Anz_Faces_MeshNr[Nr_Mesh]; // Weil jedes Face je 3 Indices hat StartNr1ter_Indice=StartNr1ter_Indice * 3; } */ /* //Experiment: if (m_Nr_akt_Mesh==0) { StartNr1ter_Indice=0; } if (m_Nr_akt_Mesh==1) { StartNr1ter_Indice=36; } if (m_Nr_akt_Mesh==2) { StartNr1ter_Indice=72; } */ // Zeilen einlesen // char Zeichen; int Zahl; unsigned int Nr_ersten_Mesh_Indice; // Muß Anfangs so sein Nr_ersten_Mesh_Indice=StartNr1ter_Indice; int Ergebnis; bool Fehler; Fehler=false; // Die 3 Int-Werte der jeweiligen Dateizeile holen // // Prüfung: -OK- for ( unsigned int Nr_DateiZeile=0; Nr_DateiZeile < m_Anz_Faces_MeshNr[m_Nr_akt_Mesh]; Nr_DateiZeile++) { // hole 3 Int-Werte der aktuellen Dateizeile Ergebnis=fscanf( m_DateiInput_3D_Objekt, "%i%c %i%c %i%c %i%c%c", &Zahl, &Zeichen, &m_3D_Objekt_Indices[Nr_ersten_Mesh_Indice], &Zeichen, &m_3D_Objekt_Indices[Nr_ersten_Mesh_Indice +1], &Zeichen, &m_3D_Objekt_Indices[Nr_ersten_Mesh_Indice +2], &Zeichen, &Zeichen ); // +3 für die nächste Zeile Nr_ersten_Mesh_Indice++; Nr_ersten_Mesh_Indice++; Nr_ersten_Mesh_Indice++; // Falls Problem oder Fehler if ( (Ergebnis==0) || (Ergebnis==EOF) ) { Fehler=true; } } // Falls Problem oder Fehler if (Fehler==true) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::Lese_Faces_Mesh(...)", 6); m_z_Kl_Debug->set_Meldung("fscanf(...m_3D_Objekt_Indices[]...)", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // Wegen Lade-Probleme auf false setzen & Funktion sofort beenden m_XFile_istOK=false; } } // Inhalt der aktuellen Datei-Zeile (=m_akt_Datei_Zeile) prüfen, // und bei Fund in m_Art_aktDatZeile speichern void Kl_3D_Objekt::pruefInhalt_DatZeile(void) { // *** EXPERIMENT "Schnellere & übersichtlichere Version" (11.03.2015 nach 02:35 Uhr) *** // Erstmal auf Sonstiges setzen (Falls nichts verwertbares gefunden wird) m_Art_aktDatZeile=inDz_Sonstiges; // 99=inDz_Sonstiges // Zuerst eventuell in Dateizeile vorhandenes X-File Kommentar entfernen // Entfernt aus m_akt_Datei_Zeile "//" incl nachfolgenden Kommentar-Text. // Beispiel: Aus "} // End of AnimationSet Global" wird "} " verwandle_inKommentarlos(); // Ist aktuelle Datei-Zeile eine... // ...leere Zeile? // Prüft, ob m_akt_Datei_Zeile eine Leere Zeile ist // (Ob das Zeichen '\n' (=Zeilenvorschub) am ZeilenANFANG steht) if (pruefeAuf_LeereZeile() == true) // Prüfung=-OK- { // Art der aktuellen Dateizeile setzen m_Art_aktDatZeile=inDz_LeereZeile; // 1=inDz_LeereZeile // Funktion vorzeitig beenden, um unnötige weitere If-Vergleiche zu vermeiden return; } // ...Kommentar-Zeile? // Prüft, ob m_akt_Datei_Zeile eine Kommentarzeile ist // (Ob die Zeichen "//" oder "#" am ZeilenANFANG stehen) if (pruefeAuf_Kommentarzeile() == true) // Prüfung=-OK- { m_Art_aktDatZeile=inDz_Kommentar; return; } // 2=inDz_Kommentar // ...Template-Zeile? // Enthält m_akt_Datei_Zeile irgendwo die Zeichenfolge "template "? // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält if (pruefeAuf_Zeichenfolge("template ")==true) // Prüfung=-OK- { m_Art_aktDatZeile=inDz_Template; return; } // 10=inDz_Kommentar // ..."Frame "-Zeile? if (pruefeAuf_Zeichenfolge("Frame ")==true) // Prüfung=-OK- { m_Art_aktDatZeile=inDz_Frame; return; } // 20=inDz_Frame // ..."FrameTransformMatrix {"-Zeile? // if (pruefeAuf_Zeichenfolge("FrameTransformMatrix {")==true) // Prüfung=-ok- // { m_Art_aktDatZeile=inDz_FrameTransformMatrix; } // 30=inDz_FrameTransformMatrix // ..."Mesh " oder "template Mesh {"-Zeile? // // Zeile kann nur "Mesh {", aber auch variable Namen wie z.B. // "Mesh mesh-guard {" oder "Mesh mesh-stab {" u.v.m. enthalten! if (pruefeAuf_Zeichenfolge("Mesh ")==true) // Prüfung=-ok- { m_Art_aktDatZeile=inDz_Mesh_X; return; } // 40=inDz_Mesh_X // ..."MeshNormals {" -Zeile? if (pruefeAuf_Zeichenfolge("MeshNormals {")==true) // Prüfung=-ok- { m_Art_aktDatZeile=inDz_Normals_X; return; } // 43=inDz_Normals_X // ..."MeshTextureCoords {" -Zeile? if (pruefeAuf_Zeichenfolge("MeshTextureCoords {")==true) // Prüfung=-ok- { m_Art_aktDatZeile=inDz_MeshTextureCoords_X; return; } // 45=inDz_MeshTextureCoords_X // ..."VertexDuplicationIndices {" -Zeile? if (pruefeAuf_Zeichenfolge("VertexDuplicationIndices {")==true) // Prüfung=-ok- { m_Art_aktDatZeile=inDz_VertexDuplicationIndices_X; return; } // 50=inDz_VertexDuplicationIndices_X // ..."MeshMaterialList {" -Zeile? if (pruefeAuf_Zeichenfolge("MeshMaterialList {")==true) // Prüfung=-ok- { m_Art_aktDatZeile=inDz_MeshMaterialList_X; return; } // 60=inDz_MeshMaterialList_X // ..."Material " -Zeile? if (pruefeAuf_Zeichenfolge("Material ")==true) // Prüfung=-ok- { m_Art_aktDatZeile=inDz_Material_X; return; } // 63=inDz_Material_X // ** Animations-Einträge ** // ..."XSkinMeshHeader {" -Zeile? if (pruefeAuf_Zeichenfolge("XSkinMeshHeader {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_XSkinMeshHeader; return; } // 70=inDz_XSkinMeshHeader // ..."SkinWeights {" -Zeile? if (pruefeAuf_Zeichenfolge("SkinWeights {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_SkinWeights; return; } // 72=inDz_SkinWeights // ACHTUNG: // // Folgende Einträge wie z.B. "AnimationKey" enthalten in X-Files // ?nur von Milkshape 3D? keine geschweifte Klammern! // Also statt "AnimationKey {" steht dort "AnimationKey" ohne Klammer! // ..."AnimationSet " -Zeile? if (pruefeAuf_Zeichenfolge("AnimationSet")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_AnimationSet; return; } // 75=inDz_AnimationSet // else { // ..."Animation" -Zeile? if (pruefeAuf_Zeichenfolge("Animation")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("AnimationKey")==false && pruefeAuf_Zeichenfolge("AnimationOptions")==false) { m_Art_aktDatZeile=inDz_Animation; // 80=inDz_Animation } } } // ..."AnimationKey" oder "template AnimationKey"-Zeile? // if (pruefeAuf_Zeichenfolge("AnimationKey")==true) // Prüfung=-- // { // if (pruefeAuf_Zeichenfolge("template AnimationKey")==true) // Prüfung=-- // { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template // else // { m_Art_aktDatZeile=inDz_AnimationKey; } // 82=inDz_AnimationKey // } // Weil nur dort auf geschlossene Klammer geprüft werden soll, // wo nicht direkt nach einen Dateiblock so eine Klammer folgt if (m_Art_aktDatZeile==inDz_Sonstiges) { // ..."}" (=geschlossene Klammer) -Zeile? if (pruefeAuf_Zeichenfolge("}")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_End_Klammer; } // } // *** Original-Version (11.03.2015 vor 02:35 Uhr) *** /* // Erstmal auf Sonstiges setzen (Falls nichts verwertbares gefunden wird) m_Art_aktDatZeile=inDz_Sonstiges; // 99=inDz_Sonstiges // Ist aktuelle Datei-Zeile eine... // ...leere Zeile? // Prüft, ob m_akt_Datei_Zeile eine Leere Zeile ist // (Ob das Zeichen '\n' (=Zeilenvorschub) am ZeilenANFANG steht) if (pruefeAuf_LeereZeile() == true) // Prüfung=-OK- { m_Art_aktDatZeile=inDz_LeereZeile; } // 1=inDz_LeereZeile // ...Kommentar-Zeile? // Prüft, ob m_akt_Datei_Zeile eine Kommentarzeile ist // (Ob die Zeichen "//" oder "#" am ZeilenANFANG stehen) if (pruefeAuf_Kommentarzeile() == true) // Prüfung=-OK- { m_Art_aktDatZeile=inDz_Kommentar; } // 2=inDz_Kommentar // Falls nein, dann auf andere Dateizeilenarten überprüfen if ( (m_Art_aktDatZeile != inDz_LeereZeile) && (m_Art_aktDatZeile != inDz_Kommentar) ) { // Ist aktuelle Datei-Zeile eine... // ...Template-Zeile? // Enthält m_akt_Datei_Zeile irgendwo die Zeichenfolge "template "? // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält if (pruefeAuf_Zeichenfolge("template ")==true) // Prüfung=-OK- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Kommentar // ..."Frame "-Zeile? if (pruefeAuf_Zeichenfolge("Frame ")==true) // Prüfung=-OK- { m_Art_aktDatZeile=inDz_Frame; } // 20=inDz_Frame // ..."FrameTransformMatrix {"-Zeile? // if (pruefeAuf_Zeichenfolge("FrameTransformMatrix {")==true) // Prüfung=-ok- // { m_Art_aktDatZeile=inDz_FrameTransformMatrix; } // 30=inDz_FrameTransformMatrix // ..."Mesh " oder "template Mesh {"-Zeile? // // Zeile kann nur "Mesh {", aber auch variable Namen wie z.B. // "Mesh mesh-guard {" oder "Mesh mesh-stab {" u.v.m. enthalten! if (pruefeAuf_Zeichenfolge("Mesh ")==true) // Prüfung=-ok- { // ACHTUNG: der Eintrag "template Mesh {" enthält auch "Mesh "! // // um zu verhindern, das bei diesen Eintrag inDz_Mesh_X statt // inDz_TemplateMesh aktiviert wird, folgendes prüfen: if (pruefeAuf_Zeichenfolge("template Mesh {")==true) { m_Art_aktDatZeile=inDz_TemplateMesh; // 11=inDz_TemplateMesh } else { m_Art_aktDatZeile=inDz_Mesh_X; // 40=inDz_Mesh_X } } // ..."MeshNormals {" oder "template MeshNormals {"-Zeile? if (pruefeAuf_Zeichenfolge("MeshNormals {")==true) // Prüfung=-ok- { if (pruefeAuf_Zeichenfolge("template MeshNormals {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_Normals_X; } // 43=inDz_Normals_X } // ..."MeshTextureCoords {" oder "template MeshTextureCoords {" -Zeile? if (pruefeAuf_Zeichenfolge("MeshTextureCoords {")==true) // Prüfung=-ok- { if (pruefeAuf_Zeichenfolge("template MeshTextureCoords {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_MeshTextureCoords_X; } // 45=inDz_MeshTextureCoords_X } // ..."VertexDuplicationIndices {" oder "template VertexDuplicationIndices {"-Zeile? if (pruefeAuf_Zeichenfolge("VertexDuplicationIndices {")==true) // Prüfung=-ok- { if (pruefeAuf_Zeichenfolge("template VertexDuplicationIndices {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_VertexDuplicationIndices_X; } // 50=inDz_VertexDuplicationIndices_X } // ..."MeshMaterialList {" oder "template MeshMaterialList {"-Zeile? if (pruefeAuf_Zeichenfolge("MeshMaterialList {")==true) // Prüfung=-ok- { if (pruefeAuf_Zeichenfolge("template MeshMaterialList {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_MeshMaterialList_X; } // 60=inDz_MeshMaterialList_X } // ..."Material " oder "template Material {"-Zeile? if (pruefeAuf_Zeichenfolge("Material ")==true) // Prüfung=-ok- { if (pruefeAuf_Zeichenfolge("template Material {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_Material_X; } // 63=inDz_Material_X } // ** Animations-Einträge ** // ..."XSkinMeshHeader {" oder "template XSkinMeshHeader {"-Zeile? if (pruefeAuf_Zeichenfolge("XSkinMeshHeader {")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("template XSkinMeshHeader {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_XSkinMeshHeader; } // 70=inDz_XSkinMeshHeader } // ..."SkinWeights {" oder "template SkinWeights {"-Zeile? if (pruefeAuf_Zeichenfolge("SkinWeights {")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("template SkinWeights {")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_SkinWeights; } // 72=inDz_SkinWeights } // ACHTUNG: // // Folgende Einträge wie z.B. "AnimationKey" enthalten in X-Files // ?nur von Milkshape 3D? keine geschweifte Klammern! // Also statt "AnimationKey {" steht dort "AnimationKey" ohne Klammer! // ..."AnimationSet " oder "template AnimationSet "-Zeile? if (pruefeAuf_Zeichenfolge("AnimationSet")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("template AnimationSet")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { m_Art_aktDatZeile=inDz_AnimationSet; } // 75=inDz_AnimationSet } // else { // ..."Animation" oder "template Animation"-Zeile? if (pruefeAuf_Zeichenfolge("Animation")==true) // Prüfung=-- { if (pruefeAuf_Zeichenfolge("template Animation")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template else { if (pruefeAuf_Zeichenfolge("AnimationKey")==false && pruefeAuf_Zeichenfolge("AnimationOptions")==false) { m_Art_aktDatZeile=inDz_Animation; // 80=inDz_Animation } } } } // ..."AnimationKey" oder "template AnimationKey"-Zeile? // if (pruefeAuf_Zeichenfolge("AnimationKey")==true) // Prüfung=-- // { // if (pruefeAuf_Zeichenfolge("template AnimationKey")==true) // Prüfung=-- // { m_Art_aktDatZeile=inDz_Template; } // 10=inDz_Template // else // { m_Art_aktDatZeile=inDz_AnimationKey; } // 82=inDz_AnimationKey // } // Weil nur dort auf geschlossene Klammer geprüft werden soll, // wo nicht direkt nach einen Dateiblock so eine Klammer folgt if (m_Art_aktDatZeile==inDz_Sonstiges) { // ..."}" (=geschlossene Klammer) -Zeile? if (pruefeAuf_Zeichenfolge("}")==true) // Prüfung=-- { m_Art_aktDatZeile=inDz_End_Klammer; } } } */ /* inDz_LeereZeile =1, // 1=enthält nur Leerzeichen inDz_Kommentar =2, // 2=enthält Kommentar (beginnend mit // oder #) inDz_Template =10, // 10=enthält irgendein Template inDz_TemplateMesh =11, // 11=enthält "template Mesh {" inDz_Frame =20, // 20=enthält "Frame " inDz_FrameTransformMatrix =30, // 30=enthält "FrameTransformMatrix {" inDz_Mesh_X =40, // 40=enthält "Mesh " inDz_Normals_X =43, // 43=enthält "MeshNormals {" inDz_MeshTextureCoords_X =45, // 45=enthält "MeshTextureCoords {" inDz_VertexDuplicationIndices_X =50, // 50=enthält "VertexDuplicationIndices {" inDz_MeshMaterialList_X =60, // 60=enthält "MeshMaterialList {" inDz_Material_X =63, // 63=enthält "Material " inDz_End_Klammer =69 // 69= // Zukünftig einbauen: Für Animation von X-Files //inDz_XSkinMeshHeader =70, // 70=enthält "XSkinMeshHeader {" //inDz_SkinWeights =72, // 72=enthält "SkinWeights {" inDz_AnimationSet =75, // 75=enthält "AnimationSet " inDz_Animation =80, // 80=enthält "Animation " //inDz_AnimationKey =82, // 82=enthält "AnimationKey" inDz_AnimationOptions =90, // 90=enthält "AnimationOptions" inDz_Sonstiges =99 // 99=enthält Etwas, was nicht behandelt/abgefragt wird */ } // Prüft, ob m_akt_Datei_Zeile irgendwo die // übergebene Zeichenfolge enthält (Z.B. "template ") bool Kl_3D_Objekt::pruefeAuf_Zeichenfolge(char *Zeichenfolge) { char *pdest; int PositionImString; // Position, ab der Zeichenfolge im String // gefunden wird pdest = strstr( m_akt_Datei_Zeile, Zeichenfolge ); PositionImString = pdest - m_akt_Datei_Zeile + 1; // if (pdest != NULL) { return (true); } else { return (false); } } // Entfernt "//" incl nachfolgenden Kommentar-Text aus m_akt_Datei_Zeile. // Beispiel: Aus "} // End of AnimationSet Global" wird "} " void Kl_3D_Objekt::verwandle_inKommentarlos(void) { char *pdest; int PositionImString; // Position, ab der Zeichenfolge im String // gefunden wird // strstr()=Find a substring pdest = strstr(m_akt_Datei_Zeile, "//"); // PositionImString = pdest - m_akt_Datei_Zeile; // if (pdest != NULL) { // String soweit kürzen, daß er kein "//" & Kommentar mehr enthält m_akt_Datei_Zeile[PositionImString]='\0'; } } // Prüft, ob m_akt_Datei_Zeile eine Kommentarzeile ist // (Ob die Zeichen "//" oder "#" am ZeilenANFANG stehen) bool Kl_3D_Objekt::pruefeAuf_Kommentarzeile(void) { // Infos zu Kommentaren in X-Files // // ACHTUNG: Kommentare können überall im X-File vorkommen! // // Comments are only applicable in X-File text files. Comments can occur // anywhere in the data stream. A comment begins with either // C++ style double-slashes "//", or a number sign "#". // The comment runs to the next new line. // // Steht am Zeilenanfang "//"? if (m_akt_Datei_Zeile[0]=='/') { if (m_akt_Datei_Zeile[1]=='/') { // Prüfung=-OK- return (true); } } // Steht am Zeilenanfang "#"? if (m_akt_Datei_Zeile[0]=='#') { return (true); } // Prüfung=-OK- //strchr(m_akt_Datei_Zeile, '}') == NULL // Wenn kein Kommentar gefunden wurde return (false); } // Prüft, ob m_akt_Datei_Zeile eine Leere Zeile ist // (Ob das Zeichen '\n' (=Zeilenvorschub) am ZeilenANFANG steht) bool Kl_3D_Objekt::pruefeAuf_LeereZeile(void) { // if (m_akt_Datei_Zeile[0]=='\n') // Prüfung=-OK- { return (true); } else { return (false); } } // prüft, ob // -m_DateiInput_3D_Objekt == NULL ist, und ob // -Datei ein X-File ist. // Rückgabewert: False, falls m_DateiInput_3D_Objekt==NULL, // oder wenn Datei kein X-File ist bool Kl_3D_Objekt::pruefe_XFile_Datei(void) { // Entweder Fehlermeldung (z.B. wg. fehlender Datei) zeigen... if (m_DateiInput_3D_Objekt == NULL) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::pruefe_XFile_Datei(...)", 6); m_z_Kl_Debug->set_Meldung("beim laden der 3D-Objekt-Datei.", 5); m_z_Kl_Debug->set_Meldung("Event. Ursache: Ist die Datei vorhanden? Stimmt Dateiname?", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // return (false); } // ...oder else { // bool XDatei_IstEin_XFile; // 1.) Prüfen, ob Datei ein X-File ist // Lädt den Header (die 1.Zeile) einer geöffneten X-Datei // Bsp für Header: "xof 0303txt 0032" // // Rückgabewert: false, wenn Datei kein "xof" enthält (Datei Kein X-File ist) // ("xof"=Erkennungsmerkmal für XFile) XDatei_IstEin_XFile=lade_Header_XFile(); // if (XDatei_IstEin_XFile==false) { m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt::pruefe_XFile_Datei(...)", 6); m_z_Kl_Debug->set_Meldung("Datei ist kein X-File (Enthält kein xof):", 5); m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); return (false); } // Weil Datei ein X-File ist, // kann alles weitere geladen werden else { // return (true); } } } // Behandelt den Datei-Zeilen-Inhalt, // der in m_Art_aktDatZeile steht void Kl_3D_Objekt::behandleInhalt_DatZeile(void) { // Hier begann behobener Fehler bei XFile mit 3 Boxen: lade_Mesh_XFile() /* static char n=0; if (m_Art_aktDatZeile==inDz_Normals_X) { n++; if (n==3) { char b=0; } } */ switch (m_Art_aktDatZeile) { // 1=inDz_LeereZeile case inDz_LeereZeile: { }break; // 2=inDz_Kommentar case inDz_Kommentar: { // m_akt_Datei_Zeile enthält jetzt Text der Kommentarzeile // (Text der aktuell gelesenen Dateizeile) }break; // 10=inDz_Template case inDz_Template: { // Nur laden, wenn erlaubt // (Um mehrfache Ausgabe gleicher Fehlermeldungen & Prg-Abstürze zu vermeiden) if (m_XFile_istOK==true) { // Derzeitiger Stand: Überspringt Einträge des aktuellen Templates // des X-Files, damit Dateizeiger auf der Zeile nach dem Ende des // Templates gelangt lade_Template_XFile(); } }break; // 11=inDz_TemplateMesh case inDz_TemplateMesh: { if (m_XFile_istOK==true) { // Derzeitiger Stand: Überspringt Einträge des aktuellen Templates // des X-Files, damit Dateizeiger auf der Zeile nach dem Ende des // Templates gelangt lade_Template_XFile(); } }break; // 20=inDz_Frame case inDz_Frame: { if (m_XFile_istOK==true) { // Derzeitiger Stand: // Ließt Frame-Name & Frame-Transformations-Matrix // aus dem jew. "Frame "-Block lade_Frame_XFile(); } }break; /* // 30=inDz_FrameTransformMatrix case inDz_FrameTransformMatrix: { // Derzeitiger Stand: // Liest Einträge des jew. "FrameTransformMatrix {"-Blocks, // und speichert sie VORERST in m_3D_Objekt_Matrix lade_FrameTransformMatrix_XFile(); }break; */ // 40=inDz_Mesh_X case inDz_Mesh_X: { if (m_XFile_istOK==true) { // m_Nr_akt_Mesh kann jetzt um 1 erhöht werden, // weil laut meiner Analyse der Mesh Eintrag // immer über den anderen Einträgen steht // (andere Einträge sind z.B. Normalen & Texturkoordinaten) m_Nr_akt_Mesh++; // INFO: Wenn jetzt nur der 1.Mesh gefunden wurde, // dann ist m_Nr_akt_Mesh jetzt=0 (0=Mesh Nr.1, 1=Mesh Nr.2, usw) // Ließt die Inhalte des Mesh-Blocks // (Anzahl der Vertices, alle Vertex-Daten (X,Y,Z-Pos), // Anzahl der Faces & alle Index-Daten(Für Indexbuffer) ) lade_Mesh_XFile(); } }break; // 43=inDz_Normals_X case inDz_Normals_X: { if (m_XFile_istOK==true) { // Ließt die Inhalte des MeshNormals-Blocks // (Anzahl der Normalen?, alle Normalenvektor-Daten (nx,ny,nz). // Der Rest des Blocks wird NICHT gelesen!) lade_MeshNormals_XFile(); // Speichern, daß X-File Normalenvektoren hat m_XFile_hatNormalen=true; } }break; // 45=inDz_MeshTextureCoords_X case inDz_MeshTextureCoords_X: { if (m_XFile_istOK==true) { // Ließt die Inhalte des MeshTextureCoords-Blocks // (Anzahl der Texturkoordinaten? und alle // Texturkoordinaten-Daten (tu, tv) ) lade_MeshTextureCoords_XFile(); // speichern, daß X-File Texturkoordinaten enthält m_XFile_hatTexturkoordinaten=true; } }break; // 50=inDz_VertexDuplicationIndices_X case inDz_VertexDuplicationIndices_X: { /**/ if (m_XFile_istOK==true) { lade_VertexDuplicationIndices(); } }break; // 60=inDz_MeshMaterialList_X case inDz_MeshMaterialList_X: { /* if (m_XFile_istOK==true) { lade_MeshMaterialList(); } Infos: MeshMaterialList { 4; // 1 Materialien 6; // 6 Oberflächen/Faces 0, // 0, // 0, 0, 0, 0; { Material0 } { Material1 } { Material2 } { Material3 } { Material4 } */ }break; // 63=inDz_Material_X case inDz_Material_X: { if (m_XFile_istOK==true) { // Ließt das Material & eine eventuell vorhandene // Textur & Dateinamen dafür ein. // // ACHTUNG: Im Dateinamen der Textur darf momentan kein // Leerzeichen sein! // lade_Material_XFile(); } }break; // 69=inDz_Material_X case inDz_End_Klammer: { if (m_XFile_istOK==true) { // um 1 erhöhen m_akt_anz_EndKlammern++; //MessageBox(0, "Endklammer gefunden", "Endklammer-Test", MB_OK); } }break; // ** Animations-Einträge ** // 70=inDz_XSkinMeshHeader case inDz_XSkinMeshHeader: { // Nur laden, wenn erlaubt // (Um mehrfache Ausgabe gleicher Fehlermeldungen zu vermeiden) if (m_Animationsdaten_sindOK==true) { // Ließt die Inhalte des XSkinMeshHeader-Blocks ein, // und speichert aktuell nur den 3.Eintrag des Blocks // in "m_Anz_Bones_MeshNr[m_Nr_akt_Mesh]" lade_anim_XSkinMeshHeader(); } }break; // 72=inDz_SkinWeights case inDz_SkinWeights: { if (m_Animationsdaten_sindOK==true) { // AKTUELLER Stand: Ließt nur die Daten EINES Bones ein, // und NICHT die mehrerer Bones. // // Speichert Daten in m_anz_Vertices_Bone, m_vBoneBeeinfltrIndice[], // m_BoneWeight[], und in m_BoneSpace_Matrix. lade_anim_SkinWeights(); } }break; // 75=inDz_AnimationSet case inDz_AnimationSet: { if (m_Animationsdaten_sindOK==true) { lade_anim_AnimationSet(); } }break; // 80=inDz_Animation case inDz_Animation: { if (m_Animationsdaten_sindOK==true) { lade_anim_Animation(); } }break; /* // 82=inDz_AnimationKey case inDz_AnimationKey: { if (m_Animationsdaten_sindOK==true) { // lade_anim_AnimationKey(); } }break; */ // 99=inDz_Sonstiges case inDz_Sonstiges: { }break; }; /* inDz_LeereZeile =1, // 1=enthält nur Leerzeichen inDz_Kommentar =2, // 2=enthält Kommentar (beginnend mit // oder #) inDz_Template =10, // 10=enthält irgendein Template inDz_TemplateMesh =11, // 11=enthält "template Mesh {" inDz_Frame =20, // 20=enthält "Frame " inDz_FrameTransformMatrix =30, // 30=enthält "FrameTransformMatrix {" inDz_Mesh_X =40, // 40=enthält "Mesh " inDz_Normals_X =43, // 43=enthält "MeshNormals {" inDz_MeshTextureCoords_X =45, // 45=enthält "MeshTextureCoords {" inDz_VertexDuplicationIndices_X =50, // 50=enthält "VertexDuplicationIndices {" inDz_MeshMaterialList_X =60, // 60=enthält "MeshMaterialList {" inDz_Material_X =63, // 63=enthält "Material " // Zukünftig einbauen: Für Animation von X-Files //inDz_XSkinMeshHeader =70, // 70=enthält "XSkinMeshHeader {" //inDz_SkinWeights =72, // 72=enthält "SkinWeights {" inDz_AnimationSet =75, // 75=enthält "AnimationSet " inDz_Animation =80, // 80=enthält "Animation " //inDz_AnimationKey =82, // 82=enthält "AnimationKey" inDz_AnimationOptions =90, // 90=enthält "AnimationOptions" inDz_Sonstiges =99 // 99=enthält Etwas, was nicht behandelt/abgefragt wird */ } // setzt die X,Y & Z-Position, an die das 3D-Objekt in zeig_3D_Objekt // und die Boundingbox in zeig_BoundingBox() verschoben wird (Transformation) void Kl_3D_Objekt::set_3D_Objekt_xyzPos(float xPos, float yPos, float zPos) { // Später löschen: m_3D_Objekt_xPos=xPos; m_3D_Objekt_yPos=yPos; m_3D_Objekt_zPos=zPos; // Neu: Positionen in der Matrix speichern m_3D_Objekt_Matrix._41=xPos; m_3D_Objekt_Matrix._42=yPos; m_3D_Objekt_Matrix._43=zPos; // Darf nur ausgeführt werden, wenn X-File richtig geladen wurde. // (Um eventuellen PRG-Absturz zu vermeiden) if (m_XFile_istOK==true) { // x/y/z-Position der Boundingbox aktualisieren // (m_3D_Objekt_Matrix=Matrix fürs gesammte 3D-Objekt) m_KollisionsObj->set_Pos_KollisionsObj(&m_3D_Objekt_Matrix); } } // float Kl_3D_Objekt::get_3D_Objekt_xPos(void) { return (m_3D_Objekt_xPos); } // float Kl_3D_Objekt::get_3D_Objekt_yPos(void) { return (m_3D_Objekt_yPos); } // float Kl_3D_Objekt::get_3D_Objekt_zPos(void) { return (m_3D_Objekt_zPos); } // Gesammt-Anzahl der Vertices vom 3D-Objekt des X-Files erhalten unsigned int Kl_3D_Objekt::get_AnzVertices_3D_Objekt(void) { return (m_Anz_Vertices_3D_Objekt); } // ?Gesammt? -Anzahl der Indices vom 3D-Objekt des X-Files erhalten unsigned int Kl_3D_Objekt::get_AnzIndices_3D_Objekt(void) { return (m_Anz_Indices_3D_Objekt); } // ?Gesammt? -Anzahl der Faces vom 3D-Objekt des X-Files erhalten unsigned int Kl_3D_Objekt::get_AnzFaces_3D_Objekt(void) { return (m_Anz_Faces_3D_Objekt); } // Anzahl der Meshes vom 3D-Objekt des X-Files erhalten unsigned short int Kl_3D_Objekt::get_Anz_Meshes_3D_Objekt(void) { return (m_Anz_Meshes_3D_Obj); } // unsigned int Kl_3D_Objekt::get_Anz_Vertices__MeshNr(short int MeshNr) { return (m_Anz_Vertices_MeshNr[MeshNr]); } // unsigned int Kl_3D_Objekt::get_Anz_Faces__MeshNr(short int MeshNr) { return (m_Anz_Faces_MeshNr[MeshNr]); } // unsigned int Kl_3D_Objekt::get_3D_Obj_Vertice_AddWert__MeshNr(short int MeshNr) { return (m_3D_Obj_Vertice_AddWert_Mesh[MeshNr]); } // unsigned int Kl_3D_Objekt::get_3D_Obj_IndexbufferPos_Mesh__MeshNr(short int MeshNr) { return (m_3D_Obj_IndexbufferPos_Mesh[MeshNr]); } // float Kl_3D_Objekt::get_3D_Objekt_Vertex_x_VtxNr(unsigned int Nr_Vertex) { return (m_3D_Objekt_Vertices[Nr_Vertex].x); } // float Kl_3D_Objekt::get_3D_Objekt_Vertex_y_VtxNr(unsigned int Nr_Vertex) { return (m_3D_Objekt_Vertices[Nr_Vertex].y); } // float Kl_3D_Objekt::get_3D_Objekt_Vertex_z_VtxNr(unsigned int Nr_Vertex) { return (m_3D_Objekt_Vertices[Nr_Vertex].z); } // Übergibt alle Vertices des 3D-Objekts ans übergebene Vertice-Array void Kl_3D_Objekt::get_3D_Objekt_Vertices(CUSTOMVERTEX_3D_Objekt_1* Array_Vertices) { // Fehlerprüfung // Ist Zeiger ungültig? (Wurde kein Speicher fürs Ziel-Array reserviert?) if (Array_Vertices==NULL) { m_z_Kl_Debug->set_Meldung( "Kl_3D_Objekt::get_3D_Objekt_Vertices(...) Array_Vertices ist NULL",6); m_z_Kl_Debug->set_Meldung("Event. Ursache: Wurde Speicherreservieren vergessen?", 5); } // Kein Fehler, deswegen anfangen else { // Alle Verticebestandteile des gesammten 3D-Objekts ins Ziel-Vertice-Array kopieren unsigned int Nr_Vertice; for (Nr_Vertice=0; Nr_Vertice < m_Anz_Vertices_3D_Objekt; Nr_Vertice++) { Array_Vertices[Nr_Vertice].x=m_3D_Objekt_Vertices[Nr_Vertice].x; Array_Vertices[Nr_Vertice].y=m_3D_Objekt_Vertices[Nr_Vertice].y; Array_Vertices[Nr_Vertice].z=m_3D_Objekt_Vertices[Nr_Vertice].z; Array_Vertices[Nr_Vertice].nx=m_3D_Objekt_Vertices[Nr_Vertice].nx; Array_Vertices[Nr_Vertice].ny=m_3D_Objekt_Vertices[Nr_Vertice].ny; Array_Vertices[Nr_Vertice].nz=m_3D_Objekt_Vertices[Nr_Vertice].nz; Array_Vertices[Nr_Vertice].tu=m_3D_Objekt_Vertices[Nr_Vertice].tu; Array_Vertices[Nr_Vertice].tv=m_3D_Objekt_Vertices[Nr_Vertice].tv; } } } // Geplant: Übergibt alle Indices des 3D-Objekts ans übergebene Array void Kl_3D_Objekt::get_3D_Objekt_Indices(short int *Array_Indices) { // Fehlerprüfung // Ist Zeiger ungültig? (Wurde kein Speicher fürs Ziel-Array reserviert?) if (Array_Indices==NULL) { m_z_Kl_Debug->set_Meldung( "Kl_3D_Objekt::get_3D_Objekt_Indices(...) Array_Indices ist NULL",6); m_z_Kl_Debug->set_Meldung("Event. Ursache: Wurde Speicherreservieren vergessen?", 5); } // Kein Fehler, deswegen anfangen else { // Alle Indices des gesammten 3D-Objekts ins Ziel-Array kopieren unsigned int Nr_Indice; for (Nr_Indice=0; Nr_Indice < m_Anz_Indices_3D_Objekt; Nr_Indice++) { Array_Indices[Nr_Indice]=m_3D_Objekt_Indices[Nr_Indice]; } } } // Y-Drehung/Rotation setzen (Richtung per float Wert) // (=Drehung nach Links/rechts, wie z.B. Brumkreisel/Karussel mit Tierfiguren) // // ACHTUNG: Für Ordnungsgemäße Drehung muß XZ-0-Achse // durch Mitte des 3D-Objekts gehen! // // Standartwert=0.0f; // Maxwert=ca.3,141576f (=360 Grad * (Pi / 180.0f) // -1.5f=Nach hinten (Vom Monitor zu mir) // 0.0f=Nach links (Links vom Monitor) // 1.5f=Nach vorne (Vom Monitor zur Wand) // -3.0f=Nach rechts (Rechts vom Monitor) void Kl_3D_Objekt::set_3D_Objekt_yDrehung(float yDrehung) { m_3D_Objekt_yDrehung=yDrehung; } // Y-Drehung/Rotation setzen (Richtung siehe Pfeil-NUM-Tasten & Zahlen) // (=Drehung nach Links/rechts, wie z.B. Brumkreisel/Karussel mit Tierfiguren) // // ACHTUNG: Für Ordnungsgemäße Drehung muß XZ-0-Achse // durch Mitte des 3D-Objekts gehen! // // 2=Nach hinten (Vom Monitor zu mir) // 4=Nach links (Links vom Monitor) // 8=Nach vorne (Vom Monitor zur Wand) // 6=Nach rechts (Rechts vom Monitor) void Kl_3D_Objekt::set_3D_Objekt_yDrehung(unsigned char yDrehungsRichtung) { switch (yDrehungsRichtung) { case 2:{ m_3D_Objekt_yDrehung=-1.5f; }break; // Gesicht Nach Hinten case 4:{ m_3D_Objekt_yDrehung=0.0f; }break; // Gesicht Nach Links case 6:{ m_3D_Objekt_yDrehung=-3.0f; }break; // Gesicht Nach Rechts case 8:{ m_3D_Objekt_yDrehung=1.5f; }break; // Gesicht Nach Vorne } } // Ersetzt die bereits aus dem Mesh geladene Textur durch die Übergebene Textur // (Z.B., um Mund von sprechenden Geist zu bewegen) // Parameter: // 1=Nr des Meshes, für den die neue Textur angezeigt werden soll // 2=Neue Textur void Kl_3D_Objekt::set_3D_Objekt_Textur(unsigned short int Textur_MeshNr, LPDIRECT3DTEXTURE9 Neue_Textur) { m_3D_Objekt_Textur[Textur_MeshNr]=Neue_Textur; } // Sorgt dafür, daß sich das 3D-Objekt bewegt (=Animation) // (Ermittelt aktuellen Animationsschritt, // und verschiebt Vertices des 3D-Objekts zu den Gelenken/Joints) // // Wird diese Methode nicht aufgerufen, dann wird daß 3D-Objekt in // Startstellung angezeigt void Kl_3D_Objekt::animiere_3D_Obj(void) { // Funktion nur ausführen, wenn erlaubt // (Um Programmabstürze bei X-File Problemen zu vermeiden, // und eventuelle Prg-Meldungen trotzdem lesen zu können) if (m_Animationsdaten_sindOK==false) { return; } // 1.) ermittelt aktuellen Animationsschritt, und speichert Ergebniss // in m_akt_FrameNr ermittle_akt_Animationsschritt(); // 2.) // Verschiebt Vertices den Joints entsprechend, für aktuellen Animationsschritt verschiebe_Vertices_Joints(); } // void Kl_3D_Objekt::set_aktMaterial_Mat_bBox_bSphere(void) { // Kl_DX_KollisionsObj_r::set_aktMaterial_MatKollisionsObj(); } // zeigt ein bereits geladenes 3D-Objekt // an der mit set_3D_Objekt_xyzPos() gesetzten Position // // Wenn 3D-Objekt mit Transparenz (z.B. Bäume) angezeigt werden sollen, // dann ist vorher "Kl_3D::set_Transparenz_aktivieren()" aufzurufen. void Kl_3D_Objekt::zeig_3D_Objekt(void) { // 3D-Objekt nur zeigen, wenn erlaubt (Fehler & PRG-Absturz Vermeidung) if (m_XFile_istOK == true) { // Vertex-Format festlegen m_z_m_Grafikkarte->SetFVF(D3D_CUSTOMVERTEX_3D_Objekt_1); // verschiebt das aktuelle 3D-Objekt innerhalb der 3D-Welt // (Je größer Parameter 3(zPos),desto weiter die Entfernung zum Betrachter) // m_z_Kl_3D->verschiebe_3D_Objekt(m_3D_Objekt_xPos, m_3D_Objekt_yPos, m_3D_Objekt_zPos); D3DXMATRIX TranslationMatrix; D3DXMatrixTranslation( &TranslationMatrix, // m_3D_Objekt_xPos, // in X-Richtung m_3D_Objekt_yPos, // in Y-Richtung m_3D_Objekt_zPos // in Z-Richtung ); m_z_m_Grafikkarte->SetTransform( D3DTS_WORLD, &TranslationMatrix ); // Später einbauen ??? /* // Gesammtes 3D-Objekt positionieren usw // // (DirectX mitteilen, welche Matrix als aktuelle Welt-Transformationmatrix dient // // World-Transformation bedeutet das Platzieren eines 3D-Objekts vom local space in den // World-space. Also, wo das Objekt in der 3D-Welt platziert werden soll. // // Sollen mehrere 3D-Objekte an unterschiedlichen Positionen positioniert werden, // braucht jedes Objekt eine eigene Worlmatrix, SetTransform(), usw.) m_z_m_Grafikkarte->SetTransform( D3DTS_WORLD, // D3DTS_WORLD=Teilt Direct3D mit, daß die angegebene // Matrix für die World-Transformation benutzt werden soll. // Alles, was hinterher noch gerendert wird, richtet // sich nach dieser Matrix. &m_3D_Objekt_Matrix // &m_3D_Objekt_Matrix ); */ m_z_Kl_3D->set_m_Transformation_wurdeDurchgefuehrt__true(); // Positionen in der Matrix speichern // --> Wird schon woanders erledigt! //m_3D_Objekt_Matrix._41=m_3D_Objekt_xPos; //m_3D_Objekt_Matrix._42=m_3D_Objekt_yPos; //m_3D_Objekt_Matrix._43=m_3D_Objekt_zPos; // DX mitteilen,von welchem Indexbuffer die zu zeichnenden Daten entnommen werden sollen: m_z_m_Grafikkarte->SetIndices(m_Indexbuffer_3D_Objekt); // Falls zuvor kein 3D-Objekt durch Kl_3D verschoben,skaliert oder rotiert wurde, dann: // setzt als aktuell zu verwendene Matrix m_WorldMatrix als Matrix, // und macht die WorldMatrix zuvor zur Einheitsmatrix m_z_Kl_3D->set_aktMatrix__WorldMatrix(); // 3D-Objekt mit einem bzw mehreren Meshes zeigen for (unsigned short int akt_MeshNr=0; akt_MeshNr < m_Anz_Meshes_3D_Obj; akt_MeshNr++) { // // m_z_Kl_3D->set_akt_Material(&m_3D_Objekt_Material[akt_MeshNr]); m_z_m_Grafikkarte->SetMaterial(&m_3D_Objekt_Material[akt_MeshNr]); // Textur für aktuellen Zeichen/Rendervorgang setzen, // falls X-File einen Eintrag dafür hatte & anzeigen erlaubt ist if (m_TexturAnzeigen_erlaubt == true) { //m_z_Kl_3D->set_akt_Textur(m_3D_Objekt_Textur[akt_MeshNr]); m_z_m_Grafikkarte->SetTexture(0, m_3D_Objekt_Textur[akt_MeshNr]); } // Vertexzähler anpassen // // D3DPT_TRIANGLELIST=Dreiecksliste. Jedes Dreieck hat 3 Vertices. // Beispiel: Für 3 per Trianglelist übergebene Dreiecke werden demnach 9 Vertices übergeben. // // Prüfung auf richtige Berechnung: -OK- (Getestet mit Gitterstangen, Kübelpflanzen & Rasen) // Kl_VertexUswZaehler::Vertex_Zaehler__Kl_3D_Objekt+=m_Anz_Vertices_MeshNr[akt_MeshNr]; // Die Daten des aktuellen INDEX & Vertexbuffers rendern (Anzeigen usw) m_z_m_Grafikkarte->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, // 1.) Welche Art von Primitiven sind im Indexbuffer gespeichert? // Beispiel: "D3DPT_TRIANGLELIST"=Liste mit Dreiecken // m_3D_Obj_Vertice_AddWert_Mesh[akt_MeshNr], // 2.) Wert wird zu allen Indizes im Indexbuffer hinzuaddiert. // (?Wert? Kann negativ, null oder positiv sein, laut Buch) // // Beispiel Wenn Wert z.B.4 ist, dann würde // Index 0 zu Vertex 4, und // Index 1 zu Vertex 5, usw zeigen // 0, // 3.) Kleinster Index, der verwendet wird. // Wert ist relativ zu 2.) // (Info: DX weiß somit, welche Vertizes abrufbereit sein müssen) // m_Anz_Vertices_MeshNr[akt_MeshNr], // 4.) Wieviele Vertices sollen verwendet werden? // Beim Würfel sind es z.B. 8 // (Info: DX weiß somit, welche Vertizes abrufbereit sein müssen) // m_3D_Obj_IndexbufferPos_Mesh[akt_MeshNr], // 5.) Position im Indexbuffer, ab der Dreiecke gerendert werden. // (0=1. Index, 1=2. Index,...) // Wenn Index buffer z.B. 2 Objekte enthält, // und das 1. von 0-35 geht, und das 2. von 36-51.geht, // und nur das 2. Objekt gerendert werden soll, // dann wäre hier 36 zu übergeben // m_Anz_Faces_MeshNr[akt_MeshNr] // 6.) Wieviele Primitive (hier=Dreiecke) rendern? // Beim Würfel wären es z.B. 12 Dreiecke ); } } // Ende von "if (m_XFile_istOK == true)" } // zeigt ein bereits geladenes 3D-Objekt incl Y-Drehung // an der mit set_3D_Objekt_xyzPos() gesetzten Position und // der mit set_3D_Objekt_yDrehung() gesetzten Rotation // // (Methode ist bis auf die Y-Drehung gleich mit zeig_3D_Objekt() ) void Kl_3D_Objekt::zeig_3D_Objekt_Incl_yDrehung(void) { // 3D-Objekt nur zeigen, wenn erlaubt (Fehler & PRG-Absturz Vermeidung) if (m_XFile_istOK == true) { // Vertex-Format festlegen m_z_m_Grafikkarte->SetFVF(D3D_CUSTOMVERTEX_3D_Objekt_1); // Rotiert das aktuelle 3D-Objekt um Y-Achse (=Links/Rechtsdrehung) // ,und verschiebt es anschließend innerhalb der 3D-Welt // (Y-Drehung=wie z.B. Brumkreisel/Karussel mit Tierfiguren) // // ACHTUNG: -erst SKALIEREN, dann ROTIEREN, und dann erst VERSCHIEBEN! // (sonst funktionierts nicht richtig!) // -Für Ordnungsgemäße Drehung muß XZ-0-Achse // durch Mitte des 3D-Objekts gehen! // // Standartwert für yDrehung=0.0f; // Maxwert=ca.3,141576f (=360 Grad * (Pi / 180.0f) // -1.5f=Nach hinten (Vom Monitor zu mir) // 0.0f=Nach links (Links vom Monitor) // 1.5f=Nach vorne (Vom Monitor zur Wand) // -3.0f=Nach rechts (Rechts vom Monitor) m_z_Kl_3D->rotiereYachse_verschiebe_3D_Objekt( m_3D_Objekt_xPos, m_3D_Objekt_yPos, m_3D_Objekt_zPos, m_3D_Objekt_yDrehung ); // DX mitteilen,von welchem Indexbuffer die zu zeichnenden Daten entnommen werden sollen: m_z_m_Grafikkarte->SetIndices(m_Indexbuffer_3D_Objekt); // Falls zuvor kein 3D-Objekt durch Kl_3D verschoben,skaliert oder rotiert wurde, dann: // setzt als aktuell zu verwendene Matrix m_WorldMatrix als Matrix, // und macht die WorldMatrix zuvor zur Einheitsmatrix m_z_Kl_3D->set_aktMatrix__WorldMatrix(); // 3D-Objekt mit einem bzw mehreren Meshes zeigen for (unsigned short int akt_MeshNr=0; akt_MeshNr < m_Anz_Meshes_3D_Obj; akt_MeshNr++) { // m_z_Kl_3D->set_akt_Material(&m_3D_Objekt_Material[akt_MeshNr]); // Textur für aktuellen Zeichen/Rendervorgang setzen, // falls X-File einen Eintrag dafür hatte & anzeigen erlaubt ist if (m_TexturAnzeigen_erlaubt == true) { m_z_Kl_3D->set_akt_Textur(m_3D_Objekt_Textur[akt_MeshNr]); } // Vertexzähler anpassen // // D3DPT_TRIANGLELIST=Dreiecksliste. Jedes Dreieck hat 3 Vertices. // Beispiel: Für 3 per Trianglelist übergebene Dreiecke werden demnach 9 Vertices übergeben. // // Prüfung auf richtige Berechnung: -OK- (Getestet mit Geistern) // Kl_VertexUswZaehler::Vertex_Zaehler__Kl_3D_Objekt+=m_Anz_Vertices_MeshNr[akt_MeshNr]; // Die Daten des aktuellen INDEX & Vertexbuffers rendern (Anzeigen usw) m_z_m_Grafikkarte->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, // 1.) Welche Art von Primitiven sind im Indexbuffer gespeichert? // Beispiel: "D3DPT_TRIANGLELIST"=Liste mit Dreiecken // m_3D_Obj_Vertice_AddWert_Mesh[akt_MeshNr], // 2.) Wert wird zu allen Indizes im Indexbuffer hinzuaddiert. // (?Wert? Kann negativ, null oder positiv sein, laut Buch) // // Beispiel Wenn Wert z.B.4 ist, dann würde // Index 0 zu Vertex 4, und // Index 1 zu Vertex 5, usw zeigen // 0, // 3.) Kleinster Index, der verwendet wird. // Wert ist relativ zu 2.) // (Info: DX weiß somit, welche Vertizes abrufbereit sein müssen) // m_Anz_Vertices_MeshNr[akt_MeshNr], // 4.) Wieviele Vertices sollen verwendet werden? // Beim Würfel sind es z.B. 8 // (Info: DX weiß somit, welche Vertizes abrufbereit sein müssen) // m_3D_Obj_IndexbufferPos_Mesh[akt_MeshNr], // 5.) Position im Indexbuffer, ab der Dreiecke gerendert werden. // (0=1. Index, 1=2. Index,...) // Wenn Index buffer z.B. 2 Objekte enthält, // und das 1. von 0-35 geht, und das 2. von 36-51.geht, // und nur das 2. Objekt gerendert werden soll, // dann wäre hier 36 zu übergeben // m_Anz_Faces_MeshNr[akt_MeshNr] // 6.) Wieviele Primitive (hier=Dreiecke) rendern? // Beim Würfel wären es z.B. 12 Dreiecke ); } } // Ende von "if (m_XFile_istOK == true)" } // in VORBEREITUNG // // Aktueller STAND: Zeigt momentan nur das animierte 3D-Objekt // von "Roboterarm_MitAnimation.X". // // HINWEIS: Wurde zuvor "TEST_zeig_3D_Obj_Gelenke();" ausgeführt, // dann erfolgt automatisch Drahtgitteransicht, um Gelenke im // 3D-Modell sehen zu können! // void Kl_3D_Objekt::zeig_3D_Objekt_incl_Animation(void) { // Darf nur ausgeführt werden, wenn das X-File, // UND die Animationsdaten des X-Files richtig geladen wurde // (Um eventuellen PRG-Absturz zu vermeiden) if (m_XFile_istOK==false) { return; } if (m_Animationsdaten_sindOK==false) { return; } /* // Wenn 3D-Objekt Transparenz hat, dann MIT Transparenz anzeigen if (m_XFile_hatTransparenz==true) { // zeigt ein bereits geladenes 3D-Objekt mit Transparenz // an der mit set_3D_Objekt_xyzPos() gesetzten Position zeig_3D_Objekt_mitTransparenz(); } */ // Gesammtes 3D-Objekt positionieren usw // // (DirectX mitteilen, welche Matrix als aktuelle Welt-Transformationmatrix dient // // World-Transformation bedeutet das Platzieren eines 3D-Objekts vom local space in den // World-space. Also, wo das Objekt in der 3D-Welt platziert werden soll. // // Sollen mehrere 3D-Objekte an unterschiedlichen Positionen positioniert werden, // braucht jedes Objekt eine eigene Worlmatrix, SetTransform(), usw.) m_z_m_Grafikkarte->SetTransform( D3DTS_WORLD, // D3DTS_WORLD=Teilt Direct3D mit, daß die angegebene // Matrix für die World-Transformation benutzt werden soll. // Alles, was hinterher noch gerendert wird, richtet // sich nach dieser Matrix. &m_3D_Objekt_Matrix // &m_3D_Objekt_Matrix ); // DX mitteilen,von welchem Vertexbuffer die zu zeichnenden Daten entommen werden sollen: m_z_m_Grafikkarte-> SetStreamSource( 0, // Nr. des Datenstroms. "0"=es wird nur // 1 Datenstrom verwendet m_VertexBuffer_Animiertes_3D_Objekt, // Zeiger auf den Vertexbuffer 0, // Abstand vom Vertexbuffer-Anfang (Wenn // nicht alle VB-Daten verwendet werden // sollen) m_z_Kl_3D->m_DatGrsse_CustomVertex_3D_Objekt_1 // Größe des verwendeten // Vertex-Formats ); // Vertex-Format festlegen m_z_m_Grafikkarte->SetFVF(D3D_CUSTOMVERTEX_3D_Objekt_1); // Gesammtes 3D-Modell eventuell in Drahtgitteransicht zeigen, // damit Gelenke/Joints im Modell sichtbar sind if (m_3D_Obj_Gelenke_zeigen_aktiv==true) { // 2= 3D-Objekte als Drahtgittermodell anzeigen m_z_Kl_3D->set_RenderStatus(2); } // DX mitteilen,von welchem Indexbuffer die zu zeichnenden Daten // entnommen werden sollen: m_z_m_Grafikkarte->SetIndices(m_Indexbuffer_3D_Objekt); // 3D-Objekt mit einem bzw mehreren Meshes zeigen for (unsigned short int akt_MeshNr=0; akt_MeshNr < m_Anz_Meshes_3D_Obj; akt_MeshNr++) { // m_z_Kl_3D->set_akt_Material(&m_3D_Objekt_Material[akt_MeshNr]); // Textur für aktuellen Zeichen/Rendervorgang setzen, // falls X-File einen Eintrag dafür hatte & anzeigen erlaubt ist if (m_TexturAnzeigen_erlaubt == true) { m_z_Kl_3D->set_akt_Textur(m_3D_Objekt_Textur[akt_MeshNr]); } // Vertexzähler anpassen // // D3DPT_TRIANGLELIST=Dreiecksliste. Jedes Dreieck hat 3 Vertices. // Beispiel: Für 3 per Trianglelist übergebene Dreiecke werden demnach 9 Vertices übergeben. // // Prüfung auf richtige Berechnung: -?- (Getestet mit ???) // Kl_VertexUswZaehler::Vertex_Zaehler__Kl_3D_Objekt+=m_Anz_Vertices_MeshNr[akt_MeshNr]; // Die Daten des aktuellen INDEX & Vertexbuffers rendern (Anzeigen usw) m_z_m_Grafikkarte->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, // 1.) Welche Art von Primitiven sind im Indexbuffer gespeichert? // Beispiel: "D3DPT_TRIANGLELIST"=Liste mit Dreiecken // m_3D_Obj_Vertice_AddWert_Mesh[akt_MeshNr], // 2.) Wert wird zu allen Indizes im Indexbuffer hinzuaddiert. // (?Wert? Kann negativ, null oder positiv sein, laut Buch) // // Beispiel Wenn Wert z.B.4 ist, dann würde // Index 0 zu Vertex 4, und // Index 1 zu Vertex 5, usw zeigen // 0, // 3.) Kleinster Index, der verwendet wird. // Wert ist relativ zu 2.) // (Info: DX weiß somit, welche Vertizes abrufbereit sein müssen) // m_Anz_Vertices_MeshNr[akt_MeshNr], // 4.) Wieviele Vertices sollen verwendet werden? // Beim Würfel sind es z.B. 8 // (Info: DX weiß somit, welche Vertizes abrufbereit sein müssen) // m_3D_Obj_IndexbufferPos_Mesh[akt_MeshNr], // 5.) Position im Indexbuffer, ab der Dreiecke gerendert werden. // (0=1. Index, 1=2. Index,...) // Wenn Index buffer z.B. 2 Objekte enthält, // und das 1. von 0-35 geht, und das 2. von 36-51.geht, // und nur das 2. Objekt gerendert werden soll, // dann wäre hier 36 zu übergeben // m_Anz_Faces_MeshNr[akt_MeshNr] // 6.) Wieviele Primitive (hier=Dreiecke) rendern? // Beim Würfel wären es z.B. 12 Dreiecke ); } // Alles folgende NICHT in Drahtgitteransicht zeigen, // weil Gelenke/Joints im Modell bereits gezeigt wurden if (m_3D_Obj_Gelenke_zeigen_aktiv==true) { // 1= 3D-Objekte als solide Objekte anzeigen m_z_Kl_3D->set_RenderStatus(1); } } // Zeigt zu Kontrollzwecken die BoundingBox oder Bounding Sphere des 3D-Objekts. // // WICHTIG: // // Damit die Boundigbox auch durchsichtig (transparent) angezeigt wird, // muß vorm rendern aller bBoxen das entsprechende Material gesetzt werden, // und die Transparenz aktiviert werden: // // Kl_3D_Objekt::set_aktMaterial_Mat_bBox_bSphere(); // DX->set_Transparenz_aktivieren(true); // // Nach dem rendern aller Boundingboxen Transparenz wieder deaktivieren: // // DX->set_Transparenz_aktivieren(false); // void Kl_3D_Objekt::zeig_Bounding_Box_Sphere(void) { // Zeigt (rendert) das entsprechende Kollisionsobjekt // (Bounding Box oder Bounding Sphere) m_KollisionsObj->zeig_KollisionsObj(); } Kl_3D_Objekt::~Kl_3D_Objekt() { // m_DateiInput_3D_Objekt? if (m_DateiInput_3D_Objekt!=NULL) { // delete m_DateiInput_3D_Objekt; // delete NICHT erlaubt, da auch kein m_DateiInput_3D_Objekt=NULL; // "new m_DateiInput_3D_Objekt" stattfand! } if (m_KollisionsObj != NULL) { delete m_KollisionsObj; m_KollisionsObj=NULL; } if (m_akt_Datei_Zeile!=NULL) { delete []m_akt_Datei_Zeile; m_akt_Datei_Zeile=NULL; } if (m_DateiPfad_XFile!=NULL) { delete []m_DateiPfad_XFile; m_DateiPfad_XFile=NULL; } if (m_DateiPfad_DatName_XFile!=NULL) { delete []m_DateiPfad_DatName_XFile; m_DateiPfad_DatName_XFile=NULL; } // m_VertexBuffer_3D_Objekt? if (m_VertexBuffer_3D_Objekt!=NULL) { m_VertexBuffer_3D_Objekt->Release(); m_VertexBuffer_3D_Objekt=NULL; } // m_Indexbuffer_3D_Objekt? if (m_Indexbuffer_3D_Objekt!=NULL) { m_Indexbuffer_3D_Objekt->Release(); m_Indexbuffer_3D_Objekt=NULL; } // Texturen? // // WICHTIGER HINWEIS: Im Zuweisungsoperator wurden zwar m_AnzTexturen_3D_Objekt erzeugt, // (Texturanzahl) aber Zeigermengenmäßig wurden nur m_Anz_Meshes_3D_Obj Texturzeiger // zugewiesen // if (m_3D_Objekt_Textur[0] != NULL) { // Alle Texturen des 3D-Objekts freigeben for (unsigned int TexturNr=0; TexturNrRelease(); m_3D_Objekt_Textur[TexturNr]=NULL; } } } // Material=eine C++-Struktur if (m_3D_Objekt_Material != NULL) { delete []m_3D_Objekt_Material; m_3D_Objekt_Material=NULL; } if (m_3D_Objekt_Indices!=NULL) { delete []m_3D_Objekt_Indices; m_3D_Objekt_Indices=NULL; } if (m_Anz_Vertices_MeshNr!=NULL) { delete []m_Anz_Vertices_MeshNr; m_Anz_Vertices_MeshNr=NULL; } if (m_Anz_Faces_MeshNr!=NULL) { delete []m_Anz_Faces_MeshNr; m_Anz_Faces_MeshNr=NULL; } if (m_Anz_NormalenVekt_MeshNr!=NULL) { delete []m_Anz_NormalenVekt_MeshNr; m_Anz_NormalenVekt_MeshNr=NULL; } if (m_Anz_Texturkoordin_MeshNr!=NULL) { delete []m_Anz_Texturkoordin_MeshNr; m_Anz_Texturkoordin_MeshNr=NULL; } if (m_3D_Obj_Vertice_AddWert_Mesh!=NULL) { delete []m_3D_Obj_Vertice_AddWert_Mesh; m_3D_Obj_Vertice_AddWert_Mesh=NULL; } if (m_3D_Obj_IndexbufferPos_Mesh!=NULL) { delete []m_3D_Obj_IndexbufferPos_Mesh; m_3D_Obj_IndexbufferPos_Mesh=NULL; } }