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++; } }
/* ============ 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; }
/* ============= 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]; } } }
/* ================= 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++; } }
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; }
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; }
/* ================= 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; }
/* ================= 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; }
//=========================================================================== // // 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
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++; } }
/* =================== 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; }
/* ================= 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)++; } }
/* ================= 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++; } }
/* ================= 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++; } }
/* ================ 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 ); }
//=========================================================================== // // 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
//----------------------------------------------------------------------------- // 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; }
/* * 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++; }
/* ================= 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++; } }
/* ============ 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; }
/* ================= 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++; } }