00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "bsp.h"
00029 #include "../../common/routing.h"
00030
00031 static const vec3_t move_vec[4] = {
00032 { UNIT_SIZE, 0, 0},
00033 {-UNIT_SIZE, 0, 0},
00034 { 0, UNIT_SIZE, 0},
00035 { 0, -UNIT_SIZE, 0} };
00036
00038 static routing_t Nmap[ACTOR_MAX_SIZE];
00041 static ipos3_t wpMins, wpMaxs;
00042
00043
00047 static int CheckUnit (unsigned int unitnum)
00048 {
00049 int new_z;
00050
00051
00052 const int z = unitnum % PATHFINDING_HEIGHT;
00053 const int y = (unitnum / PATHFINDING_HEIGHT) % PATHFINDING_WIDTH;
00054 const int x = (unitnum / PATHFINDING_HEIGHT / PATHFINDING_WIDTH) % PATHFINDING_WIDTH;
00055 const int actorSize = unitnum / PATHFINDING_HEIGHT / PATHFINDING_WIDTH / PATHFINDING_WIDTH;
00056
00057
00058 if (x > wpMaxs[0] - actorSize || y > wpMaxs[1] - actorSize
00059 || x < wpMins[0] || y < wpMins[1]) {
00060
00061 return 0;
00062 }
00063
00064
00065
00066 new_z = RT_CheckCell(&mapTiles, Nmap, actorSize + 1, x, y, z, NULL);
00067
00068
00069
00070
00071 assert(new_z <= z);
00072
00073
00074 return new_z - z;
00075 }
00076
00081 static void CheckUnitThread (unsigned int unitnum)
00082 {
00083 const int basenum = unitnum * PATHFINDING_HEIGHT;
00084 int newnum;
00085 for (newnum = basenum + PATHFINDING_HEIGHT - 1; newnum >= basenum; newnum--)
00086 newnum += CheckUnit(newnum);
00087 }
00088
00089
00093 static void CheckConnectionsThread (unsigned int unitnum)
00094 {
00095
00096 const int numDirs = CORE_DIRECTIONS / (1 + RT_IS_BIDIRECTIONAL);
00097 const int dir = (unitnum % numDirs) * (RT_IS_BIDIRECTIONAL ? 2 : 1);
00098 const int y = (unitnum / numDirs) % PATHFINDING_WIDTH;
00099 const int x = (unitnum / numDirs / PATHFINDING_WIDTH) % PATHFINDING_WIDTH;
00100 const int actorSize = unitnum / numDirs / PATHFINDING_WIDTH / PATHFINDING_WIDTH;
00101
00102
00103 if (x > wpMaxs[0] - actorSize || y > wpMaxs[1] - actorSize
00104 || x < wpMins[0] || y < wpMins[1] ) {
00105
00106
00107 return;
00108 }
00109
00110 Verb_Printf(VERB_EXTRA, "%i %i %i %i (%i, %i, %i) (%i, %i, %i)\n", x, y, dir, actorSize, wpMins[0], wpMins[1], wpMins[2], wpMaxs[0], wpMaxs[1], wpMaxs[2]);
00111
00112 RT_UpdateConnectionColumn(&mapTiles, Nmap, actorSize + 1, x, y, dir, NULL);
00113
00114
00115 }
00116
00117
00124 void DoRouting (void)
00125 {
00126 int i;
00127 byte *data;
00128 vec3_t mins, maxs;
00129 pos3_t pos;
00130
00131
00132 if (config.generateDebugTrace)
00133 debugTrace = qtrue;
00134
00135
00136 PushInfo();
00137
00138
00139 EmitBrushes();
00140 EmitPlanes();
00142 MakeTracingNodes(LEVEL_ACTORCLIP + 1);
00143
00144
00145 memset(Nmap, 0, sizeof(Nmap));
00146
00147
00148 RT_GetMapSize(&mapTiles, mins, maxs);
00149
00150 VecToPos(mins, wpMins);
00151 VecToPos(maxs, wpMaxs);
00152
00153
00154 assert(wpMins[0] <= wpMaxs[0]);
00155 assert(wpMins[1] <= wpMaxs[1]);
00156 assert(wpMins[2] <= wpMaxs[2]);
00157
00158
00159 RunSingleThreadOn(CheckUnitThread, PATHFINDING_WIDTH * PATHFINDING_WIDTH * ACTOR_MAX_SIZE, config.verbosity >= VERB_NORMAL, "UNITCHECK");
00160
00161
00162 RunSingleThreadOn(CheckConnectionsThread, PATHFINDING_WIDTH * PATHFINDING_WIDTH * (CORE_DIRECTIONS / (1 + RT_IS_BIDIRECTIONAL)) * (ACTOR_MAX_SIZE), config.verbosity >= VERB_NORMAL, "CONNCHECK");
00163
00164
00165 for (i = 0; i < 2; i++) {
00166
00167 while (wpMaxs[i] > wpMins[i]) {
00168 VectorSet(pos, wpMins[0], wpMins[1], wpMaxs[2]);
00169 for (pos[i] = wpMins[i]; pos[i] <= wpMaxs[i]; pos[i]++) {
00170 if (RT_FLOOR(Nmap, 1, pos[0], pos[1], wpMaxs[2]) + wpMaxs[2] * CELL_HEIGHT != -1)
00171 break;
00172 }
00173 if (pos[i] <= wpMaxs[i])
00174 break;
00175 wpMins[i ^ 1]++;
00176 }
00177
00178 while (wpMaxs[i] > wpMins[i]) {
00179 VectorCopy(wpMaxs, pos);
00180 for (pos[i] = wpMins[i]; pos[i] <= wpMaxs[i]; pos[i]++) {
00181 if (RT_FLOOR(Nmap, 1, pos[0], pos[1], wpMaxs[2]) + wpMaxs[2] * CELL_HEIGHT != -1)
00182 break;
00183 }
00184 if (pos[i] <= wpMaxs[i])
00185 break;
00186 wpMaxs[i ^ 1]--;
00187 }
00188 }
00189
00190
00191 if (config.generateTraceFile) {
00192 RT_WriteCSVFiles(Nmap, baseFilename, wpMins, wpMaxs);
00193 }
00194
00195
00196 data = curTile->routedata;
00197 for (i = 0; i < 3; i++)
00198 wpMins[i] = LittleLong(wpMins[i]);
00199 data = CompressRouting((byte*)wpMins, data, sizeof(wpMins));
00200 for (i = 0; i < 3; i++)
00201 wpMaxs[i] = LittleLong(wpMaxs[i]);
00202 data = CompressRouting((byte*)wpMaxs, data, sizeof(wpMaxs));
00203 data = CompressRouting((byte*)Nmap, data, sizeof(Nmap));
00204
00205 curTile->routedatasize = data - curTile->routedata;
00206
00207
00208 assert(curTile->routedatasize <= MAX_MAP_ROUTING);
00209
00210
00211 PopInfo();
00212 }