Welt3D.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #include "Welt3D.h"
  2. #include "Zeichnung3D.h"
  3. #include "MausEreignis.h"
  4. #ifdef WIN32
  5. #include "Render3D.h"
  6. #endif
  7. using namespace Framework;
  8. // Inhalt der Welt3D Klasse aus Welt3D.h
  9. // Konstructor
  10. Welt3D::Welt3D()
  11. {
  12. arraySize = 100;
  13. arraySizeAlpha = 100;
  14. members = new Zeichnung3D*[ arraySize ];
  15. membersAlpha = new Zeichnung3D*[ arraySizeAlpha ];
  16. distSq = new float[ arraySizeAlpha + arraySize ];
  17. distSqSort = new float[ arraySizeAlpha + arraySize ];
  18. alphaVS = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
  19. elementsSort = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
  20. for( int i = 0; i < arraySize; i++ )
  21. members[ i ] = 0;
  22. for( int i = 0; i < arraySizeAlpha; i++ )
  23. membersAlpha[ i ] = 0;
  24. ref = 1;
  25. rend = 0;
  26. upd = 1;
  27. }
  28. // Destruktor
  29. Welt3D::~Welt3D()
  30. {
  31. for( int i = 0; i < arraySize; i++ )
  32. {
  33. if( members[ i ] )
  34. members[ i ]->release();
  35. }
  36. delete[] members;
  37. for( int i = 0; i < arraySizeAlpha; i++ )
  38. {
  39. if( membersAlpha[ i ] )
  40. membersAlpha[ i ]->release();
  41. }
  42. delete[] membersAlpha;
  43. delete[] distSq;
  44. delete[] distSqSort;
  45. delete[] alphaVS;
  46. delete[] elementsSort;
  47. }
  48. // Fügt der Welt ein Objekt hinzu
  49. // obj: Das Objekt, was hinzugefügt werden soll
  50. void Welt3D::addZeichnung( Zeichnung3D *obj )
  51. {
  52. cs.lock();
  53. Zeichnung3D **tmp = members;
  54. int max = arraySize;
  55. if( obj->hatAlpha() )
  56. {
  57. tmp = membersAlpha;
  58. max = arraySizeAlpha;
  59. }
  60. for( int i = 0; i < max; i++ )
  61. {
  62. if( !*tmp )
  63. {
  64. *tmp = obj;
  65. cs.unlock();
  66. return;
  67. }
  68. tmp++;
  69. }
  70. rend = 1;
  71. if( obj->hatAlpha() )
  72. {
  73. arraySizeAlpha += 100;
  74. Zeichnung3D **nm = new Zeichnung3D*[ arraySizeAlpha ];
  75. memcpy( nm, membersAlpha, sizeof( Zeichnung3D * ) * ( arraySizeAlpha - 100 ) );
  76. memset( &nm[ arraySizeAlpha - 100 ], 0, sizeof( Zeichnung3D * ) * 100 );
  77. delete[] membersAlpha;
  78. membersAlpha = nm;
  79. membersAlpha[ arraySizeAlpha - 100 ] = obj;
  80. delete[] distSq;
  81. delete[] distSqSort;
  82. delete[] alphaVS;
  83. delete[] elementsSort;
  84. distSq = new float[ arraySizeAlpha + arraySize ];
  85. distSqSort = new float[ arraySizeAlpha + arraySize ];
  86. alphaVS = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
  87. elementsSort = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
  88. cs.unlock();
  89. return;
  90. }
  91. arraySize += 100;
  92. Zeichnung3D **nm = new Zeichnung3D*[ arraySize ];
  93. memcpy( nm, members, sizeof( Zeichnung3D * ) * ( arraySize - 100 ) );
  94. memset( &nm[ arraySize - 100 ], 0, sizeof( Zeichnung3D * ) * 100 );
  95. delete[] members;
  96. members = nm;
  97. members[ arraySize - 100 ] = obj;
  98. delete[] distSq;
  99. delete[] distSqSort;
  100. delete[] alphaVS;
  101. delete[] elementsSort;
  102. distSq = new float[ arraySizeAlpha + arraySize ];
  103. distSqSort = new float[ arraySizeAlpha + arraySize ];
  104. alphaVS = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
  105. elementsSort = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
  106. cs.unlock();
  107. }
  108. // Entfernt ein Objekt aus der Welt
  109. // obj: Das Objekt, das entwernt werden soll
  110. void Welt3D::removeZeichnung( Zeichnung3D *obj )
  111. {
  112. cs.lock();
  113. int index = 0;
  114. if( !obj->hatAlpha() )
  115. {
  116. for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
  117. {
  118. if( *i == obj )
  119. {
  120. ( *i )->release();
  121. *i = 0;
  122. rend = 1;
  123. cs.unlock();
  124. return;
  125. }
  126. }
  127. cs.unlock();
  128. return;
  129. }
  130. for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
  131. {
  132. if( *i == obj )
  133. {
  134. ( *i )->release();
  135. *i = 0;
  136. rend = 1;
  137. cs.unlock();
  138. return;
  139. }
  140. }
  141. cs.unlock();
  142. }
  143. // Verarbeitet ein Mausereignis
  144. // me: Das Mausereignis, das verarbeitet werden soll
  145. void Welt3D::doMausEreignis( MausEreignis3D &me )
  146. {
  147. //cs.lock()
  148. //int anz = 0;
  149. //int index = 0;
  150. //for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
  151. //{
  152. // if( *i )
  153. // {
  154. // distSq[ anz ] = me.pos.abstandSq( ( *i )->getPos() );
  155. // alphaVS[ anz ] = *i;
  156. // anz++;
  157. // }
  158. //}
  159. //index = 0;
  160. //for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
  161. //{
  162. // if( *i )
  163. // {
  164. // distSq[ anz ] = me.pos.abstandSq( ( *i )->getPos() );
  165. // alphaVS[ anz ] = *i;
  166. // anz++;
  167. // }
  168. //}
  169. //float maxEntf;
  170. //int ind;
  171. //do
  172. //{
  173. // maxEntf = -1;
  174. // ind = -1;
  175. // for( int i = 0; i < anz; i++ )
  176. // {
  177. // if( !used[ i ] && distSq[ i ] > maxEntf )
  178. // {
  179. // maxEntf = distSq[ i ];
  180. // ind = i;
  181. // }
  182. // }
  183. // if( ind >= 0 )
  184. // {
  185. // alphaVS[ ind ]->doMausEreignis( me );
  186. // if( me.verarbeitet )
  187. // {
  188. // cs.unlock();
  189. // return;
  190. // }
  191. // used[ ind ] = 1;
  192. // }
  193. //} while( ind >= 0 );
  194. //cs.unlock();
  195. }
  196. // Verarbeitet die vergangene Zeit
  197. // tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
  198. // return: true, wenn sich das Objekt verändert hat, false sonnst.
  199. bool Welt3D::tick( double tickval )
  200. {
  201. if( !upd )
  202. return rend;
  203. rend = 0;
  204. upd = 0;
  205. int index = 0;
  206. cs.lock();
  207. for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
  208. {
  209. if( *i && ( *i )->hatAlpha() )
  210. {
  211. addZeichnung( *i );
  212. *i = 0;
  213. continue;
  214. }
  215. rend |= *i ? ( *i )->tick( tickval ) : 0;
  216. }
  217. index = 0;
  218. for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
  219. {
  220. rend |= *i ? ( *i )->tick( tickval ) : 0;
  221. if( *i && !( *i )->hatAlpha() )
  222. {
  223. addZeichnung( *i );
  224. *i = 0;
  225. continue;
  226. }
  227. }
  228. cs.unlock();
  229. return rend;
  230. }
  231. // Zeichnet einen ausschnitt der Welt
  232. // zRObj: Enthällt alle Werkzeuge, die zum Zeichnen verwendet werden
  233. void Welt3D::render( Render3D *zRObj )
  234. {
  235. #ifdef WIN32
  236. upd = 1;
  237. cs.lock();
  238. int index = 0;
  239. for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
  240. {
  241. if( *i && zRObj->isInFrustrum( ( *i )->getPos(), ( *i )->getRadius() ) )
  242. ( *i )->render( zRObj );
  243. }
  244. index = 0;
  245. int index2 = 0;
  246. for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
  247. {
  248. if( *i && zRObj->isInFrustrum( ( *i )->getPos(), ( *i )->getRadius(), &distSq[ index2 ] ) )
  249. {
  250. alphaVS[ index2 ] = *i;
  251. elementsSort[ index2 ] = *i;
  252. distSqSort[ index2 ] = distSq[ index2 ];
  253. index2++;
  254. }
  255. }
  256. int K;
  257. int L = 1;
  258. while( L < index2 )
  259. {
  260. K = 0;
  261. while( K + 2 * L - 1 < index2 )
  262. {
  263. //merge
  264. int I = K;
  265. int J = K + L;
  266. int N = K;
  267. while( I < K + L || J < K + 2 * L )
  268. {
  269. if( J == K + 2 * L || ( I < K + L && distSq[ I ] < distSq[ J ] ) )
  270. {
  271. distSqSort[ N ] = distSq[ I ];
  272. elementsSort[ N ] = alphaVS[ I ];
  273. I++;
  274. }
  275. else
  276. {
  277. distSqSort[ N ] = distSq[ J ];
  278. elementsSort[ N ] = alphaVS[ J ];
  279. J++;
  280. }
  281. N++;
  282. }
  283. K += 2 * L;
  284. }
  285. if( K + L - 1 < index2 - 1 )
  286. {
  287. //merge
  288. int I = K;
  289. int J = K + L;
  290. int N = K;
  291. while( I < K + L || J < index2 - 1 )
  292. {
  293. if( J == index2 || ( I < K + L && distSq[ I ] < distSq[ J ] ) )
  294. {
  295. distSqSort[ N ] = distSqSort[ I ];
  296. elementsSort[ N ] = alphaVS[ I ];
  297. I++;
  298. }
  299. else
  300. {
  301. distSqSort[ N ] = distSq[ J ];
  302. elementsSort[ N ] = alphaVS[ J ];
  303. J++;
  304. }
  305. N++;
  306. }
  307. }
  308. float *tmpF = distSq;
  309. distSq = distSqSort;
  310. distSqSort = tmpF;
  311. Zeichnung3D **tmpZ = alphaVS;
  312. alphaVS = elementsSort;
  313. elementsSort = tmpZ;
  314. L *= 2;
  315. }
  316. for( int i = index2 - 1; i >= 0; i-- )
  317. alphaVS[ i ]->render( zRObj );
  318. cs.unlock();
  319. #endif
  320. }
  321. // Erhöht den Reference Counting Zähler.
  322. // return: this.
  323. Welt3D *Welt3D::getThis()
  324. {
  325. ref++;
  326. return this;
  327. }
  328. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
  329. // return: 0.
  330. Welt3D *Welt3D::release()
  331. {
  332. ref--;
  333. if( !ref )
  334. delete this;
  335. return 0;
  336. }