/* =========================================================================== Return to Castle Wolfenstein single player GPL Source Code Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company. This file is part of the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”). RTCW SP Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. RTCW SP Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with RTCW SP Source Code. If not, see . In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ /***************************************************************************** * name: be_aas_optimize.c * * desc: decreases the .aas file size after the reachabilities have * been calculated, just dumps all the faces, edges and vertexes * * *****************************************************************************/ #include "../game/q_shared.h" #include "l_libvar.h" //#include "l_utils.h" #include "l_memory.h" #include "l_script.h" #include "l_precomp.h" #include "l_struct.h" #include "aasfile.h" #include "../game/botlib.h" #include "../game/be_aas.h" #include "be_aas_funcs.h" #include "be_interface.h" #include "be_aas_def.h" typedef struct optimized_s { //vertixes int numvertexes; aas_vertex_t *vertexes; //edges int numedges; aas_edge_t *edges; //edge index int edgeindexsize; aas_edgeindex_t *edgeindex; //faces int numfaces; aas_face_t *faces; //face index int faceindexsize; aas_faceindex_t *faceindex; //convex areas int numareas; aas_area_t *areas; // int *vertexoptimizeindex; int *edgeoptimizeindex; int *faceoptimizeindex; } optimized_t; //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int AAS_KeepEdge( aas_edge_t *edge ) { return 1; } //end of the function AAS_KeepFace //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int AAS_OptimizeEdge( optimized_t *optimized, int edgenum ) { int i, optedgenum; aas_edge_t *edge, *optedge; edge = &( *aasworld ).edges[abs( edgenum )]; if ( !AAS_KeepEdge( edge ) ) { return 0; } optedgenum = optimized->edgeoptimizeindex[abs( edgenum )]; if ( optedgenum ) { //keep the edge reversed sign if ( edgenum > 0 ) { return optedgenum; } else { return -optedgenum;} } //end if optedge = &optimized->edges[optimized->numedges]; for ( i = 0; i < 2; i++ ) { if ( optimized->vertexoptimizeindex[edge->v[i]] ) { optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]]; } //end if else { VectorCopy( ( *aasworld ).vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes] ); optedge->v[i] = optimized->numvertexes; optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes; optimized->numvertexes++; } //end else } //end for optimized->edgeoptimizeindex[abs( edgenum )] = optimized->numedges; optedgenum = optimized->numedges; optimized->numedges++; //keep the edge reversed sign if ( edgenum > 0 ) { return optedgenum; } else { return -optedgenum;} } //end of the function AAS_OptimizeEdge //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int AAS_KeepFace( aas_face_t *face ) { if ( !( face->faceflags & FACE_LADDER ) ) { return 0; } else { return 1;} } //end of the function AAS_KeepFace //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int AAS_OptimizeFace( optimized_t *optimized, int facenum ) { int i, edgenum, optedgenum, optfacenum; aas_face_t *face, *optface; face = &( *aasworld ).faces[abs( facenum )]; if ( !AAS_KeepFace( face ) ) { return 0; } optfacenum = optimized->faceoptimizeindex[abs( facenum )]; if ( optfacenum ) { //keep the face side sign if ( facenum > 0 ) { return optfacenum; } else { return -optfacenum;} } //end if optface = &optimized->faces[optimized->numfaces]; memcpy( optface, face, sizeof( aas_face_t ) ); optface->numedges = 0; optface->firstedge = optimized->edgeindexsize; for ( i = 0; i < face->numedges; i++ ) { edgenum = ( *aasworld ).edgeindex[face->firstedge + i]; optedgenum = AAS_OptimizeEdge( optimized, edgenum ); if ( optedgenum ) { optimized->edgeindex[optface->firstedge + optface->numedges] = optedgenum; optface->numedges++; optimized->edgeindexsize++; } //end if } //end for optimized->faceoptimizeindex[abs( facenum )] = optimized->numfaces; optfacenum = optimized->numfaces; optimized->numfaces++; //keep the face side sign if ( facenum > 0 ) { return optfacenum; } else { return -optfacenum;} } //end of the function AAS_OptimizeFace //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_OptimizeArea( optimized_t *optimized, int areanum ) { int i, facenum, optfacenum; aas_area_t *area, *optarea; area = &( *aasworld ).areas[areanum]; optarea = &optimized->areas[areanum]; memcpy( optarea, area, sizeof( aas_area_t ) ); optarea->numfaces = 0; optarea->firstface = optimized->faceindexsize; for ( i = 0; i < area->numfaces; i++ ) { facenum = ( *aasworld ).faceindex[area->firstface + i]; optfacenum = AAS_OptimizeFace( optimized, facenum ); if ( optfacenum ) { optimized->faceindex[optarea->firstface + optarea->numfaces] = optfacenum; optarea->numfaces++; optimized->faceindexsize++; } //end if } //end for } //end of the function AAS_OptimizeArea //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_OptimizeAlloc( optimized_t *optimized ) { optimized->vertexes = (aas_vertex_t *) GetClearedMemory( ( *aasworld ).numvertexes * sizeof( aas_vertex_t ) ); optimized->numvertexes = 0; optimized->edges = (aas_edge_t *) GetClearedMemory( ( *aasworld ).numedges * sizeof( aas_edge_t ) ); optimized->numedges = 1; //edge zero is a dummy optimized->edgeindex = (aas_edgeindex_t *) GetClearedMemory( ( *aasworld ).edgeindexsize * sizeof( aas_edgeindex_t ) ); optimized->edgeindexsize = 0; optimized->faces = (aas_face_t *) GetClearedMemory( ( *aasworld ).numfaces * sizeof( aas_face_t ) ); optimized->numfaces = 1; //face zero is a dummy optimized->faceindex = (aas_faceindex_t *) GetClearedMemory( ( *aasworld ).faceindexsize * sizeof( aas_faceindex_t ) ); optimized->faceindexsize = 0; optimized->areas = (aas_area_t *) GetClearedMemory( ( *aasworld ).numareas * sizeof( aas_area_t ) ); optimized->numareas = ( *aasworld ).numareas; // optimized->vertexoptimizeindex = (int *) GetClearedMemory( ( *aasworld ).numvertexes * sizeof( int ) ); optimized->edgeoptimizeindex = (int *) GetClearedMemory( ( *aasworld ).numedges * sizeof( int ) ); optimized->faceoptimizeindex = (int *) GetClearedMemory( ( *aasworld ).numfaces * sizeof( int ) ); } //end of the function AAS_OptimizeAlloc //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_OptimizeStore( optimized_t *optimized ) { //store the optimized vertexes if ( ( *aasworld ).vertexes ) { FreeMemory( ( *aasworld ).vertexes ); } ( *aasworld ).vertexes = optimized->vertexes; ( *aasworld ).numvertexes = optimized->numvertexes; //store the optimized edges if ( ( *aasworld ).edges ) { FreeMemory( ( *aasworld ).edges ); } ( *aasworld ).edges = optimized->edges; ( *aasworld ).numedges = optimized->numedges; //store the optimized edge index if ( ( *aasworld ).edgeindex ) { FreeMemory( ( *aasworld ).edgeindex ); } ( *aasworld ).edgeindex = optimized->edgeindex; ( *aasworld ).edgeindexsize = optimized->edgeindexsize; //store the optimized faces if ( ( *aasworld ).faces ) { FreeMemory( ( *aasworld ).faces ); } ( *aasworld ).faces = optimized->faces; ( *aasworld ).numfaces = optimized->numfaces; //store the optimized face index if ( ( *aasworld ).faceindex ) { FreeMemory( ( *aasworld ).faceindex ); } ( *aasworld ).faceindex = optimized->faceindex; ( *aasworld ).faceindexsize = optimized->faceindexsize; //store the optimized areas if ( ( *aasworld ).areas ) { FreeMemory( ( *aasworld ).areas ); } ( *aasworld ).areas = optimized->areas; ( *aasworld ).numareas = optimized->numareas; //free optimize indexes FreeMemory( optimized->vertexoptimizeindex ); FreeMemory( optimized->edgeoptimizeindex ); FreeMemory( optimized->faceoptimizeindex ); } //end of the function AAS_OptimizeStore //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_Optimize( void ) { int i, sign; optimized_t optimized; AAS_OptimizeAlloc( &optimized ); for ( i = 1; i < ( *aasworld ).numareas; i++ ) { AAS_OptimizeArea( &optimized, i ); } //end for //reset the reachability face pointers for ( i = 0; i < ( *aasworld ).reachabilitysize; i++ ) { //NOTE: for TRAVEL_ELEVATOR the facenum is the model number of // the elevator if ( ( *aasworld ).reachability[i].traveltype == TRAVEL_ELEVATOR ) { continue; } //NOTE: for TRAVEL_JUMPPAD the facenum is the Z velocity and the edgenum is the hor velocity if ( ( *aasworld ).reachability[i].traveltype == TRAVEL_JUMPPAD ) { continue; } //NOTE: for TRAVEL_FUNCBOB the facenum and edgenum contain other coded information if ( ( *aasworld ).reachability[i].traveltype == TRAVEL_FUNCBOB ) { continue; } // sign = ( *aasworld ).reachability[i].facenum; ( *aasworld ).reachability[i].facenum = optimized.faceoptimizeindex[abs( ( *aasworld ).reachability[i].facenum )]; if ( sign < 0 ) { ( *aasworld ).reachability[i].facenum = -( *aasworld ).reachability[i].facenum; } sign = ( *aasworld ).reachability[i].edgenum; ( *aasworld ).reachability[i].edgenum = optimized.edgeoptimizeindex[abs( ( *aasworld ).reachability[i].edgenum )]; if ( sign < 0 ) { ( *aasworld ).reachability[i].edgenum = -( *aasworld ).reachability[i].edgenum; } } //end for //store the optimized AAS data into (*aasworld) AAS_OptimizeStore( &optimized ); //print some nice stuff :) botimport.Print( PRT_MESSAGE, "AAS data optimized.\n" ); } //end of the function AAS_Optimize