void EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes ){ int j; brush_t *b; bspBrush_t *db; bspBrushSide_t *cp; /* set initial brush */ if ( firstBrush != NULL ) { *firstBrush = numBSPBrushes; } if ( numBrushes != NULL ) { *numBrushes = 0; } /* walk list of brushes */ for ( b = brushes; b != NULL; b = b->next ) { /* check limits */ AUTOEXPAND_BY_REALLOC_BSP( Brushes, 1024 ); /* get bsp brush */ b->outputNum = numBSPBrushes; db = &bspBrushes[ numBSPBrushes ]; numBSPBrushes++; if ( numBrushes != NULL ) { ( *numBrushes )++; } db->shaderNum = EmitShader( b->contentShader->shader, &b->contentShader->contentFlags, &b->contentShader->surfaceFlags ); db->firstSide = numBSPBrushSides; /* walk sides */ db->numSides = 0; for ( j = 0; j < b->numsides; j++ ) { /* set output number to bogus initially */ b->sides[ j ].outputNum = -1; /* check count */ AUTOEXPAND_BY_REALLOC_BSP( BrushSides, 1024 ); /* emit side */ b->sides[ j ].outputNum = numBSPBrushSides; cp = &bspBrushSides[ numBSPBrushSides ]; db->numSides++; numBSPBrushSides++; cp->planeNum = b->sides[ j ].planenum; /* emit shader */ if ( b->sides[ j ].shaderInfo ) { cp->shaderNum = EmitShader( b->sides[ j ].shaderInfo->shader, &b->sides[ j ].shaderInfo->contentFlags, &b->sides[ j ].shaderInfo->surfaceFlags ); } else{ cp->shaderNum = EmitShader( NULL, NULL, NULL ); } } } }
void EmitLeaf(node_t * node) { bspLeaf_t *leaf_p; brush_t *b; drawSurfRef_t *dsr; /* check limits */ if(numBSPLeafs >= MAX_MAP_LEAFS) Error("MAX_MAP_LEAFS"); leaf_p = &bspLeafs[numBSPLeafs]; numBSPLeafs++; leaf_p->cluster = node->cluster; leaf_p->area = node->area; /* emit bounding box */ VectorCopy(node->mins, leaf_p->mins); VectorCopy(node->maxs, leaf_p->maxs); /* emit leaf brushes */ leaf_p->firstBSPLeafBrush = numBSPLeafBrushes; for(b = node->brushlist; b; b = b->next) { /* something is corrupting brushes */ if((size_t) b < 256) { Sys_Printf("WARNING: Node brush list corrupted (0x%p)\n", b); break; } //% if( b->guard != 0xDEADBEEF ) //% Sys_Printf( "Brush %6d: 0x%08X Guard: 0x%08X Next: 0x%08X Original: 0x%08X Sides: %d\n", b->brushNum, b, b, b->next, b->original, b->numsides ); AUTOEXPAND_BY_REALLOC_BSP(LeafBrushes, 1024); bspLeafBrushes[numBSPLeafBrushes] = b->original->outputNum; numBSPLeafBrushes++; } leaf_p->numBSPLeafBrushes = numBSPLeafBrushes - leaf_p->firstBSPLeafBrush; /* emit leaf surfaces */ if(node->opaque) return; /* add the drawSurfRef_t drawsurfs */ leaf_p->firstBSPLeafSurface = numBSPLeafSurfaces; for(dsr = node->drawSurfReferences; dsr; dsr = dsr->nextRef) { AUTOEXPAND_BY_REALLOC_BSP(LeafSurfaces, 1024); bspLeafSurfaces[numBSPLeafSurfaces] = dsr->outputNum; numBSPLeafSurfaces++; } leaf_p->numBSPLeafSurfaces = numBSPLeafSurfaces - leaf_p->firstBSPLeafSurface; }
int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags ){ int i; shaderInfo_t *si; /* handle special cases */ if ( shader == NULL ) { shader = "noshader"; } /* try to find an existing shader */ for ( i = 0; i < numBSPShaders; i++ ) { /* ydnar: handle custom surface/content flags */ if ( surfaceFlags != NULL && bspShaders[ i ].surfaceFlags != *surfaceFlags ) { continue; } if ( contentFlags != NULL && bspShaders[ i ].contentFlags != *contentFlags ) { continue; } /* compare name */ if ( !Q_stricmp( shader, bspShaders[ i ].shader ) ) { return i; } } // i == numBSPShaders /* get shaderinfo */ si = ShaderInfoForShader( shader ); /* emit a new shader */ AUTOEXPAND_BY_REALLOC_BSP( Shaders, 1024 ); numBSPShaders++; strcpy( bspShaders[ i ].shader, shader ); bspShaders[ i ].surfaceFlags = si->surfaceFlags; bspShaders[ i ].contentFlags = si->contentFlags; /* handle custom content/surface flags */ if ( surfaceFlags != NULL ) { bspShaders[ i ].surfaceFlags = *surfaceFlags; } if ( contentFlags != NULL ) { bspShaders[ i ].contentFlags = *contentFlags; } /* recursively emit any damage shaders */ if ( si->damageShader != NULL && si->damageShader[ 0 ] != '\0' ) { Sys_FPrintf( SYS_VRB, "Shader %s has damage shader %s\n", si->shader, si->damageShader ); EmitShader( si->damageShader, NULL, NULL ); } /* return it */ return i; }
void BeginModel(void) { bspModel_t *mod; /* test limits */ AUTOEXPAND_BY_REALLOC_BSP(Models, 256); /* get model and entity */ mod = &bspModels[numBSPModels]; /* set firsts */ mod->firstBSPSurface = numBSPDrawSurfaces; mod->firstBSPBrush = numBSPBrushes; }
int EmitDrawNode_r(node_t * node) { bspNode_t *n; int i, n0; /* check for leafnode */ if(node->planenum == PLANENUM_LEAF) { EmitLeaf(node); return -numBSPLeafs; } /* emit a node */ AUTOEXPAND_BY_REALLOC_BSP(Nodes, 1024); n0 = numBSPNodes; n = &bspNodes[n0]; numBSPNodes++; 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] = -(numBSPLeafs + 1); EmitLeaf(node->children[i]); } else { n->children[i] = numBSPNodes; EmitDrawNode_r(node->children[i]); // n may have become invalid here, so... n = &bspNodes[n0]; } } return n - bspNodes; }
void EmitPlanes( void ){ int i; bspPlane_t *bp; plane_t *mp; /* walk plane list */ mp = mapplanes; for ( i = 0; i < nummapplanes; i++, mp++ ) { AUTOEXPAND_BY_REALLOC_BSP( Planes, 1024 ); bp = &bspPlanes[ numBSPPlanes ]; VectorCopy( mp->normal, bp->normal ); bp->dist = mp->dist; numBSPPlanes++; } /* emit some statistics */ Sys_FPrintf( SYS_VRB, "%9d BSP planes\n", numBSPPlanes ); }
void BeginBSPFile( void ){ /* these values may actually be initialized if the file existed when loaded, so clear them explicitly */ numBSPModels = 0; numBSPNodes = 0; numBSPBrushSides = 0; numBSPLeafSurfaces = 0; numBSPLeafBrushes = 0; /* leave leaf 0 as an error, because leafs are referenced as negative number nodes */ numBSPLeafs = 1; /* ydnar: gs mods: set the first 6 drawindexes to 0 1 2 2 1 3 for triangles and quads */ numBSPDrawIndexes = 6; AUTOEXPAND_BY_REALLOC_BSP( DrawIndexes, 1024 ); bspDrawIndexes[ 0 ] = 0; bspDrawIndexes[ 1 ] = 1; bspDrawIndexes[ 2 ] = 2; bspDrawIndexes[ 3 ] = 0; bspDrawIndexes[ 4 ] = 2; bspDrawIndexes[ 5 ] = 3; }
void BeginModel( void ){ bspModel_t *mod; brush_t *b; entity_t *e; vec3_t mins, maxs; vec3_t lgMins, lgMaxs; /* ydnar: lightgrid mins/maxs */ parseMesh_t *p; int i; /* test limits */ AUTOEXPAND_BY_REALLOC_BSP( Models, 256 ); /* get model and entity */ mod = &bspModels[ numBSPModels ]; e = &entities[ mapEntityNum ]; /* ydnar: lightgrid mins/maxs */ ClearBounds( lgMins, lgMaxs ); /* bound the brushes */ ClearBounds( mins, maxs ); for ( b = e->brushes; b; b = b->next ) { /* ignore non-real brushes (origin, etc) */ if ( b->numsides == 0 ) { continue; } AddPointToBounds( b->mins, mins, maxs ); AddPointToBounds( b->maxs, mins, maxs ); /* ydnar: lightgrid bounds */ if ( b->compileFlags & C_LIGHTGRID ) { AddPointToBounds( b->mins, lgMins, lgMaxs ); AddPointToBounds( b->maxs, lgMins, lgMaxs ); } } /* bound patches */ 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 ); } /* ydnar: lightgrid mins/maxs */ if ( lgMins[ 0 ] < 99999 ) { /* use lightgrid bounds */ VectorCopy( lgMins, mod->mins ); VectorCopy( lgMaxs, mod->maxs ); } else { /* use brush/patch bounds */ VectorCopy( mins, mod->mins ); VectorCopy( maxs, mod->maxs ); } /* note size */ Sys_FPrintf( SYS_VRB, "BSP bounds: { %f %f %f } { %f %f %f }\n", mins[ 0 ], mins[ 1 ], mins[ 2 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ] ); Sys_FPrintf( SYS_VRB, "Lightgrid bounds: { %f %f %f } { %f %f %f }\n", lgMins[ 0 ], lgMins[ 1 ], lgMins[ 2 ], lgMaxs[ 0 ], lgMaxs[ 1 ], lgMaxs[ 2 ] ); /* set firsts */ mod->firstBSPSurface = numBSPDrawSurfaces; mod->firstBSPBrush = numBSPBrushes; }