Ejemplo n.º 1
0
/*
==================
PortalizeWorld

Builds the exact polyhedrons for the nodes and leafs
==================
*/
void
PortalizeWorld(node_t *headnode)
{
    Message(msgProgress, "Portalize");

    iNodesDone = 0;

    MakeHeadnodePortals(headnode);
    CutNodePortals_r(headnode);

    if (hullnum)
	return;

    // save portal file for vis tracing
    WritePortalfile(headnode);

    Message(msgStat, "%5i vis leafs", num_visleafs);
    Message(msgStat, "%5i vis portals", num_visportals);
}
Ejemplo n.º 2
0
/*
===========
FillOutside

===========
*/
node_t *FillOutside (node_t *node, qboolean leakfile)
{
    int			s;
    vec_t		*v;
    int			i;
    qboolean	inside;
    qboolean	ret;
    vec3_t		origin;
    char		*cl;

    qprintf ("----- FillOutside ----\n");

    if (nofill)
    {
        printf ("skipped\n");
        return node;
    }

    //
    // place markers for all entities so
    // we know if we leak inside
    //
    inside = false;
    for (i=1 ; i<num_entities ; i++)
    {
        GetVectorForKey (&entities[i], "origin", origin);
        if (!VectorCompare(origin, vec3_origin))
        {
            cl = ValueForKey (&entities[i], "classname");
            origin[2] += 1;	// so objects on floor are ok

            // nudge playerstart around if needed so clipping hulls allways
            // have a vlaid point
            if (!strcmp (cl, "info_player_start"))
            {
                int	x, y;

                for (x=-16 ; x<=16 ; x += 16)
                {
                    for (y=-16 ; y<=16 ; y += 16)
                    {
                        origin[0] += x;
                        origin[1] += y;
                        if (PlaceOccupant (i, origin, node))
                        {
                            inside = true;
                            goto gotit;
                        }
                        origin[0] -= x;
                        origin[1] -= y;
                    }
                }
gotit:
                ;
            }
            else
            {
                if (PlaceOccupant (i, origin, node))
                    inside = true;
            }
        }
    }

    if (!inside)
    {
        printf ("Hullnum %i: No entities in empty space -- no filling performed\n", hullnum);
        return node;
    }

    s = !(outside_node.portals->nodes[1] == &outside_node);

// first check to see if an occupied leaf is hit
    outleafs = 0;
    valid++;

    prevleaknode = NULL;

    if (leakfile)
    {
        pointfile = fopen (pointfilename, "w");
        if (!pointfile)
            Error ("Couldn't open %s\n", pointfilename);
        StripExtension (pointfilename);
        strcat (pointfilename, ".lin");
        linefile = fopen (pointfilename, "w");
        if (!linefile)
            Error ("Couldn't open %s\n", pointfilename);
    }

    ret = RecursiveFillOutside (outside_node.portals->nodes[s], false);

    if (leakfile)
    {
        fclose (pointfile);
        fclose (linefile);
    }

    if (ret)
    {
        printf("LEAK LEAK LEAK\n");
        GetVectorForKey (&entities[hit_occupied], "origin", origin);
        qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
        qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n"
                 , origin[0], origin[1], origin[2]);
        qprintf ("no filling performed\n");
        qprintf ("point file and line file generated\n");
        qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
        if (leakonly)
            Error ("Stopped by leak.");
        return node;
    }

// now go back and fill things in
    valid++;
    RecursiveFillOutside (outside_node.portals->nodes[s], true);

// remove faces and nodes from filled in leafs
    c_falsenodes = 0;
    c_free_faces = 0;
    c_keep_faces = 0;
    node = ClearOutFaces_r (node);

    qprintf ("%5i outleafs\n", outleafs);
    qprintf ("%5i freed faces\n", c_free_faces);
    qprintf ("%5i keep faces\n", c_keep_faces);
    qprintf ("%5i falsenodes\n", c_falsenodes);

// save portal file for vis tracing
    if (leakfile)
        WritePortalfile (node);

    return node;
}
Ejemplo n.º 3
0
/*
===============
ProcessEntity
===============
*/
void ProcessEntity (int entnum)
{
	entity_t *ent;
	char	mod[80];
	surface_t	*surfs;
	node_t		*nodes;
	brushset_t	*bs;
	

	ent = &entities[entnum];
	if (!ent->brushes)
		return;		// non-bmodel entity

	if (entnum > 0)
	{
		worldmodel = false;
		if (entnum == 1)
			qprintf ("--- Internal Entities ---\n");
		sprintf (mod, "*%i", nummodels);
		if (verbose)
			PrintEntity (ent);

		if (hullnum == 0)
			printf ("MODEL: %s\n", mod);
		SetKeyValue (ent, "model", mod);
	}
	else
		worldmodel = true;
	

//
// take the brush_ts and clip off all overlapping and contained faces,
// leaving a perfect skin of the model with no hidden faces
//
	bs = Brush_LoadEntity (ent, hullnum);
	
	if (!bs->brushes)
	{
		PrintEntity (ent);
		Error ("Entity with no valid brushes");
	}
	
	brushset = bs;
	surfs = CSGFaces (bs);

	if (hullnum != 0)
	{
		nodes = SolidBSP (surfs, true);
		if (entnum == 0 && !nofill)	// assume non-world bmodels are simple
		{
			PortalizeWorld (nodes);
			if (FillOutside (nodes))
			{
				surfs = GatherNodeFaces (nodes);
				nodes = SolidBSP (surfs, false);	// make a really good tree with proper heuristic splitting plane selection
			}
			FreeAllPortals (nodes);
		}
		WriteNodePlanes (nodes);
		WriteClipNodes (nodes);
		BumpModel (hullnum);
	}
	else
	{
	//
	// SolidBSP generates a node tree
	//
	// if not the world, make a good tree first
	// the world is just going to make a bad tree
	// because the outside filling will force a regeneration later
		nodes = SolidBSP (surfs, entnum == 0);	
		
	//
	// build all the portals in the bsp tree
	// some portals are solid polygons, and some are paths to other leafs
	//
		if (entnum == 0 && !nofill)	// assume non-world bmodels are simple
		{
			PortalizeWorld (nodes);
		
			if (FillOutside (nodes))
			{
				FreeAllPortals (nodes);

			// get the remaining faces together into surfaces again
				surfs = GatherNodeFaces (nodes);
	
			// merge polygons
				MergeAll (surfs);
	
			// make a really good tree
				nodes = SolidBSP (surfs, false);
	
			// make the real portals for vis tracing
				PortalizeWorld (nodes);
	
			// save portal file for vis tracing
				WritePortalfile (nodes);
				
			// fix tjunctions
				tjunc (nodes);
			}
			FreeAllPortals (nodes);
		}

		WriteNodePlanes (nodes);
		MakeFaceEdges (nodes);
		WriteDrawNodes (nodes);
	}
}