Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

363 lines
9.1 KiB

  1. #define STB_CONNECTED_COMPONENTS_IMPLEMENTATION
  2. #define STBCC_GRID_COUNT_X_LOG2 10
  3. #define STBCC_GRID_COUNT_Y_LOG2 10
  4. #include "stb_connected_components.h"
  5. #ifdef GRID_TEST
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include <direct.h>
  9. //#define STB_DEFINE
  10. #include "stb.h"
  11. //#define STB_IMAGE_IMPLEMENTATION
  12. #include "stb_image.h"
  13. //#define STB_IMAGE_WRITE_IMPLEMENTATION
  14. #include "stb_image_write.h"
  15. typedef struct
  16. {
  17. uint16 x,y;
  18. } point;
  19. point leader[1024][1024];
  20. uint32 color[1024][1024];
  21. point find(int x, int y)
  22. {
  23. point p,q;
  24. p = leader[y][x];
  25. if (p.x == x && p.y == y)
  26. return p;
  27. q = find(p.x, p.y);
  28. leader[y][x] = q;
  29. return q;
  30. }
  31. void onion(int x1, int y1, int x2, int y2)
  32. {
  33. point p = find(x1,y1);
  34. point q = find(x2,y2);
  35. if (p.x == q.x && p.y == q.y)
  36. return;
  37. leader[p.y][p.x] = q;
  38. }
  39. void reference(uint8 *map, int w, int h)
  40. {
  41. int i,j;
  42. for (j=0; j < h; ++j) {
  43. for (i=0; i < w; ++i) {
  44. leader[j][i].x = i;
  45. leader[j][i].y = j;
  46. }
  47. }
  48. for (j=1; j < h-1; ++j) {
  49. for (i=1; i < w-1; ++i) {
  50. if (map[j*w+i] == 255) {
  51. if (map[(j+1)*w+i] == 255) onion(i,j, i,j+1);
  52. if (map[(j)*w+i+1] == 255) onion(i,j, i+1,j);
  53. }
  54. }
  55. }
  56. for (j=0; j < h; ++j) {
  57. for (i=0; i < w; ++i) {
  58. uint32 c = 0xff000000;
  59. if (leader[j][i].x == i && leader[j][i].y == j) {
  60. if (map[j*w+i] == 255)
  61. c = stb_randLCG() | 0xff404040;
  62. }
  63. color[j][i] = c;
  64. }
  65. }
  66. for (j=0; j < h; ++j) {
  67. for (i=0; i < w; ++i) {
  68. if (leader[j][i].x != i || leader[j][i].y != j) {
  69. point p = find(i,j);
  70. color[j][i] = color[p.y][p.x];
  71. }
  72. }
  73. }
  74. }
  75. void write_map(stbcc_grid *g, int w, int h, char *filename)
  76. {
  77. int i,j;
  78. for (j=0; j < h; ++j) {
  79. for (i=0; i < w; ++i) {
  80. unsigned int c;
  81. c = stbcc_get_unique_id(g,i,j);
  82. c = stb_rehash_improved(c)&0xffffff;
  83. if (c == STBCC_NULL_UNIQUE_ID)
  84. c = 0xff000000;
  85. else
  86. c = (~c)^0x555555;
  87. if (i % 32 == 0 || j %32 == 0) {
  88. int r = (c >> 16) & 255;
  89. int g = (c >> 8) & 255;
  90. int b = c & 255;
  91. r = (r+130)/2;
  92. g = (g+130)/2;
  93. b = (b+130)/2;
  94. c = 0xff000000 + (r<<16) + (g<<8) + b;
  95. }
  96. color[j][i] = c;
  97. }
  98. }
  99. stbi_write_png(filename, w, h, 4, color, 4*w);
  100. }
  101. void test_connected(stbcc_grid *g)
  102. {
  103. int n = stbcc_query_grid_node_connection(g, 512, 90, 512, 871);
  104. //printf("%d ", n);
  105. }
  106. static char *message;
  107. LARGE_INTEGER start;
  108. void start_timer(char *s)
  109. {
  110. message = s;
  111. QueryPerformanceCounter(&start);
  112. }
  113. void end_timer(void)
  114. {
  115. LARGE_INTEGER end, freq;
  116. double tm;
  117. QueryPerformanceCounter(&end);
  118. QueryPerformanceFrequency(&freq);
  119. tm = (end.QuadPart - start.QuadPart) / (double) freq.QuadPart;
  120. printf("%6.4lf ms: %s\n", tm * 1000, message);
  121. }
  122. extern void quicktest(void);
  123. int loc[5000][2];
  124. int main(int argc, char **argv)
  125. {
  126. stbcc_grid *g;
  127. int w,h, i,j,k=0, count=0, r;
  128. uint8 *map = stbi_load("data/map_03.png", &w, &h, 0, 1);
  129. assert(map);
  130. quicktest();
  131. for (j=0; j < h; ++j)
  132. for (i=0; i < w; ++i)
  133. map[j*w+i] = ~map[j*w+i];
  134. for (i=0; i < w; ++i)
  135. for (j=0; j < h; ++j)
  136. //map[j*w+i] = (((i+1) ^ (j+1)) >> 1) & 1 ? 255 : 0;
  137. map[j*w+i] = stb_max(abs(i-w/2),abs(j-h/2)) & 1 ? 255 : 0;
  138. //map[j*w+i] = (((i ^ j) >> 5) ^ (i ^ j)) & 1 ? 255 : 0;
  139. //map[j*w+i] = stb_rand() & 1 ? 255 : 0;
  140. #if 1
  141. for (i=0; i < 100000; ++i)
  142. map[(stb_rand()%h)*w + stb_rand()%w] ^= 255;
  143. #endif
  144. _mkdir("tests/output/stbcc");
  145. stbi_write_png("tests/output/stbcc/reference.png", w, h, 1, map, 0);
  146. //reference(map, w, h);
  147. g = malloc(stbcc_grid_sizeof());
  148. printf("Size: %d\n", stbcc_grid_sizeof());
  149. #if 0
  150. memset(map, 0, w*h);
  151. stbcc_init_grid(g, map, w, h);
  152. {
  153. int n;
  154. char **s = stb_stringfile("c:/x/clockwork_update.txt", &n);
  155. write_map(g, w, h, "tests/output/stbcc/base.png");
  156. for (i=1; i < n; i += 1) {
  157. int x,y,t;
  158. sscanf(s[i], "%d %d %d", &x, &y, &t);
  159. if (i == 571678)
  160. write_map(g, w, h, stb_sprintf("tests/output/stbcc/clockwork_good.png", i));
  161. stbcc_update_grid(g, x, y, t);
  162. if (i == 571678)
  163. write_map(g, w, h, stb_sprintf("tests/output/stbcc/clockwork_bad.png", i));
  164. //if (i > 571648 && i <= 571712)
  165. //write_map(g, w, h, stb_sprintf("tests/output/stbcc/clockwork_%06d.png", i));
  166. }
  167. write_map(g, w, h, stb_sprintf("tests/output/stbcc/clockwork_%06d.png", i-1));
  168. }
  169. return 0;
  170. #endif
  171. start_timer("init");
  172. stbcc_init_grid(g, map, w, h);
  173. end_timer();
  174. //g = stb_file("c:/x/clockwork_path.bin", 0);
  175. write_map(g, w, h, "tests/output/stbcc/base.png");
  176. for (i=0; i < 5000;) {
  177. loc[i][0] = stb_rand() % w;
  178. loc[i][1] = stb_rand() % h;
  179. if (stbcc_query_grid_open(g, loc[i][0], loc[i][1]))
  180. ++i;
  181. }
  182. r = 0;
  183. start_timer("reachable");
  184. for (i=0; i < 2000; ++i) {
  185. for (j=0; j < 2000; ++j) {
  186. int x1 = loc[i][0], y1 = loc[i][1];
  187. int x2 = loc[2000+j][0], y2 = loc[2000+j][1];
  188. r += stbcc_query_grid_node_connection(g, x1,y1, x2,y2);
  189. }
  190. }
  191. end_timer();
  192. printf("%d reachable\n", r);
  193. printf("Cluster size: %d,%d\n", STBCC__CLUSTER_SIZE_X, STBCC__CLUSTER_SIZE_Y);
  194. #if 1
  195. for (j=0; j < 10; ++j) {
  196. for (i=0; i < 5000; ++i) {
  197. loc[i][0] = stb_rand() % w;
  198. loc[i][1] = stb_rand() % h;
  199. }
  200. start_timer("updating 2500");
  201. for (i=0; i < 2500; ++i) {
  202. if (stbcc_query_grid_open(g, loc[i][0], loc[i][1]))
  203. stbcc_update_grid(g, loc[i][0], loc[i][1], 1);
  204. else
  205. stbcc_update_grid(g, loc[i][0], loc[i][1], 0);
  206. }
  207. end_timer();
  208. write_map(g, w, h, stb_sprintf("tests/output/stbcc/update_random_%d.png", j*i));
  209. }
  210. #endif
  211. #if 0
  212. start_timer("removing");
  213. count = 0;
  214. for (i=0; i < 1800; ++i) {
  215. int x,y,a,b;
  216. x = stb_rand() % (w-32);
  217. y = stb_rand() % (h-32);
  218. if (i & 1) {
  219. for (a=0; a < 32; ++a)
  220. for (b=0; b < 1; ++b)
  221. if (stbcc_query_grid_open(g, x+a, y+b)) {
  222. stbcc_update_grid(g, x+a, y+b, 1);
  223. ++count;
  224. }
  225. } else {
  226. for (a=0; a < 1; ++a)
  227. for (b=0; b < 32; ++b)
  228. if (stbcc_query_grid_open(g, x+a, y+b)) {
  229. stbcc_update_grid(g, x+a, y+b, 1);
  230. ++count;
  231. }
  232. }
  233. //if (i % 100 == 0) write_map(g, w, h, stb_sprintf("tests/output/stbcc/open_random_%d.png", i+1));
  234. }
  235. end_timer();
  236. printf("Removed %d grid spaces\n", count);
  237. write_map(g, w, h, stb_sprintf("tests/output/stbcc/open_random_%d.png", i));
  238. r = 0;
  239. start_timer("reachable");
  240. for (i=0; i < 1000; ++i) {
  241. for (j=0; j < 1000; ++j) {
  242. int x1 = loc[i][0], y1 = loc[i][1];
  243. int x2 = loc[j][0], y2 = loc[j][1];
  244. r += stbcc_query_grid_node_connection(g, x1,y1, x2,y2);
  245. }
  246. }
  247. end_timer();
  248. printf("%d reachable\n", r);
  249. start_timer("adding");
  250. count = 0;
  251. for (i=0; i < 1800; ++i) {
  252. int x,y,a,b;
  253. x = stb_rand() % (w-32);
  254. y = stb_rand() % (h-32);
  255. if (i & 1) {
  256. for (a=0; a < 32; ++a)
  257. for (b=0; b < 1; ++b)
  258. if (!stbcc_query_grid_open(g, x+a, y+b)) {
  259. stbcc_update_grid(g, x+a, y+b, 0);
  260. ++count;
  261. }
  262. } else {
  263. for (a=0; a < 1; ++a)
  264. for (b=0; b < 32; ++b)
  265. if (!stbcc_query_grid_open(g, x+a, y+b)) {
  266. stbcc_update_grid(g, x+a, y+b, 0);
  267. ++count;
  268. }
  269. }
  270. //if (i % 100 == 0) write_map(g, w, h, stb_sprintf("tests/output/stbcc/close_random_%d.png", i+1));
  271. }
  272. end_timer();
  273. write_map(g, w, h, stb_sprintf("tests/output/stbcc/close_random_%d.png", i));
  274. printf("Added %d grid spaces\n", count);
  275. #endif
  276. #if 0 // for map_02.png
  277. start_timer("process");
  278. for (k=0; k < 20; ++k) {
  279. for (j=0; j < h; ++j) {
  280. int any=0;
  281. for (i=0; i < w; ++i) {
  282. if (map[j*w+i] > 10 && map[j*w+i] < 250) {
  283. //start_timer(stb_sprintf("open %d,%d", i,j));
  284. stbcc_update_grid(g, i, j, 0);
  285. test_connected(g);
  286. //end_timer();
  287. any = 1;
  288. }
  289. }
  290. if (any) write_map(g, w, h, stb_sprintf("tests/output/stbcc/open_row_%04d.png", j));
  291. }
  292. for (j=0; j < h; ++j) {
  293. int any=0;
  294. for (i=0; i < w; ++i) {
  295. if (map[j*w+i] > 10 && map[j*w+i] < 250) {
  296. //start_timer(stb_sprintf("close %d,%d", i,j));
  297. stbcc_update_grid(g, i, j, 1);
  298. test_connected(g);
  299. //end_timer();
  300. any = 1;
  301. }
  302. }
  303. if (any) write_map(g, w, h, stb_sprintf("tests/output/stbcc/close_row_%04d.png", j));
  304. }
  305. }
  306. end_timer();
  307. #endif
  308. return 0;
  309. }
  310. #endif