Exemplo n.º 1
0
/*
   ============
   EndBSPFile
   ============
 */
void EndBSPFile( void ){
	char path[1024];

#if 0
	int len;
	byte    *buf;
#endif

	EmitBrushes();
	EmitPlanes();
	UnparseEntities();

	// load the pop
#if 0
	sprintf( path, "%s/pics/pop.lmp", gamedir );
	len = LoadFile( path, &buf );
	memcpy( dpop, buf, sizeof( dpop ) );
	free( buf );
#endif

	// write the map
	sprintf( path, "%s.bsp", source );
	Sys_Printf( "Writing %s\n", path );
	WriteBSPFile( path );
}
Exemplo n.º 2
0
/**
 * @brief Finishes a new bsp and writes to disk
 * @sa BeginBSPFile
 */
void EndBSPFile (const char* filename)
{
	EmitBrushes();
	EmitPlanes();
	UnparseEntities();

	/* write the map */
	Verb_Printf(VERB_LESS, "Writing %s\n", filename);
	WriteBSPFile(filename);
}
Exemplo n.º 3
0
/*
============
EndBSPFile
============
*/
void EndBSPFile (void)
{
    // Mark noshadow faces.
    MarkNoShadowFaces();

    EmitBrushes ();
    EmitPlanes ();

    // stick flat normals at the verts
    SaveVertexNormals();

    // Figure out lightmap extents for all faces.
    UpdateAllFaceLightmapExtents();

    // Generate geometry and lightmap alpha for displacements.
    EmitDispLMAlphaAndNeighbors();

    // Emit overlay data.
    Overlay_EmitOverlayFaces();
    OverlayTransition_EmitOverlayFaces();

    // phys collision needs dispinfo to operate (needs to generate phys collision for displacement surfs)
    EmitPhysCollision();

    // We can't calculate this properly until vvis (since we need vis to do this), so we set
    // to zero everywhere by default.
    ClearDistToClosestWater();

    // Emit static props found in the .vmf file
    EmitStaticProps();

    // Place detail props found in .vmf and based on material properties
    EmitDetailObjects();

    // Compute bounds after creating disp info because we need to reference it
    ComputeBoundsNoSkybox();

    // Make sure that we have a water lod control eneity if we have water in the map.
    EnsurePresenceOfWaterLODControlEntity();

    // Doing this here because stuff about may filter out entities
    UnparseEntities ();

    // remove unused texinfos
    CompactTexinfos();

    // Figure out which faces want macro textures.
    DiscoverMacroTextures();

    char fileName[1024];
    V_strncpy( fileName, source, sizeof( fileName ) );
    V_DefaultExtension( fileName, ".bsp", sizeof( fileName ) );
    Msg ("Writing %s\n", fileName);
    WriteBSPFile (fileName);
}
Exemplo n.º 4
0
/*
============
EndBSPFile
============
*/
void EndBSPFile (void)
{
	char	path[1024];

	EmitBrushes ();
	EmitPlanes ();
	UnparseEntities ();

	// write the map
	sprintf (path, "%s.bsp", source);
	Con_Print ("Writing %s\n", path);
	WriteBSPFile (path);
}
Exemplo n.º 5
0
/*
 * @brief
 */
void EndBSPFile(void) {

	EmitBrushes();
	EmitPlanes();
	EmitAreaPortals();

	UnparseEntities();

	// now that the verts have been resolved, align the normals count
	d_bsp.num_normals = d_bsp.num_vertexes;

	// write the map
	Com_Verbose("Writing %s\n", bsp_name);
	WriteBSPFile(bsp_name);
}
Exemplo n.º 6
0
/*
============
EndBSPFile
============
*/
void EndBSPFile( void ) {
#if 0
	char path[1024];
	int len;
	byte    *buf;
#endif


	EmitBrushes();
	EmitPlanes();
	Q2_UnparseEntities();

	// load the pop
#if 0
	sprintf( path, "%s/pics/pop.lmp", gamedir );
	len = LoadFile( path, &buf );
	memcpy( dpop, buf, sizeof( dpop ) );
	FreeMemory( buf );
#endif
}
Exemplo n.º 7
0
/*
==================
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 );
}
Exemplo n.º 8
0
Arquivo: bsp.c Projeto: Teivaz/nebula2
void ProcessSubModel( void )
{
    entity_t    *e;
    tree_t        *tree;
    brush_t        *b, *bc;
    node_t        *node;
    
    
    /* start a brush model */
    BeginModel();
    e = &entities[ mapEntityNum ];
    e->firstDrawSurf = numMapDrawSurfs;
    
    /* ydnar: gs mods */
    ClearMetaTriangles();
    
    /* check for patches with adjacent edges that need to lod together */
    PatchMapDrawSurfs( e );
    
    /* allocate a tree */
    node = AllocNode();
    node->planenum = PLANENUM_LEAF;
    tree = AllocTree();
    tree->headnode = node;
    
    /* add the sides to the tree */
    ClipSidesIntoTree( e, tree );
    
    /* ydnar: 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 );

    /* just put all the brushes in headnode */
    for( b = e->brushes; b; b = b->next )
    {
        bc = CopyBrush( b );
        bc->next = node->brushlist;
        node->brushlist = bc;
    }
    
    /* 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 and project lightmaps */
    ClassifyEntitySurfaces( e );
    
    /* ydnar: project decals */
    MakeEntityDecals( e );
    
    /* ydnar: meta surfaces */
    MakeEntityMetaTriangles( e );
    SmoothMetaTriangles();
    FixMetaTJunctions();
    MergeMetaTriangles();
    
    /* 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, node );
    FreeTree( tree );
}
Exemplo n.º 9
0
Arquivo: bsp.c Projeto: Teivaz/nebula2
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 );
}
Exemplo n.º 10
0
/**
 * @brief Calculates the routing of a map
 * @sa CheckUnit
 * @sa CheckConnections
 * @sa ProcessWorldModel
 */
void DoRouting (void)
{
	int i;
	byte* data;
	vec3_t mins, maxs;
	pos3_t pos;

	/* Turn on trace debugging if requested. */
	if (config.generateDebugTrace)
		debugTrace = true;

	/* Record the current mapTiles[0] state so we can remove all CLIPS when done. */
	PushInfo();

	/* build tracing structure */
	EmitBrushes();
	EmitPlanes(); /** This is needed for tracing to work!!! */
	/** @note LEVEL_TRACING is not an actual level */
	MakeTracingNodes(LEVEL_ACTORCLIP + 1);

	/* Reset the whole block of map data to 0 */
	Nmap.init();

	/* get world bounds for optimizing */
	RT_GetMapSize(&mapTiles, mins, maxs);
	/* Com_Printf("Vectors: (%f, %f, %f) to (%f, %f, %f)\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); */
	VecToPos(mins, wpMins);
	VecToPos(maxs, wpMaxs);

	/* Verify the world extents are not lopsided. */
	assert(wpMins[0] <= wpMaxs[0]);
	assert(wpMins[1] <= wpMaxs[1]);
	assert(wpMins[2] <= wpMaxs[2]);

	/* scan area heights */
	RunSingleThreadOn(CheckUnitThread, PATHFINDING_WIDTH * PATHFINDING_WIDTH * ACTOR_MAX_SIZE, config.verbosity >= VERB_NORMAL, "UNITCHECK");

	/* scan connections */
	RunSingleThreadOn(CheckConnectionsThread, PATHFINDING_WIDTH * PATHFINDING_WIDTH * (CORE_DIRECTIONS / (1 + RT_IS_BIDIRECTIONAL)) * (ACTOR_MAX_SIZE), config.verbosity >= VERB_NORMAL, "CONNCHECK");

	/* Try to shrink the world bounds along the x and y coordinates */
	for (i = 0; i < 2; i++) {			/* for x and y, but not z */
		int j = i ^ 1;					/* if i points to x, j points to y and vice versa */
		/* Increase the mins */
		while (wpMaxs[j] > wpMins[j]) {
			VectorSet(pos, wpMins[0], wpMins[1], wpMaxs[2]);
			for (pos[i] = wpMins[i]; pos[i] <= wpMaxs[i]; pos[i]++) {	/* for all cells in an x or y row */
				if (Nmap.getFloor(1, pos[0], pos[1], wpMaxs[2]) + wpMaxs[2] * CELL_HEIGHT != -1)	/* no floor ? */
					break;
			}
			if (pos[i] <= wpMaxs[i])	/* found a floor before the end of the row ? */
				break;					/* break while */
			wpMins[j]++;				/* if it was an x-row, increase y-value of mins and vice versa */
		}
		/* Decrease the maxs */
		while (wpMaxs[j] > wpMins[j]) {
			VectorCopy(wpMaxs, pos);
			for (pos[i] = wpMins[i]; pos[i] <= wpMaxs[i]; pos[i]++) {
				if (Nmap.getFloor(1, pos[0], pos[1], wpMaxs[2]) + wpMaxs[2] * CELL_HEIGHT != -1)
					break;
			}
			if (pos[i] <= wpMaxs[i])
				break;
			wpMaxs[j]--;
		}
	}

	/* Output the floor trace file if set */
	if (config.generateTraceFile) {
		RT_WriteCSVFiles(Nmap, baseFilename, wpMins, wpMaxs);
	}

	/* store the data */
	data = curTile->routedata;
	for (i = 0; i < 3; i++)
		wpMins[i] = LittleLong(wpMins[i]);
	data = CompressRouting((byte*)wpMins, data, sizeof(wpMins));
	for (i = 0; i < 3; i++)
		wpMaxs[i] = LittleLong(wpMaxs[i]);
	data = CompressRouting((byte*)wpMaxs, data, sizeof(wpMaxs));
	data = CompressRouting((byte*)&Nmap, data, sizeof(Nmap));

	curTile->routedatasize = data - curTile->routedata;

	/* Ensure that we did not exceed our allotment of memory for this data. */
	assert(curTile->routedatasize <= MAX_MAP_ROUTING);

	/* Remove the CLIPS fom the tracing structure by resetting it. */
	PopInfo();
}
Exemplo n.º 11
0
/*
   PseudoCompileBSP()
   a stripped down ProcessModels
 */
void PseudoCompileBSP( qboolean need_tree, const char *BSPFilePath, const char *surfaceFilePath ){
	int models;
	char modelValue[10];
	entity_t *entity;
	face_t *faces;
	tree_t *tree;
	node_t *node;
	brush_t *brush;
	side_t *side;
	int i;

	SetDrawSurfacesBuffer();
	mapDrawSurfs = safe_malloc( sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS );
	memset( mapDrawSurfs, 0, sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS );
	numMapDrawSurfs = 0;

	BeginBSPFile();
	models = 1;
	for ( mapEntityNum = 0; mapEntityNum < numEntities; mapEntityNum++ )
	{
		/* get entity */
		entity = &entities[ mapEntityNum ];
		if ( entity->brushes == NULL && entity->patches == NULL ) {
			continue;
		}

		if ( mapEntityNum != 0 ) {
			sprintf( modelValue, "*%d", models++ );
			SetKeyValue( entity, "model", modelValue );
		}

		/* process the model */
		Sys_FPrintf( SYS_VRB, "############### model %i ###############\n", numBSPModels );
		BeginModel();

		entity->firstDrawSurf = numMapDrawSurfs;

		ClearMetaTriangles();
		PatchMapDrawSurfs( entity );

		if ( mapEntityNum == 0 && need_tree ) {
			faces = MakeStructuralBSPFaceList( entities[0].brushes );
			tree = FaceBSP( faces );
			node = tree->headnode;
		}
		else
		{
			node = AllocNode();
			node->planenum = PLANENUM_LEAF;
			tree = AllocTree();
			tree->headnode = node;
		}

		/* a minimized ClipSidesIntoTree */
		for ( brush = entity->brushes; brush; brush = brush->next )
		{
			/* walk the brush sides */
			for ( i = 0; i < brush->numsides; i++ )
			{
				/* get side */
				side = &brush->sides[ i ];
				if ( side->winding == NULL ) {
					continue;
				}
				/* shader? */
				if ( side->shaderInfo == NULL ) {
					continue;
				}
				/* save this winding as a visible surface */
				DrawSurfaceForSide( entity, brush, side, side->winding );
			}
		}

		if ( meta ) {
			ClassifyEntitySurfaces( entity );
			MakeEntityDecals( entity );
			MakeEntityMetaTriangles( entity );
			SmoothMetaTriangles();
			MergeMetaTriangles();
		}
		FilterDrawsurfsIntoTree( entity, tree );

		FilterStructuralBrushesIntoTree( entity, tree );
		FilterDetailBrushesIntoTree( entity, tree );

		EmitBrushes( entity->brushes, &entity->firstBrush, &entity->numBrushes );
		EndModel( entity, node );
	}
	EndBSPFile( qfalse, BSPFilePath, surfaceFilePath );
}