M3Datei.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. #include "M3Datei.h"
  2. #include "Datei.h"
  3. #include "GraphicsApi.h"
  4. #include "Model3D.h"
  5. using namespace Framework;
  6. // Content of the M3Datei class from M3Datei.h
  7. // Constructor
  8. M3Datei::M3Datei()
  9. : ReferenceCounter()
  10. {
  11. modelName = 0;
  12. modelPos = 0;
  13. }
  14. // Constructor
  15. // pfad: the path to the file
  16. M3Datei::M3Datei(const char* pfad)
  17. : M3Datei()
  18. {
  19. this->pfad = pfad;
  20. }
  21. // Constructor
  22. // pfad: the path to the file
  23. M3Datei::M3Datei(Text* pfad)
  24. : M3Datei(pfad->getText())
  25. {
  26. pfad->release();
  27. }
  28. // Destructor
  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. // sets the path to the file
  84. // pfad: the path
  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. // reads header information from the file needed for its usage.
  92. void M3Datei::leseDaten()
  93. {
  94. if (modelName) modelName = (RCArray<Text>*)modelName->release();
  95. if (modelPos) modelPos = (Array<__int64>*)modelPos->release();
  96. modelName = new RCArray<Text>();
  97. modelPos = new Array<__int64>();
  98. Datei d;
  99. d.setDatei(pfad);
  100. if (!d.open(Datei::Style::lesen)) return;
  101. unsigned char anz = 0;
  102. d.lese((char*)&anz, 1);
  103. for (int i = 0; i < anz; i++)
  104. {
  105. char len = 0;
  106. d.lese(&len, 1);
  107. char* n = new char[len + 1];
  108. n[(int)len] = 0;
  109. d.lese(n, len);
  110. modelName->add(new Text(n));
  111. delete[] n;
  112. __int64 p = 0;
  113. d.lese((char*)&p, 8);
  114. modelPos->add(p);
  115. }
  116. d.close();
  117. }
  118. // Saves 3D model data to the file
  119. // zMdr: A pointer to the data to be saved without increased reference
  120. // counter name: The name under which the data is stored in the file
  121. // return: 1 if the model was saved. 0 if an error
  122. // occurred during saving
  123. bool M3Datei::saveModel(Model3DData* zMdr, Text* name)
  124. {
  125. bool ret = saveModel(zMdr, name->getText());
  126. name->release();
  127. return ret;
  128. }
  129. // Saves 3D model data to the file
  130. // zMdr: A pointer to the data to be saved without increased reference
  131. // counter name: The name under which the data is stored in the file
  132. // return: 1 if the model was saved. 0 if an error
  133. // occurred during saving
  134. bool M3Datei::saveModel(Model3DData* zMdr, const char* name)
  135. {
  136. if (!modelName || !pfad.getLength()) return 0;
  137. if (hatModel(name) && !removeModel(name)) return 0;
  138. int anz = modelName->getEintragAnzahl();
  139. anz = modelName->getEintragAnzahl();
  140. Datei d;
  141. d.setDatei(pfad);
  142. d.open(Datei::Style::lesen);
  143. Datei neu;
  144. neu.setDatei(pfad);
  145. neu.zPfad()->append("0");
  146. while (neu.existiert())
  147. neu.zPfad()->append("0");
  148. if (!neu.open(Datei::Style::schreiben))
  149. {
  150. if (d.istOffen()) d.close();
  151. return 0;
  152. }
  153. modelName->add(new Text(name));
  154. int offs = textLength(name) + 9;
  155. for (int i = 0; i < anz; i++)
  156. modelPos->set(modelPos->get(i) + offs, i);
  157. if (d.getSize() < 0)
  158. modelPos->add(offs + 1);
  159. else
  160. modelPos->add(d.getSize() + offs);
  161. anz++;
  162. char tmp = (char)anz;
  163. neu.schreibe(&tmp, 1);
  164. for (int i = 0; i < anz; i++)
  165. {
  166. char len = (char)modelName->z(i)->getLength();
  167. neu.schreibe(&len, 1);
  168. neu.schreibe(modelName->z(i)->getText(), len);
  169. __int64 pos = modelPos->get(i);
  170. neu.schreibe((char*)&pos, 8);
  171. }
  172. if (d.existiert())
  173. {
  174. d.setLPosition(modelPos->get(0) - offs, 0);
  175. __int64 dl = d.getSize() - d.getLPosition();
  176. char bytes[2048];
  177. while (dl)
  178. {
  179. int l = dl > 2048 ? 2048 : (int)dl;
  180. d.lese(bytes, l);
  181. neu.schreibe(bytes, l);
  182. dl -= l;
  183. }
  184. }
  185. d.close();
  186. int vAnz = zMdr->getVertexAnzahl();
  187. neu.schreibe((char*)&vAnz, 4);
  188. for (int i = 0; i < vAnz; i++)
  189. {
  190. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].knochenId, 4);
  191. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].pos.x, 4);
  192. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].pos.y, 4);
  193. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].pos.z, 4);
  194. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].tPos.x, 4);
  195. neu.schreibe((char*)&zMdr->zVertexBuffer()[i].tPos.y, 4);
  196. }
  197. int pAnz = zMdr->getPolygonAnzahl();
  198. neu.schreibe((char*)&pAnz, 4);
  199. for (int p = 0; p < pAnz; p++)
  200. {
  201. Polygon3D* pol = zMdr->getPolygon(p);
  202. int anz = pol->indexAnz;
  203. neu.schreibe((char*)&anz, 4);
  204. neu.schreibe((char*)pol->indexList, anz * 4);
  205. }
  206. float factor = zMdr->getAmbientFactor();
  207. neu.schreibe((char*)&factor, 4);
  208. factor = zMdr->getDiffusFactor();
  209. neu.schreibe((char*)&factor, 4);
  210. factor = zMdr->getSpecularFactor();
  211. neu.schreibe((char*)&factor, 4);
  212. Skeleton* skelet = zMdr->copySkelett();
  213. if (skelet)
  214. {
  215. bool b = 1;
  216. neu.schreibe((char*)&b, 1);
  217. int nId = skelet->getNextBoneId();
  218. neu.schreibe((char*)&nId, 4);
  219. saveKnochen(skelet->zRootBone(), &neu);
  220. skelet->release();
  221. }
  222. else
  223. {
  224. bool b = 0;
  225. neu.schreibe((char*)&b, 1);
  226. }
  227. d.remove();
  228. neu.close();
  229. neu.umbenennen(pfad);
  230. return 1;
  231. }
  232. // Deletes a 3D model from the file
  233. // name: The name of the model
  234. // return: 1 if the model was deleted. 0 if the model was not found
  235. // or an error occurred during saving
  236. bool M3Datei::removeModel(Text* name)
  237. {
  238. bool res = removeModel(name->getText());
  239. name->release();
  240. return res;
  241. }
  242. // Deletes a 3D model from the file
  243. // name: The name of the model
  244. // return: 1 if the model was deleted. 0 if the model was not found
  245. // or an error occurred during saving
  246. bool M3Datei::removeModel(const char* name)
  247. {
  248. if (!modelName || !pfad.getLength()) return 0;
  249. if (!hatModel(name)) return 0;
  250. Datei d;
  251. d.setDatei(pfad);
  252. if (!d.open(Datei::Style::lesen)) return 0;
  253. __int64 startPosition = modelPos->get(0);
  254. Datei neu;
  255. neu.setDatei(pfad);
  256. neu.zPfad()->append("0");
  257. while (neu.existiert())
  258. neu.zPfad()->append("0");
  259. if (!neu.open(Datei::Style::schreiben))
  260. {
  261. d.close();
  262. return 0;
  263. }
  264. char anz = (char)(modelName->getEintragAnzahl() - 1);
  265. neu.schreibe(&anz, 1);
  266. __int64 offset = textLength(name) + 9;
  267. __int64 removedLength = 0;
  268. __int64 removedPosition = 0;
  269. int removedIndex = 0;
  270. for (int i = 0; i < anz + 1; i++)
  271. {
  272. if (!modelName->z(i)->istGleich(name))
  273. {
  274. char len = (char)modelName->z(i)->getLength();
  275. neu.schreibe(&len, 1);
  276. neu.schreibe(modelName->z(i)->getText(), len);
  277. modelPos->set(modelPos->get(i) - offset, i);
  278. __int64 pos = modelPos->get(i);
  279. neu.schreibe((char*)&pos, 8);
  280. }
  281. else
  282. {
  283. removedPosition = modelPos->get(i);
  284. removedIndex = i;
  285. if (modelName->getEintragAnzahl() > i + 1)
  286. {
  287. removedLength = modelPos->get(i + 1) - modelPos->get(i);
  288. offset += removedLength;
  289. }
  290. else
  291. {
  292. removedLength = d.getSize() - removedPosition;
  293. }
  294. }
  295. }
  296. d.setLPosition(startPosition, 0);
  297. __int64 dl = removedPosition - startPosition;
  298. char bytes[2048];
  299. while (dl)
  300. {
  301. int l = dl > 2048 ? 2048 : (int)dl;
  302. d.lese(bytes, l);
  303. neu.schreibe(bytes, l);
  304. dl -= l;
  305. }
  306. d.setLPosition(removedPosition + removedLength, 0);
  307. dl = d.getSize() - removedPosition - removedLength;
  308. while (dl)
  309. {
  310. int l = dl > 2048 ? 2048 : (int)dl;
  311. d.lese(bytes, l);
  312. neu.schreibe(bytes, l);
  313. dl -= l;
  314. }
  315. d.close();
  316. d.remove();
  317. neu.close();
  318. neu.umbenennen(pfad);
  319. modelName->remove(removedIndex);
  320. modelPos->remove(removedIndex);
  321. return 1;
  322. }
  323. // Loads a 3D model from the file
  324. // name: The name of the model to load
  325. // return: The loaded data
  326. Model3DData* M3Datei::ladeModel(
  327. Text* name, GraphicsApi* zApi, Text* uniqueName) const
  328. {
  329. Model3DData* d = ladeModel(name->getText(), zApi, uniqueName->getText());
  330. name->release();
  331. uniqueName->release();
  332. return d;
  333. }
  334. // Loads a 3D model from the file
  335. // name: The name of the model to load
  336. // return: The loaded data
  337. Model3DData* M3Datei::ladeModel(
  338. const char* name, GraphicsApi* zApi, const char* uniqueName) const
  339. {
  340. if (!modelName || !pfad.getLength()) return 0;
  341. __int64 pos = -1;
  342. auto p = modelPos->begin();
  343. for (auto n = modelName->begin(); n && p; n++, p++)
  344. {
  345. if (n->istGleich(name))
  346. {
  347. pos = p;
  348. break;
  349. }
  350. }
  351. if (pos > 0)
  352. {
  353. Datei d;
  354. d.setDatei(pfad);
  355. if (!d.open(Datei::Style::lesen))
  356. {
  357. return 0;
  358. }
  359. d.setLPosition(pos, 0);
  360. Model3DData* model;
  361. if (zApi)
  362. {
  363. model = zApi->createModel(uniqueName);
  364. }
  365. else
  366. {
  367. model = new Model3DData(0, 0, -1);
  368. }
  369. int vAnz;
  370. d.lese((char*)&vAnz, 4);
  371. Vertex3D* vertices = new Vertex3D[vAnz];
  372. for (int i = 0; i < vAnz; i++)
  373. {
  374. d.lese((char*)&vertices[i].knochenId, 4);
  375. d.lese((char*)&vertices[i].pos.x, 4);
  376. d.lese((char*)&vertices[i].pos.y, 4);
  377. d.lese((char*)&vertices[i].pos.z, 4);
  378. d.lese((char*)&vertices[i].tPos.x, 4);
  379. d.lese((char*)&vertices[i].tPos.y, 4);
  380. }
  381. model->setVertecies(vertices, vAnz);
  382. int pAnz;
  383. d.lese((char*)&pAnz, 4);
  384. for (int i = 0; i < pAnz; i++)
  385. {
  386. Polygon3D* p = new Polygon3D();
  387. d.lese((char*)&p->indexAnz, 4);
  388. p->indexList = new int[p->indexAnz];
  389. d.lese((char*)p->indexList, p->indexAnz * 4);
  390. model->addPolygon(p);
  391. }
  392. float factor;
  393. d.lese((char*)&factor, 4);
  394. model->setAmbientFactor(factor);
  395. d.lese((char*)&factor, 4);
  396. model->setDiffusFactor(factor);
  397. d.lese((char*)&factor, 4);
  398. model->setSpecularFactor(factor);
  399. bool b;
  400. d.lese((char*)&b, 1);
  401. if (b)
  402. {
  403. Skeleton* s = new Skeleton();
  404. int nId;
  405. d.lese((char*)&nId, 4);
  406. s->nextId = nId;
  407. s->rootBone = readKnochen(&d);
  408. model->setSkelettZ(s);
  409. }
  410. model->calculateNormals();
  411. d.close();
  412. return model;
  413. }
  414. return 0;
  415. }
  416. // Checks whether a specific 3D model exists in the file
  417. // name: The name of the 3D model to search for
  418. // return: 1 if the model was found. 0 otherwise
  419. bool M3Datei::hatModel(const char* name) const
  420. {
  421. if (!modelName || !pfad.getLength()) return 0;
  422. for (auto n = modelName->begin(); n; n++)
  423. {
  424. if (n->istGleich(name)) return 1;
  425. }
  426. return 0;
  427. }
  428. // Returns the number of stored models
  429. int M3Datei::getModelAnzahl() const
  430. {
  431. if (!modelName || !pfad.getLength()) return 0;
  432. return modelName->getEintragAnzahl();
  433. }
  434. // Returns the name of a specific model
  435. // i: The index of the model
  436. // return: A pointer to the name of the model without increased reference
  437. // counter
  438. Text* M3Datei::zModelName(int i) const
  439. {
  440. if (!modelName || !pfad.getLength()) return 0;
  441. return modelName->z(i);
  442. }