M3Datei.cpp 13 KB

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