M3Datei.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. #include "M3Datei.h"
  2. #include "Datei.h"
  3. #include "GraphicsApi.h"
  4. #include "Model3D.h"
  5. using namespace Framework;
  6. // Inhalt der M3Datei Klasse
  7. // Konstruktor
  8. M3Datei::M3Datei()
  9. : ReferenceCounter()
  10. {
  11. modelName = 0;
  12. modelPos = 0;
  13. }
  14. // Konstruktor
  15. // pfad: Der Pfad zur Datei
  16. M3Datei::M3Datei(const char* pfad)
  17. : M3Datei()
  18. {
  19. this->pfad = pfad;
  20. }
  21. // Konstruktor
  22. // pfad: Der Pfad zur Datei
  23. M3Datei::M3Datei(Text* pfad)
  24. : M3Datei(pfad->getText())
  25. {
  26. pfad->release();
  27. }
  28. // Destruktor
  29. M3Datei::~M3Datei()
  30. {
  31. if (modelName) modelName->release();
  32. if (modelPos) modelPos->release();
  33. }
  34. void M3Datei::saveKnochen(Bone* k, Datei* zDat)
  35. {
  36. bool c = k != 0;
  37. zDat->schreibe((char*)&c, 1);
  38. if (c)
  39. {
  40. int id = k->getId();
  41. zDat->schreibe((char*)&id, 4);
  42. float f = k->getPosition().x;
  43. zDat->schreibe((char*)&f, 4);
  44. f = k->getPosition().y;
  45. zDat->schreibe((char*)&f, 4);
  46. f = k->getPosition().z;
  47. zDat->schreibe((char*)&f, 4);
  48. f = k->getRotation().x;
  49. zDat->schreibe((char*)&f, 4);
  50. f = k->getRotation().y;
  51. zDat->schreibe((char*)&f, 4);
  52. f = k->getRotation().z;
  53. zDat->schreibe((char*)&f, 4);
  54. saveKnochen(k->zFirstSibling(), zDat);
  55. saveKnochen(k->zFirstChild(), zDat);
  56. }
  57. }
  58. Bone* Framework::M3Datei::readKnochen(Datei* zDat) const
  59. {
  60. bool c;
  61. zDat->lese((char*)&c, 1);
  62. if (c)
  63. {
  64. int id;
  65. zDat->lese((char*)&id, 4);
  66. Bone* k = new Bone(id);
  67. Vec3<float> pos;
  68. zDat->lese((char*)&pos.x, 4);
  69. zDat->lese((char*)&pos.y, 4);
  70. zDat->lese((char*)&pos.z, 4);
  71. k->setPosition(pos);
  72. Vec3<float> rot;
  73. zDat->lese((char*)&rot.x, 4);
  74. zDat->lese((char*)&rot.y, 4);
  75. zDat->lese((char*)&rot.z, 4);
  76. k->setRotation(rot);
  77. k->addSiblingBone(readKnochen(zDat));
  78. k->addChildBone(id, readKnochen(zDat));
  79. return k;
  80. }
  81. return 0;
  82. }
  83. // Setzt den Pfad zur Datei
  84. // pfad: Pfad zur Datei
  85. void M3Datei::setPfad(const char* pfad)
  86. {
  87. this->pfad = pfad;
  88. if (modelName) modelName = (RCArray<Text>*)modelName->release();
  89. if (modelPos) modelPos = (Array<__int64>*)modelPos->release();
  90. }
  91. // Ließt grundlegende Informationen aus der Datei, die für ihre Verwendung
  92. // benötigt werden
  93. void M3Datei::leseDaten()
  94. {
  95. if (modelName) modelName = (RCArray<Text>*)modelName->release();
  96. if (modelPos) modelPos = (Array<__int64>*)modelPos->release();
  97. modelName = new RCArray<Text>();
  98. modelPos = new Array<__int64>();
  99. Datei d;
  100. d.setDatei(pfad);
  101. if (!d.open(Datei::Style::lesen)) return;
  102. unsigned char anz = 0;
  103. d.lese((char*)&anz, 1);
  104. for (int i = 0; i < anz; i++)
  105. {
  106. char len = 0;
  107. d.lese(&len, 1);
  108. char* n = new char[len + 1];
  109. n[(int)len] = 0;
  110. d.lese(n, len);
  111. modelName->add(new Text(n));
  112. delete[] n;
  113. __int64 p = 0;
  114. d.lese((char*)&p, 8);
  115. modelPos->add(p);
  116. }
  117. d.close();
  118. }
  119. // Speichert 3D Modell Daten in der Datei
  120. // zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference
  121. // Counter name: Der Name, unter dem die Daten in der Datei gespeichert werden
  122. // sollen return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler
  123. // beim speichern auftrat
  124. bool M3Datei::saveModel(Model3DData* zMdr, Text* name)
  125. {
  126. bool ret = saveModel(zMdr, name->getText());
  127. name->release();
  128. return ret;
  129. }
  130. // Speichert 3D Modell Daten in der Datei
  131. // zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference
  132. // Counter name: Der Name, unter dem die Daten in der Datei gespeichert werden
  133. // sollen return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler
  134. // beim speichern auftrat
  135. bool M3Datei::saveModel(Model3DData* zMdr, const char* name)
  136. {
  137. if (!modelName || !pfad.getLength()) return 0;
  138. if (hatModel(name) && !removeModel(name)) return 0;
  139. int anz = modelName->getEintragAnzahl();
  140. anz = modelName->getEintragAnzahl();
  141. Datei d;
  142. d.setDatei(pfad);
  143. d.open(Datei::Style::lesen);
  144. Datei neu;
  145. neu.setDatei(pfad);
  146. neu.zPfad()->append("0");
  147. while (neu.existiert())
  148. neu.zPfad()->append("0");
  149. if (!neu.open(Datei::Style::schreiben))
  150. {
  151. if (d.istOffen()) d.close();
  152. return 0;
  153. }
  154. modelName->add(new Text(name));
  155. int offs = textLength(name) + 9;
  156. for (int i = 0; i < anz; i++)
  157. modelPos->set(modelPos->get(i) + offs, i);
  158. if (d.getSize() < 0)
  159. modelPos->add(offs + 1);
  160. else
  161. modelPos->add(d.getSize() + offs);
  162. anz++;
  163. char tmp = (char)anz;
  164. neu.schreibe(&tmp, 1);
  165. for (int i = 0; i < anz; i++)
  166. {
  167. char len = (char)modelName->z(i)->getLength();
  168. neu.schreibe(&len, 1);
  169. neu.schreibe(modelName->z(i)->getText(), len);
  170. __int64 pos = modelPos->get(i);
  171. neu.schreibe((char*)&pos, 8);
  172. }
  173. if (d.existiert())
  174. {
  175. d.setLPosition(modelPos->get(0) - offs, 0);
  176. __int64 dl = d.getSize() - d.getLPosition();
  177. char bytes[2048];
  178. while (dl)
  179. {
  180. int l = dl > 2048 ? 2048 : (int)dl;
  181. d.lese(bytes, l);
  182. neu.schreibe(bytes, l);
  183. dl -= l;
  184. }
  185. }
  186. d.close();
  187. int vAnz = zMdr->getVertexAnzahl();
  188. neu.schreibe((char*)&vAnz, 4);
  189. for (int i = 0; i < vAnz; i++)
  190. {
  191. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].knochenId, 4);
  192. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].pos.x, 4);
  193. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].pos.y, 4);
  194. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].pos.z, 4);
  195. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].tPos.x, 4);
  196. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].tPos.y, 4);
  197. }
  198. int pAnz = zMdr->getPolygonAnzahl();
  199. neu.schreibe((char*)&pAnz, 4);
  200. for (int p = 0; p < pAnz; p++)
  201. {
  202. Polygon3D* pol = zMdr->getPolygon(p);
  203. int anz = pol->indexAnz;
  204. neu.schreibe((char*)&anz, 4);
  205. neu.schreibe((char*)pol->indexList, anz * 4);
  206. }
  207. float factor = zMdr->getAmbientFactor();
  208. neu.schreibe((char*)&factor, 4);
  209. factor = zMdr->getDiffusFactor();
  210. neu.schreibe((char*)&factor, 4);
  211. factor = zMdr->getSpecularFactor();
  212. neu.schreibe((char*)&factor, 4);
  213. Skeleton* skelet = zMdr->copySkelett();
  214. if (skelet)
  215. {
  216. bool b = 1;
  217. neu.schreibe((char*)&b, 1);
  218. int nId = skelet->getNextBoneId();
  219. neu.schreibe((char*)&nId, 4);
  220. saveKnochen(skelet->zRootBone(), &neu);
  221. skelet->release();
  222. }
  223. else
  224. {
  225. bool b = 0;
  226. neu.schreibe((char*)&b, 1);
  227. }
  228. d.remove();
  229. neu.close();
  230. neu.umbenennen(pfad);
  231. return 1;
  232. }
  233. // Löscht ein 3D Modell aus der Datei
  234. // name: Der Name des Modells
  235. // return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden
  236. // wurde, oder ein fehler beim speichern auftrat
  237. bool M3Datei::removeModel(Text* name)
  238. {
  239. bool res = removeModel(name->getText());
  240. name->release();
  241. return res;
  242. }
  243. // Löscht ein 3D Modell aus der Datei
  244. // name: Der Name des Modells
  245. // return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden
  246. // wurde, oder ein fehler beim speichern auftrat
  247. bool M3Datei::removeModel(const char* name)
  248. {
  249. if (!modelName || !pfad.getLength()) return 0;
  250. if (!hatModel(name)) return 0;
  251. Datei d;
  252. d.setDatei(pfad);
  253. if (!d.open(Datei::Style::lesen)) return 0;
  254. __int64 startPosition = modelPos->get(0);
  255. Datei neu;
  256. neu.setDatei(pfad);
  257. neu.zPfad()->append("0");
  258. while (neu.existiert())
  259. neu.zPfad()->append("0");
  260. if (!neu.open(Datei::Style::schreiben))
  261. {
  262. d.close();
  263. return 0;
  264. }
  265. char anz = (char)(modelName->getEintragAnzahl() - 1);
  266. neu.schreibe(&anz, 1);
  267. __int64 offset = textLength(name) + 9;
  268. __int64 removedLength = 0;
  269. __int64 removedPosition = 0;
  270. int removedIndex = 0;
  271. for (int i = 0; i < anz + 1; i++)
  272. {
  273. if (!modelName->z(i)->istGleich(name))
  274. {
  275. char len = (char)modelName->z(i)->getLength();
  276. neu.schreibe(&len, 1);
  277. neu.schreibe(modelName->z(i)->getText(), len);
  278. modelPos->set(modelPos->get(i) - offset, i);
  279. __int64 pos = modelPos->get(i);
  280. neu.schreibe((char*)&pos, 8);
  281. }
  282. else
  283. {
  284. removedPosition = modelPos->get(i);
  285. removedIndex = i;
  286. if (modelName->getEintragAnzahl() > i + 1)
  287. {
  288. removedLength = modelPos->get(i + 1) - modelPos->get(i);
  289. offset += removedLength;
  290. }
  291. else
  292. {
  293. removedLength = d.getSize() - removedPosition;
  294. }
  295. }
  296. }
  297. d.setLPosition(startPosition, 0);
  298. __int64 dl = removedPosition - startPosition;
  299. char bytes[2048];
  300. while (dl)
  301. {
  302. int l = dl > 2048 ? 2048 : (int)dl;
  303. d.lese(bytes, l);
  304. neu.schreibe(bytes, l);
  305. dl -= l;
  306. }
  307. d.setLPosition(removedPosition + removedLength, 0);
  308. dl = d.getSize() - removedPosition - removedLength;
  309. while (dl)
  310. {
  311. int l = dl > 2048 ? 2048 : (int)dl;
  312. d.lese(bytes, l);
  313. neu.schreibe(bytes, l);
  314. dl -= l;
  315. }
  316. d.close();
  317. d.remove();
  318. neu.close();
  319. neu.umbenennen(pfad);
  320. modelName->remove(removedIndex);
  321. modelPos->remove(removedIndex);
  322. return 1;
  323. }
  324. // Lähd ein 3D Modell aus der Datei
  325. // name: Der name des zu ladenden Modells
  326. // return: Die geladenen Daten
  327. Model3DData* M3Datei::ladeModel(
  328. Text* name, GraphicsApi* zApi, Text* uniqueName) const
  329. {
  330. Model3DData* d = ladeModel(name->getText(), zApi, uniqueName->getText());
  331. name->release();
  332. uniqueName->release();
  333. return d;
  334. }
  335. // Lähd ein 3D Modell aus der Datei
  336. // name: Der name des zu ladenden Modells
  337. // return: Die geladenen Daten
  338. Model3DData* M3Datei::ladeModel(
  339. const char* name, GraphicsApi* zApi, const char* uniqueName) const
  340. {
  341. if (!modelName || !pfad.getLength()) return 0;
  342. __int64 pos = -1;
  343. auto p = modelPos->begin();
  344. for (auto n = modelName->begin(); n && p; n++, p++)
  345. {
  346. if (n->istGleich(name))
  347. {
  348. pos = p;
  349. break;
  350. }
  351. }
  352. if (pos > 0)
  353. {
  354. Datei d;
  355. d.setDatei(pfad);
  356. if (!d.open(Datei::Style::lesen))
  357. {
  358. return 0;
  359. }
  360. d.setLPosition(pos, 0);
  361. Model3DData* model = zApi->createModel(uniqueName);
  362. int vAnz;
  363. d.lese((char*)&vAnz, 4);
  364. Vertex3D* vertices = new Vertex3D[vAnz];
  365. for (int i = 0; i < vAnz; i++)
  366. {
  367. d.lese((char*)&vertices[i].knochenId, 4);
  368. d.lese((char*)&vertices[i].pos.x, 4);
  369. d.lese((char*)&vertices[i].pos.y, 4);
  370. d.lese((char*)&vertices[i].pos.z, 4);
  371. d.lese((char*)&vertices[i].tPos.x, 4);
  372. d.lese((char*)&vertices[i].tPos.y, 4);
  373. }
  374. model->setVertecies(vertices, vAnz);
  375. int pAnz;
  376. d.lese((char*)&pAnz, 4);
  377. for (int i = 0; i < pAnz; i++)
  378. {
  379. Polygon3D* p = new Polygon3D();
  380. d.lese((char*)&p->indexAnz, 4);
  381. p->indexList = new int[p->indexAnz];
  382. d.lese((char*)p->indexList, p->indexAnz * 4);
  383. model->addPolygon(p);
  384. }
  385. float factor;
  386. d.lese((char*)&factor, 4);
  387. model->setAmbientFactor(factor);
  388. d.lese((char*)&factor, 4);
  389. model->setDiffusFactor(factor);
  390. d.lese((char*)&factor, 4);
  391. model->setSpecularFactor(factor);
  392. bool b;
  393. d.lese((char*)&b, 1);
  394. if (b)
  395. {
  396. Skeleton* s = new Skeleton();
  397. int nId;
  398. d.lese((char*)&nId, 4);
  399. s->nextId = nId;
  400. s->rootBone = readKnochen(&d);
  401. model->setSkelettZ(s);
  402. }
  403. model->calculateNormals();
  404. d.close();
  405. return model;
  406. }
  407. return 0;
  408. }
  409. // überprft, ob ein bestimmtes 3D Modell in der Datei existiert
  410. // name: Der Name des zu suchenden 3D Modells
  411. // return: 1, wenn das Modell gefunden wurde. 0 sonst
  412. bool M3Datei::hatModel(const char* name) const
  413. {
  414. if (!modelName || !pfad.getLength()) return 0;
  415. for (auto n = modelName->begin(); n; n++)
  416. {
  417. if (n->istGleich(name)) return 1;
  418. }
  419. return 0;
  420. }
  421. // ügibt die Anzahl der gespeicherten Modelle zurück
  422. int M3Datei::getModelAnzahl() const
  423. {
  424. if (!modelName || !pfad.getLength()) return 0;
  425. return modelName->getEintragAnzahl();
  426. }
  427. // Gibt den Namen eines Bestimmten Modells zurück
  428. // i: Der Index des Modells
  429. // return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
  430. Text* M3Datei::zModelName(int i) const
  431. {
  432. if (!modelName || !pfad.getLength()) return 0;
  433. return modelName->z(i);
  434. }