Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

be_aas_optimize.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 /*****************************************************************************
00024  * name:        be_aas_optimize.c
00025  *
00026  * desc:        decreases the .aas file size after the reachabilities have
00027  *              been calculated, just dumps all the faces, edges and vertexes
00028  *
00029  * $Archive: /MissionPack/code/botlib/be_aas_optimize.c $
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     //vertexes
00049     int numvertexes;
00050     aas_vertex_t *vertexes;
00051     //edges
00052     int numedges;
00053     aas_edge_t *edges;
00054     //edge index
00055     int edgeindexsize;
00056     aas_edgeindex_t *edgeindex;
00057     //faces
00058     int numfaces;
00059     aas_face_t *faces;
00060     //face index
00061     int faceindexsize;
00062     aas_faceindex_t *faceindex;
00063     //convex areas
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 // Parameter:               -
00075 // Returns:                 -
00076 // Changes Globals:     -
00077 //===========================================================================
00078 int AAS_KeepEdge(aas_edge_t *edge)
00079 {
00080     return 1;
00081 } //end of the function AAS_KeepFace
00082 //===========================================================================
00083 //
00084 // Parameter:               -
00085 // Returns:                 -
00086 // Changes Globals:     -
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         //keep the edge reversed sign
00100         if (edgenum > 0) return optedgenum;
00101         else return -optedgenum;
00102     } //end if
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         } //end if
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         } //end else
00119     } //end for
00120     optimized->edgeoptimizeindex[abs(edgenum)] = optimized->numedges;
00121     optedgenum = optimized->numedges;
00122     optimized->numedges++;
00123     //keep the edge reversed sign
00124     if (edgenum > 0) return optedgenum;
00125     else return -optedgenum;
00126 } //end of the function AAS_OptimizeEdge
00127 //===========================================================================
00128 //
00129 // Parameter:               -
00130 // Returns:                 -
00131 // Changes Globals:     -
00132 //===========================================================================
00133 int AAS_KeepFace(aas_face_t *face)
00134 {
00135     if (!(face->faceflags & FACE_LADDER)) return 0;
00136     else return 1;
00137 } //end of the function AAS_KeepFace
00138 //===========================================================================
00139 //
00140 // Parameter:               -
00141 // Returns:                 -
00142 // Changes Globals:     -
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         //keep the face side sign
00156         if (facenum > 0) return optfacenum;
00157         else return -optfacenum;
00158     } //end if
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         } //end if
00175     } //end for
00176     optimized->faceoptimizeindex[abs(facenum)] = optimized->numfaces;
00177     optfacenum = optimized->numfaces;
00178     optimized->numfaces++;
00179     //keep the face side sign
00180     if (facenum > 0) return optfacenum;
00181     else return -optfacenum;
00182 } //end of the function AAS_OptimizeFace
00183 //===========================================================================
00184 //
00185 // Parameter:               -
00186 // Returns:                 -
00187 // Changes Globals:     -
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         } //end if
00210     } //end for
00211 } //end of the function AAS_OptimizeArea
00212 //===========================================================================
00213 //
00214 // Parameter:               -
00215 // Returns:                 -
00216 // Changes Globals:     -
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; //edge zero is a dummy
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; //face zero is a dummy
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 } //end of the function AAS_OptimizeAlloc
00237 //===========================================================================
00238 //
00239 // Parameter:               -
00240 // Returns:                 -
00241 // Changes Globals:     -
00242 //===========================================================================
00243 void AAS_OptimizeStore(optimized_t *optimized)
00244 {
00245     //store the optimized vertexes
00246     if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
00247     aasworld.vertexes = optimized->vertexes;
00248     aasworld.numvertexes = optimized->numvertexes;
00249     //store the optimized edges
00250     if (aasworld.edges) FreeMemory(aasworld.edges);
00251     aasworld.edges = optimized->edges;
00252     aasworld.numedges = optimized->numedges;
00253     //store the optimized edge index
00254     if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
00255     aasworld.edgeindex = optimized->edgeindex;
00256     aasworld.edgeindexsize = optimized->edgeindexsize;
00257     //store the optimized faces
00258     if (aasworld.faces) FreeMemory(aasworld.faces);
00259     aasworld.faces = optimized->faces;
00260     aasworld.numfaces = optimized->numfaces;
00261     //store the optimized face index
00262     if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
00263     aasworld.faceindex = optimized->faceindex;
00264     aasworld.faceindexsize = optimized->faceindexsize;
00265     //store the optimized areas
00266     if (aasworld.areas) FreeMemory(aasworld.areas);
00267     aasworld.areas = optimized->areas;
00268     aasworld.numareas = optimized->numareas;
00269     //free optimize indexes
00270     FreeMemory(optimized->vertexoptimizeindex);
00271     FreeMemory(optimized->edgeoptimizeindex);
00272     FreeMemory(optimized->faceoptimizeindex);
00273 } //end of the function AAS_OptimizeStore
00274 //===========================================================================
00275 //
00276 // Parameter:               -
00277 // Returns:                 -
00278 // Changes Globals:     -
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     } //end for
00290     //reset the reachability face pointers
00291     for (i = 0; i < aasworld.reachabilitysize; i++)
00292     {
00293         //NOTE: for TRAVEL_ELEVATOR the facenum is the model number of
00294         //      the elevator
00295         if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR) continue;
00296         //NOTE: for TRAVEL_JUMPPAD the facenum is the Z velocity and the edgenum is the hor velocity
00297         if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == TRAVEL_JUMPPAD) continue;
00298         //NOTE: for TRAVEL_FUNCBOB the facenum and edgenum contain other coded information
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     } //end for
00308     //store the optimized AAS data into aasworld
00309     AAS_OptimizeStore(&optimized);
00310     //print some nice stuff :)
00311     botimport.Print(PRT_MESSAGE, "AAS data optimized.\n");
00312 } //end of the function AAS_Optimize

Generated on Thu Aug 25 12:37:09 2005 for Quake III Arena by  doxygen 1.3.9.1