// Kl_3D_Objekt_AnimDaten erweitert Kl_3D_Objekt um Funktionen zur Animation // eines 3D-Objekts. Einige Membervariablen werden außerdem auch in Kl_3D_Objekt genutzt, // also in beiden Klassen // Programmierer & Autor: Daniel Opitz (www.GhostWorld3D.Beepworld.de) // Letzte Änderung: 02.02.2014 (Kl_3D_Objekt_AnimDaten.h) & 16.04.2014 (Kl_3D_Objekt_AnimDaten.cpp) #ifndef _Kl_3D_Objekt_AnimDatenh_ #define _Kl_3D_Objekt_AnimDatenh_ // Für D3DXMATRIX #include "d3dx9.h" // Klasse bekanntmachen #include "Private Klassen\Kl_DX\Kl_3D_Kugel\Kl_3D_Kugel.h" #include "Private Klassen\Kl_DX\Kl_3D\Kl_3D.h" class Kl_3D_Objekt_AnimDaten { public: static void init_Kl_3D_Objekt_AnimDaten(LPDIRECT3DDEVICE9 z_m_Grafikkarte, Kl_3D *z_Kl_3D); void loesch_Bone_Hierarchie(void); void loesch_Verbindungs_Bones(void); void TEST_zeig_Bone_Hierarchie_MB(void); void TEST_zeig_3D_Obj_Gelenke(void); protected: Kl_3D_Objekt_AnimDaten::Kl_3D_Objekt_AnimDaten(); Kl_3D_Objekt_AnimDaten::~Kl_3D_Objekt_AnimDaten(); // Für Zugriff auf andere Klassen static LPDIRECT3DDEVICE9 m_z_m_Grafikkarte; static Kl_3D *m_z_Kl_3D; static Kl_Debug *m_z_Kl_Debug; // Struktur für Bones des Animations-Skelettes für ein bewegbares 3D-Objekt // eines X-Files // (Animationshierarchie, z.B. für Animation von Mensch oder Roboter) // (=Baumstruktur? M-Way / ?Multiway?-Tree Struktur) struct str_Bones { char *Bone_Name; // Name des Bones (=Framename aus X-File) str_Bones *str_Parent_Bone; // Vorheriger Bone (Vorgänger-Knoten) str_Bones **str_Child_Bone; // Nachfolgender Bone (Child-Bone der entsprechenden Child-Ebene) // Z.B.: str_Child_Bone[0]=1. Child Ebene (incl all der Nachfolger) // Z.B.: str_Child_Bone[1]=2. Child Ebene // Z.B.: str_Child_Bone[2]=3. Child Ebene // // Bsp für 1.Child-Ebene: Hüfte Rechts. // Nachfolger-Knoten wären z.B: Bein_R, Wade_R, Fuß_R // // Bsp für 2.Child-Ebene: Hüfte links // Nachfolger (1.Child-Ebene): Bein_L, Wade_L, Fuß_L // // Bsp für 3.Child-Ebene: Rücken unten // Nachfolger (1.Child-Ebene): Rücken oben // // Bsp für 4.Child-Ebene: Frame Roboter_Mensch // Nachfolger (1.Child-Ebene): - // // // (**str_Child_Bone=Zeiger auf Zeiger (auch mehrfache Indirektion genannt), // könnte auch so geschrieben werden: "str_Bones *str_Child_Bone[]"; // Ist also ein Array mit Zeigern) int anz_EndKlammern; // Anzahl der "}"'s für diesen letzten Child Bone int Child_Ebene; // 1=zu str_Child_Bone_2, 2=zu str_Child_Bone_3, usw, wechseln // // *** Daten für Darstellung usw *** // D3DXMATRIX FrameTransform_Matrix;// Matrix aus den X-File Dateiblock "Frame" // // *** Daten je eines SkinWeights-Blocks *** // unsigned long int anz_Vertices; // Anzahl der vertexIndices (und Weights) dieses Bones unsigned long int *vBoneBeeinfltrIndice; // (vertexIndices). Vertice, der vom Bone beeinflußt wird float *BoneWeight; // (Vertex Weights/Skin Weights). Weight für vom Bone beeinflußten Vertice D3DXMATRIX Offset_Matrix; // Matrix vom "SkinWeights" Block des X-Files // (matrixOffset). Transforms Mesh Vertices to the // Space of the Bone // // *** Daten für Animation *** // unsigned short int anz_Mtr_Keys; // Anzahl der Matrix Keys für diesen Bone D3DXMATRIX *animKey_Matrix; // Matrix des aktuellen Animation Keys dieses Bones D3DXMATRIX *abs_Matrix_Gelenk; // D3DXQUATERNION *animKey__Rotation; // Quaternation des aktuellen Rotation Keys dieses Bones D3DXVECTOR3 *animKey__Scale; // Scalierung des aktuellen Scale Keys dieses Bones D3DXVECTOR3 *animKey__Position; // Position des aktuellen Position Keys dieses Bones // Destruktor für die Struktur str_Bones ~str_Bones() { // Speicher wieder freigeben für... // ...Arrays delete [] Bone_Name; delete [] vBoneBeeinfltrIndice; delete [] BoneWeight; delete [] animKey_Matrix; delete [] abs_Matrix_Gelenk; delete [] animKey__Rotation; delete [] animKey__Scale; delete [] animKey__Position; // ...enthaltene Bones if (str_Child_Bone != NULL) { // ?Jedes einzelne Array-Element? löschen // for (unsigned char Child_Ebene=0; Child_Ebene < max_anz_ChildEbenen; Child_Ebene++) for (unsigned char Child_Ebene=0; Child_Ebene < 23; Child_Ebene++) { delete str_Child_Bone[Child_Ebene]; str_Child_Bone[Child_Ebene]=NULL; } // Zeiger auf ?Array mit den Array Elementen? löschen delete str_Child_Bone; str_Child_Bone=NULL; } // Aktivieren=PRG-Absturz. Warum? if (str_Parent_Bone!=NULL) { delete str_Parent_Bone; str_Parent_Bone=NULL; } } }; // Struktur für einfach verkettete Liste, die allein dazu dient, // str_Bones.Child_Ebene resetten (wieder auf 1 setzen) zu können, // damit die gesammte Bonehierarchie wieder von vorne durchsucht werden kann. // (Ohne Reset ist erneutes Durchsuchen der Bonehierarchie NICHT möglich!) struct str_VL_VerbngsBones { str_Bones *Bone; // Zeiger auf Verbindungsbone (=Bone mit mehr als // nur eine Child-Ebene. Z.B. Joint_Root, Joint_Brust) str_VL_VerbngsBones *Naechster; // Zeiger auf nächstes Element in verketteter Liste str_VL_VerbngsBones *Parent; // Zeiger auf vorheriges Element in verketteter Liste // Destruktor für die Struktur str_VL_VerbngsBones ~str_VL_VerbngsBones() { if (Bone!=NULL) { delete Bone; Bone=NULL; } if (Naechster!=NULL) { delete Naechster; Naechster=NULL; } if (Parent!=NULL) { delete Parent; Parent=NULL; } } }; str_Bones *m_str_root_Bone; // Start Knoten für 1. Bone (=Root-Bone) des // Animationsskelets (Bone/Frame-Hierarchie bzw Tree), // um von hier aus zu den anderen Knoten zu gelangen str_Bones *m_str_akt_Bone; // für Bone, mit dem aktuell gearbeitet wird str_VL_VerbngsBones *m_str_VerbBone; // Verkettete Liste Fürs Reseten der // Child-Ebene eines Verbindungsbones // vorm Rendern str_VL_VerbngsBones *m_str_VerbBone_ROOT; // Startknoten von VL Verbindungsbones D3DXMATRIX m_3D_Objekt_Matrix; // Matrix fürs gesammte 3D-Objekt // (Z.B. fürs ganze Auto incl. 4 Räder, etc) // Für Positionierung, Drehung & Größenänderung des 3D-Objekts // per entsprechenden X-Datei Einträgen und Prg-Funktionen. bool m_XFile_hat_Animation; // Ist true, wenn Animationsdaten, also wenn // mind. 1 Joint/Gelenk vorhanden ist bool m_XFile_nutzt_MatrixKeys; // true=X-File nutzt Matrix-Keys, // false=X-File nutzt Rotation-, Scale-, und Positions-Keys bool m_Animationsdaten_sindOK; // Ist false,wenns beim laden der Animationsdaten // des X-Files Probleme gab (Um Prg-Abstürze zu vermeiden, // und Prg-Meldungen trotz Problemen lesen zu können) CUSTOMVERTEX_3D_Objekt_1 *m_3D_Objekt_Vertices; // Original Vertices des X-Files CUSTOMVERTEX_3D_Objekt_1 *m_3D_Obj_Vertices_Animation; // Vertices für Darstellung der // aktuellen Animation (=An Bone-Pos // verschobene Vertices) unsigned int m_DatGroesse_3D_Objekt_Vertices; // LPDIRECT3DVERTEXBUFFER9 m_VertexBuffer_Animiertes_3D_Objekt;// Für animierte Vertices unsigned short int m_max_anz_Mtr_Keys; // Höchste gefundene Anzahl Matrix Keys für irgendeine // Animation unsigned char max_anz_ChildEbenen; // Wieviele Child-Ebenen ein Bone maximal haben darf D3DXMATRIX *m_Tmp_MatrixKey; // Zum Matrix-Key zwischenspeichern, damit geladene Matrixen // später in lade_anim_Animation() verwendet werden können D3DXQUATERNION *m_Tmp_RotationKey; // Zum Rotation-Key zwischenspeichern, damit geladener Rotation-Key // später in lade_anim_Animation() verwendet werden kann D3DXVECTOR3 *m_Tmp_ScaleKey; // Zum Scale-Key zwischenspeichern, damit geladener Scale-Key // später in lade_anim_Animation() verwendet werden kann D3DXVECTOR3 *m_Tmp_PositionKey; // Zum Position-Key zwischenspeichern, damit geladener Position-Key // später in lade_anim_Animation() verwendet werden kann unsigned short int m_anz_MeshesMitJoints; // Anzahl der Meshes, die Joints enthalten unsigned short int m_anz_AnimationKeys; // Anzahl der AnimationKey Dateiblöcke unsigned short int m_akt_AnimSchritt; // Aktuell: Für Animation eines AnimationKey Dateiblocks // (Welcher Animationsschritt einer Animation aktiv ist) unsigned short int m_anz_Joints; // Anzahl der Gelenke/Joints des 3D-Modells bool m_3D_Obj_Gelenke_zeigen_aktiv; // Ist true, wenn TEST_zeig_3D_Obj_Gelenke() ausgeführt wird, // (damit animierte 3D-Objekt in Drahtgitteransicht // angezeigt werden, und somit die Gelenke zu sehen sind) unsigned int m_akt_anz_EndKlammern; // Enthält aktuelle Anzahl an "}"s (Endklammern) // außerhalb von in { } eingeschlossenen Dateiblöcken // Wird z.B. von erzeuge_Bone() benötigt bool m_1tenSkinWeight_geladen; // Um Childebenen-Bones resetten zu können unsigned short int m_akt_anz_Mtr_Keys; // Anzahl der Matrix Keys des aktuellen AnimationKey-Blocks void erzeuge_Bone(char *FrameName, D3DXMATRIX *FrameTransformMatrix); void erzeuge_Verbindungs_Bone(void); Kl_3D_Objekt_AnimDaten::str_Bones *suche_Bone(char *Name_Bone); void ermittle_akt_Animationsschritt(void); void berechne_Matrixen_Gelenkpositionen(void); void berechne_Matrix_Keys(unsigned short int MatrixKey_Nr); void verschiebe_Vertices_Joints(void); void Reset_Verbindungs_Bones(void); private: unsigned char m_akt_3D_obj_Anim_Zeit; // Zeit von einen Animationsschritt zum nächsten Kl_3D_Kugel *m_3D_Kugel; // Für testweises anzeigen der Joints/Gelenke }; #endif