M3Datei.cpp 13 KB

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