/** * @param[in] mapTiles List of tiles the current (RMA-)map is composed of * @param[in] start trace start vector * @param[in] end trace end vector * @param[in] box The box we move through the world * @param[in] levelmask Selects which submodels get scanned. * @param[in] brushmask brushes the trace should stop at (see MASK_*) * @param[in] brushreject brushes the trace should ignore (see MASK_*) * @brief Traces all submodels in all tiles. Used by ufo and ufo_ded. */ trace_t CM_CompleteBoxTrace (mapTiles_t *mapTiles, const vec3_t start, const vec3_t end, const AABB &box, int levelmask, int brushmask, int brushreject) { trace_t newtr, tr; int tile, i; vec3_t smin, smax, emin, emax, wpmins, wpmaxs; const vec3_t offset = {UNIT_SIZE / 2, UNIT_SIZE / 2, UNIT_HEIGHT / 2}; OBJZERO(tr); tr.fraction = 2.0f; /* Prep the mins and maxs */ for (i = 0; i < 3; i++) { smin[i] = start[i] + std::min(box.mins[i], box.maxs[i]); smax[i] = start[i] + std::max(box.mins[i], box.maxs[i]); emin[i] = end[i] + std::min(box.mins[i], box.maxs[i]); emax[i] = end[i] + std::max(box.mins[i], box.maxs[i]); } /* trace against all loaded map tiles */ for (tile = 0; tile < mapTiles->numTiles; tile++) { mapTile_t *myTile = &mapTiles->mapTiles[tile]; PosToVec(myTile->wpMins, wpmins); VectorSubtract(wpmins, offset, wpmins); PosToVec(myTile->wpMaxs, wpmaxs); VectorAdd(wpmaxs, offset, wpmaxs); /* If the trace is completely outside of the tile, then skip it. */ if (smax[0] < wpmins[0] && emax[0] < wpmins[0]) continue; if (smax[1] < wpmins[1] && emax[1] < wpmins[1]) continue; if (smax[2] < wpmins[2] && emax[2] < wpmins[2]) continue; if (smin[0] > wpmaxs[0] && emin[0] > wpmaxs[0]) continue; if (smin[1] > wpmaxs[1] && emin[1] > wpmaxs[1]) continue; if (smin[2] > wpmaxs[2] && emin[2] > wpmaxs[2]) continue; newtr = TR_TileBoxTrace(myTile, start, end, box, levelmask, brushmask, brushreject); newtr.mapTile = tile; /* memorize the trace with the minimal fraction */ if (newtr.fraction == 0.0) return newtr; if (newtr.fraction < tr.fraction) tr = newtr; } return tr; }
/** * @param[in] mapTiles List of tiles the current (RMA-)map is composed of * @param[in] trLine The line to trace * @param[in] box The box we move through the world * @param[in] levelmask Selects which submodels get scanned. * @param[in] brushmask brushes the trace should stop at (see MASK_*) * @param[in] brushreject brushes the trace should ignore (see MASK_*) * @brief Traces all submodels in all tiles. Used by ufo and ufo_ded. */ trace_t CM_CompleteBoxTrace (mapTiles_t* mapTiles, const Line& trLine, const AABB& box, int levelmask, int brushmask, int brushreject) { int tile; vec3_t smin, smax, emin, emax, wpmins, wpmaxs; const vec3_t offset = {UNIT_SIZE / 2, UNIT_SIZE / 2, UNIT_HEIGHT / 2}; trace_t tr; tr.fraction = 2.0f; VectorCopy(trLine.stop, tr.endpos); /* optimistically set the endpos just in case we are outside of ALL the tiles, so TR_TileBoxTrace won't do it */ /* Prep the mins and maxs */ for (int i = 0; i < 3; i++) { smin[i] = trLine.start[i] + std::min(box.mins[i], box.maxs[i]); smax[i] = trLine.start[i] + std::max(box.mins[i], box.maxs[i]); emin[i] = trLine.stop[i] + std::min(box.mins[i], box.maxs[i]); emax[i] = trLine.stop[i] + std::max(box.mins[i], box.maxs[i]); } /* trace against all loaded map tiles */ for (tile = 0; tile < mapTiles->numTiles; tile++) { MapTile& myTile = mapTiles->mapTiles[tile]; PosToVec(myTile.wpMins, wpmins); VectorSubtract(wpmins, offset, wpmins); PosToVec(myTile.wpMaxs, wpmaxs); VectorAdd(wpmaxs, offset, wpmaxs); /* If the trace is completely outside of the tile, then skip it. */ if (smax[0] < wpmins[0] && emax[0] < wpmins[0]) continue; if (smax[1] < wpmins[1] && emax[1] < wpmins[1]) continue; if (smax[2] < wpmins[2] && emax[2] < wpmins[2]) continue; if (smin[0] > wpmaxs[0] && emin[0] > wpmaxs[0]) continue; if (smin[1] > wpmaxs[1] && emin[1] > wpmaxs[1]) continue; if (smin[2] > wpmaxs[2] && emin[2] > wpmaxs[2]) continue; trace_t newtr = TR_TileBoxTrace(&myTile, trLine.start, trLine.stop, box, levelmask, brushmask, brushreject); newtr.mapTile = tile; /* memorize the trace with the minimal fraction */ if (newtr.fraction == 0.0) return newtr; if (newtr.fraction < tr.fraction) tr = newtr; } return tr; }