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"
15 //#define STB_IMAGE_IMPLEMENTATION
16 #include "stb_image.h"
18 //#define STB_IMAGE_WRITE_IMPLEMENTATION
19 #include "stb_image_write.h"
26 point leader
[1024][1024];
27 uint32 color
[1024][1024];
29 point
find(int x
, int y
)
33 if (p
.x
== x
&& p
.y
== y
)
40 void onion(int x1
, int y1
, int x2
, int y2
)
42 point p
= find(x1
,y1
);
43 point q
= find(x2
,y2
);
45 if (p
.x
== q
.x
&& p
.y
== q
.y
)
51 void reference(uint8
*map
, int w
, int h
)
55 for (j
=0; j
< h
; ++j
) {
56 for (i
=0; i
< w
; ++i
) {
62 for (j
=1; j
< h
-1; ++j
) {
63 for (i
=1; i
< w
-1; ++i
) {
64 if (map
[j
*w
+i
] == 255) {
65 if (map
[(j
+1)*w
+i
] == 255) onion(i
,j
, i
,j
+1);
66 if (map
[(j
)*w
+i
+1] == 255) onion(i
,j
, i
+1,j
);
71 for (j
=0; j
< h
; ++j
) {
72 for (i
=0; i
< w
; ++i
) {
73 uint32 c
= 0xff000000;
74 if (leader
[j
][i
].x
== i
&& leader
[j
][i
].y
== j
) {
75 if (map
[j
*w
+i
] == 255)
76 c
= stb_randLCG() | 0xff404040;
82 for (j
=0; j
< h
; ++j
) {
83 for (i
=0; i
< w
; ++i
) {
84 if (leader
[j
][i
].x
!= i
|| leader
[j
][i
].y
!= j
) {
86 color
[j
][i
] = color
[p
.y
][p
.x
];
92 void write_map(stbcc_grid
*g
, int w
, int h
, char *filename
)
95 for (j
=0; j
< h
; ++j
) {
96 for (i
=0; i
< w
; ++i
) {
98 c
= stbcc_get_unique_id(g
,i
,j
);
99 c
= stb_rehash_improved(c
)&0xffffff;
100 if (c
== STBCC_NULL_UNIQUE_ID
)
104 if (i
% 32 == 0 || j
%32 == 0) {
105 int r
= (c
>> 16) & 255;
106 int g
= (c
>> 8) & 255;
111 c
= 0xff000000 + (r
<<16) + (g
<<8) + b
;
116 stbi_write_png(filename
, w
, h
, 4, color
, 4*w
);
119 void test_connected(stbcc_grid
*g
)
121 int n
= stbcc_query_grid_node_connection(g
, 512, 90, 512, 871);
125 static char *message
;
128 void start_timer(char *s
)
131 QueryPerformanceCounter(&start
);
136 LARGE_INTEGER end
, freq
;
139 QueryPerformanceCounter(&end
);
140 QueryPerformanceFrequency(&freq
);
142 tm
= (end
.QuadPart
- start
.QuadPart
) / (double) freq
.QuadPart
;
143 printf("%6.4lf ms: %s\n", tm
* 1000, message
);
146 extern void quicktest(void);
149 int main(int argc
, char **argv
)
153 int w
,h
, i
,j
,k
=0, count
=0, r
;
154 uint8
*map
= stbi_load("data/map_03.png", &w
, &h
, 0, 1);
159 for (j
=0; j
< h
; ++j
)
160 for (i
=0; i
< w
; ++i
)
161 map
[j
*w
+i
] = ~map
[j
*w
+i
];
163 for (i
=0; i
< w
; ++i
)
164 for (j
=0; j
< h
; ++j
)
165 //map[j*w+i] = (((i+1) ^ (j+1)) >> 1) & 1 ? 255 : 0;
166 map
[j
*w
+i
] = stb_max(abs(i
-w
/2),abs(j
-h
/2)) & 1 ? 255 : 0;
167 //map[j*w+i] = (((i ^ j) >> 5) ^ (i ^ j)) & 1 ? 255 : 0;
168 //map[j*w+i] = stb_rand() & 1 ? 255 : 0;
171 for (i
=0; i
< 100000; ++i
)
172 map
[(stb_rand()%h
)*w
+ stb_rand()%w
] ^= 255;
175 _mkdir("tests/output/stbcc");
177 stbi_write_png("tests/output/stbcc/reference.png", w
, h
, 1, map
, 0);
179 //reference(map, w, h);
181 g
= malloc(stbcc_grid_sizeof());
182 printf("Size: %d\n", stbcc_grid_sizeof());
186 stbcc_init_grid(g
, map
, w
, h
);
189 char **s
= stb_stringfile("c:/x/clockwork_update.txt", &n
);
190 write_map(g
, w
, h
, "tests/output/stbcc/base.png");
191 for (i
=1; i
< n
; i
+= 1) {
193 sscanf(s
[i
], "%d %d %d", &x
, &y
, &t
);
195 write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/clockwork_good.png", i
));
196 stbcc_update_grid(g
, x
, y
, t
);
198 write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/clockwork_bad.png", i
));
199 //if (i > 571648 && i <= 571712)
200 //write_map(g, w, h, stb_sprintf("tests/output/stbcc/clockwork_%06d.png", i));
202 write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/clockwork_%06d.png", i
-1));
209 stbcc_init_grid(g
, map
, w
, h
);
211 //g = stb_file("c:/x/clockwork_path.bin", 0);
212 write_map(g
, w
, h
, "tests/output/stbcc/base.png");
214 for (i
=0; i
< 5000;) {
215 loc
[i
][0] = stb_rand() % w
;
216 loc
[i
][1] = stb_rand() % h
;
217 if (stbcc_query_grid_open(g
, loc
[i
][0], loc
[i
][1]))
222 start_timer("reachable");
223 for (i
=0; i
< 2000; ++i
) {
224 for (j
=0; j
< 2000; ++j
) {
225 int x1
= loc
[i
][0], y1
= loc
[i
][1];
226 int x2
= loc
[2000+j
][0], y2
= loc
[2000+j
][1];
227 r
+= stbcc_query_grid_node_connection(g
, x1
,y1
, x2
,y2
);
231 printf("%d reachable\n", r
);
233 printf("Cluster size: %d,%d\n", STBCC__CLUSTER_SIZE_X
, STBCC__CLUSTER_SIZE_Y
);
236 for (j
=0; j
< 10; ++j
) {
237 for (i
=0; i
< 5000; ++i
) {
238 loc
[i
][0] = stb_rand() % w
;
239 loc
[i
][1] = stb_rand() % h
;
241 start_timer("updating 2500");
242 for (i
=0; i
< 2500; ++i
) {
243 if (stbcc_query_grid_open(g
, loc
[i
][0], loc
[i
][1]))
244 stbcc_update_grid(g
, loc
[i
][0], loc
[i
][1], 1);
246 stbcc_update_grid(g
, loc
[i
][0], loc
[i
][1], 0);
249 write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/update_random_%d.png", j
*i
));
254 start_timer("removing");
256 for (i
=0; i
< 1800; ++i
) {
258 x
= stb_rand() % (w
-32);
259 y
= stb_rand() % (h
-32);
262 for (a
=0; a
< 32; ++a
)
263 for (b
=0; b
< 1; ++b
)
264 if (stbcc_query_grid_open(g
, x
+a
, y
+b
)) {
265 stbcc_update_grid(g
, x
+a
, y
+b
, 1);
269 for (a
=0; a
< 1; ++a
)
270 for (b
=0; b
< 32; ++b
)
271 if (stbcc_query_grid_open(g
, x
+a
, y
+b
)) {
272 stbcc_update_grid(g
, x
+a
, y
+b
, 1);
277 //if (i % 100 == 0) write_map(g, w, h, stb_sprintf("tests/output/stbcc/open_random_%d.png", i+1));
280 printf("Removed %d grid spaces\n", count
);
281 write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/open_random_%d.png", i
));
285 start_timer("reachable");
286 for (i
=0; i
< 1000; ++i
) {
287 for (j
=0; j
< 1000; ++j
) {
288 int x1
= loc
[i
][0], y1
= loc
[i
][1];
289 int x2
= loc
[j
][0], y2
= loc
[j
][1];
290 r
+= stbcc_query_grid_node_connection(g
, x1
,y1
, x2
,y2
);
294 printf("%d reachable\n", r
);
296 start_timer("adding");
298 for (i
=0; i
< 1800; ++i
) {
300 x
= stb_rand() % (w
-32);
301 y
= stb_rand() % (h
-32);
304 for (a
=0; a
< 32; ++a
)
305 for (b
=0; b
< 1; ++b
)
306 if (!stbcc_query_grid_open(g
, x
+a
, y
+b
)) {
307 stbcc_update_grid(g
, x
+a
, y
+b
, 0);
311 for (a
=0; a
< 1; ++a
)
312 for (b
=0; b
< 32; ++b
)
313 if (!stbcc_query_grid_open(g
, x
+a
, y
+b
)) {
314 stbcc_update_grid(g
, x
+a
, y
+b
, 0);
319 //if (i % 100 == 0) write_map(g, w, h, stb_sprintf("tests/output/stbcc/close_random_%d.png", i+1));
322 write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/close_random_%d.png", i
));
323 printf("Added %d grid spaces\n", count
);
327 #if 0 // for map_02.png
328 start_timer("process");
329 for (k
=0; k
< 20; ++k
) {
330 for (j
=0; j
< h
; ++j
) {
332 for (i
=0; i
< w
; ++i
) {
333 if (map
[j
*w
+i
] > 10 && map
[j
*w
+i
] < 250) {
334 //start_timer(stb_sprintf("open %d,%d", i,j));
335 stbcc_update_grid(g
, i
, j
, 0);
341 if (any
) write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/open_row_%04d.png", j
));
344 for (j
=0; j
< h
; ++j
) {
346 for (i
=0; i
< w
; ++i
) {
347 if (map
[j
*w
+i
] > 10 && map
[j
*w
+i
] < 250) {
348 //start_timer(stb_sprintf("close %d,%d", i,j));
349 stbcc_update_grid(g
, i
, j
, 1);
355 if (any
) write_map(g
, w
, h
, stb_sprintf("tests/output/stbcc/close_row_%04d.png", j
));