void xml_Select (char *msg, int entitynum, int brushnum, qboolean bError) { xmlNodePtr node, select; char buf[1024]; char level[2]; // now build a proper "select" XML node sprintf (buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg); node = xmlNewNode (NULL, (xmlChar*)"select"); xmlNodeSetContent (node, (xmlChar*)buf); level[0] = (int)'0' + (bError ? SYS_ERR : SYS_WRN) ; level[1] = 0; xmlSetProp (node, (xmlChar*)"level", (xmlChar *)&level); // a 'select' information sprintf (buf, "%i %i", entitynum, brushnum); select = xmlNewNode (NULL, (xmlChar*)"brush"); xmlNodeSetContent (select, (xmlChar*)buf); xmlAddChild (node, select); xml_SendNode (node); sprintf (buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg); if (bError) Error(buf); else Sys_FPrintf (SYS_NOXML, "%s\n", buf); }
// all output ends up through here void FPrintf (int flag, char *buf) { xmlNodePtr node; static qboolean bGotXML = false; char level[2]; printf(buf); // the following part is XML stuff only.. but maybe we don't want that message to go down the XML pipe? if (flag == SYS_NOXML) return; // ouput an XML file of the run // use the DOM interface to build a tree /* <message level='flag'> message string .. various nodes to describe corresponding geometry .. </message> */ if (!bGotXML) { // initialize doc = xmlNewDoc("1.0"); doc->children = xmlNewDocRawNode(doc, NULL, "q3map_feedback", NULL); bGotXML = true; } node = xmlNewNode (NULL, "message"); xmlNodeSetContent (node, buf); level[0] = (int)'0' + flag; level[1] = 0; xmlSetProp (node, "level", (char *)&level ); xml_SendNode (node); }
void xml_Winding(char *msg, vec3_t p[], int numpoints, qboolean die) { xmlNodePtr node, winding; char buf[WINDING_BUFSIZE]; char smlbuf[128]; char level[2]; int i; node = xmlNewNode(NULL, "windingmsg"); xmlNodeSetContent(node, msg); level[0] = (int)'0' + SYS_ERR; level[1] = 0; xmlSetProp(node, "level", (char *)&level); // a 'winding' node sprintf(buf, "%i ", numpoints); for(i = 0; i < numpoints; i++) { sprintf(smlbuf, "(%g %g %g)", p[i][0], p[i][1], p[i][2]); // don't overflow if(strlen(buf) + strlen(smlbuf) > WINDING_BUFSIZE) break; strcat(buf, smlbuf); } winding = xmlNewNode(NULL, "winding"); xmlNodeSetContent(winding, buf); xmlAddChild(node, winding); xml_SendNode(node); if(die) Error(msg); else Sys_Printf("%s\n", msg); }
void xml_Point (char *msg, vec3_t pt, qboolean bError ) { xmlNodePtr node, point; char buf[1024]; char level[2]; node = xmlNewNode( NULL, (xmlChar *)"pointmsg" ); xmlNodeSetContent( node, (xmlChar *)msg ); level[0] = (int)'0' + (bError ? SYS_ERR : SYS_WRN); level[1] = 0; xmlSetProp( node, (xmlChar *)"level", (xmlChar *)&level ); /* a 'point' node */ if( pt ) sprintf( buf, "%g %g %g", pt[0], pt[1], pt[2] ); else sprintf( buf, "%g %g %g", 0, 0, 0 ); point = xmlNewNode( NULL, (xmlChar *)"point" ); xmlNodeSetContent( point, (xmlChar *)buf ); xmlAddChild( node, point ); xml_SendNode( node ); /* print */ if( pt ) sprintf( buf, "%s (%g %g %g)", msg, pt[0], pt[1], pt[2] ); else sprintf( buf, "%s", msg ); if( bError ) Error( buf ); else Sys_FPrintf( SYS_NOXML, "%s\n", buf ); }
void xml_Point( char *msg, vec3_t pt ){ xmlNodePtr node, point; char buf[1024]; char level[2]; node = xmlNewNode( NULL, (xmlChar*)"pointmsg" ); xmlNodeSetContent( node, (xmlChar*)msg ); level[0] = (int)'0' + SYS_ERR; level[1] = 0; xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level ); // a 'point' node sprintf( buf, "%g %g %g", pt[0], pt[1], pt[2] ); point = xmlNewNode( NULL, (xmlChar*)"point" ); xmlNodeSetContent( point, (xmlChar*)buf ); xmlAddChild( node, point ); xml_SendNode( node ); sprintf( buf, "%s (%g %g %g)", msg, pt[0], pt[1], pt[2] ); Error( buf ); }
void ProcessWorldModel( void ) { int i, s; entity_t *e; tree_t *tree; face_t *faces; qboolean ignoreLeaks, leaked; xmlNodePtr polyline, leaknode; char level[ 2 ], shader[ 1024 ]; const char *value; /* sets integer blockSize from worldspawn "_blocksize" key if it exists */ value = ValueForKey( &entities[ 0 ], "_blocksize" ); if( value[ 0 ] == '\0' ) value = ValueForKey( &entities[ 0 ], "blocksize" ); if( value[ 0 ] == '\0' ) value = ValueForKey( &entities[ 0 ], "chopsize" ); /* sof2 */ if( value[ 0 ] != '\0' ) { /* scan 3 numbers */ s = sscanf( value, "%d %d %d", &blockSize[ 0 ], &blockSize[ 1 ], &blockSize[ 2 ] ); /* handle legacy case */ if( s == 1 ) { blockSize[ 1 ] = blockSize[ 0 ]; blockSize[ 2 ] = blockSize[ 0 ]; } } Sys_Printf( "block size = { %d %d %d }\n", blockSize[ 0 ], blockSize[ 1 ], blockSize[ 2 ] ); /* sof2: ignore leaks? */ value = ValueForKey( &entities[ 0 ], "_ignoreleaks" ); /* ydnar */ if( value[ 0 ] == '\0' ) value = ValueForKey( &entities[ 0 ], "ignoreleaks" ); if( value[ 0 ] == '1' ) ignoreLeaks = qtrue; else ignoreLeaks = qfalse; /* begin worldspawn model */ BeginModel(); e = &entities[ 0 ]; e->firstDrawSurf = 0; /* ydnar: gs mods */ ClearMetaTriangles(); /* check for patches with adjacent edges that need to lod together */ PatchMapDrawSurfs( e ); /* build an initial bsp tree using all of the sides of all of the structural brushes */ faces = MakeStructuralBSPFaceList( entities[ 0 ].brushes ); tree = FaceBSP( faces ); MakeTreePortals( tree ); FilterStructuralBrushesIntoTree( e, tree ); /* see if the bsp is completely enclosed */ if( FloodEntities( tree ) || ignoreLeaks ) { /* rebuild a better bsp tree using only the sides that are visible from the inside */ FillOutside( tree->headnode ); /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */ ClipSidesIntoTree( e, tree ); /* build a visible face tree */ faces = MakeVisibleBSPFaceList( entities[ 0 ].brushes ); FreeTree( tree ); tree = FaceBSP( faces ); MakeTreePortals( tree ); FilterStructuralBrushesIntoTree( e, tree ); leaked = qfalse; /* ydnar: flood again for skybox */ if( skyboxPresent ) FloodEntities( tree ); } else { Sys_FPrintf( SYS_NOXML, "**********************\n" ); Sys_FPrintf( SYS_NOXML, "******* leaked *******\n" ); Sys_FPrintf( SYS_NOXML, "**********************\n" ); polyline = LeakFile( tree ); leaknode = xmlNewNode( NULL, "message" ); xmlNodeSetContent( leaknode, "MAP LEAKED\n" ); xmlAddChild( leaknode, polyline ); level[0] = (int) '0' + SYS_ERR; level[1] = 0; xmlSetProp( leaknode, "level", (char*) &level ); xml_SendNode( leaknode ); if( leaktest ) { Sys_Printf ("--- MAP LEAKED, ABORTING LEAKTEST ---\n"); exit( 0 ); } leaked = qtrue; /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */ ClipSidesIntoTree( e, tree ); } /* save out information for visibility processing */ NumberClusters( tree ); if( !leaked ) WritePortalFile( tree ); /* flood from entities */ FloodAreas( tree ); /* create drawsurfs for triangle models */ AddTriangleModels( e ); /* create drawsurfs for surface models */ AddEntitySurfaceModels( e ); /* generate bsp brushes from map brushes */ EmitBrushes( e->brushes, &e->firstBrush, &e->numBrushes ); /* add references to the detail brushes */ FilterDetailBrushesIntoTree( e, tree ); /* drawsurfs that cross fog boundaries will need to be split along the fog boundary */ if( !nofog ) FogDrawSurfaces( e ); /* subdivide each drawsurf as required by shader tesselation */ if( !nosubdivide ) SubdivideFaceSurfaces( e, tree ); /* add in any vertexes required to fix t-junctions */ if( !notjunc ) FixTJunctions( e ); /* ydnar: classify the surfaces */ ClassifyEntitySurfaces( e ); /* ydnar: project decals */ MakeEntityDecals( e ); /* ydnar: meta surfaces */ MakeEntityMetaTriangles( e ); SmoothMetaTriangles(); FixMetaTJunctions(); MergeMetaTriangles(); /* ydnar: debug portals */ if( debugPortals ) MakeDebugPortalSurfs( tree ); /* ydnar: fog hull */ value = ValueForKey( &entities[ 0 ], "_foghull" ); if( value[ 0 ] != '\0' ) { sprintf( shader, "textures/%s", value ); MakeFogHullSurfs( e, tree, shader ); } /* ydnar: bug 645: do flares for lights */ for( i = 0; i < numEntities && emitFlares; i++ ) { entity_t *light, *target; const char *value, *flareShader; vec3_t origin, targetOrigin, normal, color; int lightStyle; /* get light */ light = &entities[ i ]; value = ValueForKey( light, "classname" ); if( !strcmp( value, "light" ) ) { /* get flare shader */ flareShader = ValueForKey( light, "_flareshader" ); value = ValueForKey( light, "_flare" ); if( flareShader[ 0 ] != '\0' || value[ 0 ] != '\0' ) { /* get specifics */ GetVectorForKey( light, "origin", origin ); GetVectorForKey( light, "_color", color ); lightStyle = IntForKey( light, "_style" ); if( lightStyle == 0 ) lightStyle = IntForKey( light, "style" ); /* handle directional spotlights */ value = ValueForKey( light, "target" ); if( value[ 0 ] != '\0' ) { /* get target light */ target = FindTargetEntity( value ); if( target != NULL ) { GetVectorForKey( target, "origin", targetOrigin ); VectorSubtract( targetOrigin, origin, normal ); VectorNormalize( normal, normal ); } } else //% VectorClear( normal ); VectorSet( normal, 0, 0, -1 ); /* create the flare surface (note shader defaults automatically) */ DrawSurfaceForFlare( mapEntityNum, origin, normal, color, (char*) flareShader, lightStyle ); } } } /* add references to the final drawsurfs in the apropriate clusters */ FilterDrawsurfsIntoTree( e, tree ); /* match drawsurfaces back to original brushsides (sof2) */ FixBrushSides( e ); /* finish */ EndModel( e, tree->headnode ); FreeTree( tree ); }
/* ============ ProcessWorldModel ============ */ void ProcessWorldModel(void) { int s; entity_t *e; tree_t *tree; bspFace_t *faces; qboolean leaked; xmlNodePtr polyline, leaknode; char level[2]; const char *value; e = &entities[0]; e->firstDrawSurf = 0; //numMapDrawSurfs; // sets integer blockSize from worldspawn "_blocksize" key if it exists value = ValueForKey(e, "_blocksize"); if(value[0] == '\0') value = ValueForKey(e, "blocksize"); if(value[0] == '\0') value = ValueForKey(e, "chopsize"); // sof2 if(value[0] != '\0') { // scan 3 numbers s = sscanf(value, "%d %d %d", &blockSize[0], &blockSize[1], &blockSize[2]); // handle legacy case if(s == 1) { blockSize[1] = blockSize[0]; blockSize[2] = blockSize[0]; } } Sys_Printf("block size = { %d %d %d }\n", blockSize[0], blockSize[1], blockSize[2]); BeginModel(e); // check for patches with adjacent edges that need to LOD together PatchMapDrawSurfs(e); // build an initial bsp tree using all of the sides // of all of the structural brushes faces = MakeStructuralBspFaceList(entities[0].brushes); tree = FaceBSP(faces); MakeTreePortals(tree); FilterStructuralBrushesIntoTree(e, tree); if(drawFlag) { // draw unoptimized portals in new window drawTree = tree; Draw_Scene(DrawTree); } // see if the bsp is completely enclosed if(FloodEntities(tree)) { // rebuild a better bsp tree using only the // sides that are visible from the inside FillOutside(tree->headnode); // chop the sides to the convex hull of // their visible fragments, giving us the smallest // polygons ClipSidesIntoTree(e, tree); faces = MakeVisibleBspFaceList(entities[0].brushes); FreeTree(tree); tree = FaceBSP(faces); MakeTreePortals(tree); FilterStructuralBrushesIntoTree(e, tree); leaked = qfalse; } else { Sys_FPrintf(SYS_NOXML, "**********************\n"); Sys_FPrintf(SYS_NOXML, "******* leaked *******\n"); Sys_FPrintf(SYS_NOXML, "**********************\n"); polyline = LeakFile(tree); leaknode = xmlNewNode(NULL, "message"); xmlNodeSetContent(leaknode, "MAP LEAKED\n"); xmlAddChild(leaknode, polyline); level[0] = (int)'0' + SYS_ERR; level[1] = 0; xmlSetProp(leaknode, "level", (char *)&level); xml_SendNode(leaknode); if(leaktest) { Sys_Printf("--- MAP LEAKED, ABORTING LEAKTEST ---\n"); exit(0); } leaked = qtrue; // chop the sides to the convex hull of // their visible fragments, giving us the smallest // polygons ClipSidesIntoTree(e, tree); } // save out information for visibility processing NumberClusters(tree); if(!leaked) { WritePortalFile(tree); } if(glview) { // dump the portals for debugging WriteGLView(tree, source); } FloodAreas(tree); if(drawFlag) { // draw optimized portals in new window drawTree = tree; Draw_Scene(DrawTree); } // add references to the detail brushes FilterDetailBrushesIntoTree(e, tree); // create drawsurfs for triangle models AddTriangleModels(); // drawsurfs that cross fog boundaries will need to // be split along the bound if(!nofog) { FogDrawSurfs(); // may fragment drawsurfs } // subdivide each drawsurf as required by shader tesselation if(!nosubdivide) { SubdivideDrawSurfs(e, tree); } // merge together all common shaders on the same plane and remove // all colinear points, so extra tjunctions won't be generated if(!nomerge) { MergeSides(e, tree); // !@# testing } // add in any vertexes required to fix tjunctions if(!notjunc) { FixTJunctions(e); } // allocate lightmaps for faces and patches AllocateLightmaps(e); // add references to the final drawsurfs in the apropriate clusters FilterDrawsurfsIntoTree(e, tree); EndModel(e, tree->headnode); FreeTree(tree); }