Model3D.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. #include "Model3D.h"
  2. #include "Render3D.h"
  3. #include "Model2D.h"
  4. #include "DXBuffer.h"
  5. #include "Textur.h"
  6. #include <d3d11.h>
  7. using namespace Framework;
  8. // Inhalt der Knochen Klasse
  9. // Konstruktor
  10. Knochen::Knochen( int id )
  11. {
  12. pos = Vec3< float >( 0, 0, 0 );
  13. winkel = Vec3< float >( 0, 0, 0 );
  14. geschwister = 0;
  15. kinder = 0;
  16. this->id = id;
  17. }
  18. // Destruktor
  19. Knochen::~Knochen()
  20. {
  21. delete geschwister;
  22. delete kinder;
  23. }
  24. // private
  25. // Fügt dem Knochen ein Geschwister Knochen hinzu
  26. // k: Der Knochen, der hinzugefügt werden soll
  27. void Knochen::addGeschwisterKnochen( Knochen *k )
  28. {
  29. if( !geschwister )
  30. geschwister = k;
  31. else
  32. geschwister->addGeschwisterKnochen( k );
  33. }
  34. // public
  35. // Setzt die Position des Knochens relativ zum Model Ursprung
  36. // pos: Die Position
  37. void Knochen::setPosition( Vec3< float > &pos )
  38. {
  39. this->pos = pos;
  40. }
  41. // Setzt die Drehung des Knochens relativ zum Model Ursprung
  42. // winkel: Ein Vektor der die Drehung um die verschiedenen Achsen als Komponenten hat
  43. void Knochen::setDrehung( Vec3< float > &winkel )
  44. {
  45. this->winkel = winkel;
  46. }
  47. // Fügt einem bestimmten Knochen ein Kind Knochen hinzu
  48. // id: Die id des Knochens, wo der Knochen als Kind hinzugefügt werden soll
  49. // k: Der Knochen, der hinzugefügt werden soll
  50. void Knochen::addKind( int id, Knochen *k )
  51. {
  52. if( this->id == id )
  53. {
  54. if( !kinder )
  55. kinder = k;
  56. else
  57. kinder->addGeschwisterKnochen( k );
  58. }
  59. else
  60. {
  61. if( kinder )
  62. kinder->addKind( id, k );
  63. else
  64. {
  65. Text err = "Es wurde kein Knochen mit der Id: ";
  66. err += id;
  67. err += " im Skelett gefunden, um ein Kind Knochen hinzuzufügen. Datei:" __FILE__ ", Zeile: ";
  68. err += __LINE__;
  69. err += "!";
  70. delete k;
  71. throw std::out_of_range( err );
  72. }
  73. }
  74. }
  75. // Berechnet die Matrizen des Knochen und die von all seinen Geschwister Knochen und Kind Knochen
  76. // elternMat: Die fertig berechnete Matrix des Elternknochens
  77. // matBuffer: Ein Array, in dem alle berechneten Matrizen gespeichert werden sollen
  78. // kamMatrix: Die vereiniegung der view und projektions Matrizen
  79. void Knochen::kalkulateMatrix( Mat4< float > &elternMat, Mat4< float > *matBuffer, Mat4< float > &kamMat )
  80. {
  81. if( geschwister )
  82. geschwister->kalkulateMatrix( elternMat, matBuffer, kamMat );
  83. matBuffer[ id ] = matBuffer[ id ].translation( pos ) * matBuffer[ id ].rotationZ( winkel.z ) * matBuffer[ id ].rotationX( winkel.x ) * matBuffer[ id ].rotationY( winkel.y );
  84. matBuffer[ id ] = elternMat * matBuffer[ id ];
  85. if( kinder )
  86. kinder->kalkulateMatrix( matBuffer[ id ], matBuffer, kamMat );
  87. matBuffer[ id ] = kamMat * matBuffer[ id ];
  88. }
  89. // Kopiert den Knochen mit allen Geschwister Knochen und Kind Knochen
  90. Knochen *Knochen::kopiereKnochen() const
  91. {
  92. Knochen *ret = new Knochen( id );
  93. ret->pos = pos;
  94. ret->winkel = winkel;
  95. if( geschwister )
  96. ret->geschwister = geschwister->kopiereKnochen();
  97. if( kinder )
  98. ret->kinder = kinder->kopiereKnochen();
  99. return ret;
  100. }
  101. // Gibt die Id des Knochens zurück
  102. int Knochen::getId() const
  103. {
  104. return id;
  105. }
  106. // Inhalt der Skelett Klasse
  107. // Konstruktor
  108. Skelett::Skelett()
  109. {
  110. k = 0;
  111. nextId = 0;
  112. ref = 1;
  113. }
  114. // Destruktor
  115. Skelett::~Skelett()
  116. {
  117. if( k )
  118. delete k;
  119. }
  120. // Gibt die Id des nächsten Knochens zurück und berechnet die neue Id für den Knochen danach
  121. // Es können maximal 128 Knochen für ein Skelett existieren. Wenn diese Zahl überschritten wird, so wird -1 zurückgegeben
  122. int Skelett::getNextKnochenId()
  123. {
  124. return nextId++;
  125. }
  126. // Fügt dem Skellet einen Knochen hinzu
  127. // k: Der Knochen
  128. // elternId: Die Id des Eltern Knochens. Wenn der Knochen kein Elternknochen besitzt, kannder Parameter weggelassen werden.
  129. void Skelett::addKnochen( Knochen *k, int elternId )
  130. {
  131. if( !this->k )
  132. this->k = k;
  133. else
  134. this->k->addKind( elternId, k );
  135. if( k->getId() >= nextId )
  136. nextId = k->getId() + 1;
  137. }
  138. // Berechnet die Matrizen der Knochen
  139. // modelMatrix: Die Matrix, die das Skelett in den Raum der Welt transformiert
  140. // matBuffer: Ein Array von Matrizen, der durch die Knochen Matrizen gefüllt wird
  141. // return: gibt die Anzahl der verwendeten Matrizen zurück
  142. // kamMatrix: Die vereiniegung der view und projektions Matrizen
  143. int Skelett::kalkulateMatrix( Mat4< float > &modelMatrix, Mat4< float > *matBuffer, Mat4< float > &kamMatrix )
  144. {
  145. k->kalkulateMatrix( modelMatrix, matBuffer, kamMatrix );
  146. return nextId;
  147. }
  148. // Kopiert das Skelett
  149. Skelett *Skelett::kopiereSkelett() const
  150. {
  151. Skelett *ret = new Skelett();
  152. ret->nextId = nextId;
  153. if( k )
  154. ret->addKnochen( k->kopiereKnochen() );
  155. return ret;
  156. }
  157. // Erhöht den Reference Counting Zähler.
  158. Skelett *Skelett::getThis()
  159. {
  160. ref++;
  161. return this;
  162. }
  163. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  164. // return: 0.
  165. Skelett *Skelett::release()
  166. {
  167. ref--;
  168. if( !ref )
  169. delete this;
  170. return 0;
  171. }
  172. // Inhalt des Polygon3D Struct
  173. // Konstruktor
  174. Polygon3D::Polygon3D()
  175. {
  176. indexAnz = 0;
  177. indexList = 0;
  178. indexBuffer = new DXIndexBuffer( sizeof( int ) );
  179. }
  180. // Destruktor
  181. Polygon3D::~Polygon3D()
  182. {
  183. indexBuffer->release();
  184. delete[] indexList;
  185. }
  186. // Inhalt der Model3DData Klasse
  187. // Konstruktor
  188. Model3DData::Model3DData()
  189. {
  190. id = -1;
  191. skelett = 0;
  192. vertexList = 0;
  193. polygons = new Array< Polygon3D* >();
  194. vertexBuffer = new DXVertexBuffer( sizeof( Vertex3D ) );
  195. radius = 0;
  196. ref = 1;
  197. }
  198. // Destruktor
  199. Model3DData::~Model3DData()
  200. {
  201. clearModel();
  202. vertexBuffer->release();
  203. polygons->release();
  204. }
  205. // Löscht alle Model daten
  206. void Model3DData::clearModel()
  207. {
  208. delete[] vertexList;
  209. vertexList = 0;
  210. for( auto i = polygons->getArray(); i.set; i++ )
  211. delete i.var;
  212. polygons->leeren();
  213. if( skelett )
  214. skelett->release();
  215. skelett = 0;
  216. radius = 0;
  217. }
  218. // Setzt den Zeiger auf ein standartmäßig verwendete Skelett
  219. // s: Das Skelett, das verwendet werden soll
  220. void Model3DData::setSkelettZ( Skelett *s )
  221. {
  222. if( skelett )
  223. skelett->release();
  224. skelett = s;
  225. }
  226. // Setzt einen Zeiger auf eine Liste mit allen Vertecies des Models
  227. // vertexList: Ein Array mit Vertecies
  228. // anz: Die Anzahl der Vertecies im Array
  229. void Model3DData::setVertecies( Vertex3D *vertexList, int anz )
  230. {
  231. delete[] this->vertexList;
  232. this->vertexList = vertexList;
  233. vertexBuffer->setData( vertexList );
  234. vertexBuffer->setLänge( sizeof( Vertex3D ) * anz );
  235. radius = 0;
  236. for( int i = 0; i < anz; i++ )
  237. {
  238. float r = vertexList[ i ].pos.län();
  239. if( r > radius )
  240. radius = r;
  241. }
  242. }
  243. // Fügt ein Polygon zum Model hinzu
  244. // polygon: Das Polygon, das hinzugefügt erden soll
  245. void Model3DData::addPolygon( Polygon3D *polygon )
  246. {
  247. polygons->add( polygon );
  248. }
  249. // Konvertiert ein 2d Model zu 3D
  250. // model: Das 2d Model, das zu 3d konvertiert werden soll
  251. // z: Die z koordinate aller punkte des Models
  252. void Model3DData::copyModel2D( Model2DData *model, float z )
  253. {
  254. if( model && model->vListen && model->polygons )
  255. {
  256. clearModel();
  257. int vAnz = 0;
  258. for( auto i = model->polygons->getArray(); i.set; i++ )
  259. vAnz += i.var.vertex->getEintragAnzahl();
  260. vertexList = new Vertex3D[ vAnz ];
  261. vertexBuffer->setData( vertexList );
  262. vertexBuffer->setLänge( sizeof( Vertex3D ) * vAnz );
  263. int index = 0;
  264. for( auto i = model->vListen->getArray(); i.set; i++ )
  265. {
  266. Polygon3D *p = new Polygon3D();
  267. p->indexAnz = 0;
  268. for( auto j = i.var->getArray(); j.set; j++ )
  269. {
  270. for( auto *k = &j.var->zListe()->getArray(); k->next->next && k->next->next->set; k = k->next )
  271. p->indexAnz += 3;
  272. }
  273. p->indexList = new int[ p->indexAnz ];
  274. p->indexBuffer->setData( p->indexList );
  275. p->indexBuffer->setLänge( sizeof( int ) * p->indexAnz );
  276. p->indexAnz = 0;
  277. for( auto j = i.var->getArray(); j.set; j++ )
  278. {
  279. for( auto *k = &j.var->zListe()->getArray(); k && k->set; k = k->next )
  280. {
  281. vertexList[ index ].pos = Vec3< float >( k->var->punkt->x, k->var->punkt->y, z );
  282. vertexList[ index ].tPos = ( Vec2< float > )*k->var->textur;
  283. if( k->next && k->next->set && k->next->next && k->next->next->set )
  284. {
  285. p->indexList[ p->indexAnz ] = index;
  286. p->indexAnz++;
  287. p->indexList[ p->indexAnz ] = index + 1;
  288. p->indexAnz++;
  289. p->indexList[ p->indexAnz ] = index + 2;
  290. p->indexAnz++;
  291. }
  292. index++;
  293. }
  294. }
  295. addPolygon( p );
  296. }
  297. }
  298. }
  299. // Entfernt ein Polygon
  300. // index: Der Index des Polygons
  301. void Model3DData::removePolygon( int index )
  302. {
  303. if( !polygons->hat( index ) )
  304. return;
  305. delete polygons->get( index );
  306. polygons->lösche( index );
  307. }
  308. // Aktualisiert die Vertecies
  309. // zRObj: Das Objekt, mit dem die Grafikkarte verwaltet wird
  310. void Model3DData::aktualisiereVertecies( Render3D *zRObj )
  311. {
  312. vertexBuffer->copieren( zRObj );
  313. }
  314. // Berechnet die Matrizen der Knochen
  315. // modelMatrix: Die Matrix, die das Skelett in den Raum der Welt transformiert
  316. // matBuffer: Ein Array von Matrizen, der durch die Knochen Matrizen gefüllt wird
  317. // return: gibt die Anzahl der verwendeten Matrizen zurück
  318. // kamMatrix: Die vereiniegung der view und projektions Matrizen
  319. int Model3DData::kalkulateMatrix( Mat4< float > &modelMatrix, Mat4< float > *matBuffer, Mat4< float > &kamMatrix ) const
  320. {
  321. if( !skelett )
  322. return 0;
  323. return skelett->kalkulateMatrix( modelMatrix, matBuffer, kamMatrix );
  324. }
  325. // Zeichnet alle Polygons
  326. // world: Die Welt Matrix, die das Model in die Welt transformiert
  327. // zTxt: Eine Liste mit Texturen der einzelnen Polygone
  328. // zRObj: Das Objekt, mit dem gezeichnet werden soll
  329. void Model3DData::render( Mat4< float > &welt, const Model3DTextur *zTxt, Render3D *zRObj )
  330. {
  331. int ind = 0;
  332. for( auto *i = &polygons->getArray(); i && i->set; i = i->next )
  333. {
  334. i->var->indexBuffer->copieren( zRObj );
  335. Textur *t = zTxt->zPolygonTextur( ind );
  336. if( t && t->brauchtUpdate() )
  337. t->updateTextur( zRObj );
  338. zRObj->draw( i->var->indexBuffer, t );
  339. ind++;
  340. }
  341. }
  342. // Gibt die Anzahl an Polygonen zurück
  343. int Model3DData::getPolygonAnzahl() const
  344. {
  345. return polygons->getEintragAnzahl();
  346. }
  347. // Gibt ein bestimmtes Polygon zurück
  348. // index: Der Index des Polygons
  349. Polygon3D *Model3DData::getPolygon( int index ) const
  350. {
  351. if( !polygons->hat( index ) )
  352. return 0;
  353. return polygons->get( index );
  354. }
  355. // Gibt den radius einer Kugel zurück, die das gesammte Model umschließt
  356. float Model3DData::getRadius() const
  357. {
  358. return radius;
  359. }
  360. // Gibt die Id der Daten zurück, wenn sie in einer Model3DList registriert wurden. (siehe Framework::zM3DRegister())
  361. int Model3DData::getId() const
  362. {
  363. return id;
  364. }
  365. // Gibt einen Buffer mit allen Vertecies des Models zurück
  366. const DXVertexBuffer *Model3DData::zVertexBuffer() const
  367. {
  368. return vertexBuffer;
  369. }
  370. // Erhöht den Reference Counting Zähler.
  371. // return: this.
  372. Model3DData *Model3DData::getThis()
  373. {
  374. ref++;
  375. return this;
  376. }
  377. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  378. // return: 0.
  379. Model3DData *Model3DData::release()
  380. {
  381. ref--;
  382. if( !ref )
  383. delete this;
  384. return 0;
  385. }
  386. // Inhalt der Model3DTextur
  387. // Konstruktor
  388. Model3DTextur::Model3DTextur()
  389. {
  390. textures = new RCArray< Textur >();
  391. ref = 1;
  392. }
  393. // Destruktor
  394. Model3DTextur::~Model3DTextur()
  395. {
  396. textures->release();
  397. }
  398. // Legt fest, welche Textur für welches Polygon ist
  399. // pI: Der Index des Polygons
  400. // txt: Die Textur des Polygons
  401. void Model3DTextur::setPolygonTextur( int pI, Textur *txt )
  402. {
  403. textures->set( txt, pI );
  404. }
  405. // Gibt einen Zeiger auf die Textur eines Polygons zurück ohne erhöhten Reference Counter
  406. // i: Der Index des Polygons
  407. Textur *Model3DTextur::zPolygonTextur( int i ) const
  408. {
  409. return textures->z( i );
  410. }
  411. // Erhöht den Reference Counting Zähler.
  412. // return: this.
  413. Model3DTextur *Model3DTextur::getThis()
  414. {
  415. ref++;
  416. return this;
  417. }
  418. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  419. // return: 0.
  420. Model3DTextur *Model3DTextur::release()
  421. {
  422. ref--;
  423. if( !ref )
  424. delete this;
  425. return 0;
  426. }
  427. // Inhalt der Model3D Klasse
  428. // Konstruktor
  429. Model3D::Model3D()
  430. : Zeichnung3D()
  431. {
  432. model = 0;
  433. textur = 0;
  434. skelett = 0;
  435. ref = 1;
  436. }
  437. // Destruktor
  438. Model3D::~Model3D()
  439. {
  440. if( model )
  441. model->release();
  442. if( textur )
  443. textur->release();
  444. if( skelett )
  445. skelett->release();
  446. }
  447. // Setzt den Zeiger auf das zum Annimieren verwendete Skelett
  448. // s: Das Skelett, das verwendet werden soll
  449. void Model3D::setSkelettZ( Skelett *s )
  450. {
  451. if( skelett )
  452. skelett->release();
  453. skelett = s;
  454. }
  455. // Setzt die Daten des Models
  456. // data: Die Daten
  457. void Model3D::setModelDaten( Model3DData *data )
  458. {
  459. if( model )
  460. model->release();
  461. model = data;
  462. }
  463. // Setzt die zum Zeichnen zu benutzenden Texturen
  464. // txt: Ein Liste mit Texturen zu den verschiedenen Polygonen zugeordnet
  465. void Model3D::setModelTextur( Model3DTextur *txt )
  466. {
  467. if( textur )
  468. textur->release();
  469. textur = txt;
  470. }
  471. // Errechnet die Matrizen aller Knochen des Skeletts des Models
  472. // viewProj: Die miteinander multiplizierten Kameramatrizen
  473. // matBuffer: Ein Array mit Matrizen, der gefüllt werden soll
  474. // return: Die Anzahl der Matrizen, die das Model benötigt
  475. int Model3D::errechneMatrizen( Mat4< float > &viewProj, Mat4< float > *matBuffer )
  476. {
  477. int ret = 0;
  478. if( skelett )
  479. ret = skelett->kalkulateMatrix( welt, matBuffer, viewProj );
  480. else if( model )
  481. ret = model->kalkulateMatrix( welt, matBuffer, viewProj );
  482. if( !ret )
  483. return __super::errechneMatrizen( viewProj, matBuffer );
  484. return ret;
  485. }
  486. // Verarbeitet die vergangene Zeit
  487. // tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
  488. // return: true, wenn sich das Objekt verändert hat, false sonnst.
  489. bool Model3D::tick( double tickval )
  490. {
  491. radius = model ? model->getRadius() : 0;
  492. return __super::tick( tickval );
  493. }
  494. // Zeichnet das Model
  495. // zRObj: Ein Zeiger auf das Objekt, das zum Zeichnen verwendet werden soll (ohne erhöhten Reference Counter)
  496. void Model3D::render( Render3D *zRObj )
  497. {
  498. if( !model )
  499. return;
  500. model->aktualisiereVertecies( zRObj );
  501. zRObj->beginnModel( this );
  502. model->render( welt, textur, zRObj );
  503. }
  504. // Gibt die Id der Daten zurück, wenn sie in einer Model3DList registriert wurden. (siehe Framework::zM3DRegister())
  505. int Model3D::getDatenId() const
  506. {
  507. return model ? model->getId() : -1;
  508. }
  509. // Gibt einen Buffer mit allen Vertecies des Models zurück
  510. const DXVertexBuffer *Model3D::zVertexBuffer() const
  511. {
  512. return model ? model->zVertexBuffer() : 0;
  513. }
  514. // Erhöht den Reference Counting Zähler.
  515. // return: this.
  516. Model3D *Model3D::getThis()
  517. {
  518. ref++;
  519. return this;
  520. }
  521. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  522. // return: 0.
  523. Model3D *Model3D::release()
  524. {
  525. ref--;
  526. if( !ref )
  527. delete this;
  528. return 0;
  529. }