123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- #include "M3Datei.h"
- #include "Datei.h"
- #include "Model3D.h"
- using namespace Framework;
- // Inhalt der M3Datei Klasse
- // Konstruktor
- M3Datei::M3Datei()
- : ReferenceCounter()
- {
- modelName = 0;
- modelPos = 0;
- }
- // Konstruktor
- // pfad: Der Pfad zur Datei
- M3Datei::M3Datei( const char *pfad )
- : M3Datei()
- {
- this->pfad = pfad;
- }
- // Konstruktor
- // pfad: Der Pfad zur Datei
- M3Datei::M3Datei( Text *pfad )
- : M3Datei( pfad->getText() )
- {
- pfad->release();
- }
- // Destruktor
- M3Datei::~M3Datei()
- {
- if( modelName )
- modelName->release();
- if( modelPos )
- 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
- void M3Datei::setPfad( const char *pfad )
- {
- this->pfad = pfad;
- if( modelName )
- modelName = ( RCArray<Text>* )modelName->release();
- if( modelPos )
- modelPos = ( Array<__int64>* )modelPos->release();
- }
- // Ließt grundlegende Informationen aus der Datei, die für ihre Verwendung benötigt werden
- void M3Datei::leseDaten()
- {
- if( modelName )
- modelName = ( RCArray<Text>* )modelName->release();
- if( modelPos )
- modelPos = ( Array<__int64>* )modelPos->release();
- modelName = new RCArray< Text >();
- modelPos = new Array< __int64 >();
- Datei d;
- d.setDatei( pfad );
- if( !d.open( Datei::Style::lesen ) )
- return;
- unsigned char anz = 0;
- d.lese( (char *)&anz, 1 );
- for( int i = 0; i < anz; i++ )
- {
- char len = 0;
- d.lese( &len, 1 );
- char *n = new char[ len + 1 ];
- n[ (int)len ] = 0;
- d.lese( n, len );
- modelName->add( new Text( n ) );
- delete[] n;
- __int64 p = 0;
- d.lese( (char *)&p, 8 );
- modelPos->add( p );
- }
- d.close();
- }
- // Speichert 3D Modell Daten in der Datei
- // zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
- // name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
- // return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
- bool M3Datei::saveModel( Model3DData *zMdr, Text *name )
- {
- bool ret = saveModel( zMdr, name->getText() );
- name->release();
- return ret;
- }
- // Speichert 3D Modell Daten in der Datei
- // zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
- // name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
- // return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
- bool M3Datei::saveModel( Model3DData *zMdr, const char *name )
- {
- if( !modelName || !pfad.getLength() )
- return 0;
- if( hatModel( name ) && !removeModel( name ) )
- return 0;
- int anz = modelName->getEintragAnzahl();
- anz = modelName->getEintragAnzahl();
- Datei d;
- d.setDatei( pfad );
- d.open( Datei::Style::lesen );
- Datei neu;
- neu.setDatei( pfad );
- neu.zPfad()->append( "0" );
- while( neu.existiert() )
- neu.zPfad()->append( "0" );
- if( !neu.open( Datei::Style::schreiben ) )
- {
- if( d.istOffen() )
- d.close();
- return 0;
- }
- modelName->add( new Text( name ) );
- int offs = textLength( name ) + 9;
- for( int i = 0; i < anz; i++ )
- modelPos->set( modelPos->get( i ) + offs, i );
- if( d.getSize() < 0 )
- modelPos->add( offs + 1 );
- else
- modelPos->add( d.getSize() + offs );
- anz++;
- char tmp = (char)anz;
- neu.schreibe( &tmp, 1 );
- for( int i = 0; i < anz; i++ )
- {
- char len = (char)modelName->z( i )->getLength();
- neu.schreibe( &len, 1 );
- neu.schreibe( modelName->z( i )->getText(), len );
- __int64 pos = modelPos->get( i );
- neu.schreibe( (char *)&pos, 8 );
- }
- if( d.existiert() )
- {
- d.setLPosition( modelPos->get( 0 ) - offs, 0 );
- __int64 dl = d.getSize() - d.getLPosition();
- char bytes[ 2048 ];
- while( dl )
- {
- int l = dl > 2048 ? 2048 : (int)dl;
- d.lese( bytes, l );
- neu.schreibe( bytes, l );
- dl -= l;
- }
- }
- d.close();
- 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;
- 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 );
- return 1;
- }
- // Löscht ein 3D Modell aus der Datei
- // name: Der Name des Modells
- // 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 )
- {
- bool res = removeModel( name->getText() );
- name->release();
- return res;
- }
- // Löscht ein 3D Modell aus der Datei
- // name: Der Name des Modells
- // 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 )
- {
- if( !modelName || !pfad.getLength() )
- return 0;
- if( !hatModel( name ) )
- return 0;
- Datei d;
- d.setDatei( pfad );
- if( !d.open( Datei::Style::lesen ) )
- return 0;
- __int64 startPosition = modelPos->get( 0 );
- Datei neu;
- neu.setDatei( pfad );
- neu.zPfad()->append( "0" );
- while( neu.existiert() )
- neu.zPfad()->append( "0" );
- if( !neu.open( Datei::Style::schreiben ) )
- {
- d.close();
- return 0;
- }
- char anz = (char)( modelName->getEintragAnzahl() - 1 );
- neu.schreibe( &anz, 1 );
- __int64 offset = textLength( name ) + 9;
- __int64 removedLength = 0;
- __int64 removedPosition = 0;
- int removedIndex = 0;
- for( int i = 0; i < anz + 1; i++ )
- {
- if( !modelName->z( i )->istGleich( name ) )
- {
- char len = (char)modelName->z( i )->getLength();
- neu.schreibe( &len, 1 );
- neu.schreibe( modelName->z( i )->getText(), len );
- modelPos->set( modelPos->get( i ) - offset, i );
- __int64 pos = modelPos->get( i );
- neu.schreibe( (char *)&pos, 8 );
- }
- else
- {
- removedPosition = modelPos->get( i );
- removedIndex = i;
- if( modelName->getEintragAnzahl() > i + 1 )
- {
- removedLength = modelPos->get( i + 1 ) - modelPos->get( i );
- offset += removedLength;
- }
- }
- }
- d.setLPosition( startPosition, 0 );
- __int64 dl = removedPosition - startPosition;
- char bytes[ 2048 ];
- while( dl )
- {
- int l = dl > 2048 ? 2048 : (int)dl;
- d.lese( bytes, l );
- neu.schreibe( bytes, l );
- dl -= l;
- }
- d.setLPosition( removedPosition + removedLength, 0 );
- dl = d.getSize() - removedPosition - removedLength;
- while( dl )
- {
- int l = dl > 2048 ? 2048 : (int)dl;
- d.lese( bytes, l );
- neu.schreibe( bytes, l );
- dl -= l;
- }
- d.close();
- d.remove();
- neu.close();
- neu.umbenennen( pfad );
- modelName->remove( removedIndex );
- modelPos->remove( removedIndex );
- return 1;
- }
- // Lähd ein 3D Modell aus der Datei
- // name: Der name des zu ladenden Modells
- // return: Die geladenen Daten
- Model3DData *M3Datei::ladeModel( Text *name ) const
- {
- Model3DData *d = ladeModel( name->getText() );
- name->release();
- return d;
- }
- // Lähd ein 3D Modell aus der Datei
- // name: Der name des zu ladenden Modells
- // return: Die geladenen Daten
- Model3DData *M3Datei::ladeModel( const char *name ) const
- {
- if( !modelName || !pfad.getLength() )
- return 0;
- __int64 pos = -1;
- auto p = modelPos->begin();
- for( auto n = modelName->begin(); 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, p->indexAnz * 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 );
- }
- model->calculateNormals();
- d.close();
- return model;
- }
- return 0;
- }
- // überprft, ob ein bestimmtes 3D Modell in der Datei existiert
- // name: Der Name des zu suchenden 3D Modells
- // return: 1, wenn das Modell gefunden wurde. 0 sonst
- bool M3Datei::hatModel( const char *name ) const
- {
- if( !modelName || !pfad.getLength() )
- return 0;
- for( auto n = modelName->begin(); n; n++ )
- {
- if( n->istGleich( name ) )
- return 1;
- }
- return 0;
- }
- // ügibt die Anzahl der gespeicherten Modelle zurück
- int M3Datei::getModelAnzahl() const
- {
- if( !modelName || !pfad.getLength() )
- return 0;
- return modelName->getEintragAnzahl();
- }
- // Gibt den Namen eines Bestimmten Modells zurück
- // i: Der Index des Modells
- // return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
- Text *M3Datei::zModelName( int i ) const
- {
- if( !modelName || !pfad.getLength() )
- return 0;
- return modelName->z( i );
- }
|