| 250 | |
| 251 | |
| 252 | static bool floodRegion(int x, int y, int i, |
| 253 | unsigned short level, unsigned short r, |
| 254 | rcCompactHeightfield& chf, |
| 255 | unsigned short* srcReg, unsigned short* srcDist, |
| 256 | rcTempVector<LevelStackEntry>& stack) |
| 257 | { |
| 258 | const int w = chf.width; |
| 259 | |
| 260 | const unsigned char area = chf.areas[i]; |
| 261 | |
| 262 | // Flood fill mark region. |
| 263 | stack.clear(); |
| 264 | stack.push_back(LevelStackEntry(x, y, i)); |
| 265 | srcReg[i] = r; |
| 266 | srcDist[i] = 0; |
| 267 | |
| 268 | unsigned short lev = level >= 2 ? level-2 : 0; |
| 269 | int count = 0; |
| 270 | |
| 271 | while (stack.size() > 0) |
| 272 | { |
| 273 | LevelStackEntry& back = stack.back(); |
| 274 | int cx = back.x; |
| 275 | int cy = back.y; |
| 276 | int ci = back.index; |
| 277 | stack.pop_back(); |
| 278 | |
| 279 | const rcCompactSpan& cs = chf.spans[ci]; |
| 280 | |
| 281 | // Check if any of the neighbours already have a valid region set. |
| 282 | unsigned short ar = 0; |
| 283 | for (int dir = 0; dir < 4; ++dir) |
| 284 | { |
| 285 | // 8 connected |
| 286 | if (rcGetCon(cs, dir) != RC_NOT_CONNECTED) |
| 287 | { |
| 288 | const int ax = cx + rcGetDirOffsetX(dir); |
| 289 | const int ay = cy + rcGetDirOffsetY(dir); |
| 290 | const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(cs, dir); |
| 291 | if (chf.areas[ai] != area) |
| 292 | continue; |
| 293 | unsigned short nr = srcReg[ai]; |
| 294 | if (nr & RC_BORDER_REG) // Do not take borders into account. |
| 295 | continue; |
| 296 | if (nr != 0 && nr != r) |
| 297 | { |
| 298 | ar = nr; |
| 299 | break; |
| 300 | } |
| 301 | |
| 302 | const rcCompactSpan& as = chf.spans[ai]; |
| 303 | |
| 304 | const int dir2 = (dir+1) & 0x3; |
| 305 | if (rcGetCon(as, dir2) != RC_NOT_CONNECTED) |
| 306 | { |
| 307 | const int ax2 = ax + rcGetDirOffsetX(dir2); |
| 308 | const int ay2 = ay + rcGetDirOffsetY(dir2); |
| 309 | const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2); |
no test coverage detected