| 299 | #define VIS_NO 2 |
| 300 | |
| 301 | int BNode_FindDirLocalVisibleBNode(int roomnum, vector *pos, vector *fvec, float rad) { |
| 302 | int i; |
| 303 | float best_dot = -1.01f; |
| 304 | float closest_dist = 800.0f; |
| 305 | int closest_node = -1; |
| 306 | bool f_retry = false; |
| 307 | |
| 308 | float min_bn_rad = rad / 4.0f; |
| 309 | if (min_bn_rad > MAX_BNODE_SIZE) { |
| 310 | min_bn_rad = MAX_BNODE_SIZE; |
| 311 | } |
| 312 | |
| 313 | bn_list *bnlist = BNode_GetBNListPtr(roomnum); |
| 314 | |
| 315 | retry: |
| 316 | |
| 317 | for (i = 0; i < bnlist->num_nodes; i++) { |
| 318 | vector to = bnlist->nodes[i].pos - *pos; |
| 319 | float dist = vm_NormalizeVector(&to); |
| 320 | |
| 321 | if (dist < closest_dist) { |
| 322 | float dot = *fvec * to; |
| 323 | |
| 324 | if (dot > 0.0f || f_retry) { |
| 325 | float node_size = 0.0f; |
| 326 | |
| 327 | /* if(!f_retry) |
| 328 | { |
| 329 | for(j = 0; j < bnlist->nodes[i].num_edges; j++) |
| 330 | { |
| 331 | if(bnlist->nodes[i].edges[j].max_rad > node_size) |
| 332 | { |
| 333 | node_size = bnlist->nodes[i].edges[j].max_rad; |
| 334 | } |
| 335 | } |
| 336 | } |
| 337 | */ |
| 338 | if (!f_retry || (f_retry && BNode_vis[i] == VIS_NO_CHECK)) { |
| 339 | fvi_query fq; |
| 340 | fvi_info hit_info; |
| 341 | |
| 342 | fq.p0 = pos; |
| 343 | fq.startroom = (roomnum > Highest_room_index && roomnum <= Highest_room_index + 8) |
| 344 | ? GetTerrainRoomFromPos(pos) |
| 345 | : roomnum; |
| 346 | fq.p1 = &bnlist->nodes[i].pos; |
| 347 | fq.rad = min_bn_rad; |
| 348 | fq.thisobjnum = -1; |
| 349 | fq.ignore_obj_list = NULL; |
| 350 | fq.flags = FQ_CHECK_OBJS | FQ_NO_RELINK | FQ_IGNORE_NON_LIGHTMAP_OBJECTS; |
| 351 | |
| 352 | if (fvi_FindIntersection(&fq, &hit_info) == HIT_NONE) { |
| 353 | BNode_vis[i] = VIS_OK; |
| 354 | best_dot = dot; |
| 355 | closest_node = i; |
| 356 | } else { |
| 357 | if (!f_retry) { |
| 358 | BNode_vis[i] = VIS_NO; |
no test coverage detected