コード例 #1
0
ファイル: portals.cpp プロジェクト: 0xFEEDC0DE64/UltraGame
/*
==============
SplitNodePortals

Move or split the portals that bound node so that the node's
children have portals instead of node.
==============
*/
void SplitNodePortals (node_t *node)
{
	portal_t	*p, *next_portal, *new_portal;
	node_t		*f, *b, *other_node;
	int			side = 0;
	plane_t		*plane;
	winding_t	*frontwinding, *backwinding;

	plane = &mapplanes[node->planenum];
	f = node->children[0];
	b = node->children[1];

	for (p = node->portals ; p ; p = next_portal)	
	{
		if (p->nodes[0] == node)
			side = 0;
		else if (p->nodes[1] == node)
			side = 1;
		else
			Error ("CutNodePortals_r: mislinked portal");
		next_portal = p->next[side];

		other_node = p->nodes[!side];
		RemovePortalFromNode (p, p->nodes[0]);
		RemovePortalFromNode (p, p->nodes[1]);

//
// cut the portal into two portals, one on each side of the cut plane
//
		ClipWindingEpsilon (p->winding, plane->normal, plane->dist,
			SPLIT_WINDING_EPSILON, &frontwinding, &backwinding);

		if (frontwinding && WindingIsTiny(frontwinding))
		{
			FreeWinding (frontwinding);
			frontwinding = NULL;
			c_tinyportals++;
		}

		if (backwinding && WindingIsTiny(backwinding))
		{
			FreeWinding (backwinding);
			backwinding = NULL;
			c_tinyportals++;
		}

		if (!frontwinding && !backwinding)
		{	// tiny windings on both sides
			continue;
		}

		if (!frontwinding)
		{
			FreeWinding (backwinding);
			if (side == 0)
				AddPortalToNodes (p, b, other_node);
			else
				AddPortalToNodes (p, other_node, b);
			continue;
		}
		if (!backwinding)
		{
			FreeWinding (frontwinding);
			if (side == 0)
				AddPortalToNodes (p, f, other_node);
			else
				AddPortalToNodes (p, other_node, f);
			continue;
		}
		
	// the winding is split
		new_portal = AllocPortal ();
		*new_portal = *p;
		new_portal->winding = backwinding;
		FreeWinding (p->winding);
		p->winding = frontwinding;

		if (side == 0)
		{
			AddPortalToNodes (p, f, other_node);
			AddPortalToNodes (new_portal, b, other_node);
		}
		else
		{
			AddPortalToNodes (p, other_node, f);
			AddPortalToNodes (new_portal, other_node, b);
		}
	}

	node->portals = NULL;
}
コード例 #2
0
ファイル: portals.c プロジェクト: Diskutant/RTCW-SP
void MakeNodePortal(node_t *node)
{
	portal_t    *new_portal, *p;
	winding_t   *w;
	vec3_t normal;
	float dist = 0;       // TTimo: init
	int side = 0;

	w = BaseWindingForNode(node);

	// clip the portal by all the other portals in the node
	for(p = node->portals; p && w; p = p->next[side])
	{
		if(p->nodes[0] == node)
		{
			side = 0;
			VectorCopy(p->plane.normal, normal);
			dist = p->plane.dist;
		} //end if
		else if(p->nodes[1] == node)
		{
			side = 1;
			VectorSubtract(vec3_origin, p->plane.normal, normal);
			dist = -p->plane.dist;
		} //end else if
		else
		{
			Error("MakeNodePortal: mislinked portal");
		} //end else

		ChopWindingInPlace(&w, normal, dist, 0.1);
	} //end for

	if(!w)
	{
		return;
	} //end if

	if(WindingIsTiny(w))
	{
		c_tinyportals++;
		FreeWinding(w);
		return;
	} //end if

#ifdef DEBUG
	/* //NOTE: don't use this winding ok check
	    // all the invalid windings only have a degenerate edge
	    if (WindingError(w))
	    {
	        Log_Print("MakeNodePortal: %s\n", WindingErrorString());
	        FreeWinding(w);
	        return;
	    } //end if*/
#endif //DEBUG


	new_portal = AllocPortal();
	new_portal->plane = mapplanes[node->planenum];

#ifdef ME
	new_portal->planenum = node->planenum;
#endif //ME

	new_portal->onnode = node;
	new_portal->winding = w;
	AddPortalToNodes(new_portal, node->children[0], node->children[1]);
} //end of the function MakeNodePortal
コード例 #3
0
ファイル: portals.c プロジェクト: Diskutant/RTCW-SP
//===========================================================================
// Move or split the portals that bound node so that the node's
// children have portals instead of node.
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
void SplitNodePortals(node_t *node)
{
	portal_t    *p, *next_portal, *new_portal;
	node_t *f, *b, *other_node;
	int side = 0; // TTimo: init
	plane_t *plane;
	winding_t *frontwinding, *backwinding;

	plane = &mapplanes[node->planenum];
	f = node->children[0];
	b = node->children[1];

	for(p = node->portals ; p ; p = next_portal)
	{
		if(p->nodes[0] == node)
		{
			side = 0;
		}
		else if(p->nodes[1] == node)
		{
			side = 1;
		}
		else
		{
			Error("SplitNodePortals: mislinked portal");
		}

		next_portal = p->next[side];

		other_node = p->nodes[!side];
		RemovePortalFromNode(p, p->nodes[0]);
		RemovePortalFromNode(p, p->nodes[1]);

//
// cut the portal into two portals, one on each side of the cut plane
//
		ClipWindingEpsilon(p->winding, plane->normal, plane->dist,
		                   SPLIT_WINDING_EPSILON, &frontwinding, &backwinding);

		if(frontwinding && WindingIsTiny(frontwinding))
		{
			FreeWinding(frontwinding);
			frontwinding = NULL;
			c_tinyportals++;
		} //end if

		if(backwinding && WindingIsTiny(backwinding))
		{
			FreeWinding(backwinding);
			backwinding = NULL;
			c_tinyportals++;
		} //end if

#ifdef DEBUG
		/*  //NOTE: don't use this winding ok check
		        // all the invalid windings only have a degenerate edge
		        if (frontwinding && WindingError(frontwinding))
		        {
		            Log_Print("SplitNodePortals: front %s\n", WindingErrorString());
		            FreeWinding(frontwinding);
		            frontwinding = NULL;
		        } //end if
		        if (backwinding && WindingError(backwinding))
		        {
		            Log_Print("SplitNodePortals: back %s\n", WindingErrorString());
		            FreeWinding(backwinding);
		            backwinding = NULL;
		        } //end if*/
#endif //DEBUG

		if(!frontwinding && !backwinding)      // tiny windings on both sides
		{
			continue;
		}

		if(!frontwinding)
		{
			FreeWinding(backwinding);

			if(side == 0)
			{
				AddPortalToNodes(p, b, other_node);
			}
			else
			{
				AddPortalToNodes(p, other_node, b);
			}

			continue;
		}

		if(!backwinding)
		{
			FreeWinding(frontwinding);

			if(side == 0)
			{
				AddPortalToNodes(p, f, other_node);
			}
			else
			{
				AddPortalToNodes(p, other_node, f);
			}

			continue;
		}

		// the winding is split
		new_portal = AllocPortal();
		*new_portal = *p;
		new_portal->winding = backwinding;
		FreeWinding(p->winding);
		p->winding = frontwinding;

		if(side == 0)
		{
			AddPortalToNodes(p, f, other_node);
			AddPortalToNodes(new_portal, b, other_node);
		} //end if
		else
		{
			AddPortalToNodes(p, other_node, f);
			AddPortalToNodes(new_portal, other_node, b);
		} //end else
	}

	node->portals = NULL;
} //end of the function SplitNodePortals
コード例 #4
0
ファイル: portals.c プロジェクト: Diskutant/RTCW-SP
void MakeHeadnodePortals(tree_t *tree)
{
	vec3_t bounds[2];
	int i, j, n;
	portal_t    *p, *portals[6];
	plane_t bplanes[6], *pl;
	node_t *node;

	node = tree->headnode;

// pad with some space so there will never be null volume leaves
	for(i = 0 ; i < 3 ; i++)
	{
		bounds[0][i] = tree->mins[i] - SIDESPACE;
		bounds[1][i] = tree->maxs[i] + SIDESPACE;
	}

	tree->outside_node.planenum = PLANENUM_LEAF;
	tree->outside_node.brushlist = NULL;
	tree->outside_node.portals = NULL;
	tree->outside_node.contents = 0;

	for(i = 0 ; i < 3 ; i++)
		for(j = 0 ; j < 2 ; j++)
		{
			n = j * 3 + i;

			p = AllocPortal();
			portals[n] = p;

			pl = &bplanes[n];
			memset(pl, 0, sizeof(*pl));

			if(j)
			{
				pl->normal[i] = -1;
				pl->dist = -bounds[j][i];
			}
			else
			{
				pl->normal[i] = 1;
				pl->dist = bounds[j][i];
			}

			p->plane = *pl;
			p->winding = BaseWindingForPlane(pl->normal, pl->dist);
			AddPortalToNodes(p, node, &tree->outside_node);
		}

// clip the basewindings by all the other planes
	for(i = 0 ; i < 6 ; i++)
	{
		for(j = 0 ; j < 6 ; j++)
		{
			if(j == i)
			{
				continue;
			}

			ChopWindingInPlace(&portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON);
		} //end for
	} //end for
} //end of the function MakeHeadNodePortals
コード例 #5
0
/*
==============
SplitNodePortals

Move or split the portals that bound node so that the node's
children have portals instead of node.
==============
*/
static void SplitNodePortals( node_t *node ) {
	uPortal_t	*p, *next_portal, *new_portal;
	node_t		*f, *b, *other_node;
	int			side;
	idPlane		*plane;
	idWinding	*frontwinding, *backwinding;
	plane = &dmapGlobals.mapPlanes[node->planenum];
	f = node->children[0];
	b = node->children[1];
	for( p = node->portals ; p ; p = next_portal ) {
		if( p->nodes[0] == node ) {
			side = 0;
		} else if( p->nodes[1] == node ) {
			side = 1;
		} else {
			common->Error( "SplitNodePortals: mislinked portal" );
			side = 0;	// quiet a compiler warning
		}
		next_portal = p->next[side];
		other_node = p->nodes[!side];
		RemovePortalFromNode( p, p->nodes[0] );
		RemovePortalFromNode( p, p->nodes[1] );
		//
		// cut the portal into two portals, one on each side of the cut plane
		//
		p->winding->Split( *plane, SPLIT_WINDING_EPSILON, &frontwinding, &backwinding );
		if( frontwinding && frontwinding->IsTiny() ) {
			delete frontwinding;
			frontwinding = NULL;
			c_tinyportals++;
		}
		if( backwinding && backwinding->IsTiny() ) {
			delete backwinding;
			backwinding = NULL;
			c_tinyportals++;
		}
		if( !frontwinding && !backwinding ) {
			// tiny windings on both sides
			continue;
		}
		if( !frontwinding ) {
			delete backwinding;
			if( side == 0 ) {
				AddPortalToNodes( p, b, other_node );
			} else {
				AddPortalToNodes( p, other_node, b );
			}
			continue;
		}
		if( !backwinding ) {
			delete frontwinding;
			if( side == 0 ) {
				AddPortalToNodes( p, f, other_node );
			} else {
				AddPortalToNodes( p, other_node, f );
			}
			continue;
		}
		// the winding is split
		new_portal = AllocPortal();
		*new_portal = *p;
		new_portal->winding = backwinding;
		delete p->winding;
		p->winding = frontwinding;
		if( side == 0 ) {
			AddPortalToNodes( p, f, other_node );
			AddPortalToNodes( new_portal, b, other_node );
		} else {
			AddPortalToNodes( p, other_node, f );
			AddPortalToNodes( new_portal, other_node, b );
		}
	}
	node->portals = NULL;
}
コード例 #6
0
ファイル: portals.c プロジェクト: AEonZR/GtkRadiant
/*
==================
MakeNodePortal

create the new portal by taking the full plane winding for the cutting plane
and clipping it by all of parents of this node
==================
*/
void MakeNodePortal (node_t *node)
{
    portal_t	*new_portal, *p;
    winding_t	*w;
    vec3_t		normal;
    float		dist;
    int			side;

    w = BaseWindingForNode (node);

    // clip the portal by all the other portals in the node
    for (p = node->portals ; p && w; p = p->next[side])
    {
        if (p->nodes[0] == node)
        {
            side = 0;
            VectorCopy (p->plane.normal, normal);
            dist = p->plane.dist;
        }
        else if (p->nodes[1] == node)
        {
            side = 1;
            VectorSubtract (vec3_origin, p->plane.normal, normal);
            dist = -p->plane.dist;
        }
        else
            Error ("CutNodePortals_r: mislinked portal");

        ChopWindingInPlace (&w, normal, dist, CLIP_EPSILON);
    }

    if (!w)
    {
        return;
    }


    /* ydnar: adding this here to fix degenerate windings */
#if 0
    if( FixWinding( w ) == qfalse )
    {
        c_badportals++;
        FreeWinding( w );
        return;
    }
#endif

    if (WindingIsTiny (w))
    {
        c_tinyportals++;
        FreeWinding (w);
        return;
    }

    new_portal = AllocPortal ();
    new_portal->plane = mapplanes[node->planenum];
    new_portal->onnode = node;
    new_portal->winding = w;
    new_portal->compileFlags = node->compileFlags;
    AddPortalToNodes (new_portal, node->children[0], node->children[1]);
}
コード例 #7
0
ファイル: portals.cpp プロジェクト: revelator/MHDoom
static void MakeHeadnodePortals( tree_t *tree )
{
	idBounds	bounds;
	int			i, j, n;
	uPortal_t	*p, *portals[6];
	idPlane		bplanes[6], *pl;
	node_t *node;
	
	node = tree->headnode;
	
	tree->outside_node.planenum = PLANENUM_LEAF;
	tree->outside_node.brushlist = NULL;
	tree->outside_node.portals = NULL;
	tree->outside_node.opaque = false;
	
	// if no nodes, don't go any farther
	if( node->planenum == PLANENUM_LEAF )
	{
		return;
	}
	
	// pad with some space so there will never be null volume leafs
	for( i = 0; i < 3; i++ )
	{
		bounds[0][i] = tree->bounds[0][i] - SIDESPACE;
		bounds[1][i] = tree->bounds[1][i] + SIDESPACE;
		
		if( bounds[0][i] >= bounds[1][i] )
		{
			common->Error( "Backwards tree volume" );
		}
	}
	
	for( i = 0; i < 3; i++ )
	{
		for( j = 0; j < 2; j++ )
		{
			n = j * 3 + i;
			
			p = AllocPortal();
			portals[n] = p;
			
			pl = &bplanes[n];
			memset( pl, 0, sizeof( *pl ) );
			
			if( j )
			{
				( *pl ) [i] = -1;
				( *pl ) [3] = bounds[j][i];
			}
			else
			{
				( *pl ) [i] = 1;
				( *pl ) [3] = -bounds[j][i];
			}
			
			p->plane = *pl;
			p->winding = new idWinding( *pl );
			AddPortalToNodes( p, node, &tree->outside_node );
		}
	}
	
	// clip the basewindings by all the other planes
	for( i = 0; i < 6; i++ )
	{
		for( j = 0; j < 6; j++ )
		{
			if( j == i )
			{
				continue;
			}
			
			portals[i]->winding = portals[i]->winding->Clip( bplanes[j], ON_EPSILON );
		}
	}
}
コード例 #8
0
/*
================
CutNodePortals_r
================
*/
static void CutNodePortals_r (node_t *node)
{
	plane_t 	*plane, clipplane;
	node_t		*f, *b, *other_node;
	portal_t	*p, *new_portal, *next_portal;
	winding_t	*w, *frontwinding, *backwinding;
	int			side;

	// Vic: properly calculate the bounding box
	CalcNodeBounds (node);

	//
	// separate the portals on node into it's children
	//
	if (node->contents)
		return;			// at a leaf, no more dividing

	plane = &mapplanes[node->planenum];

	f = node->children[0];
	b = node->children[1];

	//
	// create the new portal by taking the full plane winding for the cutting plane
	// and clipping it by all of the planes from the other portals
	//
	w = BaseWindingForPlane (&mapplanes[node->planenum]);
	side = 0;	// shut up compiler warning
	for (p = node->portals ; p ; p = p->next[side])
	{
		clipplane = mapplanes[p->planenum];
		if (p->nodes[0] == node)
			side = 0;
		else if (p->nodes[1] == node)
		{
			clipplane.dist = -clipplane.dist;
			VectorNegate (clipplane.normal, clipplane.normal);
			side = 1;
		}
		else
			Error ("CutNodePortals_r: mislinked portal");

		w = ClipWinding (w, &clipplane, true);
		if (!w)
		{
			printf ("WARNING: CutNodePortals_r:new portal was clipped away\n");
			break;
		}
	}

	if (w)
	{
		// if the plane was not clipped on all sides, there was an error
		new_portal = AllocPortal ();
		new_portal->planenum = node->planenum;
		new_portal->winding = w;
		AddPortalToNodes (new_portal, f, b);
	}

	// partition the portals
	for (p = node->portals ; p ; p = next_portal)
	{
		if (p->nodes[0] == node)
			side = 0;
		else if (p->nodes[1] == node)
			side = 1;
		else
			Error ("CutNodePortals_r: mislinked portal");
		next_portal = p->next[side];

		other_node = p->nodes[!side];
		RemovePortalFromNode (p, p->nodes[0]);
		RemovePortalFromNode (p, p->nodes[1]);

		// cut the portal into two portals, one on each side of the cut plane
		DivideWindingEpsilon( p->winding, plane, &frontwinding, &backwinding, ON_EPSILON );

		if (!frontwinding)
		{
			if (side == 0)
				AddPortalToNodes (p, b, other_node);
			else
				AddPortalToNodes (p, other_node, b);
			continue;
		}
		if (!backwinding)
		{
			if (side == 0)
				AddPortalToNodes (p, f, other_node);
			else
				AddPortalToNodes (p, other_node, f);
			continue;
		}

		// the winding is split
		new_portal = AllocPortal ();
		*new_portal = *p;
		new_portal->winding = backwinding;
		FreeWinding (p->winding);
		p->winding = frontwinding;

		if (side == 0)
		{
			AddPortalToNodes (p, f, other_node);
			AddPortalToNodes (new_portal, b, other_node);
		}
		else
		{
			AddPortalToNodes (p, other_node, f);
			AddPortalToNodes (new_portal, other_node, b);
		}
	}

	CutNodePortals_r (f);
	CutNodePortals_r (b);
}