Browse Source

Model3DData Objekte können in M3Dateien gespeichert und aus ihnen geladen werden

Kolja Strohm 4 years ago
parent
commit
e28fa47de4
4 changed files with 228 additions and 47 deletions
  1. 173 31
      M3Datei.cpp
  2. 5 0
      M3Datei.h
  3. 36 12
      Model3D.cpp
  4. 14 4
      Model3D.h

+ 173 - 31
M3Datei.cpp

@@ -37,6 +37,57 @@ M3Datei::~M3Datei()
         modelPos->release();
 }
 
+void M3Datei::saveKnochen( Knochen *k, Datei *zDat )
+{
+    bool c = k != 0;
+    zDat->schreibe( (char *)& c, 1 );
+    if( c )
+    {
+        int id = k->getId();
+        zDat->schreibe( (char *)& id, 4 );
+        float f = k->getPosition().x;
+        zDat->schreibe( (char *)& f, 4 );
+        f = k->getPosition().y;
+        zDat->schreibe( (char *)& f, 4 );
+        f = k->getPosition().z;
+        zDat->schreibe( (char *)& f, 4 );
+        f = k->getDrehung().x;
+        zDat->schreibe( (char *)& f, 4 );
+        f = k->getDrehung().y;
+        zDat->schreibe( (char *)& f, 4 );
+        f = k->getDrehung().z;
+        zDat->schreibe( (char *)& f, 4 );
+        saveKnochen( k->zGeschwister(), zDat );
+        saveKnochen( k->zKind(), zDat );
+    }
+}
+
+Knochen *Framework::M3Datei::readKnochen( Datei *zDat ) const
+{
+    bool c;
+    zDat->lese( (char *)& c, 1 );
+    if( c )
+    {
+        int id;
+        zDat->lese( (char *)& id, 4 );
+        Knochen *k = new Knochen( id );
+        Vec3< float > pos;
+        zDat->lese( (char *)& pos.x, 4 );
+        zDat->lese( (char *)& pos.y, 4 );
+        zDat->lese( (char *)& pos.z, 4 );
+        k->setPosition( pos );
+        Vec3< float > rot;
+        zDat->lese( (char *)& rot.x, 4 );
+        zDat->lese( (char *)& rot.y, 4 );
+        zDat->lese( (char *)& rot.z, 4 );
+        k->setDrehung( rot );
+        k->addGeschwisterKnochen( readKnochen( zDat ) );
+        k->addKind( id, readKnochen( zDat ) );
+        return k;
+    }
+    return 0;
+}
+
 // Setzt den Pfad zur Datei
 
 //  pfad: Pfad zur Datei
@@ -63,7 +114,7 @@ void M3Datei::leseDaten()
     if( !d.open( Datei::Style::lesen ) )
         return;
     unsigned char anz = 0;
-    d.lese( (char*)&anz, 1 );
+    d.lese( (char *)& anz, 1 );
     for( int i = 0; i < anz; i++ )
     {
         char len = 0;
@@ -74,7 +125,7 @@ void M3Datei::leseDaten()
         modelName->add( new Text( n ) );
         delete[] n;
         __int64 p = 0;
-        d.lese( (char*)&p, 8 );
+        d.lese( (char *)& p, 8 );
         modelPos->add( p );
     }
     d.close();
@@ -134,7 +185,7 @@ bool M3Datei::saveModel( Model3DData *zMdr, const char *name )
         neu.schreibe( &len, 1 );
         neu.schreibe( modelName->z( i )->getText(), len );
         __int64 pos = modelPos->get( i );
-        neu.schreibe( (char*)&pos, 8 );
+        neu.schreibe( (char *)& pos, 8 );
     }
     if( d.existiert() )
     {
@@ -150,33 +201,47 @@ bool M3Datei::saveModel( Model3DData *zMdr, const char *name )
         }
     }
     d.close();
-    /*char pAnz = zMdr->getPolygonAnzahl();
-    neu.schreibe( &pAnz, 1 );
+    int vAnz = zMdr->getVertexAnzahl();
+    neu.schreibe( (char *)& vAnz, 4 );
+    for( int i = 0; i < vAnz; i++ )
+    {
+        neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].knochenId, 4 );
+        neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].pos.x, 4 );
+        neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].pos.y, 4 );
+        neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].pos.z, 4 );
+        neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].tPos.x, 4 );
+        neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].tPos.y, 4 );
+    }
+    int pAnz = zMdr->getPolygonAnzahl();
+    neu.schreibe( (char *)& pAnz, 4 );
     for( int p = 0; p < pAnz; p++ )
     {
         Polygon3D *pol = zMdr->getPolygon( p );
         int anz = pol->indexAnz;
-        int vAnz = pol.vertex->getEintragAnzahl();
-        char textur = 1;
-        for( int i = 0; i < vAnz; i++ )
-            textur &= (char)zMdr->polygons->get( p ).tKordinaten->hat( i );
-        neu.schreibe( &textur, 1 );
-        neu.schreibe( (char*)&vAnz, 4 );
-        for( int i = 0; i < vAnz; i++ )
-        {
-            float v = zMdr->polygons->get( p ).vertex->get( i ).x;
-            neu.schreibe( (char*)&v, 4 );
-            v = zMdr->polygons->get( p ).vertex->get( i ).y;
-            neu.schreibe( (char*)&v, 4 );
-            if( textur )
-            {
-                int t = zMdr->polygons->get( p ).tKordinaten->get( i ).x;
-                neu.schreibe( (char*)&t, 4 );
-                t = zMdr->polygons->get( p ).tKordinaten->get( i ).y;
-                neu.schreibe( (char*)&t, 4 );
-            }
-        }
-    }*/
+        neu.schreibe( (char *)& anz, 4 );
+        neu.schreibe( (char *)pol->indexList, anz * 4 );
+    }
+    float factor = zMdr->getAmbientFactor();
+    neu.schreibe( (char *)& factor, 4 );
+    factor = zMdr->getDiffusFactor();
+    neu.schreibe( (char *)& factor, 4 );
+    factor = zMdr->getSpecularFactor();
+    neu.schreibe( (char *)& factor, 4 );
+    Skelett *skelet = zMdr->copySkelett();
+    if( skelet )
+    {
+        bool b = 1;
+        neu.schreibe( (char*)&b, 1 );
+        int nId = skelet->zNextKnochenId();
+        neu.schreibe( (char *)& nId, 4 );
+        saveKnochen( skelet->zKnochen(), &neu );
+        skelet->release();
+    }
+    else
+    {
+        bool b = 0;
+        neu.schreibe( (char *)& b, 1 );
+    }
     d.remove();
     neu.close();
     neu.umbenennen( pfad );
@@ -189,7 +254,9 @@ bool M3Datei::saveModel( Model3DData *zMdr, const char *name )
 //  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
 bool M3Datei::removeModel( Text *name )
 {
-    return 0;
+    bool res = removeModel( name->getText() );
+    name->release();
+    return res;
 }
 
 // Löscht ein 3D Modell aus der Datei
@@ -197,6 +264,7 @@ bool M3Datei::removeModel( Text *name )
 //  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
 bool M3Datei::removeModel( const char *name )
 {
+    // TODO: implement this
     return 0;
 }
 
@@ -205,7 +273,9 @@ bool M3Datei::removeModel( const char *name )
 //  return: Die geladenen Daten
 Model3DData *M3Datei::ladeModel( Text *name ) const
 {
-    return 0;
+    Model3DData *d = ladeModel( name->getText() );
+    name->release();
+    return d;
 }
 
 // Lähd ein 3D Modell aus der Datei
@@ -213,6 +283,70 @@ Model3DData *M3Datei::ladeModel( Text *name ) const
 //  return: Die geladenen Daten
 Model3DData *M3Datei::ladeModel( const char *name ) const
 {
+    __int64 pos = -1;
+    auto p = modelPos->getIterator();
+    for( auto n = modelName->getIterator(); n && p; n++, p++ )
+    {
+        if( n->istGleich( name ) )
+        {
+            pos = p;
+            break;
+        }
+    }
+    if( pos > 0 )
+    {
+        Datei d;
+        d.setDatei( pfad );
+        if( !d.open( Datei::Style::lesen ) )
+        {
+            return 0;
+        }
+        d.setLPosition( pos, 0 );
+        Model3DData *model = new Model3DData();
+        int vAnz;
+        d.lese( (char *)& vAnz, 4 );
+        Vertex3D *vertices = new Vertex3D[ vAnz ];
+        for( int i = 0; i < vAnz; i++ )
+        {
+            d.lese( (char *)& vertices[ i ].knochenId, 4 );
+            d.lese( (char *)& vertices[ i ].pos.x, 4 );
+            d.lese( (char *)& vertices[ i ].pos.y, 4 );
+            d.lese( (char *)& vertices[ i ].pos.z, 4 );
+            d.lese( (char *)& vertices[ i ].tPos.x, 4 );
+            d.lese( (char *)& vertices[ i ].tPos.y, 4 );
+        }
+        model->setVertecies( vertices, vAnz );
+        int pAnz;
+        d.lese( (char *)& pAnz, 4 );
+        for( int i = 0; i < pAnz; i++ )
+        {
+            Polygon3D *p = new Polygon3D();
+            d.lese( (char *)& p->indexAnz, 4 );
+            p->indexList = new int[ p->indexAnz ];
+            d.lese( (char *)p->indexList, pAnz * 4 );
+            model->addPolygon( p );
+        }
+        float factor;
+        d.lese( (char *)& factor, 4 );
+        model->setAmbientFactor( factor );
+        d.lese( (char *)& factor, 4 );
+        model->setDiffusFactor( factor );
+        d.lese( (char *)& factor, 4 );
+        model->setSpecularFactor( factor );
+        bool b;
+        d.lese( (char *)& b, 1 );
+        if( b )
+        {
+            Skelett *s = new Skelett();
+            int nId;
+            d.lese( (char *)& nId, 4 );
+            s->setNextKnochenId( nId );
+            s->addKnochen( readKnochen( &d ) );
+            model->setSkelettZ( s );
+        }
+        d.close();
+        return model;
+    }
     return 0;
 }
 
@@ -221,13 +355,18 @@ Model3DData *M3Datei::ladeModel( const char *name ) const
 //  return: 1, wenn das Modell gefunden wurde. 0 sonst
 bool M3Datei::hatModel( const char *name ) const
 {
+    for( auto n = modelName->getIterator(); n; n++ )
+    {
+        if( n->istGleich( name ) )
+            return 1;
+    }
     return 0;
 }
 
 // ügibt die Anzahl der gespeicherten Modelle zurück
 int M3Datei::getModelAnzahl() const
 {
-    return 0;
+    return modelName->getEintragAnzahl();
 }
 
 // Gibt den Namen eines Bestimmten Modells zurück
@@ -235,19 +374,22 @@ int M3Datei::getModelAnzahl() const
 //  return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
 Text *M3Datei::zModelName( int i ) const
 {
-    return 0;
+    return modelName->z( i );
 }
 
 // Erhöht den Reference Counting Zähler.
 //  return: this.
 M3Datei *M3Datei::getThis()
 {
-    return 0;
+    ref++;
+    return this;
 }
 
 // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
 //  return: 0.
 M3Datei *M3Datei::release()
 {
+    if( !--ref )
+        delete this;
     return 0;
 }

+ 5 - 0
M3Datei.h

@@ -6,6 +6,8 @@ namespace Framework
 {
     class Text;
     class Model3DData;
+    class Knochen;
+    class Datei;
 
     // Verwaltet eine Datei, in der 3d Modelle abgespeichert wurden
     class M3Datei
@@ -16,6 +18,9 @@ namespace Framework
         Array< __int64 > *modelPos;
         int ref;
 
+        void saveKnochen( Knochen *k, Datei *zDat );
+        Knochen *readKnochen( Datei *zDat ) const;
+
     public:
         // Konstruktor
         __declspec( dllexport ) M3Datei();

+ 36 - 12
Model3D.cpp

@@ -32,18 +32,6 @@ Knochen::~Knochen()
     delete kinder;
 }
 
-// private
-
-// Fügt dem Knochen ein Geschwister Knochen hinzu
-//  k: Der Knochen, der hinzugefügt werden soll
-void Knochen::addGeschwisterKnochen( Knochen *k )
-{
-    if( !geschwister )
-        geschwister = k;
-    else
-        geschwister->addGeschwisterKnochen( k );
-}
-
 // public
 
 // Setzt die Position des Knochens relativ zum Model Ursprung
@@ -60,6 +48,16 @@ void Knochen::setDrehung( Vec3< float > &winkel )
     this->winkel = winkel;
 }
 
+// Fügt dem Knochen ein Geschwister Knochen hinzu
+//  k: Der Knochen, der hinzugefügt werden soll
+void Knochen::addGeschwisterKnochen( Knochen *k )
+{
+    if( !geschwister )
+        geschwister = k;
+    else
+        geschwister->addGeschwisterKnochen( k );
+}
+
 // Fügt einem bestimmten Knochen ein Kind Knochen hinzu
 //  id: Die id des Knochens, wo der Knochen als Kind hinzugefügt werden soll
 //  k: Der Knochen, der hinzugefügt werden soll
@@ -105,6 +103,16 @@ void Knochen::kalkulateMatrix( Mat4< float > &elternMat, Mat4< float > *matBuffe
     matBuffer[ id ] = kamMat * matBuffer[ id ];
 }
 
+Knochen *Framework::Knochen::zGeschwister() const
+{
+    return geschwister;
+}
+
+Knochen *Framework::Knochen::zKind() const
+{
+    return kinder;
+}
+
 // Kopiert den Knochen mit allen Geschwister Knochen und Kind Knochen
 Knochen *Knochen::kopiereKnochen() const
 {
@@ -171,6 +179,11 @@ int Skelett::getNextKnochenId()
     return nextId++;
 }
 
+void Framework::Skelett::setNextKnochenId( int id )
+{
+    nextId = id;
+}
+
 // Fügt dem Skellet einen Knochen hinzu
 //  k: Der Knochen
 //  elternId: Die Id des Eltern Knochens. Wenn der Knochen kein Elternknochen besitzt, kannder Parameter weggelassen werden.
@@ -204,6 +217,12 @@ float Skelett::getRadius() const
     return 0;
 }
 
+// gibt den Wurzel Knochen zurück
+Knochen *Framework::Skelett::zKnochen() const
+{
+    return k;
+}
+
 // Kopiert das Skelett
 Skelett *Skelett::kopiereSkelett() const
 {
@@ -214,6 +233,11 @@ Skelett *Skelett::kopiereSkelett() const
     return ret;
 }
 
+int Framework::Skelett::zNextKnochenId() const
+{
+    return nextId;
+}
+
 // Erhöht den Reference Counting Zähler.
 Skelett *Skelett::getThis()
 {

+ 14 - 4
Model3D.h

@@ -29,10 +29,6 @@ namespace Framework
         Knochen *kinder;
         int id;
 
-        // Fügt dem Knochen ein Geschwister Knochen hinzu
-        //  k: Der Knochen, der hinzugefügt werden soll
-        void addGeschwisterKnochen( Knochen *k );
-
     public:
         // Konstruktor
         __declspec( dllexport ) Knochen( int id );
@@ -44,6 +40,9 @@ namespace Framework
         // Setzt die Drehung des Knochens relativ zum Model Ursprung
         //  winkel: Ein Vektor der die Drehung um die verschiedenen Achsen als Komponenten hat
         __declspec( dllexport ) void setDrehung( Vec3< float > &winkel );
+        // Fügt dem Knochen ein Geschwister Knochen hinzu
+        //  k: Der Knochen, der hinzugefügt werden soll
+        void addGeschwisterKnochen( Knochen *k );
         // Fügt einem bestimmten Knochen ein Kind Knochen hinzu
         //  id: Die id des Knochens, wo der Knochen als Kind hinzugefügt werden soll
         //  k: Der Knochen, der hinzugefügt werden soll
@@ -54,6 +53,10 @@ namespace Framework
         //  scaleFactor: Die skallierung des Objektes
         //  kamMatrix: Die vereiniegung der view und projektions Matrizen
         __declspec( dllexport ) void kalkulateMatrix( Mat4< float > &elternMat, Mat4< float > *matBuffer, float scaleFactor, Mat4< float > &kamMat );
+        // Gibt den ersten Geschwisterknochen zurück
+        __declspec( dllexport ) Knochen *zGeschwister() const;
+        // Gibt den ersten KindKnochen zurück
+        __declspec( dllexport ) Knochen *zKind() const;
         // Kopiert den Knochen mit allen Geschwister Knochen und Kind Knochen
         __declspec( dllexport ) Knochen *kopiereKnochen() const;
         // Gibt die Id des Knochens zurück
@@ -84,6 +87,9 @@ namespace Framework
         // Gibt die Id des nächsten Knochens zurück und berechnet die neue Id für den Knochen danach
         // Es können maximal MAX_KNOCHEN_ANZ Knochen für ein Skelett existieren. Wenn diese Zahl überschritten wird, so wird -1 zurückgegeben
         __declspec( dllexport ) int getNextKnochenId();
+        // setzt die Id des nächsten Knochens
+        //  id: die nächste id
+        __declspec( dllexport ) void setNextKnochenId( int id );
         // Fügt dem Skellet einen Knochen hinzu
         //  k: Der Knochen
         //  elternId: Die Id des Eltern Knochens. Wenn der Knochen kein Elternknochen besitzt, kannder Parameter weggelassen werden.
@@ -97,8 +103,12 @@ namespace Framework
         __declspec( dllexport ) int kalkulateMatrix( Mat4< float > &modelMatrix, Mat4< float > *matBuffer, float scaleFactor, Mat4< float > &kamMatrix );
         // Berechnet den Radius des Skeletts
         __declspec( dllexport ) float getRadius() const;
+        // gibt den Wurzel Knochen zurück
+        __declspec( dllexport ) Knochen *zKnochen() const;
         // Kopiert das Skelett
         __declspec( dllexport ) Skelett *kopiereSkelett() const;
+        // Gibt die id des nächsten Knochens zurück ohne sie zu erhöhen
+        __declspec( dllexport ) int zNextKnochenId() const;
         // Erhöht den Reference Counting Zähler.
         //  return: this.
         __declspec( dllexport ) Skelett *getThis();