/* ============ EmitDrawingNode_r ============ */ int EmitDrawNode_r( node_t *node ){ dnode_t *n; face_t *f; 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( (short) node->mins, n->mins ); VectorCopy( (short) node->maxs, n->maxs ); planeused[node->planenum]++; planeused[node->planenum ^ 1]++; if ( node->planenum & 1 ) { Error( "WriteDrawNodes_r: odd planenum" ); } n->planenum = node->planenum; n->firstface = numfaces; if ( !node->faces ) { c_nofaces++; } else{ c_facenodes++; } for ( f = node->faces ; f ; f = f->next ) EmitFace( f ); n->numfaces = numfaces - n->firstface; // // 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; }
/* ============ EmitDrawingNode_r ============ */ int EmitDrawNode_r (node_t *node) { dnode_t *n; face_t *f; int i; if (node->planenum == PLANENUM_LEAF) { EmitLeaf (node); return -numleafs; } // emit a node if (numnodes == MAX_MAP_NODES) Error ("MAX_MAP_NODES"); node->diskId = numnodes; n = &dnodes[numnodes]; numnodes++; VECTOR_COPY (node->mins, n->mins); VECTOR_COPY (node->maxs, n->maxs); if (node->planenum & 1) Error ("WriteDrawNodes_r: odd planenum"); n->planenum = node->planenum; n->firstface = numfaces; n->area = node->area; if (!node->faces) c_nofaces++; else c_facenodes++; for (f=node->faces ; f ; f=f->next) EmitFace (f, true); n->numfaces = numfaces - n->firstface; // // 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; }
/** * @brief Writes the draw nodes * @note Called after a drawing hull is completed */ static int EmitDrawNode_r (node_t* node) { const char* side[2] = {"front", "back"}; dBspNode_t* n; const face_t* f; int i; if (node->planenum == PLANENUM_LEAF) { Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating singleton leaf.\n"); EmitLeaf(node); return -curTile->numleafs; } /* emit a node */ if (curTile->numnodes >= MAX_MAP_NODES) Sys_Error("MAX_MAP_NODES (%i)", curTile->numnodes); n = &curTile->nodes[curTile->numnodes]; Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating bsp node %i\n", curTile->numnodes); curTile->numnodes++; VectorCopy(node->mins, n->mins); VectorCopy(node->maxs, n->maxs); if (node->planenum & 1) Sys_Error("EmitDrawNode_r: odd planenum: %i", node->planenum); n->planenum = node->planenum; n->firstface = curTile->numfaces; if (!node->faces) c_nofaces++; else c_facenodes++; for (f = node->faces; f; f = f->next) EmitFace(f); n->numfaces = curTile->numfaces - n->firstface; /* recursively output the other nodes */ for (i = 0; i < 2; i++) { if (node->children[i]->planenum == PLANENUM_LEAF) { Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating child leaf for %s of bsp node " UFO_SIZE_T ".\n", side[i], n - curTile->nodes); n->children[i] = -(curTile->numleafs + 1); EmitLeaf(node->children[i]); } else { Verb_Printf(VERB_DUMP, "EmitDrawNode_r: adding child node for bsp node " UFO_SIZE_T ".\n", n - curTile->nodes); n->children[i] = curTile->numnodes; EmitDrawNode_r(node->children[i]); } } return n - curTile->nodes; }
/* ================== 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++; }
/* * @brief */ static int32_t EmitDrawNode_r(node_t * node) { d_bsp_node_t *n; face_t *f; int32_t i; if (node->plane_num == PLANENUM_LEAF) { EmitLeaf(node); return -d_bsp.num_leafs; } // emit a node if (d_bsp.num_nodes == MAX_BSP_NODES) Com_Error(ERR_FATAL, "MAX_BSP_NODES\n"); n = &d_bsp.nodes[d_bsp.num_nodes]; d_bsp.num_nodes++; VectorCopy(node->mins, n->mins); VectorCopy(node->maxs, n->maxs); if (node->plane_num & 1) Com_Error(ERR_FATAL, "Odd plane number\n"); n->plane_num = node->plane_num; n->first_face = d_bsp.num_faces; if (!node->faces) c_nofaces++; else c_facenodes++; for (f = node->faces; f; f = f->next) EmitFace(f); n->num_faces = d_bsp.num_faces - n->first_face; // recursively output the other nodes for (i = 0; i < 2; i++) { if (node->children[i]->plane_num == PLANENUM_LEAF) { n->children[i] = -(d_bsp.num_leafs + 1); EmitLeaf(node->children[i]); } else { n->children[i] = d_bsp.num_nodes; EmitDrawNode_r(node->children[i]); } } return n - d_bsp.nodes; }
/* * @brief */ void WriteBSP(node_t *head_node) { int32_t old_faces; c_nofaces = 0; c_facenodes = 0; Com_Verbose("--- WriteBSP ---\n"); old_faces = d_bsp.num_faces; d_bsp.models[d_bsp.num_models].head_node = EmitDrawNode_r(head_node); Com_Verbose("%5i nodes with faces\n", c_facenodes); Com_Verbose("%5i nodes without faces\n", c_nofaces); Com_Verbose("%5i faces\n", d_bsp.num_faces - old_faces); }
/* ============ WriteBSP ============ */ void WriteBSP( node_t *headnode ){ int oldfaces; c_nofaces = 0; c_facenodes = 0; Sys_FPrintf( SYS_VRB, "--- WriteBSP ---\n" ); oldfaces = numfaces; dmodels[nummodels].headnode = EmitDrawNode_r( headnode ); EmitAreaPortals( headnode ); Sys_FPrintf( SYS_VRB, "%5i nodes with faces\n", c_facenodes ); Sys_FPrintf( SYS_VRB, "%5i nodes without faces\n", c_nofaces ); Sys_FPrintf( SYS_VRB, "%5i faces\n", numfaces - oldfaces ); }
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; }
/* ============ WriteBSP ============ */ void WriteBSP (node_t *headnode) { int oldfaces; c_nofaces = 0; c_facenodes = 0; Con_Verbose("--- WriteBSP ---\n"); oldfaces = numfaces; dmodels[nummodels].headnode = EmitDrawNode_r (headnode); EmitAreaPortals (headnode); Con_Verbose("%5i nodes with faces\n", c_facenodes); Con_Verbose("%5i nodes without faces\n", c_nofaces); Con_Verbose("%5i faces\n", numfaces-oldfaces); }
int EmitDrawNode_r( node_t *node ) { bspNode_t *n; int i; /* check for leafnode */ if( node->planenum == PLANENUM_LEAF ) { EmitLeaf( node ); return -numBSPLeafs; } /* emit a node */ if( numBSPNodes == MAX_MAP_NODES ) Error( "MAX_MAP_NODES" ); n = &bspNodes[ numBSPNodes ]; 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]); } } return n - bspNodes; }
/** * @brief copies working data for a bsp tree into the structures used to create the bsp file. * @param[in] headnode the top-most node in this bsp tree * @return the index to the head node created. */ int WriteBSP (node_t* headnode) { int oldfaces, emittedHeadnode; c_nofaces = 0; c_facenodes = 0; Verb_Printf(VERB_EXTRA, "--- WriteBSP ---\n"); oldfaces = curTile->numfaces; emittedHeadnode = EmitDrawNode_r(headnode); Verb_Printf(VERB_EXTRA, "%5i nodes with faces\n", c_facenodes); Verb_Printf(VERB_EXTRA, "%5i nodes without faces\n", c_nofaces); Verb_Printf(VERB_EXTRA, "%5i faces\n", curTile->numfaces - oldfaces); return emittedHeadnode; }
/* ============ WriteBSP ============ */ void WriteBSP (node_t *headnode, face_t *pLeafFaceList ) { int i; int oldfaces; int oldorigfaces; c_nofaces = 0; c_facenodes = 0; qprintf ("--- WriteBSP ---\n"); oldfaces = numfaces; oldorigfaces = numorigfaces; GetEdge2_InitOptimizedList(); EmitLeafFaces( pLeafFaceList ); dmodels[nummodels].headnode = EmitDrawNode_r (headnode); // Only emit area portals for the main world. if( nummodels == 0 ) { EmitAreaPortals (headnode); } // // add all displacement faces for the particular model // for( i = 0; i < nummapdispinfo; i++ ) { int entityIndex = GetDispInfoEntityNum( &mapdispinfo[i] ); if( entityIndex == entity_num ) { EmitFaceVertexes( NULL, &mapdispinfo[i].face ); EmitFace( &mapdispinfo[i].face, FALSE ); } } EmitWaterVolumesForBSP( &dmodels[nummodels], headnode ); qprintf ("%5i nodes with faces\n", c_facenodes); qprintf ("%5i nodes without faces\n", c_nofaces); qprintf ("%5i faces\n", numfaces-oldfaces); qprintf( "%5i original faces\n", numorigfaces-oldorigfaces ); }
void EndModel( entity_t *e, node_t *headnode ){ bspModel_t *mod; /* note it */ Sys_FPrintf( SYS_VRB, "--- EndModel ---\n" ); /* emit the bsp */ mod = &bspModels[ numBSPModels ]; EmitDrawNode_r( headnode ); /* set surfaces and brushes */ mod->numBSPSurfaces = numBSPDrawSurfaces - mod->firstBSPSurface; mod->firstBSPBrush = e->firstBrush; mod->numBSPBrushes = e->numBrushes; /* increment model count */ numBSPModels++; }
void EndModel(entity_t * e, node_t * headnode) { bspModel_t *mod; bspDrawSurface_t *ds; brush_t *b; vec3_t mins, maxs; vec3_t lgMins, lgMaxs; /* ydnar: lightgrid mins/maxs */ parseMesh_t *p; const char *name; const char *model; const char *classname; int i, j; /* note it */ Sys_FPrintf(SYS_VRB, "--- EndModel ---\n"); /* emit the bsp */ mod = &bspModels[numBSPModels]; EmitDrawNode_r(headnode); /* ydnar: lightgrid mins/maxs */ ClearBounds(lgMins, lgMaxs); /* bound the brushes */ ClearBounds(mins, maxs); //BoundsAdd(mins, maxs, headnode->mins, headnode->maxs); for(b = e->brushes; b; b = b->next) { /* ignore non-real brushes (origin, etc) */ if(b->numsides == 0) continue; // Tr3B: ignore autogenerated clip brushes because their bounding sizes can be really huge if(b->generatedClipBrush) 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); } /* Tr3B: bound triangle surfaces */ classname = ValueForKey(e, "classname"); name = ValueForKey(e, "name"); model = ValueForKey(e, "model"); #if 1 if(inlineEntityModels && !e->brushes && !e->patches && model[0] != '\0' && Q_stricmp("misc_model", classname)) { qboolean noVerts = qtrue; //Sys_FPrintf(SYS_STD, "calculating BSP bounds from draw surfaces for entity '%s' with model '%s'\n", name, model); for(i = mod->firstBSPSurface; i < numBSPDrawSurfaces; i++) { ds = &bspDrawSurfaces[i]; if(!ds->numVerts) { continue; // leftover from a surface subdivision } // HACK: don't loop only through the vertices because they can contain bad data with .lwo models ... for(j = 0; j < ds->numIndexes; j += 3) { AddPointToBounds(bspDrawVerts[ds->firstVert + bspDrawIndexes[j + ds->firstIndex]].xyz, mins, maxs); noVerts = qfalse; } } if(noVerts) { // Tr3B: model could not be loaded or something else went wrong. // reset to zero bounds so the entity doesn't mess up the server collision code Sys_FPrintf(SYS_WRN, "WARNING: resetting BSP bounds for entity = '%s', classname = '%s', model = '%s'\n", name, classname, model); VectorClear(mins); VectorClear(maxs); } } #endif /* ydnar: lightgrid mins/maxs */ #if 0 // Tr3B: don't mess with the model bounds ... if(lgMins[0] < 99999) { /* use lightgrid bounds */ VectorCopy(lgMins, mod->mins); VectorCopy(lgMaxs, mod->maxs); } else #endif { /* 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 surfaces and brushes */ mod->numBSPSurfaces = numBSPDrawSurfaces - mod->firstBSPSurface; mod->firstBSPBrush = e->firstBrush; mod->numBSPBrushes = e->numBrushes; /* increment model count */ numBSPModels++; }