#include "stdafx.h" #include "Private Klassen\Kl_DX\Kl_3D_Objekt_AnimDaten\Kl_3D_Objekt_AnimDaten.h" // *** Statische Klassenelemente *** LPDIRECT3DDEVICE9 Kl_3D_Objekt_AnimDaten::m_z_m_Grafikkarte=NULL; Kl_3D *Kl_3D_Objekt_AnimDaten::m_z_Kl_3D=NULL; // *** Konstruktor *** Kl_3D_Objekt_AnimDaten::Kl_3D_Objekt_AnimDaten() { // m_3D_Objekt_Vertices=NULL; m_3D_Obj_Vertices_Animation=NULL; m_3D_Kugel=NULL; m_VertexBuffer_Animiertes_3D_Objekt=NULL; m_str_root_Bone=NULL; m_str_akt_Bone=NULL; m_str_VerbBone=NULL; m_str_VerbBone_ROOT=NULL; m_Tmp_MatrixKey=NULL; m_Tmp_RotationKey=NULL; m_Tmp_ScaleKey=NULL; m_Tmp_PositionKey=NULL; // m_max_anz_Mtr_Keys=0; m_akt_3D_obj_Anim_Zeit=0; m_anz_MeshesMitJoints=0; m_anz_AnimationKeys=0; m_akt_AnimSchritt=0; m_anz_Joints=0; m_akt_anz_EndKlammern=0; m_akt_anz_Mtr_Keys=0; m_DatGroesse_3D_Objekt_Vertices=0; // *m_Mtr_AKy_Nr m_XFile_hat_Animation=false; m_3D_Obj_Gelenke_zeigen_aktiv=false; m_1tenSkinWeight_geladen=false; // Muß Anfangs true sein, weils bei Problemen auf false gesetzt wird m_Animationsdaten_sindOK=true; // m_XFile_nutzt_MatrixKeys=false; // 23 max_anz_ChildEbenen=23; } // Statisches Kl_Debug *Kl_3D_Objekt_AnimDaten::m_z_Kl_Debug=NULL; // ** Init-Methoden ** /**/ // void Kl_3D_Objekt_AnimDaten::init_Kl_3D_Objekt_AnimDaten(LPDIRECT3DDEVICE9 z_m_Grafikkarte, Kl_3D *z_Kl_3D) { // m_z_m_Grafikkarte=z_m_Grafikkarte; m_z_Kl_3D=z_Kl_3D; } // 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 void Kl_3D_Objekt_AnimDaten::erzeuge_Bone(char *FrameName, D3DXMATRIX *FrameTransformMatrix) { // *** 1. Neuen Bone erzeugen *** // str_Bones *Neuer_Bone; Neuer_Bone=NULL; Neuer_Bone=new str_Bones; // Frame-Name speichern Neuer_Bone->Bone_Name=NULL; Neuer_Bone->Bone_Name=new char[255]; Neuer_Bone->Bone_Name[0]='\0'; strcpy(Neuer_Bone->Bone_Name, FrameName); // Werte vorbelegen // Speicher für 23 ?Array-Elemente? erzeugen Neuer_Bone->str_Child_Bone=new str_Bones*[max_anz_ChildEbenen]; for (unsigned char Child_Ebene=0; Child_Ebene < max_anz_ChildEbenen; Child_Ebene++) { Neuer_Bone->str_Child_Bone[Child_Ebene]=NULL; } Neuer_Bone->str_Parent_Bone=NULL; Neuer_Bone->anz_EndKlammern=0; Neuer_Bone->Child_Ebene=0; Neuer_Bone->anz_Vertices=0; Neuer_Bone->vBoneBeeinfltrIndice=NULL; Neuer_Bone->BoneWeight=NULL; Neuer_Bone->anz_Mtr_Keys=0; Neuer_Bone->animKey_Matrix=NULL; Neuer_Bone->abs_Matrix_Gelenk=NULL; Neuer_Bone->animKey__Rotation=NULL; Neuer_Bone->animKey__Scale=NULL; Neuer_Bone->animKey__Position=NULL; // Matrixen initialisieren D3DXMatrixIdentity(&Neuer_Bone->FrameTransform_Matrix); D3DXMatrixIdentity(&Neuer_Bone->Offset_Matrix); // FrameTransformMatrix aus X-File in Matrix des Bones kopieren Neuer_Bone->FrameTransform_Matrix._11=FrameTransformMatrix->_11; Neuer_Bone->FrameTransform_Matrix._12=FrameTransformMatrix->_12; Neuer_Bone->FrameTransform_Matrix._13=FrameTransformMatrix->_13; Neuer_Bone->FrameTransform_Matrix._14=FrameTransformMatrix->_14; Neuer_Bone->FrameTransform_Matrix._21=FrameTransformMatrix->_21; Neuer_Bone->FrameTransform_Matrix._22=FrameTransformMatrix->_22; Neuer_Bone->FrameTransform_Matrix._23=FrameTransformMatrix->_23; Neuer_Bone->FrameTransform_Matrix._24=FrameTransformMatrix->_24; Neuer_Bone->FrameTransform_Matrix._31=FrameTransformMatrix->_31; Neuer_Bone->FrameTransform_Matrix._32=FrameTransformMatrix->_32; Neuer_Bone->FrameTransform_Matrix._33=FrameTransformMatrix->_33; Neuer_Bone->FrameTransform_Matrix._34=FrameTransformMatrix->_34; Neuer_Bone->FrameTransform_Matrix._41=FrameTransformMatrix->_41; Neuer_Bone->FrameTransform_Matrix._42=FrameTransformMatrix->_42; Neuer_Bone->FrameTransform_Matrix._43=FrameTransformMatrix->_43; Neuer_Bone->FrameTransform_Matrix._44=FrameTransformMatrix->_44; // *** 2. Neuen Bone entsprechend in der Bone-Hierarchie speichern *** // Wenn dies der 1.Bone (=Root-Bone) ist, dann... if (m_str_root_Bone==NULL) { // ...neuen Bone zwischenspeichern m_str_akt_Bone=Neuer_Bone; // ...Root-Bone als Zeiger auf 1.Bone zwischenspeichern m_str_root_Bone=m_str_akt_Bone; } // Wenn dies NICHT der 1.Bone (=Root-Bone) ist, dann... else { // Zwischenspeicher für Parent Bone str_Bones *letzter_Parent_Bone; // ...ENTWEDER einen Nachfolger-Child setzen... if (m_akt_anz_EndKlammern==0) { // Aktuellen Bone als Parent Bone zwischenspeichern letzter_Parent_Bone=m_str_akt_Bone; // Den neuen Bone im 1.Child des AKTUELLEN Bones speichern m_str_akt_Bone->str_Child_Bone[0]=Neuer_Bone; // als jetzt aktuellen Bone den Childbone von akt Bone setzen m_str_akt_Bone=m_str_akt_Bone->str_Child_Bone[0]; // Zuvor zwischengespeicherten Parent Bone jetzt setzen m_str_akt_Bone->str_Parent_Bone=letzter_Parent_Bone; } // ...ODER den 1. Child der nächsten Child-Ebene setzen else { // Anzahl der Endklammern in Bone speichern m_str_akt_Bone->anz_EndKlammern=m_akt_anz_EndKlammern; // Solange in der Bonehierarchie zurück gehen, // wie Endklammern vorhanden sind unsigned int Schritte; Schritte=0; while (Schritte != m_akt_anz_EndKlammern) { // EXPERIMENT (Um Geister anzuzeigen) //if (m_str_akt_Bone->str_Parent_Bone != NULL) //{ // m_str_akt_Bone=m_str_akt_Bone->str_Parent_Bone; //} // Schritte++; } // Muß jetzt wieder 0 sein m_akt_anz_EndKlammern=0; // Verbindungs-Bone einfügen // (Nur für ein Bone/Knoten, der mind. 2 Child-Ebenen hat, // darf ein Verbindungsbone erzeugt werden) if (m_str_akt_Bone->str_Child_Bone[1] == NULL) { erzeuge_Verbindungs_Bone(); } // Aktuellen Bone als Parent Bone zwischenspeichern letzter_Parent_Bone=m_str_akt_Bone; // den 1. Child der nächsten Child-Ebene setzen unsigned char Nr; Nr=1; bool gefunden; gefunden=false; do { if (Nr < max_anz_ChildEbenen) { // den 1. Child der nächsten Child-Ebene setzen if (m_str_akt_Bone->str_Child_Bone[Nr]==NULL) { m_str_akt_Bone->str_Child_Bone[Nr]=Neuer_Bone; m_str_akt_Bone=m_str_akt_Bone->str_Child_Bone[Nr]; gefunden=true; } Nr++; } else { m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::erzeuge_Bone(...)", 6); m_z_Kl_Debug->set_Meldung("Child-Ebene überschritten. erlaubt sind max 5 Child-Ebenen", 5); m_z_Kl_Debug->set_Meldung("(Quellcodeseitig aber erhöhbar)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); gefunden=true; // return; } }while (gefunden==false); // Zuvor zwischengespeicherten Parent Bone jetzt setzen m_str_akt_Bone->str_Parent_Bone=letzter_Parent_Bone; } /* if (strcmp(m_str_akt_Bone->Bone_Name,"j_FussHL")==0) { m_akt_anz_EndKlammern; m_str_akt_Bone; m_str_root_Bone; m_str_VerbBone_ROOT; char b=0; } */ } } // 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 bzw bei Problem Kl_3D_Objekt_AnimDaten::str_Bones *Kl_3D_Objekt_AnimDaten::suche_Bone(char *Name_Bone) { // 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 (NULL); } // Eine leere Bone-Hierarchie darf nicht gelöscht werden if (m_str_root_Bone==NULL) { // m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt_AnimDaten::suche_Bone(...)", 6); m_z_Kl_Debug->set_Meldung("Bonehierarchie ist leer...", 5); m_z_Kl_Debug->set_Meldung("(m_str_root_Bone ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // return (NULL); } // Zuerst Verbindungs-Bones resetten // (Child-Ebene der Verbindungsbones wieder auf 0 zurück setzen, // damit XXX ) Reset_Verbindungs_Bones(); // Aktuellen Bone auf Startknoten setzen str_Bones *akt_Bone; akt_Bone=m_str_root_Bone; int Ergebnis; // Alle Knoten durchgehen while (akt_Bone != NULL) { // Wurde gesuchter Bone bereits gefunden? Ergebnis=strcmp(akt_Bone->Bone_Name, Name_Bone); if (Ergebnis==0) { return (akt_Bone); } // Kann Bonehierarchie verlassen werden? // (Z.B. von "Frame Roboterbeine" oder "Frame Roboter_Mensch", // nach "Frame Joint_Root", und zuletzt nach "Frame Scene_Root" gehen) if (akt_Bone->str_Child_Bone[0] == NULL && akt_Bone->anz_EndKlammern==0) { // Je einen Bone XXX (Z.B. "Frame Roboterbeine oder Roboter_Mensch") while (akt_Bone->str_Parent_Bone != NULL) { // Zum nächsten Bone gehen akt_Bone=akt_Bone->str_Parent_Bone; } // Damit While-Schleife verlassen werden kann akt_Bone=NULL; } // Wenn Bonehierarchie noch nicht verlassen werden kann, // nächsten Bone ermitteln else { // Wenn aktueller Bone keine Endklammern hat, // zum nächsten Child-Bone gehen if (akt_Bone->anz_EndKlammern==0) { akt_Bone=akt_Bone->str_Child_Bone[0]; } // Ansonsten in den Childs wieder zurück gehen, // in Anzahl der Endklammern, // und bei nächster Child-Ebene weitermachen else { int Endklammern; // Anzahl der Endklammern zwischen speichern Endklammern=akt_Bone->anz_EndKlammern; // in Bone-Hierarchie zurück gehen for (int i=0; i < Endklammern; i++) { akt_Bone=akt_Bone->str_Parent_Bone; } // +1, wg. nächster Child-Ebene akt_Bone->Child_Ebene++; // Bone auf Bone der nächsten Child-Ebene setzen akt_Bone=akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]; } } } // Meldung über nicht gefundenen Bone-Name ausgeben char Text[255]; Text[0]='\0'; strcpy(Text, "Folgender Name wurde nicht gefunden: "); strcat(Text, Name_Bone); m_z_Kl_Debug->set_Meldung("in Kl_3D_Objekt_AnimDaten::suche_Bone(...)", 6); m_z_Kl_Debug->set_Meldung(Text, 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // NULL zurückgeben, weil gesuchter Bone nicht gefunden wurd return (NULL); } // Verbindungs-Bone einfügen void Kl_3D_Objekt_AnimDaten::erzeuge_Verbindungs_Bone(void) { // Text-EXPERIMENT if (m_str_akt_Bone==NULL) { m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::erzeuge_Verbindungs_Bone(...)", 6); m_z_Kl_Debug->set_Meldung("(m_str_akt_Bone ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); } if (m_str_VerbBone_ROOT==NULL) { m_str_VerbBone_ROOT=new str_VL_VerbngsBones(); m_str_VerbBone_ROOT->Bone=m_str_akt_Bone; m_str_VerbBone_ROOT->Parent=NULL; m_str_VerbBone_ROOT->Naechster=NULL; m_str_VerbBone=m_str_VerbBone_ROOT; } // else { str_VL_VerbngsBones *vorheriger_vBone; vorheriger_vBone=m_str_VerbBone; m_str_VerbBone->Naechster=new str_VL_VerbngsBones(); m_str_VerbBone=m_str_VerbBone->Naechster; m_str_VerbBone->Bone=m_str_akt_Bone; m_str_VerbBone->Parent=vorheriger_vBone; m_str_VerbBone->Naechster=NULL; } } // 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) void Kl_3D_Objekt_AnimDaten::Reset_Verbindungs_Bones(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; } // Eine leere Bone-Hierarchie darf nicht verwendet werden if (m_str_VerbBone_ROOT == NULL) { m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::Reset_Verbindungs_Bones(...)", 6); m_z_Kl_Debug->set_Meldung("(m_str_VerbBone_ROOT ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); return; } // str_VL_VerbngsBones *vBone; vBone=m_str_VerbBone_ROOT; // Child-Ebene des 1.Verbindungsbones wieder auf 0 setzen vBone->Bone->Child_Ebene=0; // Child-Ebene aller weiteren Verbindungsbones wieder auf 1 setzen while (vBone->Naechster != NULL) { vBone=vBone->Naechster; vBone->Bone->Child_Ebene=0; } } // ** Grundlegende-Methoden ** // ermittelt aktuellen Animationsschritt, und speichert Ergebniss // in m_akt_FrameNr void Kl_3D_Objekt_AnimDaten::ermittle_akt_Animationsschritt(void) { // Wenn Zeit noch nicht erreicht ist if (m_akt_3D_obj_Anim_Zeit < 2) { m_akt_3D_obj_Anim_Zeit++; } // Wenn Zeit schon erreicht ist, // dann aktuelle Animation machen else { // Zeit-Zähler zurück setzen m_akt_3D_obj_Anim_Zeit=0; // Nr für den aktuellen Matrix-Key erhöhen // if (m_akt_FrameNr < m_anz_Mtr_Keys[1]) if (m_akt_AnimSchritt < m_max_anz_Mtr_Keys-1) { m_akt_AnimSchritt++; } else { m_akt_AnimSchritt=0; } } } // Berechnet für alle Gelenke alle Animationspositionen der Gelenke (Joints) // Ergebnisse werden in akt_Bone->abs_Matrix_Gelenk[] gespeichert. void Kl_3D_Objekt_AnimDaten::berechne_Matrixen_Gelenkpositionen(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; } // Eine leere Bone-Hierarchie darf nicht verwendet werden if (m_str_root_Bone==NULL) { // m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::berechne_Matrixen_Gelenkpositionen(...)", 6); m_z_Kl_Debug->set_Meldung("Bonehierarchie ist leer...", 5); m_z_Kl_Debug->set_Meldung("(m_str_root_Bone ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // return; } // Zuerst Verbindungs-Bones resetten // (Child-Ebene der Verbindungsbones wieder auf 0 zurück setzen, // damit XXX ) Reset_Verbindungs_Bones(); // Aktuellen Bone auf Startknoten setzen str_Bones *akt_Bone; akt_Bone=m_str_root_Bone; // akt_Bone=akt_Bone->str_Child_Bone[0]; // Die Allererste absolute Matrix hat keinen Parent // m_3D_Objekt_Matrix bestimmt Position des Gesammten 3D-Objekts // for (unsigned short int MtrKey_Nr=0; MtrKey_Nr < akt_Bone->anz_Mtr_Keys; MtrKey_Nr++) { akt_Bone->abs_Matrix_Gelenk[MtrKey_Nr]= akt_Bone->animKey_Matrix[MtrKey_Nr] * m_3D_Objekt_Matrix; // Original (Blender X-File falsch // gedreht) // m_3D_Objekt_Matrix * akt_Bone->animKey_Matrix[MtrKey_Nr]; // So ist Blender X-File // richtig gedreht } // Alle Knoten while (akt_Bone != NULL) { // Kann Bonehierarchie verlassen werden? // (Z.B. von "Frame Roboterbeine" oder "Frame Roboter_Mensch", // nach "Frame Joint_Root", und zuletzt nach "Frame Scene_Root" gehen) if (akt_Bone->str_Child_Bone[0] == NULL && akt_Bone->anz_EndKlammern==0) { // Je einen Bone XXX (Z.B. "Frame Roboterbeine oder Roboter_Mensch") while (akt_Bone->str_Parent_Bone != NULL) { // Zum nächsten Bone gehen akt_Bone=akt_Bone->str_Parent_Bone; } // Damit While-Schleife verlassen werden kann akt_Bone=NULL; } // EXPERIMENT //if (strcmp(akt_Bone->Bone_Name, "j_FussHL")==0) { akt_Bone=NULL; } // Wenn Bonehierarchie noch nicht verlassen werden kann, // nächsten Bone ermitteln else { // Wenn aktueller Bone keine Endklammern hat, // zum nächsten Child-Bone gehen if (akt_Bone->anz_EndKlammern==0) { // akt_Bone=akt_Bone->str_Child_Bone[0]; // Alle weiteren absoluten Matrixen haben Parents for (unsigned short int MtrKey_Nr=0; MtrKey_Nr < akt_Bone->anz_Mtr_Keys; MtrKey_Nr++) { akt_Bone->abs_Matrix_Gelenk[MtrKey_Nr]= akt_Bone->animKey_Matrix[MtrKey_Nr] * akt_Bone->str_Parent_Bone->abs_Matrix_Gelenk[MtrKey_Nr]; } } // Ansonsten in den Childs wieder zurück gehen, // in Anzahl der Endklammern, // und bei nächster Child-Ebene weitermachen else { int Endklammern; // Anzahl der Endklammern zwischen speichern Endklammern=akt_Bone->anz_EndKlammern; // in Bone-Hierarchie zurück gehen for (int i=0; i < Endklammern; i++) { akt_Bone=akt_Bone->str_Parent_Bone; } // +1, wg. nächster Child-Ebene akt_Bone->Child_Ebene++; // if (akt_Bone->Child_Ebene < max_anz_ChildEbenen) { // Bone auf Bone der nächsten Child-Ebene setzen akt_Bone=akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]; } else { // m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::berechne_Matrixen_Gelenkpositionen(...)", 6); m_z_Kl_Debug->set_Meldung("Child-Ebene überschritten. erlaubt sind max 5 Child-Ebenen", 5); m_z_Kl_Debug->set_Meldung("(Quellcodeseitig aber erhöhbar)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // akt_Bone=NULL; m_Animationsdaten_sindOK=false; return; } /**/ // for (unsigned short int MtrKey_Nr=0; MtrKey_Nr < akt_Bone->anz_Mtr_Keys; MtrKey_Nr++) { akt_Bone->abs_Matrix_Gelenk[MtrKey_Nr]= akt_Bone->animKey_Matrix[MtrKey_Nr] * akt_Bone->str_Parent_Bone->abs_Matrix_Gelenk[MtrKey_Nr]; } } } } } // 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 void Kl_3D_Objekt_AnimDaten::berechne_Matrix_Keys(unsigned short int MatrixKey_Nr) { // ACHTUNG: // // -Da weder in Büchern noch im WWW gut verwertbare Hinweise gefunden wurden, // wie ein Scale-, Rotation- & Translation Key programmiertechnisch in einen Matrixkey // umgewandelt werden kann, programmierte ich hier meine eigene Methode. // Sie scheint ok zu sein, könnte aber u.U. eventuell Fehlerhaft sein! // // -erst SKALIEREN, dann ROTIEREN, und erst dann VERSCHIEBEN // 1.Skalieren (Scale in Matrix speichern) m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]._11=m_str_akt_Bone->animKey__Scale[MatrixKey_Nr].x; m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]._22=m_str_akt_Bone->animKey__Scale[MatrixKey_Nr].y; m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]._33=m_str_akt_Bone->animKey__Scale[MatrixKey_Nr].z; // 2.Rotieren (Rotation in Matrix speichern) // Quaternion vorab schonmal normalisieren, falls erforderlich (aus Animationsbuch) // D3DXQuaternionNormalize(&m_str_akt_Bone->animKey__Rotation[MatrixKey_Nr], // &m_str_akt_Bone->animKey__Rotation[MatrixKey_Nr]); D3DXMATRIX Rotationsmatrix; D3DXMatrixIdentity(&Rotationsmatrix); // Quaternion in Rotationsmatrix umwandeln // (Builds a rotation matrix from a quaternion) D3DXMatrixRotationQuaternion( &Rotationsmatrix, // [in, out] Pointer to the D3DXMATRIX structure // that is the result of the operation &m_str_akt_Bone->animKey__Rotation[MatrixKey_Nr] // [in] Pointer to the source // D3DXQUATERNION structure ); // aus Animationsbuch: // Convert transformation matrix to left-handed D3DXMatrixTranspose(&Rotationsmatrix, &Rotationsmatrix); // Position in Matrix speichern // m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]=Rotationsmatrix * m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]; m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]=m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr] * Rotationsmatrix; // 3.Position (Translation in Matrix speichern) m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]._41=m_str_akt_Bone->animKey__Position[MatrixKey_Nr].x; m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]._42=m_str_akt_Bone->animKey__Position[MatrixKey_Nr].y; m_str_akt_Bone->animKey_Matrix[MatrixKey_Nr]._43=m_str_akt_Bone->animKey__Position[MatrixKey_Nr].z; // Meine andere Methode hierfür: /* // 1.Skalierung (Scale) in Matrix speichern D3DXMATRIX SkalierungsMatrix; D3DXMatrixIdentity(&SkalierungsMatrix); SkalierungsMatrix._11=m_str_akt_Bone->animKey__Scale[MtrKey_Nr].x; SkalierungsMatrix._22=m_str_akt_Bone->animKey__Scale[MtrKey_Nr].y; SkalierungsMatrix._33=m_str_akt_Bone->animKey__Scale[MtrKey_Nr].z; // 2.Quaternion in Rotationsmatrix umwandeln D3DXMATRIX Rotationsmatrix; D3DXMatrixIdentity(&Rotationsmatrix); D3DXMatrixRotationQuaternion( &Rotationsmatrix, // [in, out] Pointer to the D3DXMATRIX structure // that is the result of the operation &m_str_akt_Bone->animKey__Rotation[MtrKey_Nr] // [in] Pointer to the source // D3DXQUATERNION structure ); // aus Animationsbuch: // Convert transformation matrix to left-handed D3DXMatrixTranspose(&Rotationsmatrix, &Rotationsmatrix); // 3.Translation (Position) in Matrix speichern D3DXMATRIX PositionsMatrix; D3DXMatrixIdentity(&PositionsMatrix); PositionsMatrix._41=m_str_akt_Bone->animKey__Position[MtrKey_Nr].x; PositionsMatrix._42=m_str_akt_Bone->animKey__Position[MtrKey_Nr].y; PositionsMatrix._43=m_str_akt_Bone->animKey__Position[MtrKey_Nr].z; // 4.Matrixen kombinieren m_str_akt_Bone->animKey_Matrix[MtrKey_Nr]= SkalierungsMatrix * Rotationsmatrix * PositionsMatrix; */ } // Verschiebt Vertices den Joints entsprechend, für aktuellen Animationsschritt void Kl_3D_Objekt_AnimDaten::verschiebe_Vertices_Joints(void) { // *** Altes Animationssystem: Roboterarm ohne Bonehierarchie *** /* // unsigned short int JointNr; D3DXMATRIX OrigVertexPos_Matrix; // enthält originale, unanimierte Verticepositionen des 3d-Modells D3DXMATRIX NeueVertexPos_Matrix; // enthält Verticepositionen für aktuellen Animationsschritt // des 3d-Modells // JointNr=0; // D3DXMatrixIdentity(&OrigVertexPos_Matrix); D3DXMatrixIdentity(&NeueVertexPos_Matrix); // 1.) Vertices dem aktuellen Animationsschritt entsprechend verschieben for (unsigned int Nr=0; Nrkopiere_Vertices_in_Vertexbuffer(m_VertexBuffer_Animiertes_3D_Objekt, m_3D_Obj_Vertices_Animation, m_DatGroesse_3D_Objekt_Vertices); */ // *** NEUES Animationssystem: Animation mit Bonehierarchie *** D3DXMATRIX OrigVertexPos_Matrix; // enthält originale, unanimierte Verticepositionen des 3D-Modells D3DXMATRIX NeueVertexPos_Matrix; // enthält Verticepositionen für aktuellen Animationsschritt // des 3D-Modells D3DXMatrixIdentity(&OrigVertexPos_Matrix); // Zuerst Verbindungs-Bones resetten // (Child-Ebene der Verbindungsbones wieder auf 0 zurück setzen, // damit XXX ) Reset_Verbindungs_Bones(); // Aktuellen Bone auf Startknoten setzen str_Bones *akt_Bone; akt_Bone=m_str_root_Bone; unsigned long int Nr; // Alle Knoten while (akt_Bone != NULL) { // Nur Bones verwenden, die auch Gelenke der Bonehierarchie sind // ("Frame Scene_Root" z.B. gehört nicht dazu) if (akt_Bone->anz_Vertices != 0) { // Alle Indices dieses Bones for (unsigned long int IndiceNr=0; IndiceNr < akt_Bone->anz_Vertices; IndiceNr++) { // Nr=akt_Bone->vBoneBeeinfltrIndice[IndiceNr]; // Vertex dem aktuellen Animationsschritt entsprechend verschieben // OrigVertexPos_Matrix füllen OrigVertexPos_Matrix._41=m_3D_Objekt_Vertices[Nr].x; OrigVertexPos_Matrix._42=m_3D_Objekt_Vertices[Nr].y; OrigVertexPos_Matrix._43=m_3D_Objekt_Vertices[Nr].z; // Neue Vertex-Position des aktuellen Animationsschritts ermitteln //if (m_akt_AnimSchritt < akt_Bone->anz_Mtr_Keys-1) //{ D3DXMatrixIdentity(&NeueVertexPos_Matrix); NeueVertexPos_Matrix= OrigVertexPos_Matrix * akt_Bone->Offset_Matrix * akt_Bone->abs_Matrix_Gelenk[m_akt_AnimSchritt]; /* // EXPERIMENT (bei Katze.x funktionierts nicht, siehe Katzenschwanz) akt_Bone->Offset_Matrix * akt_Bone->abs_Matrix_Gelenk[m_akt_AnimSchritt] * OrigVertexPos_Matrix; */ //} // Neue Vertex-Position setzen m_3D_Obj_Vertices_Animation[Nr].x=NeueVertexPos_Matrix._41; m_3D_Obj_Vertices_Animation[Nr].y=NeueVertexPos_Matrix._42; m_3D_Obj_Vertices_Animation[Nr].z=NeueVertexPos_Matrix._43; // EXPERIMENT: Müssen BoneWeights hier eingesetzt werden? // // Von Gamedev.net: ...The weight is "how much" the vertex position will be moved relative // to the bone when the bone moves. /* m_3D_Obj_Vertices_Animation[Nr].x=NeueVertexPos_Matrix._41 * akt_Bone->BoneWeight[IndiceNr]; m_3D_Obj_Vertices_Animation[Nr].y=NeueVertexPos_Matrix._42 * akt_Bone->BoneWeight[IndiceNr]; m_3D_Obj_Vertices_Animation[Nr].z=NeueVertexPos_Matrix._43 * akt_Bone->BoneWeight[IndiceNr]; */ } } // Kann Bonehierarchie verlassen werden? // (Z.B. von "Frame Roboterbeine" oder "Frame Roboter_Mensch", // nach "Frame Joint_Root", und zuletzt nach "Frame Scene_Root" gehen) if (akt_Bone->str_Child_Bone[0] == NULL && akt_Bone->anz_EndKlammern==0) { // Je einen Bone XXX (Z.B. "Frame Roboterbeine oder Roboter_Mensch") while (akt_Bone->str_Parent_Bone != NULL) { // Zum nächsten Bone gehen akt_Bone=akt_Bone->str_Parent_Bone; } // Damit While-Schleife verlassen werden kann akt_Bone=NULL; } // Wenn Bonehierarchie noch nicht verlassen werden kann, // nächsten Bone ermitteln else { // Wenn aktueller Bone keine Endklammern hat, // zum nächsten Child-Bone gehen if (akt_Bone->anz_EndKlammern==0) { akt_Bone=akt_Bone->str_Child_Bone[0]; } // Ansonsten in den Childs wieder zurück gehen, // in Anzahl der Endklammern, // und bei nächster Child-Ebene weitermachen else { int Endklammern; // Anzahl der Endklammern zwischen speichern Endklammern=akt_Bone->anz_EndKlammern; // in Bone-Hierarchie zurück gehen for (int i=0; i < Endklammern; i++) { akt_Bone=akt_Bone->str_Parent_Bone; } // +1, wg. nächster Child-Ebene akt_Bone->Child_Ebene++; // Bone auf Bone der nächsten Child-Ebene setzen akt_Bone=akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]; } } } // 2.) Vertices der Animation in den "3D-Objekt-Vertexbuffer für Animation" kopieren: m_z_Kl_3D->kopiere_Vertices_in_Vertexbuffer(m_VertexBuffer_Animiertes_3D_Objekt, m_3D_Obj_Vertices_Animation, m_DatGroesse_3D_Objekt_Vertices); } // ** Kontroll- & Test-Methoden ** // Zeigt zu Kontrollzwecken die gesammte Bonehierarchie in einer Messagebox // // ACHTUNG: // -Es werden nur max. 4 Child-Ebenen/Childs angezeigt // -Ist ein Frame-Name zu lang, gibts Darstellungs- & Reihenfolge-Probleme! void Kl_3D_Objekt_AnimDaten::TEST_zeig_Bone_Hierarchie_MB(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; } // if (m_str_root_Bone==NULL) { m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::TEST_zeig_Bone_Hierarchie_MB(...)", 6); m_z_Kl_Debug->set_Meldung("Bonehierarchie ist leer...", 5); m_z_Kl_Debug->set_Meldung("(m_str_root_Bone ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); } char text_Bone_Name[255]; char text_Child[255]; char text_Child2[255]; char text_Child3[255]; char text_Child4[255]; char text_Parent[255]; char Gesammt_Text[4096]; // String erzeugen strcpy(Gesammt_Text, "\0"); // Aktuellen Bone auf Startknoten setzen str_Bones *akt_Bone; akt_Bone=m_str_root_Bone; // Zuerst Verbindungs-Bones resetten // (Child-Ebene der Verbindungsbones wieder auf 0 zurück setzen, // damit XXX ) Reset_Verbindungs_Bones(); // Alle Knoten while (akt_Bone != NULL) { // *** Texte erzeugen *** // Bone-Name strcpy(text_Bone_Name, akt_Bone->Bone_Name); // Parent strcpy(text_Parent, "\t P.: "); if (akt_Bone->str_Parent_Bone != NULL) { strcat(text_Parent, akt_Bone->str_Parent_Bone->Bone_Name); } else { strcat(text_Parent, "-Kein P.-"); } // Child 1 strcpy(text_Child, "\t Child 1: "); if (akt_Bone->str_Child_Bone[0] != NULL) { strcat(text_Child, akt_Bone->str_Child_Bone[0]->Bone_Name); } else { strcat(text_Child, "-Kein Chie.-"); } // Child 2 strcpy(text_Child2, "\t Child 2: "); if (akt_Bone->str_Child_Bone[1] != NULL) { strcat(text_Child2, akt_Bone->str_Child_Bone[1]->Bone_Name); } else { strcat(text_Child2, "-Kein Chie.-"); } // Child 3 strcpy(text_Child3, "\t Child 3: "); if (akt_Bone->str_Child_Bone[2] != NULL) { strcat(text_Child3, akt_Bone->str_Child_Bone[2]->Bone_Name); } else { strcat(text_Child3, "-Kein Chie.-"); } // Child 4 strcpy(text_Child4, "\t Child 4: "); if (akt_Bone->str_Child_Bone[3] != NULL) { strcat(text_Child4, akt_Bone->str_Child_Bone[3]->Bone_Name); } else { strcat(text_Child4, "-Kein Chie.-"); } // Child 5 passt nicht mehr in MB // // ... // // *** Nächsten Bone ermitteln *** // Kann Bonehierarchie verlassen werden? // (Z.B. von "Frame Roboterbeine" oder "Frame Roboter_Mensch", // nach "Frame Joint_Root", und zuletzt nach "Frame Scene_Root" gehen) if (akt_Bone->str_Child_Bone[0] == NULL && akt_Bone->anz_EndKlammern==0) { // Je einen Bone XXX (Z.B. "Frame Roboterbeine oder Roboter_Mensch") while (akt_Bone->str_Parent_Bone != NULL) { // Zum nächsten Bone gehen akt_Bone=akt_Bone->str_Parent_Bone; } // Damit While-Schleife verlassen werden kann akt_Bone=NULL; } // Wenn Bonehierarchie noch nicht verlassen werden kann, // nächsten Bone ermitteln else { // Wenn aktueller Bone keine Endklammern hat, // zum nächsten Child-Bone gehen if (akt_Bone->anz_EndKlammern==0) { akt_Bone=akt_Bone->str_Child_Bone[0]; } // Ansonsten in den Childs wieder zurück gehen, // in Anzahl der Endklammern, // und bei nächster Child-Ebene weitermachen else { int Endklammern; // Anzahl der Endklammern zwischen speichern Endklammern=akt_Bone->anz_EndKlammern; // in Bone-Hierarchie zurück gehen for (int i=0; i < Endklammern; i++) { akt_Bone=akt_Bone->str_Parent_Bone; } // +1, wg. nächster Child-Ebene akt_Bone->Child_Ebene++; // Bone auf Bone der nächsten Child-Ebene setzen akt_Bone=akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]; } } // *** Text um Werte des aktuellen Knotens ergänzen *** strcat(Gesammt_Text, text_Bone_Name); strcat(Gesammt_Text, text_Child); strcat(Gesammt_Text, text_Child2); strcat(Gesammt_Text, text_Child3); strcat(Gesammt_Text, text_Child4); strcat(Gesammt_Text, text_Parent); strcat(Gesammt_Text, "\n"); } // Kontrollwerte anzeigen MessageBox(NULL, Gesammt_Text, "Animationsskelett - Kontrolle der Bone-Hierarchie", MB_OK); } // Aktueller STAND: zeigt Joints/Gelenke von "Roboterarm_MitAnimation.X" // als kleine Kugeln // // ACHTUNG: Methode MUß VOR "zeig_3D_Objekt_incl_Animation()" // ausgeführt werden! Sonst darstellungsfehler des 3D-Objekts. void Kl_3D_Objekt_AnimDaten::TEST_zeig_3D_Obj_Gelenke(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; } // Eine leere Bone-Hierarchie darf nicht verwendet werden if (m_str_root_Bone==NULL) { // m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::TEST_zeig_3D_Obj_Gelenke(...)", 6); m_z_Kl_Debug->set_Meldung("Bonehierarchie ist leer...", 5); m_z_Kl_Debug->set_Meldung("(m_str_root_Bone ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // return; } // m_3D_Obj_Gelenke_zeigen_aktiv=true; // if (m_3D_Kugel==NULL) { m_3D_Kugel=new Kl_3D_Kugel[m_anz_Joints]; // for (int i=0; i < m_anz_Joints; i++) { // Erzeugt eine ganze 3D-Kugel. // xyz 0.0f ist in der Mitte der Kugel! // // Parameter: 1.=AnzVerticesZeile, 2.=AnzVerticesSpalte, 3=Radius // Beispiele // AnzVerticesZeile=10; // 6=grobe,klotzige-, 10=eckige-, 30=runde- Kugel // AnzVerticesSpalte=10; // 6=grobe,klotzige-, 10=eckige-, 30=runde- Kugel // Radius=1.0f; // 0.2f=kleine, 1.0f=große 4.2f= richtig große. usw? Kugel // m_3D_Kugel[i].init_3D_Kugel_9(10, 10, 0.05f); } } // int Kugel_Nr; Kugel_Nr=0; // Für Anzeigeposition der jeweiligen Kugel D3DXMATRIX mat_EndPos; // Zuerst Verbindungs-Bones resetten // (Child-Ebene der Verbindungsbones wieder auf 0 zurück setzen, // damit XXX ) Reset_Verbindungs_Bones(); // Aktuellen Bone auf Startknoten setzen str_Bones *akt_Bone; akt_Bone=m_str_root_Bone; //akt_Bone=akt_Bone->str_Child_Bone; // Alle Knoten while (akt_Bone != NULL) { // Nur Bones anzeigen, die auch Gelenke der Bonehierarchie sind // ("Frame Scene_Root" gehört z.B. nicht dazu) if (akt_Bone->anz_Vertices != 0) { // Matrix für 3D-Kugel Pos berechnen mat_EndPos=akt_Bone->abs_Matrix_Gelenk[m_akt_AnimSchritt] * m_3D_Objekt_Matrix; // Gelenk als 3D-Kugel anzeigen m_z_m_Grafikkarte->SetTransform(D3DTS_WORLD, &mat_EndPos); m_3D_Kugel[Kugel_Nr].zeig_3D_Kugel(); Kugel_Nr++; } // Kann Bonehierarchie verlassen werden? // (Z.B. von "Frame Roboterbeine" oder "Frame Roboter_Mensch", // nach "Frame Joint_Root", und zuletzt nach "Frame Scene_Root" gehen) if (akt_Bone->str_Child_Bone[0] == NULL && akt_Bone->anz_EndKlammern==0) { // Je einen Bone XXX (Z.B. "Frame Roboterbeine oder Roboter_Mensch") while (akt_Bone->str_Parent_Bone != NULL) { // Zum nächsten Bone gehen akt_Bone=akt_Bone->str_Parent_Bone; } // Damit While-Schleife verlassen werden kann akt_Bone=NULL; } // Wenn Bonehierarchie noch nicht verlassen werden kann, // nächsten Bone ermitteln else { // Wenn aktueller Bone keine Endklammern hat, // zum nächsten Child-Bone gehen if (akt_Bone->anz_EndKlammern==0) { akt_Bone=akt_Bone->str_Child_Bone[0]; } // Ansonsten in den Childs wieder zurück gehen, // in Anzahl der Endklammern, // und bei nächster Child-Ebene weitermachen else { int Endklammern; // Anzahl der Endklammern zwischen speichern Endklammern=akt_Bone->anz_EndKlammern; // in Bone-Hierarchie zurück gehen for (int i=0; i < Endklammern; i++) { akt_Bone=akt_Bone->str_Parent_Bone; } // +1, wg. nächster Child-Ebene akt_Bone->Child_Ebene++; // Bone auf Bone der nächsten Child-Ebene setzen akt_Bone=akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]; } } } } // Gibt durch löschen der gesammten Bone-Hierarchie (Aller Knoten) // den davon verwendeten Speicher wieder frei // // TESTS=-OK- am 28.01.2015 // // (Getestet mit X-File für Roboterarm, Roboterbeine und Robotermensch) void Kl_3D_Objekt_AnimDaten::loesch_Bone_Hierarchie(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; } // Eine leere Bone-Hierarchie darf nicht gelöscht werden if (m_str_root_Bone==NULL) { // m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::loesch_Bone_Hierarchie(...)", 6); m_z_Kl_Debug->set_Meldung("Bonehierarchie ist leer...", 5); m_z_Kl_Debug->set_Meldung("(m_str_root_Bone ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // return; } // Aktuellen Bone auf Startknoten setzen str_Bones *akt_Bone; akt_Bone=m_str_root_Bone; // Verbindungs-Bones resetten // (Child-Ebene der Verbindungsbones wieder auf 0 zurück setzen, // damit XXX ) Reset_Verbindungs_Bones(); // Solange Bones existieren while (akt_Bone!=NULL) { // Kann Bone-Hierarchie schon verlassen werden // (schon zurück zum Root-Bone gehen)? // Falls ja, dann die letzten Bones löschen // // (Z.B. erst "Frame Roboterbeine" oder "Frame Roboter_Mensch", // dann "Frame Joint_Root", und zuletzt "Frame Scene_Root") if (akt_Bone->str_Child_Bone[0] == NULL && akt_Bone->anz_EndKlammern==0) { // Je einen Bone löschen (Z.B. "Frame Roboterbeine oder Roboter_Mensch") while (akt_Bone->str_Parent_Bone != NULL) { // Vorab Zeiger auf Nächsten Bone setzen // (Bone links vor den zu löschenden Bone sichern) str_Bones *vorheriger_Bone; vorheriger_Bone=akt_Bone->str_Parent_Bone; // Den zu löschenden Bone löschen delete akt_Bone; akt_Bone=NULL; // Zum nächsten Bone gehen // (Aktuellen Bone auf Knoten links vor dem gelöschten Bone setzen) akt_Bone=vorheriger_Bone; // Child der aktuellen Child-Ebene darf nicht mehr // rechts auf gelöschten Bone zeigen akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]=NULL; } // Den Root-Bone löschen (Frame Scene_Root) delete akt_Bone; // Muß jetzt NULL sein & damit While-Schleife verlassen werden kann akt_Bone=NULL; // Bonehierarchie existiert jetzt nicht mehr, // deswegen muß m_str_root_Bone jetzt auch NULL sein! m_str_root_Bone=NULL; } // Wenn Bonehierarchie noch nicht verlassen werden kann: // Alle Bones der aktuellen Child-Ebene löschen else { // zum letzten Child-Bone der aktuellen Child-Ebene gehen while (akt_Bone->anz_EndKlammern==0) { akt_Bone=akt_Bone->str_Child_Bone[0]; } // int anz_Endklammern; anz_Endklammern=akt_Bone->anz_EndKlammern; // Bones der aktuellen Child-Ebene der Endklammeranzahl entsprechend löschen for (int akt_Endklammer=0; akt_Endklammer < anz_Endklammern; akt_Endklammer++) { // Vorab Zeiger auf Nächsten Bone setzen // (Bone links vor den zu löschenden Bone sichern) str_Bones *vorheriger_Bone; vorheriger_Bone=akt_Bone->str_Parent_Bone; // Den zu löschenden Bone löschen delete akt_Bone; akt_Bone=NULL; // Zum nächsten Bone gehen // (Aktuellen Bone auf Knoten links vor dem gelöschten Bone setzen) akt_Bone=vorheriger_Bone; // Child der aktuellen Child-Ebene darf nicht mehr // rechts auf gelöschten Bone zeigen akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]=NULL; } // +1, wg. nächster Child-Ebene akt_Bone->Child_Ebene++; // Bone auf Bone der nächsten Child-Ebene setzen akt_Bone=akt_Bone->str_Child_Bone[akt_Bone->Child_Ebene]; } } } // void Kl_3D_Objekt_AnimDaten::loesch_Verbindungs_Bones(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; } // Eine leere Bone-Hierarchie darf nicht gelöscht werden if (m_str_root_Bone==NULL) { // m_z_Kl_Debug->set_Meldung( "in Kl_3D_Objekt_AnimDaten::loesch_Verbindungs_Bones(...)", 6); m_z_Kl_Debug->set_Meldung("Bonehierarchie ist leer...", 5); m_z_Kl_Debug->set_Meldung("(m_str_VerbBone_ROOT ist NULL)", 5); //m_z_Kl_Debug->set_Meldung(m_DateiPfad_DatName_XFile, 5); // return; } // Aktuellen Verbindungs-Bone auf Startknoten setzen str_VL_VerbngsBones *akt_VerbBone; akt_VerbBone=m_str_VerbBone_ROOT; str_VL_VerbngsBones *vorheriger_vBone; // zum letzten Child-Bone gehen while (akt_VerbBone->Naechster != NULL) { akt_VerbBone=akt_VerbBone->Naechster; } // do { vorheriger_vBone=akt_VerbBone->Parent; delete akt_VerbBone; akt_VerbBone=vorheriger_vBone; }while (akt_VerbBone->Parent != NULL); delete akt_VerbBone; m_str_VerbBone_ROOT=NULL; /* akt_VerbBone->Parent; akt_VerbBone->Naechster; char b=0; */ } Kl_3D_Objekt_AnimDaten::~Kl_3D_Objekt_AnimDaten() { // // if (m_3D_Objekt_Vertices!=NULL) { delete [] m_3D_Objekt_Vertices; m_3D_Objekt_Vertices=NULL; } if (m_3D_Obj_Vertices_Animation!=NULL) { delete [] m_3D_Obj_Vertices_Animation; m_3D_Obj_Vertices_Animation=NULL; } if (m_3D_Kugel != NULL) { delete [] m_3D_Kugel; m_3D_Kugel=NULL; } if (m_VertexBuffer_Animiertes_3D_Objekt!=NULL) { m_VertexBuffer_Animiertes_3D_Objekt->Release(); m_VertexBuffer_Animiertes_3D_Objekt=NULL; } if (m_Tmp_MatrixKey != NULL) { delete [] m_Tmp_MatrixKey; m_Tmp_MatrixKey=NULL; } if (m_Tmp_RotationKey != NULL) { delete [] m_Tmp_RotationKey; m_Tmp_RotationKey=NULL; } if (m_Tmp_ScaleKey != NULL) { delete [] m_Tmp_ScaleKey; m_Tmp_ScaleKey=NULL; } if (m_Tmp_PositionKey != NULL) { delete [] m_Tmp_PositionKey; m_Tmp_PositionKey=NULL; } if (m_str_root_Bone != NULL) { // Gibt durch löschen der gesammten Bone-Hierarchie (Aller Knoten) // den davon verwendeten Speicher wieder frei loesch_Bone_Hierarchie(); // loesch_Verbindungs_Bones(); } //char b=0; } // 2 Dimensionales Array erstellen & Löschen, Beispiel. // // Lösch-Muster für dynamische 2 dimensionale Arrays // ausm WWW (mind 2 mal in ähnlicher Ausführung gefunden): /* Zweidimensionales Array erzeugen & löschen: // z=FirstDimension // S=SecondDimension int z, s; cout << “Zeilen und Spalten eingeben: “; cin >> z >> s; // 1.Schritt: Dynamisches Array von Zeigern anlegen int** mat = new int*[z]; // 2.Schritt: An jeden Zeiger ein Array hängen for(int i=0; i