1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition 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.
- Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition 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 Doom 3 BFG Edition 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.
- ===========================================================================
- */
- #pragma hdrstop
- #include "../idlib/precompiled.h"
- #include "AASFile.h"
- #include "AASFile_local.h"
- /*
- ===============================================================================
- idReachability
- ===============================================================================
- */
- /*
- ================
- Reachability_Write
- ================
- */
- bool Reachability_Write( idFile *fp, idReachability *reach ) {
- fp->WriteFloatString( "\t\t%d %d (%f %f %f) (%f %f %f) %d %d",
- (int) reach->travelType, (int) reach->toAreaNum, reach->start.x, reach->start.y, reach->start.z,
- reach->end.x, reach->end.y, reach->end.z, reach->edgeNum, (int) reach->travelTime );
- return true;
- }
- /*
- ================
- Reachability_Read
- ================
- */
- bool Reachability_Read( idLexer &src, idReachability *reach ) {
- reach->travelType = src.ParseInt();
- reach->toAreaNum = src.ParseInt();
- src.Parse1DMatrix( 3, reach->start.ToFloatPtr() );
- src.Parse1DMatrix( 3, reach->end.ToFloatPtr() );
- reach->edgeNum = src.ParseInt();
- reach->travelTime = src.ParseInt();
- return true;
- }
- /*
- ================
- idReachability::CopyBase
- ================
- */
- void idReachability::CopyBase( idReachability &reach ) {
- travelType = reach.travelType;
- toAreaNum = reach.toAreaNum;
- start = reach.start;
- end = reach.end;
- edgeNum = reach.edgeNum;
- travelTime = reach.travelTime;
- }
- /*
- ===============================================================================
- idReachability_Special
- ===============================================================================
- */
- /*
- ================
- Reachability_Special_Write
- ================
- */
- bool Reachability_Special_Write( idFile *fp, idReachability_Special *reach ) {
- int i;
- const idKeyValue *keyValue;
- fp->WriteFloatString( "\n\t\t{\n" );
- for ( i = 0; i < reach->dict.GetNumKeyVals(); i++ ) {
- keyValue = reach->dict.GetKeyVal( i );
- fp->WriteFloatString( "\t\t\t\"%s\" \"%s\"\n", keyValue->GetKey().c_str(), keyValue->GetValue().c_str() );
- }
- fp->WriteFloatString( "\t\t}\n" );
- return true;
- }
- /*
- ================
- Reachability_Special_Read
- ================
- */
- bool Reachability_Special_Read( idLexer &src, idReachability_Special *reach ) {
- idToken key, value;
- src.ExpectTokenString( "{" );
- while( src.ReadToken( &key ) ) {
- if ( key == "}" ) {
- return true;
- }
- src.ExpectTokenType( TT_STRING, 0, &value );
- reach->dict.Set( key, value );
- }
- return false;
- }
- /*
- ===============================================================================
- idAASSettings
- ===============================================================================
- */
- /*
- ============
- idAASSettings::idAASSettings
- ============
- */
- idAASSettings::idAASSettings() {
- numBoundingBoxes = 1;
- boundingBoxes[0] = idBounds( idVec3( -16, -16, 0 ), idVec3( 16, 16, 72 ) );
- usePatches = false;
- writeBrushMap = false;
- playerFlood = false;
- noOptimize = false;
- allowSwimReachabilities = false;
- allowFlyReachabilities = false;
- fileExtension = "aas48";
- // physics settings
- gravity = idVec3( 0, 0, -1066 );
- gravityDir = gravity;
- gravityValue = gravityDir.Normalize();
- invGravityDir = -gravityDir;
- maxStepHeight = 14.0f;
- maxBarrierHeight = 32.0f;
- maxWaterJumpHeight = 20.0f;
- maxFallHeight = 64.0f;
- minFloorCos = 0.7f;
- // fixed travel times
- tt_barrierJump = 100;
- tt_startCrouching = 100;
- tt_waterJump = 100;
- tt_startWalkOffLedge = 100;
- }
- /*
- ============
- idAASSettings::ParseBool
- ============
- */
- bool idAASSettings::ParseBool( idLexer &src, bool &b ) {
- if ( !src.ExpectTokenString( "=" ) ) {
- return false;
- }
- b = src.ParseBool();
- return true;
- }
- /*
- ============
- idAASSettings::ParseInt
- ============
- */
- bool idAASSettings::ParseInt( idLexer &src, int &i ) {
- if ( !src.ExpectTokenString( "=" ) ) {
- return false;
- }
- i = src.ParseInt();
- return true;
- }
- /*
- ============
- idAASSettings::ParseFloat
- ============
- */
- bool idAASSettings::ParseFloat( idLexer &src, float &f ) {
- if ( !src.ExpectTokenString( "=" ) ) {
- return false;
- }
- f = src.ParseFloat();
- return true;
- }
- /*
- ============
- idAASSettings::ParseVector
- ============
- */
- bool idAASSettings::ParseVector( idLexer &src, idVec3 &vec ) {
- if ( !src.ExpectTokenString( "=" ) ) {
- return false;
- }
- return ( src.Parse1DMatrix( 3, vec.ToFloatPtr() ) != 0 );
- }
- /*
- ============
- idAASSettings::ParseBBoxes
- ============
- */
- bool idAASSettings::ParseBBoxes( idLexer &src ) {
- idToken token;
- idBounds bounds;
- numBoundingBoxes = 0;
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- while( src.ReadToken( &token ) ) {
- if ( token == "}" ) {
- return true;
- }
- src.UnreadToken( &token );
- src.Parse1DMatrix( 3, bounds[0].ToFloatPtr() );
- if ( !src.ExpectTokenString( "-" ) ) {
- return false;
- }
- src.Parse1DMatrix( 3, bounds[1].ToFloatPtr() );
- boundingBoxes[numBoundingBoxes++] = bounds;
- }
- return false;
- }
- /*
- ============
- idAASSettings::FromParser
- ============
- */
- bool idAASSettings::FromParser( idLexer &src ) {
- idToken token;
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- // parse the file
- while ( 1 ) {
- if ( !src.ReadToken( &token ) ) {
- break;
- }
- if ( token == "}" ) {
- break;
- }
- if ( token == "bboxes" ) {
- if ( !ParseBBoxes( src ) ) { return false; }
- }
- else if ( token == "usePatches" ) {
- if ( !ParseBool( src, usePatches ) ) { return false; }
- }
- else if ( token == "writeBrushMap" ) {
- if ( !ParseBool( src, writeBrushMap ) ) { return false; }
- }
- else if ( token == "playerFlood" ) {
- if ( !ParseBool( src, playerFlood ) ) { return false; }
- }
- else if ( token == "allowSwimReachabilities" ) {
- if ( !ParseBool( src, allowSwimReachabilities ) ) { return false; }
- }
- else if ( token == "allowFlyReachabilities" ) {
- if ( !ParseBool( src, allowFlyReachabilities ) ) { return false; }
- }
- else if ( token == "fileExtension" ) {
- src.ExpectTokenString( "=" );
- src.ExpectTokenType( TT_STRING, 0, &token );
- fileExtension = token;
- }
- else if ( token == "gravity" ) {
- ParseVector( src, gravity );
- gravityDir = gravity;
- gravityValue = gravityDir.Normalize();
- invGravityDir = -gravityDir;
- }
- else if ( token == "maxStepHeight" ) {
- if ( !ParseFloat( src, maxStepHeight ) ) { return false; }
- }
- else if ( token == "maxBarrierHeight" ) {
- if ( !ParseFloat( src, maxBarrierHeight ) ) { return false; }
- }
- else if ( token == "maxWaterJumpHeight" ) {
- if ( !ParseFloat( src, maxWaterJumpHeight ) ) { return false; }
- }
- else if ( token == "maxFallHeight" ) {
- if ( !ParseFloat( src, maxFallHeight ) ) { return false; }
- }
- else if ( token == "minFloorCos" ) {
- if ( !ParseFloat( src, minFloorCos ) ) { return false; }
- }
- else if ( token == "tt_barrierJump" ) {
- if ( !ParseInt( src, tt_barrierJump ) ) { return false; }
- }
- else if ( token == "tt_startCrouching" ) {
- if ( !ParseInt( src, tt_startCrouching ) ) { return false; }
- }
- else if ( token == "tt_waterJump" ) {
- if ( !ParseInt( src, tt_waterJump ) ) { return false; }
- }
- else if ( token == "tt_startWalkOffLedge" ) {
- if ( !ParseInt( src, tt_startWalkOffLedge ) ) { return false; }
- }
- else {
- src.Error( "invalid token '%s'", token.c_str() );
- }
- }
- if ( numBoundingBoxes <= 0 ) {
- src.Error( "no valid bounding box" );
- }
- return true;
- }
- /*
- ============
- idAASSettings::FromFile
- ============
- */
- bool idAASSettings::FromFile( const idStr &fileName ) {
- idLexer src( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT );
- idStr name;
- name = fileName;
- common->Printf( "loading %s\n", name.c_str() );
- if ( !src.LoadFile( name ) ) {
- common->Error( "WARNING: couldn't load %s\n", name.c_str() );
- return false;
- }
- if ( !src.ExpectTokenString( "settings" ) ) {
- common->Error( "%s is not a settings file", name.c_str() );
- return false;
- }
- if ( !FromParser( src ) ) {
- common->Error( "failed to parse %s", name.c_str() );
- return false;
- }
- return true;
- }
- /*
- ============
- idAASSettings::FromDict
- ============
- */
- bool idAASSettings::FromDict( const char *name, const idDict *dict ) {
- idBounds bounds;
- if ( !dict->GetVector( "mins", "0 0 0", bounds[ 0 ] ) ) {
- common->Error( "Missing 'mins' in entityDef '%s'", name );
- }
- if ( !dict->GetVector( "maxs", "0 0 0", bounds[ 1 ] ) ) {
- common->Error( "Missing 'maxs' in entityDef '%s'", name );
- }
- numBoundingBoxes = 1;
- boundingBoxes[0] = bounds;
- if ( !dict->GetBool( "usePatches", "0", usePatches ) ) {
- common->Error( "Missing 'usePatches' in entityDef '%s'", name );
- }
- if ( !dict->GetBool( "writeBrushMap", "0", writeBrushMap ) ) {
- common->Error( "Missing 'writeBrushMap' in entityDef '%s'", name );
- }
- if ( !dict->GetBool( "playerFlood", "0", playerFlood ) ) {
- common->Error( "Missing 'playerFlood' in entityDef '%s'", name );
- }
- if ( !dict->GetBool( "allowSwimReachabilities", "0", allowSwimReachabilities ) ) {
- common->Error( "Missing 'allowSwimReachabilities' in entityDef '%s'", name );
- }
- if ( !dict->GetBool( "allowFlyReachabilities", "0", allowFlyReachabilities ) ) {
- common->Error( "Missing 'allowFlyReachabilities' in entityDef '%s'", name );
- }
- if ( !dict->GetString( "fileExtension", "", fileExtension ) ) {
- common->Error( "Missing 'fileExtension' in entityDef '%s'", name );
- }
- if ( !dict->GetVector( "gravity", "0 0 -1066", gravity ) ) {
- common->Error( "Missing 'gravity' in entityDef '%s'", name );
- }
- gravityDir = gravity;
- gravityValue = gravityDir.Normalize();
- invGravityDir = -gravityDir;
- if ( !dict->GetFloat( "maxStepHeight", "0", maxStepHeight ) ) {
- common->Error( "Missing 'maxStepHeight' in entityDef '%s'", name );
- }
- if ( !dict->GetFloat( "maxBarrierHeight", "0", maxBarrierHeight ) ) {
- common->Error( "Missing 'maxBarrierHeight' in entityDef '%s'", name );
- }
- if ( !dict->GetFloat( "maxWaterJumpHeight", "0", maxWaterJumpHeight ) ) {
- common->Error( "Missing 'maxWaterJumpHeight' in entityDef '%s'", name );
- }
- if ( !dict->GetFloat( "maxFallHeight", "0", maxFallHeight ) ) {
- common->Error( "Missing 'maxFallHeight' in entityDef '%s'", name );
- }
- if ( !dict->GetFloat( "minFloorCos", "0", minFloorCos ) ) {
- common->Error( "Missing 'minFloorCos' in entityDef '%s'", name );
- }
- if ( !dict->GetInt( "tt_barrierJump", "0", tt_barrierJump ) ) {
- common->Error( "Missing 'tt_barrierJump' in entityDef '%s'", name );
- }
- if ( !dict->GetInt( "tt_startCrouching", "0", tt_startCrouching ) ) {
- common->Error( "Missing 'tt_startCrouching' in entityDef '%s'", name );
- }
- if ( !dict->GetInt( "tt_waterJump", "0", tt_waterJump ) ) {
- common->Error( "Missing 'tt_waterJump' in entityDef '%s'", name );
- }
- if ( !dict->GetInt( "tt_startWalkOffLedge", "0", tt_startWalkOffLedge ) ) {
- common->Error( "Missing 'tt_startWalkOffLedge' in entityDef '%s'", name );
- }
- return true;
- }
- /*
- ============
- idAASSettings::WriteToFile
- ============
- */
- bool idAASSettings::WriteToFile( idFile *fp ) const {
- int i;
- fp->WriteFloatString( "{\n" );
- fp->WriteFloatString( "\tbboxes\n\t{\n" );
- for ( i = 0; i < numBoundingBoxes; i++ ) {
- fp->WriteFloatString( "\t\t(%f %f %f)-(%f %f %f)\n", boundingBoxes[i][0].x, boundingBoxes[i][0].y,
- boundingBoxes[i][0].z, boundingBoxes[i][1].x, boundingBoxes[i][1].y, boundingBoxes[i][1].z );
- }
- fp->WriteFloatString( "\t}\n" );
- fp->WriteFloatString( "\tusePatches = %d\n", usePatches );
- fp->WriteFloatString( "\twriteBrushMap = %d\n", writeBrushMap );
- fp->WriteFloatString( "\tplayerFlood = %d\n", playerFlood );
- fp->WriteFloatString( "\tallowSwimReachabilities = %d\n", allowSwimReachabilities );
- fp->WriteFloatString( "\tallowFlyReachabilities = %d\n", allowFlyReachabilities );
- fp->WriteFloatString( "\tfileExtension = \"%s\"\n", fileExtension.c_str() );
- fp->WriteFloatString( "\tgravity = (%f %f %f)\n", gravity.x, gravity.y, gravity.z );
- fp->WriteFloatString( "\tmaxStepHeight = %f\n", maxStepHeight );
- fp->WriteFloatString( "\tmaxBarrierHeight = %f\n", maxBarrierHeight );
- fp->WriteFloatString( "\tmaxWaterJumpHeight = %f\n", maxWaterJumpHeight );
- fp->WriteFloatString( "\tmaxFallHeight = %f\n", maxFallHeight );
- fp->WriteFloatString( "\tminFloorCos = %f\n", minFloorCos );
- fp->WriteFloatString( "\ttt_barrierJump = %d\n", tt_barrierJump );
- fp->WriteFloatString( "\ttt_startCrouching = %d\n", tt_startCrouching );
- fp->WriteFloatString( "\ttt_waterJump = %d\n", tt_waterJump );
- fp->WriteFloatString( "\ttt_startWalkOffLedge = %d\n", tt_startWalkOffLedge );
- fp->WriteFloatString( "}\n" );
- return true;
- }
- /*
- ============
- idAASSettings::ValidForBounds
- ============
- */
- bool idAASSettings::ValidForBounds( const idBounds &bounds ) const {
- int i;
- for ( i = 0; i < 3; i++ ) {
- if ( bounds[0][i] < boundingBoxes[0][0][i] ) {
- return false;
- }
- if ( bounds[1][i] > boundingBoxes[0][1][i] ) {
- return false;
- }
- }
- return true;
- }
- /*
- ============
- idAASSettings::ValidEntity
- ============
- */
- bool idAASSettings::ValidEntity( const char *classname ) const {
- idStr use_aas;
- idVec3 size;
- idBounds bounds;
- if ( playerFlood ) {
- if ( !strcmp( classname, "info_player_start" ) || !strcmp( classname , "info_player_deathmatch" ) || !strcmp( classname, "func_teleporter" ) ) {
- return true;
- }
- }
- const idDeclEntityDef *decl = static_cast<const idDeclEntityDef *>( declManager->FindType( DECL_ENTITYDEF, classname, false ) );
- if ( ( decl != NULL ) && decl->dict.GetString( "use_aas", NULL, use_aas ) && !fileExtension.Icmp( use_aas ) ) {
- if ( decl->dict.GetVector( "mins", NULL, bounds[0] ) ) {
- decl->dict.GetVector( "maxs", NULL, bounds[1] );
- } else if ( decl->dict.GetVector( "size", NULL, size ) ) {
- bounds[ 0 ].Set( size.x * -0.5f, size.y * -0.5f, 0.0f );
- bounds[ 1 ].Set( size.x * 0.5f, size.y * 0.5f, size.z );
- }
- if ( !ValidForBounds( bounds ) ) {
- common->Error( "%s cannot use %s\n", classname, fileExtension.c_str() );
- }
- return true;
- }
- return false;
- }
- /*
- ===============================================================================
- idAASFileLocal
- ===============================================================================
- */
- #define AAS_LIST_GRANULARITY 1024
- #define AAS_INDEX_GRANULARITY 4096
- #define AAS_PLANE_GRANULARITY 4096
- #define AAS_VERTEX_GRANULARITY 4096
- #define AAS_EDGE_GRANULARITY 4096
- /*
- ================
- idAASFileLocal::idAASFileLocal
- ================
- */
- idAASFileLocal::idAASFileLocal() {
- planeList.SetGranularity( AAS_PLANE_GRANULARITY );
- vertices.SetGranularity( AAS_VERTEX_GRANULARITY );
- edges.SetGranularity( AAS_EDGE_GRANULARITY );
- edgeIndex.SetGranularity( AAS_INDEX_GRANULARITY );
- faces.SetGranularity( AAS_LIST_GRANULARITY );
- faceIndex.SetGranularity( AAS_INDEX_GRANULARITY );
- areas.SetGranularity( AAS_LIST_GRANULARITY );
- nodes.SetGranularity( AAS_LIST_GRANULARITY );
- portals.SetGranularity( AAS_LIST_GRANULARITY );
- portalIndex.SetGranularity( AAS_INDEX_GRANULARITY );
- clusters.SetGranularity( AAS_LIST_GRANULARITY );
- }
- /*
- ================
- idAASFileLocal::~idAASFileLocal
- ================
- */
- idAASFileLocal::~idAASFileLocal() {
- int i;
- idReachability *reach, *next;
- for ( i = 0; i < areas.Num(); i++ ) {
- for ( reach = areas[i].reach; reach; reach = next ) {
- next = reach->next;
- delete reach;
- }
- }
- }
- /*
- ================
- idAASFileLocal::Clear
- ================
- */
- void idAASFileLocal::Clear() {
- planeList.Clear();
- vertices.Clear();
- edges.Clear();
- edgeIndex.Clear();
- faces.Clear();
- faceIndex.Clear();
- areas.Clear();
- nodes.Clear();
- portals.Clear();
- portalIndex.Clear();
- clusters.Clear();
- }
- /*
- ================
- idAASFileLocal::Write
- ================
- */
- bool idAASFileLocal::Write( const idStr &fileName, unsigned int mapFileCRC ) {
- int i, num;
- idFile *aasFile;
- idReachability *reach;
- common->Printf( "[Write AAS]\n" );
- common->Printf( "writing %s\n", fileName.c_str() );
- name = fileName;
- crc = mapFileCRC;
- aasFile = fileSystem->OpenFileWrite( fileName, "fs_basepath" );
- if ( !aasFile ) {
- common->Error( "Error opening %s", fileName.c_str() );
- return false;
- }
- aasFile->WriteFloatString( "%s \"%s\"\n\n", AAS_FILEID, AAS_FILEVERSION );
- aasFile->WriteFloatString( "%u\n\n", mapFileCRC );
- // write out the settings
- aasFile->WriteFloatString( "settings\n" );
- settings.WriteToFile( aasFile );
- // write out planes
- aasFile->WriteFloatString( "planes %d {\n", planeList.Num() );
- for ( i = 0; i < planeList.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %f %f %f %f )\n", i,
- planeList[i].Normal().x, planeList[i].Normal().y, planeList[i].Normal().z, planeList[i].Dist() );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out vertices
- aasFile->WriteFloatString( "vertices %d {\n", vertices.Num() );
- for ( i = 0; i < vertices.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %f %f %f )\n", i, vertices[i].x, vertices[i].y, vertices[i].z );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out edges
- aasFile->WriteFloatString( "edges %d {\n", edges.Num() );
- for ( i = 0; i < edges.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d %d )\n", i, edges[i].vertexNum[0], edges[i].vertexNum[1] );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out edgeIndex
- aasFile->WriteFloatString( "edgeIndex %d {\n", edgeIndex.Num() );
- for ( i = 0; i < edgeIndex.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d )\n", i, edgeIndex[i] );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out faces
- aasFile->WriteFloatString( "faces %d {\n", faces.Num() );
- for ( i = 0; i < faces.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d %d %d %d %d %d )\n", i, faces[i].planeNum, faces[i].flags,
- faces[i].areas[0], faces[i].areas[1], faces[i].firstEdge, faces[i].numEdges );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out faceIndex
- aasFile->WriteFloatString( "faceIndex %d {\n", faceIndex.Num() );
- for ( i = 0; i < faceIndex.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d )\n", i, faceIndex[i] );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out areas
- aasFile->WriteFloatString( "areas %d {\n", areas.Num() );
- for ( i = 0; i < areas.Num(); i++ ) {
- for ( num = 0, reach = areas[i].reach; reach; reach = reach->next ) {
- num++;
- }
- aasFile->WriteFloatString( "\t%d ( %d %d %d %d %d %d ) %d {\n", i, areas[i].flags, areas[i].contents,
- areas[i].firstFace, areas[i].numFaces, areas[i].cluster, areas[i].clusterAreaNum, num );
- for ( reach = areas[i].reach; reach; reach = reach->next ) {
- Reachability_Write( aasFile, reach );
- switch( reach->travelType ) {
- case TFL_SPECIAL:
- Reachability_Special_Write( aasFile, static_cast<idReachability_Special *>(reach) );
- break;
- }
- aasFile->WriteFloatString( "\n" );
- }
- aasFile->WriteFloatString( "\t}\n" );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out nodes
- aasFile->WriteFloatString( "nodes %d {\n", nodes.Num() );
- for ( i = 0; i < nodes.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d %d %d )\n", i, nodes[i].planeNum, nodes[i].children[0], nodes[i].children[1] );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out portals
- aasFile->WriteFloatString( "portals %d {\n", portals.Num() );
- for ( i = 0; i < portals.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d %d %d %d %d )\n", i, portals[i].areaNum, portals[i].clusters[0],
- portals[i].clusters[1], portals[i].clusterAreaNum[0], portals[i].clusterAreaNum[1] );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out portalIndex
- aasFile->WriteFloatString( "portalIndex %d {\n", portalIndex.Num() );
- for ( i = 0; i < portalIndex.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d )\n", i, portalIndex[i] );
- }
- aasFile->WriteFloatString( "}\n" );
- // write out clusters
- aasFile->WriteFloatString( "clusters %d {\n", clusters.Num() );
- for ( i = 0; i < clusters.Num(); i++ ) {
- aasFile->WriteFloatString( "\t%d ( %d %d %d %d )\n", i, clusters[i].numAreas, clusters[i].numReachableAreas,
- clusters[i].firstPortal, clusters[i].numPortals );
- }
- aasFile->WriteFloatString( "}\n" );
- // close file
- fileSystem->CloseFile( aasFile );
- common->Printf( "done.\n" );
- return true;
- }
- /*
- ================
- idAASFileLocal::ParseIndex
- ================
- */
- bool idAASFileLocal::ParseIndex( idLexer &src, idList<aasIndex_t> &indexes ) {
- int numIndexes, i;
- aasIndex_t index;
- numIndexes = src.ParseInt();
- indexes.Resize( numIndexes );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numIndexes; i++ ) {
- src.ParseInt();
- src.ExpectTokenString( "(" );
- index = src.ParseInt();
- src.ExpectTokenString( ")" );
- indexes.Append( index );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::ParsePlanes
- ================
- */
- bool idAASFileLocal::ParsePlanes( idLexer &src ) {
- int numPlanes, i;
- idPlane plane;
- idVec4 vec;
- numPlanes = src.ParseInt();
- planeList.Resize( numPlanes );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numPlanes; i++ ) {
- src.ParseInt();
- if ( !src.Parse1DMatrix( 4, vec.ToFloatPtr() ) ) {
- return false;
- }
- plane.SetNormal( vec.ToVec3() );
- plane.SetDist( vec[3] );
- planeList.Append( plane );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::ParseVertices
- ================
- */
- bool idAASFileLocal::ParseVertices( idLexer &src ) {
- int numVertices, i;
- idVec3 vec;
- numVertices = src.ParseInt();
- vertices.Resize( numVertices );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numVertices; i++ ) {
- src.ParseInt();
- if ( !src.Parse1DMatrix( 3, vec.ToFloatPtr() ) ) {
- return false;
- }
- vertices.Append( vec );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::ParseEdges
- ================
- */
- bool idAASFileLocal::ParseEdges( idLexer &src ) {
- int numEdges, i;
- aasEdge_t edge;
- numEdges = src.ParseInt();
- edges.Resize( numEdges );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numEdges; i++ ) {
- src.ParseInt();
- src.ExpectTokenString( "(" );
- edge.vertexNum[0] = src.ParseInt();
- edge.vertexNum[1] = src.ParseInt();
- src.ExpectTokenString( ")" );
- edges.Append( edge );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::ParseFaces
- ================
- */
- bool idAASFileLocal::ParseFaces( idLexer &src ) {
- int numFaces, i;
- aasFace_t face;
- numFaces = src.ParseInt();
- faces.Resize( numFaces );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numFaces; i++ ) {
- src.ParseInt();
- src.ExpectTokenString( "(" );
- face.planeNum = src.ParseInt();
- face.flags = src.ParseInt();
- face.areas[0] = src.ParseInt();
- face.areas[1] = src.ParseInt();
- face.firstEdge = src.ParseInt();
- face.numEdges = src.ParseInt();
- src.ExpectTokenString( ")" );
- faces.Append( face );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::ParseReachabilities
- ================
- */
- bool idAASFileLocal::ParseReachabilities( idLexer &src, int areaNum ) {
- int num, j;
- aasArea_t *area;
- idReachability reach, *newReach;
- idReachability_Special *special;
- area = &areas[areaNum];
- num = src.ParseInt();
- src.ExpectTokenString( "{" );
- area->reach = NULL;
- area->rev_reach = NULL;
- area->travelFlags = AreaContentsTravelFlags( areaNum );
- for ( j = 0; j < num; j++ ) {
- Reachability_Read( src, &reach );
- switch( reach.travelType ) {
- case TFL_SPECIAL:
- newReach = special = new (TAG_AAS) idReachability_Special();
- Reachability_Special_Read( src, special );
- break;
- default:
- newReach = new (TAG_AAS) idReachability();
- break;
- }
- newReach->CopyBase( reach );
- newReach->fromAreaNum = areaNum;
- newReach->next = area->reach;
- area->reach = newReach;
- }
- src.ExpectTokenString( "}" );
- return true;
- }
- /*
- ================
- idAASFileLocal::LinkReversedReachability
- ================
- */
- void idAASFileLocal::LinkReversedReachability() {
- int i;
- idReachability *reach;
- // link reversed reachabilities
- for ( i = 0; i < areas.Num(); i++ ) {
- for ( reach = areas[i].reach; reach; reach = reach->next ) {
- reach->rev_next = areas[reach->toAreaNum].rev_reach;
- areas[reach->toAreaNum].rev_reach = reach;
- }
- }
- }
- /*
- ================
- idAASFileLocal::ParseAreas
- ================
- */
- bool idAASFileLocal::ParseAreas( idLexer &src ) {
- int numAreas, i;
- aasArea_t area;
- numAreas = src.ParseInt();
- areas.Resize( numAreas );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numAreas; i++ ) {
- src.ParseInt();
- src.ExpectTokenString( "(" );
- area.flags = src.ParseInt();
- area.contents = src.ParseInt();
- area.firstFace = src.ParseInt();
- area.numFaces = src.ParseInt();
- area.cluster = src.ParseInt();
- area.clusterAreaNum = src.ParseInt();
- src.ExpectTokenString( ")" );
- areas.Append( area );
- ParseReachabilities( src, i );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- LinkReversedReachability();
- return true;
- }
- /*
- ================
- idAASFileLocal::ParseNodes
- ================
- */
- bool idAASFileLocal::ParseNodes( idLexer &src ) {
- int numNodes, i;
- aasNode_t node;
- numNodes = src.ParseInt();
- nodes.Resize( numNodes );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numNodes; i++ ) {
- src.ParseInt();
- src.ExpectTokenString( "(" );
- node.planeNum = src.ParseInt();
- node.children[0] = src.ParseInt();
- node.children[1] = src.ParseInt();
- src.ExpectTokenString( ")" );
- nodes.Append( node );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::ParsePortals
- ================
- */
- bool idAASFileLocal::ParsePortals( idLexer &src ) {
- int numPortals, i;
- aasPortal_t portal;
- numPortals = src.ParseInt();
- portals.Resize( numPortals );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numPortals; i++ ) {
- src.ParseInt();
- src.ExpectTokenString( "(" );
- portal.areaNum = src.ParseInt();
- portal.clusters[0] = src.ParseInt();
- portal.clusters[1] = src.ParseInt();
- portal.clusterAreaNum[0] = src.ParseInt();
- portal.clusterAreaNum[1] = src.ParseInt();
- src.ExpectTokenString( ")" );
- portals.Append( portal );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::ParseClusters
- ================
- */
- bool idAASFileLocal::ParseClusters( idLexer &src ) {
- int numClusters, i;
- aasCluster_t cluster;
- numClusters = src.ParseInt();
- clusters.Resize( numClusters );
- if ( !src.ExpectTokenString( "{" ) ) {
- return false;
- }
- for ( i = 0; i < numClusters; i++ ) {
- src.ParseInt();
- src.ExpectTokenString( "(" );
- cluster.numAreas = src.ParseInt();
- cluster.numReachableAreas = src.ParseInt();
- cluster.firstPortal = src.ParseInt();
- cluster.numPortals = src.ParseInt();
- src.ExpectTokenString( ")" );
- clusters.Append( cluster );
- }
- if ( !src.ExpectTokenString( "}" ) ) {
- return false;
- }
- return true;
- }
- /*
- ================
- idAASFileLocal::FinishAreas
- ================
- */
- void idAASFileLocal::FinishAreas() {
- int i;
- for ( i = 0; i < areas.Num(); i++ ) {
- areas[i].center = AreaReachableGoal( i );
- areas[i].bounds = AreaBounds( i );
- }
- }
- /*
- ================
- idAASFileLocal::Load
- ================
- */
- bool idAASFileLocal::Load( const idStr &fileName, unsigned int mapFileCRC ) {
- idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES );
- idToken token;
- int depth;
- unsigned int c;
- name = fileName;
- crc = mapFileCRC;
- common->Printf( "[Load AAS]\n" );
- common->Printf( "loading %s\n", name.c_str() );
- if ( !src.LoadFile( name ) ) {
- return false;
- }
- if ( !src.ExpectTokenString( AAS_FILEID ) ) {
- common->Warning( "Not an AAS file: '%s'", name.c_str() );
- return false;
- }
- if ( !src.ReadToken( &token ) || token != AAS_FILEVERSION ) {
- common->Warning( "AAS file '%s' has version %s instead of %s", name.c_str(), token.c_str(), AAS_FILEVERSION );
- return false;
- }
- if ( !src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &token ) ) {
- common->Warning( "AAS file '%s' has no map file CRC", name.c_str() );
- return false;
- }
- c = token.GetUnsignedLongValue();
- if ( mapFileCRC && c != mapFileCRC ) {
- common->Warning( "AAS file '%s' is out of date", name.c_str() );
- return false;
- }
- // clear the file in memory
- Clear();
- // parse the file
- while ( 1 ) {
- if ( !src.ReadToken( &token ) ) {
- break;
- }
- if ( token == "settings" ) {
- if ( !settings.FromParser( src ) ) { return false; }
- }
- else if ( token == "planes" ) {
- if ( !ParsePlanes( src ) ) { return false; }
- }
- else if ( token == "vertices" ) {
- if ( !ParseVertices( src ) ) { return false; }
- }
- else if ( token == "edges" ) {
- if ( !ParseEdges( src ) ) { return false; }
- }
- else if ( token == "edgeIndex" ) {
- if ( !ParseIndex( src, edgeIndex ) ) { return false; }
- }
- else if ( token == "faces" ) {
- if ( !ParseFaces( src ) ) { return false; }
- }
- else if ( token == "faceIndex" ) {
- if ( !ParseIndex( src, faceIndex ) ) { return false; }
- }
- else if ( token == "areas" ) {
- if ( !ParseAreas( src ) ) { return false; }
- }
- else if ( token == "nodes" ) {
- if ( !ParseNodes( src ) ) { return false; }
- }
- else if ( token == "portals" ) {
- if ( !ParsePortals( src ) ) { return false; }
- }
- else if ( token == "portalIndex" ) {
- if ( !ParseIndex( src, portalIndex ) ) { return false; }
- }
- else if ( token == "clusters" ) {
- if ( !ParseClusters( src ) ) { return false; }
- }
- else {
- src.Error( "idAASFileLocal::Load: bad token \"%s\"", token.c_str() );
- return false;
- }
- }
- FinishAreas();
- depth = MaxTreeDepth();
- if ( depth > MAX_AAS_TREE_DEPTH ) {
- src.Error( "idAASFileLocal::Load: tree depth = %d", depth );
- }
- common->UpdateLevelLoadPacifier();
- common->Printf( "done.\n" );
- return true;
- }
- /*
- ================
- idAASFileLocal::MemorySize
- ================
- */
- int idAASFileLocal::MemorySize() const {
- int size;
- size = planeList.Size();
- size += vertices.Size();
- size += edges.Size();
- size += edgeIndex.Size();
- size += faces.Size();
- size += faceIndex.Size();
- size += areas.Size();
- size += nodes.Size();
- size += portals.Size();
- size += portalIndex.Size();
- size += clusters.Size();
- size += sizeof( idReachability_Walk ) * NumReachabilities();
- return size;
- }
- /*
- ================
- idAASFileLocal::PrintInfo
- ================
- */
- void idAASFileLocal::PrintInfo() const {
- common->Printf( "%6d KB file size\n", MemorySize() >> 10 );
- common->Printf( "%6d areas\n", areas.Num() );
- common->Printf( "%6d max tree depth\n", MaxTreeDepth() );
- ReportRoutingEfficiency();
- }
- /*
- ================
- idAASFileLocal::NumReachabilities
- ================
- */
- int idAASFileLocal::NumReachabilities() const {
- int i, num;
- idReachability *reach;
- num = 0;
- for ( i = 0; i < areas.Num(); i++ ) {
- for ( reach = areas[i].reach; reach; reach = reach->next ) {
- num++;
- }
- }
- return num;
- }
- /*
- ================
- idAASFileLocal::ReportRoutingEfficiency
- ================
- */
- void idAASFileLocal::ReportRoutingEfficiency() const {
- int numReachableAreas, total, i, n;
- numReachableAreas = 0;
- total = 0;
- for ( i = 0; i < clusters.Num(); i++ ) {
- n = clusters[i].numReachableAreas;
- numReachableAreas += n;
- total += n * n;
- }
- total += numReachableAreas * portals.Num();
- common->Printf( "%6d reachable areas\n", numReachableAreas );
- common->Printf( "%6d reachabilities\n", NumReachabilities() );
- common->Printf( "%6d KB max routing cache\n", ( total * 3 ) >> 10 );
- }
- /*
- ================
- idAASFileLocal::DeleteReachabilities
- ================
- */
- void idAASFileLocal::DeleteReachabilities() {
- int i;
- idReachability *reach, *nextReach;
- for ( i = 0; i < areas.Num(); i++ ) {
- for ( reach = areas[i].reach; reach; reach = nextReach ) {
- nextReach = reach->next;
- delete reach;
- }
- areas[i].reach = NULL;
- areas[i].rev_reach = NULL;
- }
- }
- /*
- ================
- idAASFileLocal::DeleteClusters
- ================
- */
- void idAASFileLocal::DeleteClusters() {
- aasPortal_t portal;
- aasCluster_t cluster;
- portals.Clear();
- portalIndex.Clear();
- clusters.Clear();
- // first portal is a dummy
- memset( &portal, 0, sizeof( portal ) );
- portals.Append( portal );
- // first cluster is a dummy
- memset( &cluster, 0, sizeof( cluster ) );
- clusters.Append( cluster );
- }
|