From 952c5c128f9efaea89d41d882c4ea3ade7df4591 Mon Sep 17 00:00:00 2001 From: zakk Date: Fri, 26 Aug 2005 04:48:05 +0000 Subject: Itsa me, quake3io! git-svn-id: svn://svn.icculus.org/quake3/trunk@2 edf5b092-35ff-0310-97b2-ce42778d08ea --- q3map/writebsp.c | 418 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100755 q3map/writebsp.c (limited to 'q3map/writebsp.c') diff --git a/q3map/writebsp.c b/q3map/writebsp.c new file mode 100755 index 0000000..7a56d88 --- /dev/null +++ b/q3map/writebsp.c @@ -0,0 +1,418 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena 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 2 of the License, +or (at your option) any later version. + +Quake III Arena 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 Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +#include "qbsp.h" + +/* +============ +EmitShader +============ +*/ +int EmitShader( const char *shader ) { + int i; + shaderInfo_t *si; + + if ( !shader ) { + shader = "noshader"; + } + + for ( i = 0 ; i < numShaders ; i++ ) { + if ( !Q_stricmp( shader, dshaders[i].shader ) ) { + return i; + } + } + + if ( i == MAX_MAP_SHADERS ) { + Error( "MAX_MAP_SHADERS" ); + } + numShaders++; + strcpy( dshaders[i].shader, shader ); + + si = ShaderInfoForShader( shader ); + dshaders[i].surfaceFlags = si->surfaceFlags; + dshaders[i].contentFlags = si->contents; + + return i; +} + + +/* +============ +EmitPlanes + +There is no oportunity to discard planes, because all of the original +brushes will be saved in the map. +============ +*/ +void EmitPlanes (void) +{ + int i; + dplane_t *dp; + plane_t *mp; + + mp = mapplanes; + for (i=0 ; inormal, dp->normal); + dp->dist = mp->dist; + numplanes++; + } +} + + + +/* +================== +EmitLeaf +================== +*/ +void EmitLeaf (node_t *node) +{ + dleaf_t *leaf_p; + bspbrush_t *b; + drawSurfRef_t *dsr; + + // emit a leaf + if (numleafs >= MAX_MAP_LEAFS) + Error ("MAX_MAP_LEAFS"); + + leaf_p = &dleafs[numleafs]; + numleafs++; + + leaf_p->cluster = node->cluster; + leaf_p->area = node->area; + + // + // write bounding box info + // + VectorCopy (node->mins, leaf_p->mins); + VectorCopy (node->maxs, leaf_p->maxs); + + // + // write the leafbrushes + // + leaf_p->firstLeafBrush = numleafbrushes; + for ( b = node->brushlist ; b ; b = b->next ) { + if ( numleafbrushes >= MAX_MAP_LEAFBRUSHES ) { + Error( "MAX_MAP_LEAFBRUSHES" ); + } + dleafbrushes[numleafbrushes] = b->original->outputNumber; + numleafbrushes++; + } + leaf_p->numLeafBrushes = numleafbrushes - leaf_p->firstLeafBrush; + + // + // write the surfaces visible in this leaf + // + if ( node->opaque ) { + return; // no leaffaces in solids + } + + // add the drawSurfRef_t drawsurfs + leaf_p->firstLeafSurface = numleafsurfaces; + for ( dsr = node->drawSurfReferences ; dsr ; dsr = dsr->nextRef ) { + if ( numleafsurfaces >= MAX_MAP_LEAFFACES) + Error ("MAX_MAP_LEAFFACES"); + dleafsurfaces[numleafsurfaces] = dsr->outputNumber; + numleafsurfaces++; + } + + + leaf_p->numLeafSurfaces = numleafsurfaces - leaf_p->firstLeafSurface; +} + + +/* +============ +EmitDrawNode_r +============ +*/ +int EmitDrawNode_r (node_t *node) +{ + dnode_t *n; + int i; + + if (node->planenum == PLANENUM_LEAF) + { + EmitLeaf (node); + return -numleafs; + } + + // emit a node + if (numnodes == MAX_MAP_NODES) + Error ("MAX_MAP_NODES"); + n = &dnodes[numnodes]; + numnodes++; + + VectorCopy (node->mins, n->mins); + VectorCopy (node->maxs, n->maxs); + + if (node->planenum & 1) + Error ("WriteDrawNodes_r: odd planenum"); + n->planeNum = node->planenum; + + // + // recursively output the other nodes + // + for (i=0 ; i<2 ; i++) + { + if (node->children[i]->planenum == PLANENUM_LEAF) + { + n->children[i] = -(numleafs + 1); + EmitLeaf (node->children[i]); + } + else + { + n->children[i] = numnodes; + EmitDrawNode_r (node->children[i]); + } + } + + return n - dnodes; +} + +//========================================================= + + + +/* +============ +SetModelNumbers +============ +*/ +void SetModelNumbers (void) +{ + int i; + int models; + char value[10]; + + models = 1; + for ( i=1 ; inext ) { + if ( numbrushes == MAX_MAP_BRUSHES ) { + Error( "MAX_MAP_BRUSHES" ); + } + b->outputNumber = numbrushes; + db = &dbrushes[numbrushes]; + numbrushes++; + + db->shaderNum = EmitShader( b->contentShader->shader ); + db->firstSide = numbrushsides; + + // don't emit any generated backSide sides + db->numSides = 0; + for ( j=0 ; jnumsides ; j++ ) { + if ( b->sides[j].backSide ) { + continue; + } + if ( numbrushsides == MAX_MAP_BRUSHSIDES ) { + Error( "MAX_MAP_BRUSHSIDES "); + } + cp = &dbrushsides[numbrushsides]; + db->numSides++; + numbrushsides++; + cp->planeNum = b->sides[j].planenum; + cp->shaderNum = EmitShader( b->sides[j].shaderInfo->shader ); + } + } + +} + + +/* +================== +BeginModel +================== +*/ +void BeginModel( void ) { + dmodel_t *mod; + bspbrush_t *b; + entity_t *e; + vec3_t mins, maxs; + parseMesh_t *p; + int i; + + if ( nummodels == MAX_MAP_MODELS ) { + Error( "MAX_MAP_MODELS" ); + } + mod = &dmodels[nummodels]; + + // + // bound the brushes + // + e = &entities[entity_num]; + + ClearBounds (mins, maxs); + for ( b = e->brushes ; b ; b = b->next ) { + if ( !b->numsides ) { + continue; // not a real brush (origin brush, etc) + } + AddPointToBounds (b->mins, mins, maxs); + AddPointToBounds (b->maxs, mins, maxs); + } + + for ( p = e->patches ; p ; p = p->next ) { + for ( i = 0 ; i < p->mesh.width * p->mesh.height ; i++ ) { + AddPointToBounds( p->mesh.verts[i].xyz, mins, maxs ); + } + } + + VectorCopy (mins, mod->mins); + VectorCopy (maxs, mod->maxs); + + mod->firstSurface = numDrawSurfaces; + mod->firstBrush = numbrushes; + + EmitBrushes( e->brushes ); +} + + + + +/* +================== +EndModel +================== +*/ +void EndModel( node_t *headnode ) { + dmodel_t *mod; + + qprintf ("--- EndModel ---\n"); + + mod = &dmodels[nummodels]; + EmitDrawNode_r (headnode); + mod->numSurfaces = numDrawSurfaces - mod->firstSurface; + mod->numBrushes = numbrushes - mod->firstBrush; + + nummodels++; +} + -- cgit v1.2.3