/** * @brief This function recalculates the routing surrounding the entity name. * @sa CM_InlineModel * @sa CM_CheckUnit * @sa CM_UpdateConnection * @sa CMod_LoadSubmodels * @sa Grid_RecalcBoxRouting * @param[in] mapTiles List of tiles the current (RMA-)map is composed of * @param[in] routing The routing map (either server or client map) * @param[in] name Name of the inline model to compute the mins/maxs for * @param[in] box The box around the inline model (alternative to name) * @param[in] list The local models list (a local model has a name starting with * followed by the model number) */ void Grid_RecalcRouting (mapTiles_t *mapTiles, Routing &routing, const char *name, const GridBox &box, const char **list) { if (box.isZero()) { pos3_t min, max; vec3_t absmin, absmax; const cBspModel_t *model; unsigned int i; /* get inline model, if it is one */ if (*name != '*') { Com_Printf("Called Grid_RecalcRouting with no inline model\n"); return; } model = CM_InlineModel(mapTiles, name); if (!model) { Com_Printf("Called Grid_RecalcRouting with invalid inline model name '%s'\n", name); return; } #if 1 /* An attempt to fix the 'doors starting opened' bug (# 3456). * The main difference is the (missing) rotation of the halfVec. * The results are better, but do not fix the problem. */ CalculateMinsMaxs(model->angles, model->mins, model->maxs, model->origin, absmin, absmax); #else /* get the target model's dimensions */ if (VectorNotEmpty(model->angles)) { vec3_t minVec, maxVec; vec3_t centerVec, halfVec, newCenterVec; vec3_t m[3]; /* Find the center of the extents. */ VectorCenterFromMinsMaxs(model->mins, model->maxs, centerVec); /* Find the half height and half width of the extents. */ VectorSubtract(model->maxs, centerVec, halfVec); /* Rotate the center about the origin. */ VectorCreateRotationMatrix(model->angles, m); VectorRotate(m, centerVec, newCenterVec); /* Set minVec and maxVec to bound around newCenterVec at halfVec size. */ VectorSubtract(newCenterVec, halfVec, minVec); VectorAdd(newCenterVec, halfVec, maxVec); /* Now offset by origin then convert to position (Doors do not have 0 origins) */ VectorAdd(minVec, model->origin, absmin); VectorAdd(maxVec, model->origin, absmax); } else { /* normal */ /* Now offset by origin then convert to position (Doors do not have 0 origins) */ VectorAdd(model->mins, model->origin, absmin); VectorAdd(model->maxs, model->origin, absmax); } #endif VecToPos(absmin, min); VecToPos(absmax, max); /* fit min/max into the world size */ max[0] = std::min(max[0], (pos_t)(PATHFINDING_WIDTH - 1)); max[1] = std::min(max[1], (pos_t)(PATHFINDING_WIDTH - 1)); max[2] = std::min(max[2], (pos_t)(PATHFINDING_HEIGHT - 1)); for (i = 0; i < 3; i++) min[i] = std::max(min[i], (pos_t)0); /* We now have the dimensions, call the generic rerouting function. */ GridBox rerouteBox(min, max); Grid_RecalcBoxRouting(mapTiles, routing, rerouteBox, list); } else { /* use the passed box */ Grid_RecalcBoxRouting(mapTiles, routing, box, list); } }
/** * @brief This function recalculates the routing surrounding the entity name. * @sa CM_InlineModel * @sa CM_CheckUnit * @sa CM_UpdateConnection * @sa CMod_LoadSubmodels * @sa Grid_RecalcBoxRouting * @param[in] mapTiles List of tiles the current (RMA-)map is composed of * @param[in] routing The routing map (either server or client map) * @param[in] name Name of the inline model to compute the mins/maxs for * @param[in] box The box around the inline model (alternative to name) * @param[in] list The local models list (a local model has a name starting with * followed by the model number) */ void Grid_RecalcRouting (mapTiles_t* mapTiles, Routing& routing, const char* name, const GridBox& box, const char** list) { if (box.isZero()) { /* get inline model, if it is one */ if (*name != '*') { Com_Printf("Called Grid_RecalcRouting with no inline model\n"); return; } const cBspModel_t* model = CM_InlineModel(mapTiles, name); if (!model) { Com_Printf("Called Grid_RecalcRouting with invalid inline model name '%s'\n", name); return; } AABB absbox; #if 1 /* An attempt to fix the 'doors starting opened' bug (# 3456). * The main difference is the (missing) rotation of the halfVec. * The results are better, but do not fix the problem. */ CalculateMinsMaxs(model->angles, model->cbmBox, model->origin, absbox); #else /* get the target model's dimensions */ if (VectorNotEmpty(model->angles)) { vec3_t minVec, maxVec; vec3_t centerVec, halfVec, newCenterVec; vec3_t m[3]; /* Find the center of the extents. */ model->cbmBox.getCenter(centerVec); /* Find the half height and half width of the extents. */ VectorSubtract(model->cbmBox.maxs, centerVec, halfVec); /* Rotate the center about the origin. */ VectorCreateRotationMatrix(model->angles, m); VectorRotate(m, centerVec, newCenterVec); /* Set minVec and maxVec to bound around newCenterVec at halfVec size. */ VectorSubtract(newCenterVec, halfVec, minVec); VectorAdd(newCenterVec, halfVec, maxVec); /* Now offset by origin then convert to position (Doors do not have 0 origins) */ absbox.set(minVec, maxVec); absbox.shift(model->origin); } else { /* normal */ /* Now offset by origin then convert to position (Doors do not have 0 origins) */ absbox.set(model->cbmBox); absbox.shift(model->origin); } #endif GridBox rerouteBox(absbox); /* fit min/max into the world size */ rerouteBox.clipToMaxBoundaries(); /* We now have the dimensions, call the generic rerouting function. */ Grid_RecalcBoxRouting(mapTiles, routing, rerouteBox, list); } else { /* use the passed box */ Grid_RecalcBoxRouting(mapTiles, routing, box, list); } }