00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "../game/q_shared.h"
00034 #include "l_libvar.h"
00035 #include "l_memory.h"
00036 #include "l_script.h"
00037 #include "l_precomp.h"
00038 #include "l_struct.h"
00039 #include "aasfile.h"
00040 #include "../game/botlib.h"
00041 #include "../game/be_aas.h"
00042 #include "be_aas_funcs.h"
00043 #include "be_interface.h"
00044 #include "be_aas_def.h"
00045
00046 typedef struct optimized_s
00047 {
00048
00049 int numvertexes;
00050 aas_vertex_t *vertexes;
00051
00052 int numedges;
00053 aas_edge_t *edges;
00054
00055 int edgeindexsize;
00056 aas_edgeindex_t *edgeindex;
00057
00058 int numfaces;
00059 aas_face_t *faces;
00060
00061 int faceindexsize;
00062 aas_faceindex_t *faceindex;
00063
00064 int numareas;
00065 aas_area_t *areas;
00066
00067 int *vertexoptimizeindex;
00068 int *edgeoptimizeindex;
00069 int *faceoptimizeindex;
00070 } optimized_t;
00071
00072
00073
00074
00075
00076
00077
00078 int AAS_KeepEdge(aas_edge_t *edge)
00079 {
00080 return 1;
00081 }
00082
00083
00084
00085
00086
00087
00088 int AAS_OptimizeEdge(optimized_t *optimized, int edgenum)
00089 {
00090 int i, optedgenum;
00091 aas_edge_t *edge, *optedge;
00092
00093 edge = &aasworld.edges[abs(edgenum)];
00094 if (!AAS_KeepEdge(edge)) return 0;
00095
00096 optedgenum = optimized->edgeoptimizeindex[abs(edgenum)];
00097 if (optedgenum)
00098 {
00099
00100 if (edgenum > 0) return optedgenum;
00101 else return -optedgenum;
00102 }
00103
00104 optedge = &optimized->edges[optimized->numedges];
00105
00106 for (i = 0; i < 2; i++)
00107 {
00108 if (optimized->vertexoptimizeindex[edge->v[i]])
00109 {
00110 optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]];
00111 }
00112 else
00113 {
00114 VectorCopy(aasworld.vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes]);
00115 optedge->v[i] = optimized->numvertexes;
00116 optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes;
00117 optimized->numvertexes++;
00118 }
00119 }
00120 optimized->edgeoptimizeindex[abs(edgenum)] = optimized->numedges;
00121 optedgenum = optimized->numedges;
00122 optimized->numedges++;
00123
00124 if (edgenum > 0) return optedgenum;
00125 else return -optedgenum;
00126 }
00127
00128
00129
00130
00131
00132
00133 int AAS_KeepFace(aas_face_t *face)
00134 {
00135 if (!(face->faceflags & FACE_LADDER)) return 0;
00136 else return 1;
00137 }
00138
00139
00140
00141
00142
00143
00144 int AAS_OptimizeFace(optimized_t *optimized, int facenum)
00145 {
00146 int i, edgenum, optedgenum, optfacenum;
00147 aas_face_t *face, *optface;
00148
00149 face = &aasworld.faces[abs(facenum)];
00150 if (!AAS_KeepFace(face)) return 0;
00151
00152 optfacenum = optimized->faceoptimizeindex[abs(facenum)];
00153 if (optfacenum)
00154 {
00155
00156 if (facenum > 0) return optfacenum;
00157 else return -optfacenum;
00158 }
00159
00160 optface = &optimized->faces[optimized->numfaces];
00161 Com_Memcpy(optface, face, sizeof(aas_face_t));
00162
00163 optface->numedges = 0;
00164 optface->firstedge = optimized->edgeindexsize;
00165 for (i = 0; i < face->numedges; i++)
00166 {
00167 edgenum = aasworld.edgeindex[face->firstedge + i];
00168 optedgenum = AAS_OptimizeEdge(optimized, edgenum);
00169 if (optedgenum)
00170 {
00171 optimized->edgeindex[optface->firstedge + optface->numedges] = optedgenum;
00172 optface->numedges++;
00173 optimized->edgeindexsize++;
00174 }
00175 }
00176 optimized->faceoptimizeindex[abs(facenum)] = optimized->numfaces;
00177 optfacenum = optimized->numfaces;
00178 optimized->numfaces++;
00179
00180 if (facenum > 0) return optfacenum;
00181 else return -optfacenum;
00182 }
00183
00184
00185
00186
00187
00188
00189 void AAS_OptimizeArea(optimized_t *optimized, int areanum)
00190 {
00191 int i, facenum, optfacenum;
00192 aas_area_t *area, *optarea;
00193
00194 area = &aasworld.areas[areanum];
00195 optarea = &optimized->areas[areanum];
00196 Com_Memcpy(optarea, area, sizeof(aas_area_t));
00197
00198 optarea->numfaces = 0;
00199 optarea->firstface = optimized->faceindexsize;
00200 for (i = 0; i < area->numfaces; i++)
00201 {
00202 facenum = aasworld.faceindex[area->firstface + i];
00203 optfacenum = AAS_OptimizeFace(optimized, facenum);
00204 if (optfacenum)
00205 {
00206 optimized->faceindex[optarea->firstface + optarea->numfaces] = optfacenum;
00207 optarea->numfaces++;
00208 optimized->faceindexsize++;
00209 }
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218 void AAS_OptimizeAlloc(optimized_t *optimized)
00219 {
00220 optimized->vertexes = (aas_vertex_t *) GetClearedMemory(aasworld.numvertexes * sizeof(aas_vertex_t));
00221 optimized->numvertexes = 0;
00222 optimized->edges = (aas_edge_t *) GetClearedMemory(aasworld.numedges * sizeof(aas_edge_t));
00223 optimized->numedges = 1;
00224 optimized->edgeindex = (aas_edgeindex_t *) GetClearedMemory(aasworld.edgeindexsize * sizeof(aas_edgeindex_t));
00225 optimized->edgeindexsize = 0;
00226 optimized->faces = (aas_face_t *) GetClearedMemory(aasworld.numfaces * sizeof(aas_face_t));
00227 optimized->numfaces = 1;
00228 optimized->faceindex = (aas_faceindex_t *) GetClearedMemory(aasworld.faceindexsize * sizeof(aas_faceindex_t));
00229 optimized->faceindexsize = 0;
00230 optimized->areas = (aas_area_t *) GetClearedMemory(aasworld.numareas * sizeof(aas_area_t));
00231 optimized->numareas = aasworld.numareas;
00232
00233 optimized->vertexoptimizeindex = (int *) GetClearedMemory(aasworld.numvertexes * sizeof(int));
00234 optimized->edgeoptimizeindex = (int *) GetClearedMemory(aasworld.numedges * sizeof(int));
00235 optimized->faceoptimizeindex = (int *) GetClearedMemory(aasworld.numfaces * sizeof(int));
00236 }
00237
00238
00239
00240
00241
00242
00243 void AAS_OptimizeStore(optimized_t *optimized)
00244 {
00245
00246 if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
00247 aasworld.vertexes = optimized->vertexes;
00248 aasworld.numvertexes = optimized->numvertexes;
00249
00250 if (aasworld.edges) FreeMemory(aasworld.edges);
00251 aasworld.edges = optimized->edges;
00252 aasworld.numedges = optimized->numedges;
00253
00254 if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
00255 aasworld.edgeindex = optimized->edgeindex;
00256 aasworld.edgeindexsize = optimized->edgeindexsize;
00257
00258 if (aasworld.faces) FreeMemory(aasworld.faces);
00259 aasworld.faces = optimized->faces;
00260 aasworld.numfaces = optimized->numfaces;
00261
00262 if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
00263 aasworld.faceindex = optimized->faceindex;
00264 aasworld.faceindexsize = optimized->faceindexsize;
00265
00266 if (aasworld.areas) FreeMemory(aasworld.areas);
00267 aasworld.areas = optimized->areas;
00268 aasworld.numareas = optimized->numareas;
00269
00270 FreeMemory(optimized->vertexoptimizeindex);
00271 FreeMemory(optimized->edgeoptimizeindex);
00272 FreeMemory(optimized->faceoptimizeindex);
00273 }
00274
00275
00276
00277
00278
00279
00280 void AAS_Optimize(void)
00281 {
00282 int i, sign;
00283 optimized_t optimized;
00284
00285 AAS_OptimizeAlloc(&optimized);
00286 for (i = 1; i < aasworld.numareas; i++)
00287 {
00288 AAS_OptimizeArea(&optimized, i);
00289 }
00290
00291 for (i = 0; i < aasworld.reachabilitysize; i++)
00292 {
00293
00294
00295 if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR) continue;
00296
00297 if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD) continue;
00298
00299 if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_FUNCBOB) continue;
00300
00301 sign = aasworld.reachability[i].facenum;
00302 aasworld.reachability[i].facenum = optimized.faceoptimizeindex[abs(aasworld.reachability[i].facenum)];
00303 if (sign < 0) aasworld.reachability[i].facenum = -aasworld.reachability[i].facenum;
00304 sign = aasworld.reachability[i].edgenum;
00305 aasworld.reachability[i].edgenum = optimized.edgeoptimizeindex[abs(aasworld.reachability[i].edgenum)];
00306 if (sign < 0) aasworld.reachability[i].edgenum = -aasworld.reachability[i].edgenum;
00307 }
00308
00309 AAS_OptimizeStore(&optimized);
00310
00311 botimport.Print(PRT_MESSAGE, "AAS data optimized.\n");
00312 }