|
6 | 6 | #include "xMemMgr.h" |
7 | 7 | #include "xEnt.h" |
8 | 8 |
|
9 | | -extern float xGrid_float_0p001; |
10 | | -extern float xGrid_float_one; |
11 | | -extern float xGrid_float_one_quarter; |
12 | | - |
13 | 9 | volatile S32 gGridIterActive = 0; |
14 | 10 |
|
15 | 11 | void xGridBoundInit(xGridBound* bound, void* data) |
@@ -43,25 +39,25 @@ void xGridInit(xGrid* grid, const xBox* bounds, U16 nx, U16 nz, U8 ingrid_id) |
43 | 39 | grid->csizex = gsizex / nx; |
44 | 40 | grid->csizez = gsizex / nz; |
45 | 41 |
|
46 | | - if (__fabs(gsizex) <= xGrid_float_0p001) |
| 42 | + if (__fabs(gsizex) <= 0.001f) |
47 | 43 | { |
48 | | - grid->inv_csizex = xGrid_float_one; |
| 44 | + grid->inv_csizex = 1.0f; |
49 | 45 | } |
50 | 46 | else |
51 | 47 | { |
52 | 48 | grid->inv_csizex = nx / gsizex; |
53 | 49 | } |
54 | 50 |
|
55 | | - if (__fabs(gsizez) <= xGrid_float_0p001) |
| 51 | + if (__fabs(gsizez) <= 0.001f) |
56 | 52 | { |
57 | | - grid->inv_csizez = xGrid_float_one; |
| 53 | + grid->inv_csizez = 1.0f; |
58 | 54 | } |
59 | 55 | else |
60 | 56 | { |
61 | 57 | grid->inv_csizez = nz / gsizez; |
62 | 58 | } |
63 | 59 |
|
64 | | - grid->maxr = xGrid_float_one_quarter * MAX(grid->csizex, grid->csizez); |
| 60 | + grid->maxr = 0.25f * MAX(grid->csizex, grid->csizez); |
65 | 61 | grid->cells = (xGridBound**)xMemAllocSize(nx * nz * sizeof(xGridBound*)); |
66 | 62 | memset(grid->cells, 0, sizeof(xGridBound*) * (nz * nx)); |
67 | 63 | } |
@@ -128,6 +124,94 @@ void xGridAdd(xGrid* grid, xGridBound* bound, S32 x, S32 z) |
128 | 124 | xGridAddToCell(&grid->cells[z * grid->nx] + x, bound); |
129 | 125 | } |
130 | 126 |
|
| 127 | +S32 xGridAdd(xGrid* grid, xEnt* ent) |
| 128 | +//NONMATCH("https://decomp.me/scratch/5R7FZ") |
| 129 | +{ |
| 130 | + xBound* bound; |
| 131 | + xVec3* center; |
| 132 | + F32 maxr; |
| 133 | + |
| 134 | + bound = &ent->bound; |
| 135 | + maxr = grid->maxr; |
| 136 | + |
| 137 | + if (bound->type == XBOUND_TYPE_SPHERE) |
| 138 | + { |
| 139 | + xSphere* sph = &bound->sph; |
| 140 | + center = &sph->center; |
| 141 | + if (bound->sph.r >= maxr) |
| 142 | + { |
| 143 | + S32 r = xGridAddToCell(&grid->other, &ent->gridb); |
| 144 | + if (r) |
| 145 | + { |
| 146 | + ent->gridb.ingrid = grid->ingrid_id; |
| 147 | + } |
| 148 | + return r; |
| 149 | + } |
| 150 | + } |
| 151 | + else if (bound->type == XBOUND_TYPE_OBB) |
| 152 | + { |
| 153 | + xBBox* bbox = &bound->box; |
| 154 | + center = &bbox->center; |
| 155 | + F32 rx = bbox->box.upper.x - bbox->box.lower.x; |
| 156 | + F32 ry = bbox->box.upper.y - bbox->box.lower.y; |
| 157 | + F32 rz = bbox->box.upper.z - bbox->box.lower.z; |
| 158 | + F32 len2 = |
| 159 | + SQR(rx) * |
| 160 | + (SQR(bound->mat->right.x) + SQR(bound->mat->right.y) + SQR(bound->mat->right.z)) + |
| 161 | + SQR(ry) * (SQR(bound->mat->up.x) + SQR(bound->mat->up.y) + SQR(bound->mat->up.z)) + |
| 162 | + SQR(rz) * (SQR(bound->mat->at.x) + SQR(bound->mat->at.y) + SQR(bound->mat->at.z)); |
| 163 | + if (len2 >= 4.0f * maxr * maxr) |
| 164 | + { |
| 165 | + S32 r = xGridAddToCell(&grid->other, &ent->gridb); |
| 166 | + if (r) |
| 167 | + { |
| 168 | + ent->gridb.ingrid = grid->ingrid_id; |
| 169 | + } |
| 170 | + return r; |
| 171 | + } |
| 172 | + } |
| 173 | + else if (bound->type == XBOUND_TYPE_BOX) |
| 174 | + { |
| 175 | + xBBox* bbox = &bound->box; |
| 176 | + center = &bbox->center; |
| 177 | + F32 rx = bound->box.box.upper.x - bound->box.box.lower.x; |
| 178 | + F32 rz = bound->box.box.upper.z - bound->box.box.lower.z; |
| 179 | + F32 len2 = SQR(rx) + SQR(rz); |
| 180 | + if (len2 >= 4.0f * maxr * maxr) |
| 181 | + { |
| 182 | + S32 r = xGridAddToCell(&grid->other, &ent->gridb); |
| 183 | + if (r) |
| 184 | + { |
| 185 | + ent->gridb.ingrid = grid->ingrid_id; |
| 186 | + } |
| 187 | + return r; |
| 188 | + } |
| 189 | + } |
| 190 | + else |
| 191 | + { |
| 192 | + return 0; |
| 193 | + } |
| 194 | + |
| 195 | + F32 cgridx = center->x - grid->minx; |
| 196 | + cgridx *= grid->inv_csizex; |
| 197 | + |
| 198 | + F32 cgridz = center->z - grid->minz; |
| 199 | + cgridz *= grid->inv_csizez; |
| 200 | + |
| 201 | + S32 x = (S32)MIN(grid->nx - 1, MAX(0.0f, cgridx)); |
| 202 | + S32 z = (S32)MIN(grid->nz - 1, MAX(0.0f, cgridz)); |
| 203 | + |
| 204 | + if (1) |
| 205 | + { |
| 206 | + ent->gridb.gx = x; |
| 207 | + ent->gridb.gz = z; |
| 208 | + ent->gridb.ingrid = grid->ingrid_id; |
| 209 | + return 1; |
| 210 | + } |
| 211 | + |
| 212 | + return 0; |
| 213 | +} |
| 214 | + |
131 | 215 | S32 xGridRemove(xGridBound* bound) |
132 | 216 | { |
133 | 217 | if (bound->head) |
@@ -214,3 +298,142 @@ xGridBound* xGridIterFirstCell(xGrid* grid, F32 posx, F32 posy, F32 posz, S32& g |
214 | 298 | xGridGetCell(grid, posx, posy, posz, grx, grz); |
215 | 299 | return xGridIterFirstCell(grid, grx, grz, iter); |
216 | 300 | } |
| 301 | + |
| 302 | +S32 xGridEntIsTooBig(xGrid* grid, const xEnt* ent) |
| 303 | +{ |
| 304 | + const xBound* bound = &ent->bound; |
| 305 | + F32 maxr = grid->maxr; |
| 306 | + |
| 307 | + if (bound->type == XBOUND_TYPE_SPHERE) |
| 308 | + { |
| 309 | + const xSphere* sph = &bound->sph; |
| 310 | + if (sph->r >= maxr) |
| 311 | + { |
| 312 | + return 1; |
| 313 | + } |
| 314 | + } |
| 315 | + else if (bound->type == XBOUND_TYPE_OBB) |
| 316 | + { |
| 317 | + const xBBox* bbox = &bound->box; |
| 318 | + F32 rx = bbox->box.upper.x - bbox->box.lower.x; |
| 319 | + F32 ry = bbox->box.upper.y - bbox->box.lower.y; |
| 320 | + F32 rz = bbox->box.upper.z - bbox->box.lower.z; |
| 321 | + F32 len2 = |
| 322 | + SQR(rx) * |
| 323 | + (SQR(bound->mat->right.x) + SQR(bound->mat->right.y) + SQR(bound->mat->right.z)) + |
| 324 | + SQR(ry) * (SQR(bound->mat->up.x) + SQR(bound->mat->up.y) + SQR(bound->mat->up.z)) + |
| 325 | + SQR(rz) * (SQR(bound->mat->at.x) + SQR(bound->mat->at.y) + SQR(bound->mat->at.z)); |
| 326 | + if (len2 >= 4.0f * maxr * maxr) |
| 327 | + { |
| 328 | + return 1; |
| 329 | + } |
| 330 | + } |
| 331 | + else if (bound->type == XBOUND_TYPE_BOX) |
| 332 | + { |
| 333 | + const xBBox* bbox = &bound->box; |
| 334 | + F32 rx = bbox->box.upper.x - bbox->box.lower.x; |
| 335 | + F32 rz = bbox->box.upper.z - bbox->box.lower.z; |
| 336 | + F32 len2 = SQR(rx) + SQR(rz); |
| 337 | + if (len2 >= 4.0f * maxr * maxr) |
| 338 | + { |
| 339 | + return 1; |
| 340 | + } |
| 341 | + } |
| 342 | + |
| 343 | + return 0; |
| 344 | +} |
| 345 | + |
| 346 | +void xGridCheckPosition(xGrid* grid, xVec3* pos, xQCData* qcd, xGridCheckPositionCallback hitCB, |
| 347 | + void* cbdata) |
| 348 | +{ |
| 349 | + xGridIterator it; |
| 350 | + S32 px, pz; |
| 351 | + xGridBound* cell; |
| 352 | + |
| 353 | + cell = xGridIterFirstCell(grid, pos->x, pos->y, pos->z, px, pz, it); |
| 354 | + while (cell) |
| 355 | + { |
| 356 | + xBound* cellbound = (xBound*)(cell + 1); |
| 357 | + if (xQuickCullIsects(qcd, &cellbound->qcd) && !hitCB((xEnt*)cell->data, cbdata)) |
| 358 | + { |
| 359 | + xGridIterClose(it); |
| 360 | + return; |
| 361 | + } |
| 362 | + cell = xGridIterNextCell(it); |
| 363 | + } |
| 364 | + |
| 365 | + xBox clbox; |
| 366 | + clbox.lower.x = grid->csizex * px; |
| 367 | + clbox.lower.z = grid->csizez * pz; |
| 368 | + clbox.lower.x += grid->minx; |
| 369 | + clbox.lower.z += grid->minz; |
| 370 | + |
| 371 | + F32 clcenterx = 0.5f * grid->csizex; |
| 372 | + clcenterx += clbox.lower.x; |
| 373 | + |
| 374 | + F32 clcenterz = 0.5f * grid->csizez; |
| 375 | + clcenterz += clbox.lower.z; |
| 376 | + |
| 377 | + static S32 offs[4][3][2] = { -1, 0, -1, -1, 0, -1, 0, -1, 1, -1, 1, 0, |
| 378 | + 1, 0, 1, 1, 0, 1, 0, 1, -1, 1, -1, 0 }; |
| 379 | + |
| 380 | + static S32 k; |
| 381 | + |
| 382 | + if (pos->x < clcenterx) |
| 383 | + { |
| 384 | + if (pos->z < clcenterz) |
| 385 | + { |
| 386 | + k = 0; |
| 387 | + } |
| 388 | + else |
| 389 | + { |
| 390 | + k = 1; |
| 391 | + } |
| 392 | + } |
| 393 | + else |
| 394 | + { |
| 395 | + if (pos->z < clcenterz) |
| 396 | + { |
| 397 | + k = 3; |
| 398 | + } |
| 399 | + else |
| 400 | + { |
| 401 | + k = 2; |
| 402 | + } |
| 403 | + } |
| 404 | + |
| 405 | + for (S32 i = 0; i < 3; i++) |
| 406 | + { |
| 407 | + S32 _x = px + offs[k][i][1]; |
| 408 | + if (_x >= 0 && _x < grid->nx) |
| 409 | + { |
| 410 | + S32 _z = pz + offs[k][i][0]; |
| 411 | + if (_z >= 0 && _z < grid->nz) |
| 412 | + { |
| 413 | + cell = xGridIterFirstCell(grid, _x, _z, it); |
| 414 | + while (cell) |
| 415 | + { |
| 416 | + xBound* cellbound = (xBound*)(cell + 1); |
| 417 | + if (xQuickCullIsects(qcd, &cellbound->qcd) && !hitCB((xEnt*)cell->data, cbdata)) |
| 418 | + { |
| 419 | + xGridIterClose(it); |
| 420 | + return; |
| 421 | + } |
| 422 | + cell = xGridIterNextCell(it); |
| 423 | + } |
| 424 | + } |
| 425 | + } |
| 426 | + } |
| 427 | + |
| 428 | + cell = xGridIterFirstCell(&grid->other, it); |
| 429 | + while (cell) |
| 430 | + { |
| 431 | + xBound* cellbound = (xBound*)(cell + 1); |
| 432 | + if (xQuickCullIsects(qcd, &cellbound->qcd) && !hitCB((xEnt*)cell->data, cbdata)) |
| 433 | + { |
| 434 | + xGridIterClose(it); |
| 435 | + return; |
| 436 | + } |
| 437 | + cell = xGridIterNextCell(it); |
| 438 | + } |
| 439 | +} |
0 commit comments