M3Datei.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #include "M3Datei.h"
  2. #include "Datei.h"
  3. #include "Model3D.h"
  4. using namespace Framework;
  5. // Inhalt der M3Datei Klasse
  6. // Konstruktor
  7. M3Datei::M3Datei()
  8. {
  9. modelName = 0;
  10. modelPos = 0;
  11. }
  12. // Konstruktor
  13. // pfad: Der Pfad zur Datei
  14. M3Datei::M3Datei( const char *pfad )
  15. : M3Datei()
  16. {
  17. this->pfad = pfad;
  18. }
  19. // Konstruktor
  20. // pfad: Der Pfad zur Datei
  21. M3Datei::M3Datei( Text *pfad )
  22. : M3Datei( pfad->getText() )
  23. {
  24. pfad->release();
  25. }
  26. // Destruktor
  27. M3Datei::~M3Datei()
  28. {
  29. if( modelName )
  30. modelName->release();
  31. if( modelPos )
  32. modelPos->release();
  33. }
  34. void M3Datei::saveKnochen( Knochen *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->getDrehung().x;
  49. zDat->schreibe( (char *)& f, 4 );
  50. f = k->getDrehung().y;
  51. zDat->schreibe( (char *)& f, 4 );
  52. f = k->getDrehung().z;
  53. zDat->schreibe( (char *)& f, 4 );
  54. saveKnochen( k->zGeschwister(), zDat );
  55. saveKnochen( k->zKind(), zDat );
  56. }
  57. }
  58. Knochen *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. Knochen *k = new Knochen( 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->setDrehung( rot );
  77. k->addGeschwisterKnochen( readKnochen( zDat ) );
  78. k->addKind( 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 )
  89. modelName = modelName->release();
  90. if( modelPos )
  91. modelPos = modelPos->release();
  92. }
  93. // Ließt grundlegende Informationen aus der Datei, die für ihre Verwendung benötigt werden
  94. void M3Datei::leseDaten()
  95. {
  96. if( modelName )
  97. modelName = modelName->release();
  98. if( modelPos )
  99. modelPos = modelPos->release();
  100. modelName = new RCArray< Text >();
  101. modelPos = new Array< __int64 >();
  102. Datei d;
  103. d.setDatei( pfad );
  104. if( !d.open( Datei::Style::lesen ) )
  105. return;
  106. unsigned char anz = 0;
  107. d.lese( (char *)& anz, 1 );
  108. for( int i = 0; i < anz; i++ )
  109. {
  110. char len = 0;
  111. d.lese( &len, 1 );
  112. char *n = new char[ len + 1 ];
  113. n[ (int)len ] = 0;
  114. d.lese( n, len );
  115. modelName->add( new Text( n ) );
  116. delete[] n;
  117. __int64 p = 0;
  118. d.lese( (char *)& p, 8 );
  119. modelPos->add( p );
  120. }
  121. d.close();
  122. }
  123. // Speichert 3D Modell Daten in der Datei
  124. // zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
  125. // name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
  126. // return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
  127. bool M3Datei::saveModel( Model3DData *zMdr, Text *name )
  128. {
  129. bool ret = saveModel( zMdr, name->getText() );
  130. name->release();
  131. return ret;
  132. }
  133. // Speichert 3D Modell Daten in der Datei
  134. // zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
  135. // name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
  136. // return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
  137. bool M3Datei::saveModel( Model3DData *zMdr, const char *name )
  138. {
  139. if( !modelName || !pfad.getLength() )
  140. return 0;
  141. if( hatModel( name ) && !removeModel( name ) )
  142. return 0;
  143. int anz = modelName->getEintragAnzahl();
  144. anz = modelName->getEintragAnzahl();
  145. Datei d;
  146. d.setDatei( pfad );
  147. d.open( Datei::Style::lesen );
  148. Datei neu;
  149. neu.setDatei( pfad );
  150. neu.zPfad()->append( "0" );
  151. while( neu.existiert() )
  152. neu.zPfad()->append( "0" );
  153. if( !neu.open( Datei::Style::schreiben ) )
  154. {
  155. if( d.istOffen() )
  156. d.close();
  157. return 0;
  158. }
  159. modelName->add( new Text( name ) );
  160. int offs = textLength( name ) + 9;
  161. for( int i = 0; i < anz; i++ )
  162. modelPos->set( modelPos->get( i ) + offs, i );
  163. if( d.getSize() < 0 )
  164. modelPos->add( offs + 1 );
  165. else
  166. modelPos->add( d.getSize() + offs );
  167. anz++;
  168. char tmp = (char)anz;
  169. neu.schreibe( &tmp, 1 );
  170. for( int i = 0; i < anz; i++ )
  171. {
  172. char len = (char)modelName->z( i )->getLength();
  173. neu.schreibe( &len, 1 );
  174. neu.schreibe( modelName->z( i )->getText(), len );
  175. __int64 pos = modelPos->get( i );
  176. neu.schreibe( (char *)& pos, 8 );
  177. }
  178. if( d.existiert() )
  179. {
  180. d.setLPosition( modelPos->get( 0 ) - offs, 0 );
  181. __int64 dl = d.getSize() - d.getLPosition();
  182. char bytes[ 2048 ];
  183. while( dl )
  184. {
  185. int l = dl > 2048 ? 2048 : (int)dl;
  186. d.lese( bytes, l );
  187. neu.schreibe( bytes, l );
  188. dl -= l;
  189. }
  190. }
  191. d.close();
  192. int vAnz = zMdr->getVertexAnzahl();
  193. neu.schreibe( (char *)& vAnz, 4 );
  194. for( int i = 0; i < vAnz; i++ )
  195. {
  196. neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].knochenId, 4 );
  197. neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].pos.x, 4 );
  198. neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].pos.y, 4 );
  199. neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].pos.z, 4 );
  200. neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].tPos.x, 4 );
  201. neu.schreibe( (char *)& zMdr->zVertexBuffer()[ i ].tPos.y, 4 );
  202. }
  203. int pAnz = zMdr->getPolygonAnzahl();
  204. neu.schreibe( (char *)& pAnz, 4 );
  205. for( int p = 0; p < pAnz; p++ )
  206. {
  207. Polygon3D *pol = zMdr->getPolygon( p );
  208. int anz = pol->indexAnz;
  209. neu.schreibe( (char *)& anz, 4 );
  210. neu.schreibe( (char *)pol->indexList, anz * 4 );
  211. }
  212. float factor = zMdr->getAmbientFactor();
  213. neu.schreibe( (char *)& factor, 4 );
  214. factor = zMdr->getDiffusFactor();
  215. neu.schreibe( (char *)& factor, 4 );
  216. factor = zMdr->getSpecularFactor();
  217. neu.schreibe( (char *)& factor, 4 );
  218. Skelett *skelet = zMdr->copySkelett();
  219. if( skelet )
  220. {
  221. bool b = 1;
  222. neu.schreibe( (char*)&b, 1 );
  223. int nId = skelet->zNextKnochenId();
  224. neu.schreibe( (char *)& nId, 4 );
  225. saveKnochen( skelet->zKnochen(), &neu );
  226. skelet->release();
  227. }
  228. else
  229. {
  230. bool b = 0;
  231. neu.schreibe( (char *)& b, 1 );
  232. }
  233. d.remove();
  234. neu.close();
  235. neu.umbenennen( pfad );
  236. return 1;
  237. }
  238. // Löscht ein 3D Modell aus der Datei
  239. // name: Der Name des Modells
  240. // return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
  241. bool M3Datei::removeModel( Text *name )
  242. {
  243. bool res = removeModel( name->getText() );
  244. name->release();
  245. return res;
  246. }
  247. // Löscht ein 3D Modell aus der Datei
  248. // name: Der Name des Modells
  249. // return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
  250. bool M3Datei::removeModel( const char *name )
  251. {
  252. if( !modelName || !pfad.getLength() )
  253. return 0;
  254. if( !hatModel( name ) )
  255. return 0;
  256. Datei d;
  257. d.setDatei( pfad );
  258. if( !d.open( Datei::Style::lesen ) )
  259. return 0;
  260. __int64 startPosition = modelPos->get( 0 );
  261. Datei neu;
  262. neu.setDatei( pfad );
  263. neu.zPfad()->append( "0" );
  264. while( neu.existiert() )
  265. neu.zPfad()->append( "0" );
  266. if( !neu.open( Datei::Style::schreiben ) )
  267. {
  268. d.close();
  269. return 0;
  270. }
  271. char anz = (char)(modelName->getEintragAnzahl() - 1);
  272. neu.schreibe( &anz, 1 );
  273. __int64 offset = textLength( name ) + 9;
  274. __int64 removedLength = 0;
  275. __int64 removedPosition = 0;
  276. int removedIndex = 0;
  277. for( int i = 0; i < anz + 1; i++ )
  278. {
  279. if( !modelName->z( i )->istGleich( name ) )
  280. {
  281. char len = (char)modelName->z( i )->getLength();
  282. neu.schreibe( &len, 1 );
  283. neu.schreibe( modelName->z( i )->getText(), len );
  284. modelPos->set( modelPos->get( i ) - offset, i );
  285. __int64 pos = modelPos->get( i );
  286. neu.schreibe( (char *)& pos, 8 );
  287. }
  288. else
  289. {
  290. removedPosition = modelPos->get( i );
  291. removedIndex = i;
  292. if( modelName->getEintragAnzahl() > i + 1 )
  293. {
  294. removedLength = modelPos->get( i + 1 ) - modelPos->get( i );
  295. offset += removedLength;
  296. }
  297. }
  298. }
  299. d.setLPosition( startPosition, 0 );
  300. __int64 dl = removedPosition - startPosition;
  301. char bytes[ 2048 ];
  302. while( dl )
  303. {
  304. int l = dl > 2048 ? 2048 : (int)dl;
  305. d.lese( bytes, l );
  306. neu.schreibe( bytes, l );
  307. dl -= l;
  308. }
  309. d.setLPosition( removedPosition + removedLength, 0 );
  310. dl = d.getSize() - removedPosition - removedLength;
  311. while( dl )
  312. {
  313. int l = dl > 2048 ? 2048 : (int)dl;
  314. d.lese( bytes, l );
  315. neu.schreibe( bytes, l );
  316. dl -= l;
  317. }
  318. d.close();
  319. d.remove();
  320. neu.close();
  321. neu.umbenennen( pfad );
  322. modelName->remove( removedIndex );
  323. modelPos->remove( removedIndex );
  324. return 1;
  325. }
  326. // Lähd ein 3D Modell aus der Datei
  327. // name: Der name des zu ladenden Modells
  328. // return: Die geladenen Daten
  329. Model3DData *M3Datei::ladeModel( Text *name ) const
  330. {
  331. Model3DData *d = ladeModel( name->getText() );
  332. name->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( const char *name ) const
  339. {
  340. if( !modelName || !pfad.getLength() )
  341. return 0;
  342. __int64 pos = -1;
  343. auto p = modelPos->getIterator();
  344. for( auto n = modelName->getIterator(); 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 = new Model3DData();
  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. Skelett *s = new Skelett();
  397. int nId;
  398. d.lese( (char *)& nId, 4 );
  399. s->setNextKnochenId( nId );
  400. s->addKnochen( 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() )
  415. return 0;
  416. for( auto n = modelName->getIterator(); n; n++ )
  417. {
  418. if( n->istGleich( name ) )
  419. return 1;
  420. }
  421. return 0;
  422. }
  423. // ügibt die Anzahl der gespeicherten Modelle zurück
  424. int M3Datei::getModelAnzahl() const
  425. {
  426. if( !modelName || !pfad.getLength() )
  427. return 0;
  428. return modelName->getEintragAnzahl();
  429. }
  430. // Gibt den Namen eines Bestimmten Modells zurück
  431. // i: Der Index des Modells
  432. // return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
  433. Text *M3Datei::zModelName( int i ) const
  434. {
  435. if( !modelName || !pfad.getLength() )
  436. return 0;
  437. return modelName->z( i );
  438. }
  439. // Erhöht den Reference Counting Zähler.
  440. // return: this.
  441. M3Datei *M3Datei::getThis()
  442. {
  443. ref++;
  444. return this;
  445. }
  446. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  447. // return: 0.
  448. M3Datei *M3Datei::release()
  449. {
  450. if( !--ref )
  451. delete this;
  452. return 0;
  453. }