2
===========================================================================
3
Copyright (C) 1999-2005 Id Software, Inc.
5
This file is part of Quake III Arena source code.
7
Quake III Arena source code is free software; you can redistribute it
8
and/or modify it under the terms of the GNU General Public License as
9
published by the Free Software Foundation; either version 2 of the License,
10
or (at your option) any later version.
12
Quake III Arena source code is distributed in the hope that it will be
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Quake III Arena source code; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
===========================================================================
23
/*****************************************************************************
24
* name: be_aas_optimize.c
26
* desc: decreases the .aas file size after the reachabilities have
27
* been calculated, just dumps all the faces, edges and vertexes
29
* $Archive: /MissionPack/code/botlib/be_aas_optimize.c $
31
*****************************************************************************/
33
#include "../qcommon/q_shared.h"
37
#include "l_precomp.h"
42
#include "be_aas_funcs.h"
43
#include "be_interface.h"
44
#include "be_aas_def.h"
46
typedef struct optimized_s
50
aas_vertex_t *vertexes;
56
aas_edgeindex_t *edgeindex;
62
aas_faceindex_t *faceindex;
67
int *vertexoptimizeindex;
68
int *edgeoptimizeindex;
69
int *faceoptimizeindex;
72
//===========================================================================
77
//===========================================================================
78
int AAS_KeepEdge(aas_edge_t *edge)
81
} //end of the function AAS_KeepFace
82
//===========================================================================
87
//===========================================================================
88
int AAS_OptimizeEdge(optimized_t *optimized, int edgenum)
91
aas_edge_t *edge, *optedge;
93
edge = &aasworld.edges[abs(edgenum)];
94
if (!AAS_KeepEdge(edge)) return 0;
96
optedgenum = optimized->edgeoptimizeindex[abs(edgenum)];
99
//keep the edge reversed sign
100
if (edgenum > 0) return optedgenum;
101
else return -optedgenum;
104
optedge = &optimized->edges[optimized->numedges];
106
for (i = 0; i < 2; i++)
108
if (optimized->vertexoptimizeindex[edge->v[i]])
110
optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]];
114
VectorCopy(aasworld.vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes]);
115
optedge->v[i] = optimized->numvertexes;
116
optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes;
117
optimized->numvertexes++;
120
optimized->edgeoptimizeindex[abs(edgenum)] = optimized->numedges;
121
optedgenum = optimized->numedges;
122
optimized->numedges++;
123
//keep the edge reversed sign
124
if (edgenum > 0) return optedgenum;
125
else return -optedgenum;
126
} //end of the function AAS_OptimizeEdge
127
//===========================================================================
131
// Changes Globals: -
132
//===========================================================================
133
int AAS_KeepFace(aas_face_t *face)
135
if (!(face->faceflags & FACE_LADDER)) return 0;
137
} //end of the function AAS_KeepFace
138
//===========================================================================
142
// Changes Globals: -
143
//===========================================================================
144
int AAS_OptimizeFace(optimized_t *optimized, int facenum)
146
int i, edgenum, optedgenum, optfacenum;
147
aas_face_t *face, *optface;
149
face = &aasworld.faces[abs(facenum)];
150
if (!AAS_KeepFace(face)) return 0;
152
optfacenum = optimized->faceoptimizeindex[abs(facenum)];
155
//keep the face side sign
156
if (facenum > 0) return optfacenum;
157
else return -optfacenum;
160
optface = &optimized->faces[optimized->numfaces];
161
Com_Memcpy(optface, face, sizeof(aas_face_t));
163
optface->numedges = 0;
164
optface->firstedge = optimized->edgeindexsize;
165
for (i = 0; i < face->numedges; i++)
167
edgenum = aasworld.edgeindex[face->firstedge + i];
168
optedgenum = AAS_OptimizeEdge(optimized, edgenum);
171
optimized->edgeindex[optface->firstedge + optface->numedges] = optedgenum;
173
optimized->edgeindexsize++;
176
optimized->faceoptimizeindex[abs(facenum)] = optimized->numfaces;
177
optfacenum = optimized->numfaces;
178
optimized->numfaces++;
179
//keep the face side sign
180
if (facenum > 0) return optfacenum;
181
else return -optfacenum;
182
} //end of the function AAS_OptimizeFace
183
//===========================================================================
187
// Changes Globals: -
188
//===========================================================================
189
void AAS_OptimizeArea(optimized_t *optimized, int areanum)
191
int i, facenum, optfacenum;
192
aas_area_t *area, *optarea;
194
area = &aasworld.areas[areanum];
195
optarea = &optimized->areas[areanum];
196
Com_Memcpy(optarea, area, sizeof(aas_area_t));
198
optarea->numfaces = 0;
199
optarea->firstface = optimized->faceindexsize;
200
for (i = 0; i < area->numfaces; i++)
202
facenum = aasworld.faceindex[area->firstface + i];
203
optfacenum = AAS_OptimizeFace(optimized, facenum);
206
optimized->faceindex[optarea->firstface + optarea->numfaces] = optfacenum;
208
optimized->faceindexsize++;
211
} //end of the function AAS_OptimizeArea
212
//===========================================================================
216
// Changes Globals: -
217
//===========================================================================
218
void AAS_OptimizeAlloc(optimized_t *optimized)
220
optimized->vertexes = (aas_vertex_t *) GetClearedMemory(aasworld.numvertexes * sizeof(aas_vertex_t));
221
optimized->numvertexes = 0;
222
optimized->edges = (aas_edge_t *) GetClearedMemory(aasworld.numedges * sizeof(aas_edge_t));
223
optimized->numedges = 1; //edge zero is a dummy
224
optimized->edgeindex = (aas_edgeindex_t *) GetClearedMemory(aasworld.edgeindexsize * sizeof(aas_edgeindex_t));
225
optimized->edgeindexsize = 0;
226
optimized->faces = (aas_face_t *) GetClearedMemory(aasworld.numfaces * sizeof(aas_face_t));
227
optimized->numfaces = 1; //face zero is a dummy
228
optimized->faceindex = (aas_faceindex_t *) GetClearedMemory(aasworld.faceindexsize * sizeof(aas_faceindex_t));
229
optimized->faceindexsize = 0;
230
optimized->areas = (aas_area_t *) GetClearedMemory(aasworld.numareas * sizeof(aas_area_t));
231
optimized->numareas = aasworld.numareas;
233
optimized->vertexoptimizeindex = (int *) GetClearedMemory(aasworld.numvertexes * sizeof(int));
234
optimized->edgeoptimizeindex = (int *) GetClearedMemory(aasworld.numedges * sizeof(int));
235
optimized->faceoptimizeindex = (int *) GetClearedMemory(aasworld.numfaces * sizeof(int));
236
} //end of the function AAS_OptimizeAlloc
237
//===========================================================================
241
// Changes Globals: -
242
//===========================================================================
243
void AAS_OptimizeStore(optimized_t *optimized)
245
//store the optimized vertexes
246
if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
247
aasworld.vertexes = optimized->vertexes;
248
aasworld.numvertexes = optimized->numvertexes;
249
//store the optimized edges
250
if (aasworld.edges) FreeMemory(aasworld.edges);
251
aasworld.edges = optimized->edges;
252
aasworld.numedges = optimized->numedges;
253
//store the optimized edge index
254
if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
255
aasworld.edgeindex = optimized->edgeindex;
256
aasworld.edgeindexsize = optimized->edgeindexsize;
257
//store the optimized faces
258
if (aasworld.faces) FreeMemory(aasworld.faces);
259
aasworld.faces = optimized->faces;
260
aasworld.numfaces = optimized->numfaces;
261
//store the optimized face index
262
if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
263
aasworld.faceindex = optimized->faceindex;
264
aasworld.faceindexsize = optimized->faceindexsize;
265
//store the optimized areas
266
if (aasworld.areas) FreeMemory(aasworld.areas);
267
aasworld.areas = optimized->areas;
268
aasworld.numareas = optimized->numareas;
269
//free optimize indexes
270
FreeMemory(optimized->vertexoptimizeindex);
271
FreeMemory(optimized->edgeoptimizeindex);
272
FreeMemory(optimized->faceoptimizeindex);
273
} //end of the function AAS_OptimizeStore
274
//===========================================================================
278
// Changes Globals: -
279
//===========================================================================
280
void AAS_Optimize(void)
283
optimized_t optimized;
285
AAS_OptimizeAlloc(&optimized);
286
for (i = 1; i < aasworld.numareas; i++)
288
AAS_OptimizeArea(&optimized, i);
290
//reset the reachability face pointers
291
for (i = 0; i < aasworld.reachabilitysize; i++)
293
//NOTE: for TRAVEL_ELEVATOR the facenum is the model number of
295
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR) continue;
296
//NOTE: for TRAVEL_JUMPPAD the facenum is the Z velocity and the edgenum is the hor velocity
297
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD) continue;
298
//NOTE: for TRAVEL_FUNCBOB the facenum and edgenum contain other coded information
299
if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_FUNCBOB) continue;
301
sign = aasworld.reachability[i].facenum;
302
aasworld.reachability[i].facenum = optimized.faceoptimizeindex[abs(aasworld.reachability[i].facenum)];
303
if (sign < 0) aasworld.reachability[i].facenum = -aasworld.reachability[i].facenum;
304
sign = aasworld.reachability[i].edgenum;
305
aasworld.reachability[i].edgenum = optimized.edgeoptimizeindex[abs(aasworld.reachability[i].edgenum)];
306
if (sign < 0) aasworld.reachability[i].edgenum = -aasworld.reachability[i].edgenum;
308
//store the optimized AAS data into aasworld
309
AAS_OptimizeStore(&optimized);
310
//print some nice stuff :)
311
botimport.Print(PRT_MESSAGE, "AAS data optimized.\n");
312
} //end of the function AAS_Optimize