M3Datei.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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. leseDaten();
  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. // TODO: implement this
  254. return 0;
  255. }
  256. // Lähd ein 3D Modell aus der Datei
  257. // name: Der name des zu ladenden Modells
  258. // return: Die geladenen Daten
  259. Model3DData *M3Datei::ladeModel( Text *name ) const
  260. {
  261. Model3DData *d = ladeModel( name->getText() );
  262. name->release();
  263. return d;
  264. }
  265. // Lähd ein 3D Modell aus der Datei
  266. // name: Der name des zu ladenden Modells
  267. // return: Die geladenen Daten
  268. Model3DData *M3Datei::ladeModel( const char *name ) const
  269. {
  270. __int64 pos = -1;
  271. auto p = modelPos->getIterator();
  272. for( auto n = modelName->getIterator(); n && p; n++, p++ )
  273. {
  274. if( n->istGleich( name ) )
  275. {
  276. pos = p;
  277. break;
  278. }
  279. }
  280. if( pos > 0 )
  281. {
  282. Datei d;
  283. d.setDatei( pfad );
  284. if( !d.open( Datei::Style::lesen ) )
  285. {
  286. return 0;
  287. }
  288. d.setLPosition( pos, 0 );
  289. Model3DData *model = new Model3DData();
  290. int vAnz;
  291. d.lese( (char *)& vAnz, 4 );
  292. Vertex3D *vertices = new Vertex3D[ vAnz ];
  293. for( int i = 0; i < vAnz; i++ )
  294. {
  295. d.lese( (char *)& vertices[ i ].knochenId, 4 );
  296. d.lese( (char *)& vertices[ i ].pos.x, 4 );
  297. d.lese( (char *)& vertices[ i ].pos.y, 4 );
  298. d.lese( (char *)& vertices[ i ].pos.z, 4 );
  299. d.lese( (char *)& vertices[ i ].tPos.x, 4 );
  300. d.lese( (char *)& vertices[ i ].tPos.y, 4 );
  301. }
  302. model->setVertecies( vertices, vAnz );
  303. int pAnz;
  304. d.lese( (char *)& pAnz, 4 );
  305. for( int i = 0; i < pAnz; i++ )
  306. {
  307. Polygon3D *p = new Polygon3D();
  308. d.lese( (char *)& p->indexAnz, 4 );
  309. p->indexList = new int[ p->indexAnz ];
  310. d.lese( (char *)p->indexList, pAnz * 4 );
  311. model->addPolygon( p );
  312. }
  313. float factor;
  314. d.lese( (char *)& factor, 4 );
  315. model->setAmbientFactor( factor );
  316. d.lese( (char *)& factor, 4 );
  317. model->setDiffusFactor( factor );
  318. d.lese( (char *)& factor, 4 );
  319. model->setSpecularFactor( factor );
  320. bool b;
  321. d.lese( (char *)& b, 1 );
  322. if( b )
  323. {
  324. Skelett *s = new Skelett();
  325. int nId;
  326. d.lese( (char *)& nId, 4 );
  327. s->setNextKnochenId( nId );
  328. s->addKnochen( readKnochen( &d ) );
  329. model->setSkelettZ( s );
  330. }
  331. d.close();
  332. return model;
  333. }
  334. return 0;
  335. }
  336. // überprft, ob ein bestimmtes 3D Modell in der Datei existiert
  337. // name: Der Name des zu suchenden 3D Modells
  338. // return: 1, wenn das Modell gefunden wurde. 0 sonst
  339. bool M3Datei::hatModel( const char *name ) const
  340. {
  341. for( auto n = modelName->getIterator(); n; n++ )
  342. {
  343. if( n->istGleich( name ) )
  344. return 1;
  345. }
  346. return 0;
  347. }
  348. // ügibt die Anzahl der gespeicherten Modelle zurück
  349. int M3Datei::getModelAnzahl() const
  350. {
  351. return modelName->getEintragAnzahl();
  352. }
  353. // Gibt den Namen eines Bestimmten Modells zurück
  354. // i: Der Index des Modells
  355. // return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
  356. Text *M3Datei::zModelName( int i ) const
  357. {
  358. return modelName->z( i );
  359. }
  360. // Erhöht den Reference Counting Zähler.
  361. // return: this.
  362. M3Datei *M3Datei::getThis()
  363. {
  364. ref++;
  365. return this;
  366. }
  367. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  368. // return: 0.
  369. M3Datei *M3Datei::release()
  370. {
  371. if( !--ref )
  372. delete this;
  373. return 0;
  374. }