123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- #include "M3Datei.h"
- #include "Datei.h"
- #include "GraphicsApi.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(Bone* 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->getRotation().x;
- zDat->schreibe((char*)&f, 4);
- f = k->getRotation().y;
- zDat->schreibe((char*)&f, 4);
- f = k->getRotation().z;
- zDat->schreibe((char*)&f, 4);
- saveKnochen(k->zFirstSibling(), zDat);
- saveKnochen(k->zFirstChild(), zDat);
- }
- }
- Bone* Framework::M3Datei::readKnochen(Datei* zDat) const
- {
- bool c;
- zDat->lese((char*)&c, 1);
- if (c)
- {
- int id;
- zDat->lese((char*)&id, 4);
- Bone* k = new Bone(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->setRotation(rot);
- k->addSiblingBone(readKnochen(zDat));
- k->addChildBone(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);
- Skeleton* skelet = zMdr->copySkelett();
- if (skelet)
- {
- bool b = 1;
- neu.schreibe((char*)&b, 1);
- int nId = skelet->getNextBoneId();
- neu.schreibe((char*)&nId, 4);
- saveKnochen(skelet->zRootBone(), &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;
- }
- else
- {
- removedLength = d.getSize() - removedPosition;
- }
- }
- }
- 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, GraphicsApi* zApi, Text* uniqueName) const
- {
- Model3DData* d = ladeModel(name->getText(), zApi, uniqueName->getText());
- name->release();
- uniqueName->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, GraphicsApi* zApi, const char* uniqueName) 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 = zApi->createModel(uniqueName);
- 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)
- {
- Skeleton* s = new Skeleton();
- int nId;
- d.lese((char*)&nId, 4);
- s->nextId = nId;
- s->rootBone = 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);
- }
|