mirror of
https://github.com/TTimo/doom3.gpl.git
synced 2026-03-20 08:59:42 +01:00
hello world
This commit is contained in:
404
neo/tools/compilers/dmap/dmap.cpp
Normal file
404
neo/tools/compilers/dmap/dmap.cpp
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 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 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.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../../../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "dmap.h"
|
||||
|
||||
dmapGlobals_t dmapGlobals;
|
||||
|
||||
/*
|
||||
============
|
||||
ProcessModel
|
||||
============
|
||||
*/
|
||||
bool ProcessModel( uEntity_t *e, bool floodFill ) {
|
||||
bspface_t *faces;
|
||||
|
||||
// build a bsp tree using all of the sides
|
||||
// of all of the structural brushes
|
||||
faces = MakeStructuralBspFaceList ( e->primitives );
|
||||
e->tree = FaceBSP( faces );
|
||||
|
||||
// create portals at every leaf intersection
|
||||
// to allow flood filling
|
||||
MakeTreePortals( e->tree );
|
||||
|
||||
// classify the leafs as opaque or areaportal
|
||||
FilterBrushesIntoTree( e );
|
||||
|
||||
// see if the bsp is completely enclosed
|
||||
if ( floodFill && !dmapGlobals.noFlood ) {
|
||||
if ( FloodEntities( e->tree ) ) {
|
||||
// set the outside leafs to opaque
|
||||
FillOutside( e );
|
||||
} else {
|
||||
common->Printf ( "**********************\n" );
|
||||
common->Warning( "******* leaked *******" );
|
||||
common->Printf ( "**********************\n" );
|
||||
LeakFile( e->tree );
|
||||
// bail out here. If someone really wants to
|
||||
// process a map that leaks, they should use
|
||||
// -noFlood
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get minimum convex hulls for each visible side
|
||||
// this must be done before creating area portals,
|
||||
// because the visible hull is used as the portal
|
||||
ClipSidesByTree( e );
|
||||
|
||||
// determine areas before clipping tris into the
|
||||
// tree, so tris will never cross area boundaries
|
||||
FloodAreas( e );
|
||||
|
||||
// we now have a BSP tree with solid and non-solid leafs marked with areas
|
||||
// all primitives will now be clipped into this, throwing away
|
||||
// fragments in the solid areas
|
||||
PutPrimitivesInAreas( e );
|
||||
|
||||
// now build shadow volumes for the lights and split
|
||||
// the optimize lists by the light beam trees
|
||||
// so there won't be unneeded overdraw in the static
|
||||
// case
|
||||
Prelight( e );
|
||||
|
||||
// optimizing is a superset of fixing tjunctions
|
||||
if ( !dmapGlobals.noOptimize ) {
|
||||
OptimizeEntity( e );
|
||||
} else if ( !dmapGlobals.noTJunc ) {
|
||||
FixEntityTjunctions( e );
|
||||
}
|
||||
|
||||
// now fix t junctions across areas
|
||||
FixGlobalTjunctions( e );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ProcessModels
|
||||
============
|
||||
*/
|
||||
bool ProcessModels( void ) {
|
||||
bool oldVerbose;
|
||||
uEntity_t *entity;
|
||||
|
||||
oldVerbose = dmapGlobals.verbose;
|
||||
|
||||
for ( dmapGlobals.entityNum = 0 ; dmapGlobals.entityNum < dmapGlobals.num_entities ; dmapGlobals.entityNum++ ) {
|
||||
|
||||
entity = &dmapGlobals.uEntities[dmapGlobals.entityNum];
|
||||
if ( !entity->primitives ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
common->Printf( "############### entity %i ###############\n", dmapGlobals.entityNum );
|
||||
|
||||
// if we leaked, stop without any more processing
|
||||
if ( !ProcessModel( entity, (bool)(dmapGlobals.entityNum == 0 ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we usually don't want to see output for submodels unless
|
||||
// something strange is going on
|
||||
if ( !dmapGlobals.verboseentities ) {
|
||||
dmapGlobals.verbose = false;
|
||||
}
|
||||
}
|
||||
|
||||
dmapGlobals.verbose = oldVerbose;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
DmapHelp
|
||||
============
|
||||
*/
|
||||
void DmapHelp( void ) {
|
||||
common->Printf(
|
||||
|
||||
"Usage: dmap [options] mapfile\n"
|
||||
"Options:\n"
|
||||
"noCurves = don't process curves\n"
|
||||
"noCM = don't create collision map\n"
|
||||
"noAAS = don't create AAS files\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ResetDmapGlobals
|
||||
============
|
||||
*/
|
||||
void ResetDmapGlobals( void ) {
|
||||
dmapGlobals.mapFileBase[0] = '\0';
|
||||
dmapGlobals.dmapFile = NULL;
|
||||
dmapGlobals.mapPlanes.Clear();
|
||||
dmapGlobals.num_entities = 0;
|
||||
dmapGlobals.uEntities = NULL;
|
||||
dmapGlobals.entityNum = 0;
|
||||
dmapGlobals.mapLights.Clear();
|
||||
dmapGlobals.verbose = false;
|
||||
dmapGlobals.glview = false;
|
||||
dmapGlobals.noOptimize = false;
|
||||
dmapGlobals.verboseentities = false;
|
||||
dmapGlobals.noCurves = false;
|
||||
dmapGlobals.fullCarve = false;
|
||||
dmapGlobals.noModelBrushes = false;
|
||||
dmapGlobals.noTJunc = false;
|
||||
dmapGlobals.nomerge = false;
|
||||
dmapGlobals.noFlood = false;
|
||||
dmapGlobals.noClipSides = false;
|
||||
dmapGlobals.noLightCarve = false;
|
||||
dmapGlobals.noShadow = false;
|
||||
dmapGlobals.shadowOptLevel = SO_NONE;
|
||||
dmapGlobals.drawBounds.Clear();
|
||||
dmapGlobals.drawflag = false;
|
||||
dmapGlobals.totalShadowTriangles = 0;
|
||||
dmapGlobals.totalShadowVerts = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Dmap
|
||||
============
|
||||
*/
|
||||
void Dmap( const idCmdArgs &args ) {
|
||||
int i;
|
||||
int start, end;
|
||||
char path[1024];
|
||||
idStr passedName;
|
||||
bool leaked = false;
|
||||
bool noCM = false;
|
||||
bool noAAS = false;
|
||||
|
||||
ResetDmapGlobals();
|
||||
|
||||
if ( args.Argc() < 2 ) {
|
||||
DmapHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
common->Printf("---- dmap ----\n");
|
||||
|
||||
dmapGlobals.fullCarve = true;
|
||||
dmapGlobals.shadowOptLevel = SO_MERGE_SURFACES; // create shadows by merging all surfaces, but no super optimization
|
||||
// dmapGlobals.shadowOptLevel = SO_CLIP_OCCLUDERS; // remove occluders that are completely covered
|
||||
// dmapGlobals.shadowOptLevel = SO_SIL_OPTIMIZE;
|
||||
// dmapGlobals.shadowOptLevel = SO_CULL_OCCLUDED;
|
||||
|
||||
dmapGlobals.noLightCarve = true;
|
||||
|
||||
for ( i = 1 ; i < args.Argc() ; i++ ) {
|
||||
const char *s;
|
||||
|
||||
s = args.Argv(i);
|
||||
if ( s[0] == '-' ) {
|
||||
s++;
|
||||
if ( s[0] == '\0' ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !idStr::Icmp( s,"glview" ) ) {
|
||||
dmapGlobals.glview = true;
|
||||
} else if ( !idStr::Icmp( s, "v" ) ) {
|
||||
common->Printf( "verbose = true\n" );
|
||||
dmapGlobals.verbose = true;
|
||||
} else if ( !idStr::Icmp( s, "draw" ) ) {
|
||||
common->Printf( "drawflag = true\n" );
|
||||
dmapGlobals.drawflag = true;
|
||||
} else if ( !idStr::Icmp( s, "noFlood" ) ) {
|
||||
common->Printf( "noFlood = true\n" );
|
||||
dmapGlobals.noFlood = true;
|
||||
} else if ( !idStr::Icmp( s, "noLightCarve" ) ) {
|
||||
common->Printf( "noLightCarve = true\n" );
|
||||
dmapGlobals.noLightCarve = true;
|
||||
} else if ( !idStr::Icmp( s, "lightCarve" ) ) {
|
||||
common->Printf( "noLightCarve = false\n" );
|
||||
dmapGlobals.noLightCarve = false;
|
||||
} else if ( !idStr::Icmp( s, "noOpt" ) ) {
|
||||
common->Printf( "noOptimize = true\n" );
|
||||
dmapGlobals.noOptimize = true;
|
||||
} else if ( !idStr::Icmp( s, "verboseentities" ) ) {
|
||||
common->Printf( "verboseentities = true\n");
|
||||
dmapGlobals.verboseentities = true;
|
||||
} else if ( !idStr::Icmp( s, "noCurves" ) ) {
|
||||
common->Printf( "noCurves = true\n");
|
||||
dmapGlobals.noCurves = true;
|
||||
} else if ( !idStr::Icmp( s, "noModels" ) ) {
|
||||
common->Printf( "noModels = true\n" );
|
||||
dmapGlobals.noModelBrushes = true;
|
||||
} else if ( !idStr::Icmp( s, "noClipSides" ) ) {
|
||||
common->Printf( "noClipSides = true\n" );
|
||||
dmapGlobals.noClipSides = true;
|
||||
} else if ( !idStr::Icmp( s, "noCarve" ) ) {
|
||||
common->Printf( "noCarve = true\n" );
|
||||
dmapGlobals.fullCarve = false;
|
||||
} else if ( !idStr::Icmp( s, "shadowOpt" ) ) {
|
||||
dmapGlobals.shadowOptLevel = (shadowOptLevel_t)atoi( args.Argv( i+1 ) );
|
||||
common->Printf( "shadowOpt = %i\n",dmapGlobals.shadowOptLevel );
|
||||
i += 1;
|
||||
} else if ( !idStr::Icmp( s, "noTjunc" ) ) {
|
||||
// triangle optimization won't work properly without tjunction fixing
|
||||
common->Printf ("noTJunc = true\n" );
|
||||
dmapGlobals.noTJunc = true;
|
||||
dmapGlobals.noOptimize = true;
|
||||
common->Printf ("forcing noOptimize = true\n" );
|
||||
} else if ( !idStr::Icmp( s, "noCM" ) ) {
|
||||
noCM = true;
|
||||
common->Printf( "noCM = true\n" );
|
||||
} else if ( !idStr::Icmp( s, "noAAS" ) ) {
|
||||
noAAS = true;
|
||||
common->Printf( "noAAS = true\n" );
|
||||
} else if ( !idStr::Icmp( s, "editorOutput" ) ) {
|
||||
#ifdef _WIN32
|
||||
com_outputMsg = true;
|
||||
#endif
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i >= args.Argc() ) {
|
||||
common->Error( "usage: dmap [options] mapfile" );
|
||||
}
|
||||
|
||||
passedName = args.Argv(i); // may have an extension
|
||||
passedName.BackSlashesToSlashes();
|
||||
if ( passedName.Icmpn( "maps/", 4 ) != 0 ) {
|
||||
passedName = "maps/" + passedName;
|
||||
}
|
||||
|
||||
idStr stripped = passedName;
|
||||
stripped.StripFileExtension();
|
||||
idStr::Copynz( dmapGlobals.mapFileBase, stripped, sizeof(dmapGlobals.mapFileBase) );
|
||||
|
||||
bool region = false;
|
||||
// if this isn't a regioned map, delete the last saved region map
|
||||
if ( passedName.Right( 4 ) != ".reg" ) {
|
||||
sprintf( path, "%s.reg", dmapGlobals.mapFileBase );
|
||||
fileSystem->RemoveFile( path );
|
||||
} else {
|
||||
region = true;
|
||||
}
|
||||
|
||||
|
||||
passedName = stripped;
|
||||
|
||||
// delete any old line leak files
|
||||
sprintf( path, "%s.lin", dmapGlobals.mapFileBase );
|
||||
fileSystem->RemoveFile( path );
|
||||
|
||||
|
||||
//
|
||||
// start from scratch
|
||||
//
|
||||
start = Sys_Milliseconds();
|
||||
|
||||
if ( !LoadDMapFile( passedName ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ProcessModels() ) {
|
||||
WriteOutputFile();
|
||||
} else {
|
||||
leaked = true;
|
||||
}
|
||||
|
||||
FreeDMapFile();
|
||||
|
||||
common->Printf( "%i total shadow triangles\n", dmapGlobals.totalShadowTriangles );
|
||||
common->Printf( "%i total shadow verts\n", dmapGlobals.totalShadowVerts );
|
||||
|
||||
end = Sys_Milliseconds();
|
||||
common->Printf( "-----------------------\n" );
|
||||
common->Printf( "%5.0f seconds for dmap\n", ( end - start ) * 0.001f );
|
||||
|
||||
if ( !leaked ) {
|
||||
|
||||
if ( !noCM ) {
|
||||
|
||||
// make sure the collision model manager is not used by the game
|
||||
cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" );
|
||||
|
||||
// create the collision map
|
||||
start = Sys_Milliseconds();
|
||||
|
||||
collisionModelManager->LoadMap( dmapGlobals.dmapFile );
|
||||
collisionModelManager->FreeMap();
|
||||
|
||||
end = Sys_Milliseconds();
|
||||
common->Printf( "-------------------------------------\n" );
|
||||
common->Printf( "%5.0f seconds to create collision map\n", ( end - start ) * 0.001f );
|
||||
}
|
||||
|
||||
if ( !noAAS && !region ) {
|
||||
// create AAS files
|
||||
RunAAS_f( args );
|
||||
}
|
||||
}
|
||||
|
||||
// free the common .map representation
|
||||
delete dmapGlobals.dmapFile;
|
||||
|
||||
// clear the map plane list
|
||||
dmapGlobals.mapPlanes.Clear();
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( com_outputMsg && com_hwndMsg != NULL ) {
|
||||
unsigned int msg = ::RegisterWindowMessage( DMAP_DONE );
|
||||
::PostMessage( com_hwndMsg, msg, 0, 0 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Dmap_f
|
||||
============
|
||||
*/
|
||||
void Dmap_f( const idCmdArgs &args ) {
|
||||
|
||||
common->ClearWarnings( "running dmap" );
|
||||
|
||||
// refresh the screen each time we print so it doesn't look
|
||||
// like it is hung
|
||||
common->SetRefreshOnPrint( true );
|
||||
Dmap( args );
|
||||
common->SetRefreshOnPrint( false );
|
||||
|
||||
common->PrintWarnings();
|
||||
}
|
||||
Reference in New Issue
Block a user