Exemplo n.º 1
0
void R_BoxSurfaces_r(mnode_t *node, vector3 *mins, vector3 *maxs, surfaceType_t **list, int listsize, int *listlength, vector3 *dir) {

	int			s, c;
	msurface_t	*surf, **mark;

	// do the tail recursion in a loop
	while ( node->contents == -1 ) {
		s = BoxOnPlaneSide( mins, maxs, node->plane );
		if (s == 1) {
			node = node->children[0];
		} else if (s == 2) {
			node = node->children[1];
		} else {
			R_BoxSurfaces_r(node->children[0], mins, maxs, list, listsize, listlength, dir);
			node = node->children[1];
		}
	}

	// add the individual surfaces
	mark = node->firstmarksurface;
	c = node->nummarksurfaces;
	while (c--) {
		//
		if (*listlength >= listsize) break;
		//
		surf = *mark;

		//QtZ: optimization from UrT, this surface has already been checked
		if (surf->viewCount == tr.viewCount)
			continue;

		// check if the surface has NOIMPACT or NOMARKS set
		if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) )
			|| ( surf->shader->contentFlags & CONTENTS_FOG ) ) {
			surf->viewCount = tr.viewCount;
		}
		// extra check for surfaces to avoid list overflows
		else if (*(surf->data) == SF_FACE) {
			// the face plane should go through the box
			s = BoxOnPlaneSide( mins, maxs, &(( srfSurfaceFace_t * ) surf->data)->plane );
			if (s == 1 || s == 2) {
				surf->viewCount = tr.viewCount;
			} else if (DotProduct(&(( srfSurfaceFace_t * ) surf->data)->plane.normal, dir) > -0.5f) {
			// don't add faces that make sharp angles with the projection direction
				surf->viewCount = tr.viewCount;
			}
		}
		else if (*(surfaceType_t *) (surf->data) != SF_GRID &&
			 *(surfaceType_t *) (surf->data) != SF_TRIANGLES)
			surf->viewCount = tr.viewCount;
		// check the viewCount because the surface may have
		// already been added if it spans multiple leafs
		if (surf->viewCount != tr.viewCount) {
			surf->viewCount = tr.viewCount;
			list[*listlength] = (surfaceType_t *) surf->data;
			(*listlength)++;
		}
		mark++;
	}
}
Exemplo n.º 2
0
/*
============
QuickTestBrushToPlanenum

============
*/
int	QuickTestBrushToPlanenum (bspbrush_t *brush, int planenum, int *numsplits)
{
	int			i, num;
	plane_t		*plane;
	int			s;

	*numsplits = 0;

	// if the brush actually uses the planenum,
	// we can tell the side for sure
	for (i=0 ; i<brush->numsides ; i++)
	{
		num = brush->sides[i].planenum;
		if (num >= 0x10000)
			Error ("bad planenum");
		if (num == planenum)
			return PSIDE_BACK|PSIDE_FACING;
		if (num == (planenum ^ 1) )
			return PSIDE_FRONT|PSIDE_FACING;
	}

	// box on plane side
	plane = &mapplanes[planenum];
	s = BoxOnPlaneSide (brush->mins, brush->maxs, plane);

	// if both sides, count the visible faces split
	if (s == PSIDE_BOTH)
	{
		*numsplits += 3;
	}

	return s;
}
Exemplo n.º 3
0
/*
=============
CM_BoxLeafnums

Fills in a list of all the leafs touched
=============
*/
void CM_BoxLeafnums_r( leafList_t *ll, int nodenum ) {
	cplane_t    *plane;
	cNode_t     *node;
	int s;

	while ( 1 ) {
		if ( nodenum < 0 ) {
			ll->storeLeafs( ll, nodenum );
			return;
		}

		node = &cm.nodes[nodenum];
		plane = node->plane;
		s = BoxOnPlaneSide( ll->bounds[0], ll->bounds[1], plane );
		if ( s == 1 ) {
			nodenum = node->children[0];
		} else if ( s == 2 ) {
			nodenum = node->children[1];
		} else {
			// go down both
			CM_BoxLeafnums_r( ll, node->children[0] );
			nodenum = node->children[1];
		}

	}
}
Exemplo n.º 4
0
/*
=================
R_BoxSurfaces_r

=================
*/
void R_BoxSurfaces_r(mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int *listbmodel, int listsize, int *listlength, vec3_t dir) {

	int			s, c;
	int *mark;

	// do the tail recursion in a loop
	while ( !node->isLeaf ) {
		s = BoxOnPlaneSide( mins, maxs, node->plane );
		if (s == 1) {
			node = node->children[0];
		} else if (s == 2) {
			node = node->children[1];
		} else {
			R_BoxSurfaces_r(node->children[0], mins, maxs, list, listbmodel, listsize, listlength, dir);
			node = node->children[1];
		}
	}

	// add the individual surfaces
	mark = tr.world->marksurfaces + node->firstmarksurface;
	c = node->nummarksurfaces;
	while (c--) {
		//
		if (*listlength >= listsize) break;
		//
		R_AddSurfaceToList( 0, *mark, mins, maxs, list, listbmodel, listsize, listlength, dir );

		mark++;
	}
}
Exemplo n.º 5
0
static inline qboolean GL_ClipNode( mnode_t *node, int *clipflags ) {
    int flags = *clipflags;
    int i, bits, mask;
    
    if( flags == NODE_UNCLIPPED ) {
        return qtrue;
    }
    for( i = 0, mask = 1; i < 4; i++, mask <<= 1 ) {
        if( flags & mask ) {
            continue;
        }
        bits = BoxOnPlaneSide( node->mins, node->maxs,
            &glr.frustumPlanes[i] );
        if( bits == BOX_BEHIND ) {
            return qfalse;
        }
        if( bits == BOX_INFRONT ) {
            flags |= mask;
        }
    }

    *clipflags = flags;

    return qtrue;
}
Exemplo n.º 6
0
qboolean FrustumCheck::R_CullBox (vec3_t mins, vec3_t maxs)
{
	int i;
	for (i=0 ; i<4 ; i++)
	{
		if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2)
			return true;
	}

	// buz: also check clipping by distance
	if (farclipset)
	{
		if (BoxOnPlaneSide (mins, maxs, &farclip) == 2)
			return true;
	}

	return false;
}
Exemplo n.º 7
0
/*
=================
R_CullBox

Returns true if the box is completely outside the frustom
=================
*/
qboolean R_CullBox (vec3_t mins, vec3_t maxs)
{
	int		i;

	for (i=0 ; i<4 ; i++)
		if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2)
			return true;
	return false;
}
Exemplo n.º 8
0
/*
=================
CG_CullBox

returns true if culled
=================
*/
qboolean CG_CullBox(vec3_t mins, vec3_t maxs)
{
	int              i;
	cplane_t         *frust;

	//check against frustum planes
	for( i = 0; i < 4; i++ )
	{
		frust = &frustum[i];

		if( BoxOnPlaneSide(mins, maxs, frust ) == 2 )
			return qtrue;
	}
	return qfalse;
}
Exemplo n.º 9
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int QuickTestBrushToPlanenum( bspbrush_t *brush, int planenum, int *numsplits ) {
	int i, num;
	plane_t *plane;
	int s;

	*numsplits = 0;

	plane = &mapplanes[planenum];

#ifdef ME
	//fast axial cases
	if ( plane->type < 3 ) {
		if ( plane->dist + PLANESIDE_EPSILON < brush->mins[plane->type] ) {
			return PSIDE_FRONT;
		}
		if ( plane->dist - PLANESIDE_EPSILON > brush->maxs[plane->type] ) {
			return PSIDE_BACK;
		}
	} //end if
#endif //ME*/

	// if the brush actually uses the planenum,
	// we can tell the side for sure
	for ( i = 0; i < brush->numsides; i++ )
	{
		num = brush->sides[i].planenum;
		if ( num >= MAX_MAPFILE_PLANES ) {
			Error( "bad planenum" );
		}
		if ( num == planenum ) {
			return PSIDE_BACK | PSIDE_FACING;
		}
		if ( num == ( planenum ^ 1 ) ) {
			return PSIDE_FRONT | PSIDE_FACING;
		}

	}

	// box on plane side
	s = BoxOnPlaneSide( brush->mins, brush->maxs, plane );

	// if both sides, count the visible faces split
	if ( s == PSIDE_BOTH ) {
		*numsplits += 3;
	}

	return s;
} //end of the function QuickTestBrushToPlanenum
Exemplo n.º 10
0
static void R_BoxSurfaces_r( mbrush46_node_t* node, vec3_t mins, vec3_t maxs,
	idWorldSurface** list, int listsize, int* listlength, vec3_t dir ) {
	// RF, if this node hasn't been rendered recently, ignore it
	if ( GGameType & ( GAME_WolfSP | GAME_WolfMP | GAME_ET ) &&
		 node->visframe < tr.visCount - 2 ) {	// allow us to be a few frames behind
		return;
	}

	// do the tail recursion in a loop
	while ( node->contents == -1 ) {
		int s = BoxOnPlaneSide( mins, maxs, node->plane );
		if ( s == 1 ) {
			node = node->children[ 0 ];
		} else if ( s == 2 ) {
			node = node->children[ 1 ];
		} else {
			R_BoxSurfaces_r( node->children[ 0 ], mins, maxs, list, listsize, listlength, dir );
			node = node->children[ 1 ];
		}
	}

	// Ridah, don't mark alpha surfaces
	if ( GGameType & ( GAME_WolfSP | GAME_WolfMP | GAME_ET ) &&
		 node->contents & BSP46CONTENTS_TRANSLUCENT ) {
		return;
	}

	// add the individual surfaces
	idWorldSurface** mark = node->firstmarksurface;
	int c = node->nummarksurfaces;
	while ( c-- ) {
		if ( *listlength >= listsize ) {
			break;
		}
		idWorldSurface* surf = *mark;
		if ( !surf->CheckAddMarks( mins, maxs, dir ) ) {
			surf->viewCount = tr.viewCount;
		}
		// check the viewCount because the surface may have
		// already been added if it spans multiple leafs
		if ( surf->viewCount != tr.viewCount ) {
			surf->viewCount = tr.viewCount;
			list[ *listlength ] = surf;
			( *listlength )++;
		}
		mark++;
	}
}
Exemplo n.º 11
0
/*
===================
R_VisCullBox
===================
*/
bool R_VisCullBox( const Vector &mins, const Vector &maxs )
{
	Vector extmins, extmaxs;
	mnode_t *localstack[2048];
	int stackdepth = 0;

	if( !worldmodel || !RI.drawWorld )
		return false;

	if( r_novis->value )
		return false;

	for( int i = 0; i < 3; i++ )
	{
		extmins[i] = mins[i] - 4;
		extmaxs[i] = maxs[i] + 4;
	}

	for( mnode_t *node = worldmodel->nodes; node; )
	{
		if( node->visframe != tr.visframecount )
		{
			if( !stackdepth )
				return true;
			node = localstack[--stackdepth];
			continue;
		}

		if( node->contents < 0 )
			return false;

		int s = BoxOnPlaneSide( extmins, extmaxs, node->plane ) - 1;

		if( s < 2 )
		{
			node = node->children[s];
			continue;
		}

		// go down both sides
		if( stackdepth < ARRAYSIZE( localstack ))
			localstack[stackdepth++] = node->children[0];
		node = node->children[1];
	}

	return true;
}
Exemplo n.º 12
0
/*
=================
R_AddSurfaceToList

mins and maxs needs to be in bmodel local space
=================
*/
void R_AddSurfaceToList( int bmodelNum, int surfNum, vec3_t mins, vec3_t maxs, surfaceType_t **list, int *listbmodel, int listsize, int *listlength, vec3_t dir ) {
	int *surfViewCount;
	msurface_t	*surf;
	int s;

	if (*listlength >= listsize)
		return;

	surfViewCount = &tr.world->surfacesViewCount[surfNum];
	surf = ( msurface_t * )( tr.world->surfaces + surfNum );

	// check if the surface has NOIMPACT or NOMARKS set
	if ( surf->shader->surfaceParms & ( SURF_NOIMPACT | SURF_NOMARKS | SURF_FOG ) ) {
		*surfViewCount = tr.viewCount;
	}
	// extra check for surfaces to avoid list overflows
	else if (*(surf->data) == SF_FACE) {
		// the face plane should go through the box
		s = BoxOnPlaneSide( mins, maxs, &surf->cullinfo.plane );
		if (s == 1 || s == 2) {
			*surfViewCount = tr.viewCount;
		} else if (DotProduct(surf->cullinfo.plane.normal, dir) > -0.5) {
		// don't add faces that make sharp angles with the projection direction
			*surfViewCount = tr.viewCount;
		}
	}
	else if (*(surf->data) != SF_GRID &&
		 *(surf->data) != SF_TRIANGLES)
		*surfViewCount = tr.viewCount;
	// check the viewCount because the surface may have
	// already been added if it spans multiple leafs
	if (*surfViewCount != tr.viewCount) {
		*surfViewCount = tr.viewCount;
		list[*listlength] = surf->data;
		listbmodel[*listlength] = bmodelNum;
		(*listlength)++;
	}
}
Exemplo n.º 13
0
/*
=================
R_BoxSurfaces_r

=================
*/
void R_BoxSurfaces_r(mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int listsize, int *listlength, vec3_t dir)
{

	int        s, c;
	msurface_t *surf;
	int        *mark;

	// do the tail recursion in a loop
	while (node->contents == -1)
	{
		s = BoxOnPlaneSide(mins, maxs, node->plane);
		if (s == 1)
		{
			node = node->children[0];
		}
		else if (s == 2)
		{
			node = node->children[1];
		}
		else
		{
			R_BoxSurfaces_r(node->children[0], mins, maxs, list, listsize, listlength, dir);
			node = node->children[1];
		}
	}

	// Ridah, don't mark alpha surfaces
	if (node->contents & CONTENTS_TRANSLUCENT)
	{
		return;
	}

	// add the individual surfaces
	mark = tr.world->marksurfaces + node->firstmarksurface;
	c    = node->nummarksurfaces;
	while (c--)
	{
		int *surfViewCount;
		//
		if (*listlength >= listsize)
		{
			break;
		}
		//
		surfViewCount = &tr.world->surfacesViewCount[*mark];
		surf          = tr.world->surfaces + *mark;
		// check if the surface has NOIMPACT or NOMARKS set
		if ((surf->shader->surfaceFlags & (SURF_NOIMPACT | SURF_NOMARKS))
		    || (surf->shader->contentFlags & CONTENTS_FOG))
		{
			*surfViewCount = tr.viewCount;
		}
		// extra check for surfaces to avoid list overflows
		else if (*(surf->data) == SF_FACE)
		{
			// the face plane should go through the box
			s = BoxOnPlaneSide(mins, maxs, &surf->cullinfo.plane);
			if (s == 1 || s == 2)
			{
				*surfViewCount = tr.viewCount;
			}
			else if (DotProduct(surf->cullinfo.plane.normal, dir) > -0.5)
			{
				// don't add faces that make sharp angles with the projection direction
				*surfViewCount = tr.viewCount;
			}
		}
		else if (*(surf->data) != SF_GRID &&
		         *(surf->data) != SF_TRIANGLES)
		{
			*surfViewCount = tr.viewCount;
		}
		// check the viewCount because the surface may have
		// already been added if it spans multiple leafs
		if (*surfViewCount != tr.viewCount)
		{
			*surfViewCount    = tr.viewCount;
			list[*listlength] = surf->data;
			(*listlength)++;
		}
		mark++;
	}
}
Exemplo n.º 14
0
/*
=================
R_BoxSurfaces_r

=================
*/
void R_BoxSurfaces_r(mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int listsize, int *listlength, vec3_t dir) {

	int			s, c;
	msurface_t	*surf, **mark;

	// do the tail recursion in a loop
	while ( node->contents == -1 ) {
#ifdef _XBOX
		s = BoxOnPlaneSide( mins, maxs, tr.world->planes + node->planeNum );
#else
		s = BoxOnPlaneSide( mins, maxs, node->plane );
#endif
		if (s == 1) {
			node = node->children[0];
		} else if (s == 2) {
			node = node->children[1];
		} else {
			R_BoxSurfaces_r(node->children[0], mins, maxs, list, listsize, listlength, dir);
			node = node->children[1];
		}
	}

	// add the individual surfaces
#ifdef _XBOX
	mleaf_s *leaf = (mleaf_s*)node;
	mark = tr.world->marksurfaces + leaf->firstMarkSurfNum;
	c = leaf->nummarksurfaces;
#else
	mark = node->firstmarksurface;
	c = node->nummarksurfaces;
#endif
	while (c--) {
		//
		if (*listlength >= listsize) break;
		//
		surf = *mark;
		// check if the surface has NOIMPACT or NOMARKS set
		if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) )
			|| ( surf->shader->contentFlags & CONTENTS_FOG ) ) {
			surf->viewCount = tr.viewCount;
		}
		// extra check for surfaces to avoid list overflows
		else if (*(surf->data) == SF_FACE) {
			// the face plane should go through the box
			s = BoxOnPlaneSide( mins, maxs, &(( srfSurfaceFace_t * ) surf->data)->plane );
			if (s == 1 || s == 2) {
				surf->viewCount = tr.viewCount;
			} else if (DotProduct((( srfSurfaceFace_t * ) surf->data)->plane.normal, dir) > -0.5) {
			// don't add faces that make sharp angles with the projection direction
				surf->viewCount = tr.viewCount;
			}
		}
		else if (*(surfaceType_t *) (surf->data) != SF_GRID) surf->viewCount = tr.viewCount;
		// check the viewCount because the surface may have
		// already been added if it spans multiple leafs
		if (surf->viewCount != tr.viewCount) {
			surf->viewCount = tr.viewCount;
			list[*listlength] = (surfaceType_t *) surf->data;
			(*listlength)++;
		}
		mark++;
	}
}
Exemplo n.º 15
0
/*
================
R_RecursiveMirrorNode
================
*/
void R_RecursiveMirrorNode( mnode_t *node, uint clipflags )
{
	mextrasurf_t	*extrasurf;
	const mplane_t	*clipplane;
	int		i, clipped;
	msurface_t	*surf, **mark;
	mleaf_t		*pleaf;
	int		c, side;
	float		dot;

	if( node->contents == CONTENTS_SOLID )
		return; // hit a solid leaf

	if( node->visframe != tr.visframecount )
		return;

	if( clipflags )
	{
		for( i = 0, clipplane = RI.frustum; i < 6; i++, clipplane++ )
		{
			if(!( clipflags & ( 1<<i )))
				continue;

			clipped = BoxOnPlaneSide( node->minmaxs, node->minmaxs + 3, clipplane );
			if( clipped == 2 ) return;
			if( clipped == 1 ) clipflags &= ~(1<<i);
		}
	}

	// if a leaf node, draw stuff
	if( node->contents < 0 )
	{
		pleaf = (mleaf_t *)node;

		mark = pleaf->firstmarksurface;
		c = pleaf->nummarksurfaces;

		if( c )
		{
			do
			{
				(*mark)->visframe = tr.framecount;
				mark++;
			} while( --c );
		}
		return;
	}

	// node is just a decision point, so go down the apropriate sides

	// find which side of the node we are on
	dot = PlaneDiff( tr.modelorg, node->plane );
	side = (dot >= 0) ? 0 : 1;

	// recurse down the children, front side first
	R_RecursiveMirrorNode( node->children[side], clipflags );

	// draw stuff
	for( c = node->numsurfaces, surf = cl.worldmodel->surfaces + node->firstsurface; c; c--, surf++ )
	{
		if(!( surf->flags & SURF_REFLECT ))
			continue;

		if( R_CullSurface( surf, clipflags ))
			continue;

		extrasurf = SURF_INFO( surf, RI.currentmodel );
		extrasurf->mirrorchain = tr.mirror_entities[0].chain;
		tr.mirror_entities[0].chain = extrasurf;
	}

	// recurse down the back side
	R_RecursiveMirrorNode( node->children[!side], clipflags );
}
Exemplo n.º 16
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int TestBrushToPlanenum( bspbrush_t *brush, int planenum,
						 int *numsplits, qboolean *hintsplit, int *epsilonbrush ) {
	int i, j, num;
	plane_t *plane;
	int s = 0;
	winding_t *w;
	vec_t d, d_front, d_back;
	int front, back;
	int type;
	float dist;

	*numsplits = 0;
	*hintsplit = false;

	plane = &mapplanes[planenum];

#ifdef ME
// fast axial cases
	type = plane->type;
	if ( type < 3 ) {
		dist = plane->dist;
		if ( dist + PLANESIDE_EPSILON < brush->mins[type] ) {
			return PSIDE_FRONT;
		}
		if ( dist - PLANESIDE_EPSILON > brush->maxs[type] ) {
			return PSIDE_BACK;
		}
		if ( brush->mins[type] < dist - PLANESIDE_EPSILON &&
			 brush->maxs[type] > dist + PLANESIDE_EPSILON ) {
			s = PSIDE_BOTH;
		}
	} //end if

	if ( s != PSIDE_BOTH )
#endif //ME
	{
		// if the brush actually uses the planenum,
		// we can tell the side for sure
		for ( i = 0; i < brush->numsides; i++ )
		{
			num = brush->sides[i].planenum;
			if ( num >= MAX_MAPFILE_PLANES ) {
				Error( "bad planenum" );
			}
			if ( num == planenum ) {
				//we don't need to test this side plane again
				brush->sides[i].flags |= SFL_TESTED;
				return PSIDE_BACK | PSIDE_FACING;
			} //end if
			if ( num == ( planenum ^ 1 ) ) {
				//we don't need to test this side plane again
				brush->sides[i].flags |= SFL_TESTED;
				return PSIDE_FRONT | PSIDE_FACING;
			} //end if
		} //end for

		// box on plane side
		s = BoxOnPlaneSide( brush->mins, brush->maxs, plane );

		if ( s != PSIDE_BOTH ) {
			return s;
		}
	} //end if

// if both sides, count the visible faces split
	d_front = d_back = 0;

	for ( i = 0; i < brush->numsides; i++ )
	{
		if ( brush->sides[i].texinfo == TEXINFO_NODE ) {
			continue;       // on node, don't worry about splits
		}
		if ( !( brush->sides[i].flags & SFL_VISIBLE ) ) {
			continue;       // we don't care about non-visible
		}
		w = brush->sides[i].winding;
		if ( !w ) {
			continue;
		}
		front = back = 0;
		for ( j = 0; j < w->numpoints; j++ )
		{
			d = DotProduct( w->p[j], plane->normal ) - plane->dist;
			if ( d > d_front ) {
				d_front = d;
			}
			if ( d < d_back ) {
				d_back = d;
			}
			if ( d > 0.1 ) { // PLANESIDE_EPSILON)
				front = 1;
			}
			if ( d < -0.1 ) { // PLANESIDE_EPSILON)
				back = 1;
			}
		} //end for
		if ( front && back ) {
			if ( !( brush->sides[i].surf & SURF_SKIP ) ) {
				( *numsplits )++;
				if ( brush->sides[i].surf & SURF_HINT ) {
					*hintsplit = true;
				} //end if
			} //end if
		} //end if
	} //end for

	if ( ( d_front > 0.0 && d_front < 1.0 )
		 || ( d_back < 0.0 && d_back > -1.0 ) ) {
		( *epsilonbrush )++;
	}

#if 0
	if ( *numsplits == 0 ) { //	didn't really need to be split
		if ( front ) {
			s = PSIDE_FRONT;
		} else if ( back ) {
			s = PSIDE_BACK;
		} else { s = 0;}
	}
#endif

	return s;
} //end of the function TestBrushToPlanenum
Exemplo n.º 17
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CNPC_VehicleDriver::OverridePathMove( float flInterval )
{
	// Setup our initial path data if we've just started running a path
	if ( !m_pCurrentWaypoint )
	{
		m_vecPrevPoint = GetAbsOrigin();
		m_vecPrevPrevPoint = GetAbsOrigin();
		m_vecDesiredPosition = GetNavigator()->GetCurWaypointPos();	
		CalculatePostPoints();
	
		// Init our two waypoints
		m_Waypoints[0] = new CVehicleWaypoint( m_vecPrevPrevPoint, m_vecPrevPoint, m_vecDesiredPosition, m_vecPostPoint );
		m_Waypoints[1] = new CVehicleWaypoint( m_vecPrevPoint, m_vecDesiredPosition, m_vecPostPoint, m_vecPostPostPoint );
		m_pCurrentWaypoint = m_Waypoints[0];
		m_pNextWaypoint = m_Waypoints[1];

		m_flDistanceAlongSpline = 0.2;
	}

	// Have we reached our target? See if we've passed the current waypoint's plane.
	Vector vecAbsMins, vecAbsMaxs;
	CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs );
	if ( BoxOnPlaneSide( vecAbsMins, vecAbsMaxs, &m_pCurrentWaypoint->planeWaypoint ) == 3 )
	{
		if ( WaypointReached() )
			return true;
	}

	// Did we bypass it and reach the next one already?
	if ( m_pNextWaypoint && BoxOnPlaneSide( vecAbsMins, vecAbsMaxs, &m_pNextWaypoint->planeWaypoint ) == 3 )
	{
		if ( WaypointReached() )
			return true;
	}

	// We may have just teleported, so check to make sure we have a waypoint
	if ( !m_pCurrentWaypoint || !m_pNextWaypoint )
		return false;

	// Figure out which spline we're trucking along
	CVehicleWaypoint *pCurrentSplineBeingTraversed = m_pCurrentWaypoint;
	if ( m_flDistanceAlongSpline > 1 )
	{
		pCurrentSplineBeingTraversed = m_pNextWaypoint;
	}

	// Get our current speed, and check it against the length of the spline to know how far to advance our marker
	AngularImpulse angVel;
	Vector vecVelocity;
	IPhysicsObject *pVehiclePhysics = m_hVehicleEntity->VPhysicsGetObject();

	if( !pVehiclePhysics )
	{
		// I think my vehicle has been destroyed.
		return false;
	}

	pVehiclePhysics->GetVelocity( &vecVelocity, &angVel );
	float flSpeed = vecVelocity.Length();
	float flIncTime = gpGlobals->curtime - GetLastThink();
	float flIncrement = flIncTime * (flSpeed / pCurrentSplineBeingTraversed->GetLength());

	// Now advance our point along the spline
	m_flDistanceAlongSpline = clamp( m_flDistanceAlongSpline + flIncrement, 0, 2);
	if ( m_flDistanceAlongSpline > 1 )
	{
		// We crossed the spline boundary
		pCurrentSplineBeingTraversed = m_pNextWaypoint;
	}

	Vector vSplinePoint = pCurrentSplineBeingTraversed->GetPointAt( m_flDistanceAlongSpline > 1 ? m_flDistanceAlongSpline-1 : m_flDistanceAlongSpline );
	Vector vSplineTangent = pCurrentSplineBeingTraversed->GetTangentAt( m_flDistanceAlongSpline > 1 ? m_flDistanceAlongSpline-1 : m_flDistanceAlongSpline );

	// Now that we've got the target spline point & tangent, use it to decide what our desired velocity is.
	// If we're close to the tangent, just use the tangent. Otherwise, Lerp towards it.
	Vector vecToDesired = (vSplinePoint - GetAbsOrigin());
	float flDistToDesired = VectorNormalize( vecToDesired );
	float flTangentLength = VectorNormalize( vSplineTangent );

	if ( flDistToDesired > (flTangentLength * 0.75) )
	{
		m_vecDesiredVelocity = vecToDesired * flTangentLength;
	}
	else
	{
		VectorLerp( vSplineTangent, vecToDesired * flTangentLength, (flDistToDesired / (flTangentLength * 0.5)), m_vecDesiredVelocity );
	}

	// Decrease speed according to the turn we're trying to make
	Vector vecRight;
	m_hVehicleEntity->GetVectors( NULL, &vecRight, NULL );
	Vector vecNormVel = m_vecDesiredVelocity;
	VectorNormalize( vecNormVel );
	float flDotRight = DotProduct( vecRight, vecNormVel );
	flSpeed = (1.0 - fabs(flDotRight));
	// Don't go slower than we've been told to go
	if ( flSpeed < m_flDriversMinSpeed )
	{
		flSpeed = m_flDriversMinSpeed;
	}
	m_vecDesiredVelocity = vecNormVel * (flSpeed * m_flMaxSpeed);

	// Bunch o'debug
	if ( g_debug_vehicledriver.GetInt() & DRIVER_DEBUG_PATH )
	{
		NDebugOverlay::Box( m_vecPrevPrevPoint, -Vector(15,15,15), Vector(15,15,15), 192,0,0, true, 0.1);
		NDebugOverlay::Box( m_vecPrevPoint, -Vector(20,20,20), Vector(20,20,20), 255,0,0, true, 0.1);
		NDebugOverlay::Box( m_vecPostPoint, -Vector(20,20,20), Vector(20,20,20), 0,192,0, true, 0.1);
		NDebugOverlay::Box( m_vecPostPostPoint, -Vector(20,20,20), Vector(20,20,20), 0,128,0, true, 0.1);
		NDebugOverlay::Box( vSplinePoint, -Vector(10,10,10), Vector(10,10,10), 0,0,255, true, 0.1);
		NDebugOverlay::Line( vSplinePoint, vSplinePoint + (vSplineTangent * 40), 0,0,255, true, 0.1);

		//NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[0], pCurrentSplineBeingTraversed->splinePoints[1], 30, 255,255,255,0, false, 0.1f );
		//NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[1], pCurrentSplineBeingTraversed->splinePoints[2], 20, 255,255,255,0, false, 0.1f );
		//NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[2], pCurrentSplineBeingTraversed->splinePoints[3], 10, 255,255,255,0, false, 0.1f );

		// Draw the plane we're checking against for waypoint passing
		Vector vecPlaneRight;
		CrossProduct( m_pCurrentWaypoint->planeWaypoint.normal, Vector(0,0,1), vecPlaneRight );
		Vector vecPlane = m_pCurrentWaypoint->splinePoints[2];
		NDebugOverlay::Line( vecPlane + (vecPlaneRight * -100), vecPlane + (vecPlaneRight * 100), 255,0,0, true, 0.1);

		// Draw the next plane too
		CrossProduct( m_pNextWaypoint->planeWaypoint.normal, Vector(0,0,1), vecPlaneRight );
		vecPlane = m_pNextWaypoint->splinePoints[2];
		NDebugOverlay::Line( vecPlane + (vecPlaneRight * -100), vecPlane + (vecPlaneRight * 100), 192,0,0, true, 0.1);
	}

	if ( g_debug_vehicledriver.GetInt() & DRIVER_DEBUG_PATH_SPLINE )
	{
		for ( int i = 0; i < 10; i++ )
		{
			Vector vecTarget = m_pCurrentWaypoint->GetPointAt( 0.1 * i );
			Vector vecTangent = m_pCurrentWaypoint->GetTangentAt( 0.1 * i );
			VectorNormalize(vecTangent);
			NDebugOverlay::Box( vecTarget, -Vector(10,10,10), Vector(10,10,10), 255,0,0, true, 0.1 );
			NDebugOverlay::Line( vecTarget, vecTarget + (vecTangent * 10), 255,255,0, true, 0.1);
		}
	}

	return true;
}
Exemplo n.º 18
0
/*
* R_RecursiveWorldNode
*/
static void R_RecursiveWorldNode( mnode_t *node, unsigned int clipFlags, 
	unsigned int dlightBits, unsigned int shadowBits )
{
	unsigned int i;
	unsigned int dlightBits1;
	unsigned int shadowBits1;
	unsigned int bit;
	const cplane_t *clipplane;
	mleaf_t	*pleaf;

	while( 1 )
	{
		if( node->pvsframe != rf.pvsframecount )
			return;

		if( clipFlags )
		{
			for( i = sizeof( rn.frustum )/sizeof( rn.frustum[0] ), bit = 1, clipplane = rn.frustum; i > 0; i--, bit<<=1, clipplane++ )
			{
				if( clipFlags & bit )
				{
					int clipped = BoxOnPlaneSide( node->mins, node->maxs, clipplane );
					if( clipped == 2 )
						return;
					else if( clipped == 1 )
						clipFlags &= ~bit; // node is entirely on screen
				}
			}
		}

		if( !node->plane )
			break;

		dlightBits1 = 0;
		if( dlightBits )
		{
			float dist;
			unsigned int checkBits = dlightBits;

			for( i = 0, bit = 1; i < rsc.numDlights; i++, bit <<= 1 )
			{
				dlight_t *dl = rsc.dlights + i;
				if( dlightBits & bit )
				{
					dist = PlaneDiff( dl->origin, node->plane );
					if( dist < -dl->intensity )
						dlightBits &= ~bit;
					if( dist < dl->intensity )
						dlightBits1 |= bit;

					checkBits &= ~bit;
					if( !checkBits )
						break;
				}
			}
		}

		shadowBits1 = 0;
		if( shadowBits )
		{
			unsigned int checkBits = shadowBits;

			for( i = 0; i < rsc.numShadowGroups; i++ )
			{
				shadowGroup_t *group = rsc.shadowGroups + i;
				bit = group->bit;
				if( checkBits & bit )
				{
					int clipped = BOX_ON_PLANE_SIDE( group->visMins, group->visMaxs, node->plane );
					if( !(clipped & 1) )
						shadowBits &= ~bit;
					if( clipped & 2 )
						shadowBits1 |= bit;

					checkBits &= ~bit;
					if( !checkBits )
						break;
				}
			}
		}

		R_RecursiveWorldNode( node->children[0], clipFlags, dlightBits, shadowBits );

		node = node->children[1];
		dlightBits = dlightBits1;
		shadowBits = shadowBits1;
	}

	// if a leaf node, draw stuff
	pleaf = ( mleaf_t * )node;
	pleaf->visframe = rf.frameCount;

	// add leaf bounds to view bounds
	for( i = 0; i < 3; i++ )
	{
		rn.visMins[i] = min( rn.visMins[i], pleaf->mins[i] );
		rn.visMaxs[i] = max( rn.visMaxs[i], pleaf->maxs[i] );
	}

	rn.dlightBits |= dlightBits;
	rn.shadowBits |= shadowBits;

	R_MarkLeafSurfaces( pleaf->firstVisSurface, clipFlags, dlightBits, shadowBits );
	rf.stats.c_world_leafs++;
}
Exemplo n.º 19
0
/*
=================
R_BoxSurfaces_r

=================
*/
void R_BoxSurfaces_r(mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int listsize, int *listlength, vec3_t dir) {

	int			s, c;
	msurface_t	*surf, **mark;

	// do the tail recursion in a loop
	while ( node->contents == -1 ) {
		s = BoxOnPlaneSide( mins, maxs, node->plane );
		if (s == 1) {
			node = node->children[0];
		} else if (s == 2) {
			node = node->children[1];
		} else {
			R_BoxSurfaces_r(node->children[0], mins, maxs, list, listsize, listlength, dir);
			node = node->children[1];
		}
	}

	// add the individual surfaces
	mark = node->firstmarksurface;
	c = node->nummarksurfaces;
	while (c--) {
		//
		if (*listlength >= listsize) break;
		//
		surf = *mark;
		//ri.Printf(PRINT_ALL, "^3surf: %s\n", surf->shader->name);
		// check if the surface has NOIMPACT or NOMARKS set
		if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) )
			 ||  ( surf->shader->contentFlags & CONTENTS_FOG ) ) {
			if (r_ignoreNoMarks->integer == 0) {
				surf->viewCount = tr.viewCount;
			} else if (r_ignoreNoMarks->integer == 1) {
				if (surf->shader->contentFlags & (CONTENTS_FOG | CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA)) {
					surf->viewCount = tr.viewCount;
				}
			} else {  // r_ignoreNoMarks->integer >= 2
				// allow marks liquids, etc..
			}
		}
		// extra check for surfaces to avoid list overflows
		else if (*(surf->data) == SF_FACE) {
			// the face plane should go through the box
			s = BoxOnPlaneSide( mins, maxs, &(( srfSurfaceFace_t * ) surf->data)->plane );
			if (s == 1 || s == 2) {
				surf->viewCount = tr.viewCount;
			} else if (DotProduct((( srfSurfaceFace_t * ) surf->data)->plane.normal, dir) > -0.5) {
				// don't add faces that make sharp angles with the projection direction
				//ri.Printf(PRINT_ALL, "^3sharp angle '%s'\n", surf->shader->name);
				surf->viewCount = tr.viewCount;
			} else {
				//ri.Printf(PRINT_ALL, "^3surf: %s\n", surf->shader->name);
			}
		}
		else if (*(surfaceType_t *) (surf->data) != SF_GRID &&
				 *(surfaceType_t *) (surf->data) != SF_TRIANGLES) {
			surf->viewCount = tr.viewCount;
		}

		// check the viewCount because the surface may have
		// already been added if it spans multiple leafs
		if (surf->viewCount != tr.viewCount) {
			surf->viewCount = tr.viewCount;
			mxsurf[*listlength] = surf;
			list[*listlength] = (surfaceType_t *) surf->data;
			(*listlength)++;
			//ri.Printf(PRINT_ALL, "^3surf: %s\n", surf->shader->name);
		}
		mark++;
	}
}
Exemplo n.º 20
0
/*
============
TestBrushToPlanenum

============
*/
int	TestBrushToPlanenum (bspbrush_t *brush, int planenum,
						 int *numsplits, qboolean *hintsplit, int *epsilonbrush)
{
	int			i, j, num;
	plane_t		*plane;
	int			s;
	winding_t	*w;
	vec_t		d, d_front, d_back;
	int			front, back;

	*numsplits = 0;
	*hintsplit = false;

	// if the brush actually uses the planenum,
	// we can tell the side for sure
	for (i=0 ; i<brush->numsides ; i++)
	{
		num = brush->sides[i].planenum;
		if (num >= 0x10000)
			Error ("bad planenum");
		if (num == planenum)
			return PSIDE_BACK|PSIDE_FACING;
		if (num == (planenum ^ 1) )
			return PSIDE_FRONT|PSIDE_FACING;
	}

	// box on plane side
	plane = &mapplanes[planenum];
	s = BoxOnPlaneSide (brush->mins, brush->maxs, plane);

	if (s != PSIDE_BOTH)
		return s;

// if both sides, count the visible faces split
	d_front = d_back = 0;

	for (i=0 ; i<brush->numsides ; i++)
	{
		if (brush->sides[i].texinfo == TEXINFO_NODE)
			continue;		// on node, don't worry about splits
		if (!brush->sides[i].visible)
			continue;		// we don't care about non-visible
		w = brush->sides[i].winding;
		if (!w)
			continue;
		front = back = 0;
		for (j=0 ; j<w->numpoints; j++)
		{
			d = DotProduct (w->p[j], plane->normal) - plane->dist;
			if (d > d_front)
				d_front = d;
			if (d < d_back)
				d_back = d;

			if (d > 0.1) // PLANESIDE_EPSILON)
				front = 1;
			if (d < -0.1) // PLANESIDE_EPSILON)
				back = 1;
		}
		if (front && back)
		{
			if ( !(brush->sides[i].surf & SURF_SKIP) )
			{
				(*numsplits)++;
				if (brush->sides[i].surf & SURF_HINT)
					*hintsplit = true;
			}
		}
	}

	if ( (d_front > 0.0 && d_front < 1.0)
		|| (d_back < 0.0 && d_back > -1.0) )
		(*epsilonbrush)++;

#if 0
	if (*numsplits == 0)
	{	//	didn't really need to be split
		if (front)
			s = PSIDE_FRONT;
		else if (back)
			s = PSIDE_BACK;
		else
			s = 0;
	}
#endif

	return s;
}
Exemplo n.º 21
0
/*
=================
R_BoxSurfaces_r

=================
*/
void R_BoxSurfaces_r( mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int listsize, int *listlength, vec3_t dir ) {

	int s, c;
	msurface_t  *surf, **mark;

	// RF, if this node hasn't been rendered recently, ignore it
	if ( node->visframe < tr.visCount - 2 ) { // allow us to be a few frames behind
		return;
	}

	// do the tail recursion in a loop
	while ( node->contents == -1 ) {
		s = BoxOnPlaneSide( mins, maxs, node->plane );
		if ( s == 1 ) {
			node = node->children[0];
		} else if ( s == 2 ) {
			node = node->children[1];
		} else {
			R_BoxSurfaces_r( node->children[0], mins, maxs, list, listsize, listlength, dir );
			node = node->children[1];
		}
	}

	// Ridah, don't mark alpha surfaces
	if ( node->contents & CONTENTS_TRANSLUCENT ) {
		return;
	}

	// add the individual surfaces
	mark = node->firstmarksurface;
	c = node->nummarksurfaces;
	while ( c-- ) {
		//
		if ( *listlength >= listsize ) {
			break;
		}
		//
		surf = *mark;
		// check if the surface has NOIMPACT or NOMARKS set
		if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) )
			 || ( surf->shader->contentFlags & CONTENTS_FOG ) ) {
			surf->viewCount = tr.viewCount;
		}
		// extra check for surfaces to avoid list overflows
		else if ( *( surf->data ) == SF_FACE ) {

#if defined RTCW_ET
			if ( ( ( srfSurfaceFace_t * ) surf->data )->plane.type != PLANE_NON_PLANAR ) {
#endif // RTCW_XX

			// the face plane should go through the box
			s = BoxOnPlaneSide( mins, maxs, &( ( srfSurfaceFace_t * ) surf->data )->plane );
			if ( s == 1 || s == 2 ) {
				surf->viewCount = tr.viewCount;
			} else if ( DotProduct( ( ( srfSurfaceFace_t * ) surf->data )->plane.normal, dir ) < -0.5 )         {
				// don't add faces that make sharp angles with the projection direction
				surf->viewCount = tr.viewCount;
			}

#if !defined RTCW_ET
		} else if ( *( surfaceType_t * )( surf->data ) != SF_GRID )        {
#else
			}
		} else if ( *( surfaceType_t * )( surf->data ) != SF_GRID && *( surfaceType_t * )( surf->data ) != SF_TRIANGLES ) {
#endif // RTCW_XX

			surf->viewCount = tr.viewCount;
		}
		// check the viewCount because the surface may have
		// already been added if it spans multiple leafs
		if ( surf->viewCount != tr.viewCount ) {
			surf->viewCount = tr.viewCount;
			list[*listlength] = (surfaceType_t *) surf->data;
			( *listlength )++;
		}
		mark++;
	}
}