Kdtree.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. Oktanovy stromy
  3. Scena + okoli -> KD strom
  4. Prvky -> obalky
  5. */
  6. #ifndef __KDTREE_H
  7. #define __KDTREE_H
  8. #define KD_FULL_VISIBILITY 8
  9. /*
  10. Bunka -> min/max
  11. - zpusob rozdeleni (x/y/z)
  12. - vzdalenost delici roviny
  13. - Prusecik focus s tim ctvercem (ray-tracing)
  14. - prusecik s kamerou
  15. */
  16. #define KD_POLY 1
  17. #define KD_MESH 2
  18. typedef struct _KD_BUNKA
  19. {
  20. int mail;
  21. int polozek;
  22. void **p_polozka; //pole polozek (poly/kont)
  23. int *p_polozka_typ; // typy polozek (kontejner/poly)
  24. BOD min, max;
  25. int rovina; // delici rovina podstromu
  26. float vzdal; // vzdalenost od min
  27. int cislo;
  28. struct _KD_BUNKA *p_up; // otec stromu
  29. struct _KD_BUNKA *p_next; // dalsich 2 podstromu nebo nic
  30. } KD_BUNKA;
  31. void kd_strom_vyrob(EDIT_MESH_POLY * p_poly, int polynum,
  32. EDIT_KONTEJNER ** p_kont, int kontnum, KD_BUNKA * p_prvni);
  33. void kd_strom_tiskni(KD_BUNKA * p_prvni, int hloubka);
  34. int kd_visibility(BOD * p_min, BOD * p_max, GLMATRIX * p_m);
  35. int kd_visibility_full(BOD * p_min, BOD * p_max, GLMATRIX * p_m);
  36. int kd_intersect_kostku(BOD * p_a, BOD * p_b, BOD * p_min, BOD * p_max);
  37. int kd_intersect_kostku_dir(BOD * p_orig, BOD * p_dir, BOD * p_min,
  38. BOD * p_max);
  39. int kd_intersect_kostku_bod(BOD * p_a, BOD * p_b, BOD * p_min, BOD * p_max,
  40. BOD * p_p, float *p_t);
  41. int kd_intersect_kostku_bod_inter(BOD * p_a, BOD * p_b, BOD * p_min,
  42. BOD * p_max, BOD * p_p, float *p_t);
  43. void kresli_obalku(BOD min, BOD max, dword barva, GLMATRIX * p_tr);
  44. #define RIF(min,max) (((max)+(min))*0.5f)
  45. #ifndef MAX
  46. #define MAX(a,b) (((a) > (b)) ? (a) : (b))
  47. #endif
  48. #ifndef MIN
  49. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  50. #endif
  51. inline void kd_korekce_bunky(BOD * p_min, BOD * p_max)
  52. {
  53. float tmp;
  54. if (p_min->x > p_max->x) {
  55. tmp = p_min->x;
  56. p_min->x = p_max->x;
  57. p_max->x = tmp;
  58. }
  59. if (p_min->y > p_max->y) {
  60. tmp = p_min->y;
  61. p_min->y = p_max->y;
  62. p_max->y = tmp;
  63. }
  64. if (p_min->z > p_max->z) {
  65. tmp = p_min->z;
  66. p_min->z = p_max->z;
  67. p_max->z = tmp;
  68. }
  69. }
  70. inline void kd_bunka_min(BOD * p_min, BOD * p_gmin)
  71. {
  72. if (p_min->x < p_gmin->x)
  73. p_gmin->x = p_min->x;
  74. if (p_min->y < p_gmin->y)
  75. p_gmin->y = p_min->y;
  76. if (p_min->z < p_gmin->z)
  77. p_gmin->z = p_min->z;
  78. }
  79. inline void kd_bunka_max(BOD * p_max, BOD * p_gmax)
  80. {
  81. if (p_max->x > p_gmax->x)
  82. p_gmax->x = p_max->x;
  83. if (p_max->y > p_gmax->y)
  84. p_gmax->y = p_max->y;
  85. if (p_max->z > p_gmax->z)
  86. p_gmax->z = p_max->z;
  87. }
  88. inline void kd_bunka_min_max(BOD * p_str, BOD * p_gmin, BOD * p_gmax)
  89. {
  90. if (p_str->x < p_gmin->x)
  91. p_gmin->x = p_str->x;
  92. if (p_str->y < p_gmin->y)
  93. p_gmin->y = p_str->y;
  94. if (p_str->z < p_gmin->z)
  95. p_gmin->z = p_str->z;
  96. if (p_str->x > p_gmax->x)
  97. p_gmax->x = p_str->x;
  98. if (p_str->y > p_gmax->y)
  99. p_gmax->y = p_str->y;
  100. if (p_str->z > p_gmax->z)
  101. p_gmax->z = p_str->z;
  102. }
  103. inline void kd_bunka_min_max_koule(BOD * p_str, float radius, BOD * p_gmin,
  104. BOD * p_gmax)
  105. {
  106. if (p_str->x + radius < p_gmin->x)
  107. p_gmin->x = p_str->x + radius;
  108. if (p_str->y + radius < p_gmin->y)
  109. p_gmin->y = p_str->y + radius;
  110. if (p_str->z + radius < p_gmin->z)
  111. p_gmin->z = p_str->z + radius;
  112. if (p_str->x - radius > p_gmax->x)
  113. p_gmax->x = p_str->x - radius;
  114. if (p_str->y - radius > p_gmax->y)
  115. p_gmax->y = p_str->y - radius;
  116. if (p_str->z - radius > p_gmax->z)
  117. p_gmax->z = p_str->z - radius;
  118. }
  119. inline float kd_bunka_obsah(BOD * p_min, BOD * p_max)
  120. {
  121. float a = p_max->x - p_min->x;
  122. float b = p_max->y - p_min->y;
  123. float c = p_max->z - p_min->z;
  124. return (a * a + b * b + c * c);
  125. }
  126. /*
  127. Stred bunky je RIF(min,max)
  128. */
  129. inline BOD *kd_stred_bunky(BOD * p_min, BOD * p_max, BOD * p_bod)
  130. {
  131. p_bod->x = RIF(p_min->x, p_max->x);
  132. p_bod->y = RIF(p_min->y, p_max->y);
  133. p_bod->z = RIF(p_min->z, p_max->z);
  134. return (p_bod);
  135. }
  136. inline BOD *kd_len_bunky(BOD * p_min, BOD * p_max, BOD * p_len)
  137. {
  138. p_len->x = (p_max->x - p_min->x) * 0.5f;
  139. p_len->y = (p_max->y - p_min->y) * 0.5f;
  140. p_len->z = (p_max->z - p_min->z) * 0.5f;
  141. return (p_len);
  142. }
  143. inline void kd_bunka_expanze(BOD * p_stred, BOD * p_len, BOD * p_min,
  144. BOD * p_max)
  145. {
  146. vektor_sub(p_stred, p_len, p_min);
  147. vektor_add(p_stred, p_len, p_max);
  148. }
  149. inline void kd_bunka_expanze2(BOD * p_len, BOD * p_min, BOD * p_max)
  150. {
  151. BOD v(0, 0, 0);
  152. vektor_sub(&v, p_len, p_min);
  153. vektor_add(&v, p_len, p_max);
  154. }
  155. inline void kd_bunka_expanze3(float x, float y, float z, float dx, float dy,
  156. float dz, BOD * p_min, BOD * p_max)
  157. {
  158. p_min->x = x - dx;
  159. p_max->x = x + dx;
  160. p_min->y = y - dy;
  161. p_max->y = y + dy;
  162. p_min->z = z - dz;
  163. p_max->z = z + dz;
  164. }
  165. inline void kd_je_bod_v_kostce_orez(BOD * p_bod, BOD * p_min, BOD * p_max)
  166. {
  167. if (p_min->x > p_bod->x)
  168. p_bod->x = p_min->x;
  169. else {
  170. if (p_max->x < p_bod->x)
  171. p_bod->x = p_max->x;
  172. }
  173. if (p_min->y > p_bod->y)
  174. p_bod->y = p_min->y;
  175. else {
  176. if (p_max->y < p_bod->y)
  177. p_bod->y = p_max->y;
  178. }
  179. if (p_min->z > p_bod->z)
  180. p_bod->z = p_min->z;
  181. else {
  182. if (p_max->z < p_bod->z)
  183. p_bod->z = p_max->z;
  184. }
  185. }
  186. inline int kd_je_bod_v_kostce(BOD * p_bod, BOD * p_min, BOD * p_max)
  187. {
  188. return (p_min->x <= p_bod->x && p_bod->x <= p_max->x &&
  189. p_min->y <= p_bod->y && p_bod->y <= p_max->y &&
  190. p_min->z <= p_bod->z && p_bod->z <= p_max->z);
  191. }
  192. inline int kd_je_bod_v_bunce(KD_BUNKA * p_bunka, BOD * p_bod)
  193. {
  194. return (p_bunka->min.x <= p_bod->x && p_bod->x <= p_bunka->max.x &&
  195. p_bunka->min.y <= p_bod->y && p_bod->y <= p_bunka->max.y &&
  196. p_bunka->min.z <= p_bod->z && p_bod->z <= p_bunka->max.z);
  197. }
  198. inline int kd_je_bod_v_kostce_stred(BOD * p_bod, BOD * p_str, float vzdal)
  199. {
  200. return (p_str->x - vzdal <= p_bod->x && p_bod->x <= p_str->x + vzdal &&
  201. p_str->y - vzdal <= p_bod->y && p_bod->y <= p_str->y + vzdal &&
  202. p_str->z - vzdal <= p_bod->z && p_bod->z <= p_str->z + vzdal);
  203. }
  204. // rozdily mezi bodem a kostkou
  205. inline float kd_intersect_kostku_xyz(BOD * p_a, BOD * p_min, BOD * p_max,
  206. int rovina)
  207. {
  208. float v1, v2;
  209. // rovina X
  210. if (!rovina) {
  211. if (p_a->x >= p_min->x && p_a->x <= p_max->x) {
  212. return (0.0f);
  213. }
  214. else {
  215. v1 = (float) fabs(p_a->x - p_min->x);
  216. v2 = (float) fabs(p_a->x - p_max->x);
  217. return (v1 < v2 ? v1 : v2);
  218. }
  219. }
  220. else if (rovina == 1) {
  221. if (p_a->y >= p_min->y && p_a->y <= p_max->y) {
  222. return (0.0f);
  223. }
  224. else {
  225. v1 = (float) fabs(p_a->y - p_min->y);
  226. v2 = (float) fabs(p_a->y - p_max->y);
  227. return (v1 < v2 ? v1 : v2);
  228. }
  229. }
  230. else if (rovina == 2) {
  231. if (p_a->z >= p_min->z && p_a->z <= p_max->z) {
  232. return (0.0f);
  233. }
  234. else {
  235. v1 = (float) fabs(p_a->z - p_min->z);
  236. v2 = (float) fabs(p_a->z - p_max->z);
  237. return (v1 < v2 ? v1 : v2);
  238. }
  239. }
  240. return (FLT_MAX);
  241. }
  242. inline void kd_min_max_bod(BOD * p_a, BOD * p_min, BOD * p_max)
  243. {
  244. if (p_a->x < p_min->x)
  245. p_min->x = p_a->x;
  246. if (p_a->y < p_min->y)
  247. p_min->y = p_a->y;
  248. if (p_a->z < p_min->z)
  249. p_min->z = p_a->z;
  250. if (p_a->x > p_max->x)
  251. p_max->x = p_a->x;
  252. if (p_a->y > p_max->y)
  253. p_max->y = p_a->y;
  254. if (p_a->z > p_max->z)
  255. p_max->z = p_a->z;
  256. }
  257. inline int kd_min_max_valid(BOD * p_min, BOD * p_max)
  258. {
  259. return(p_min->x < p_max->x && p_min->y < p_max->y && p_min->z < p_max->z);
  260. }
  261. #endif