/* ============= CL_TruePointContents ============= */ int CL_TruePointContents( const vec3_t p ) { int i, contents; int oldhull; hull_t *hull; vec3_t test, offset; physent_t *pe; // sanity check if( !p ) return CONTENTS_NONE; oldhull = clgame.pmove->usehull; // get base contents from world contents = PM_HullPointContents( &cl.worldmodel->hulls[0], 0, p ); for( i = 0; i < clgame.pmove->nummoveent; i++ ) { pe = &clgame.pmove->moveents[i]; if( pe->solid != SOLID_NOT ) // disabled ? continue; // only brushes can have special contents if( !pe->model || pe->model->type != mod_brush ) continue; // check water brushes accuracy clgame.pmove->usehull = 2; hull = PM_HullForBsp( pe, clgame.pmove, offset ); clgame.pmove->usehull = oldhull; // offset the test point appropriately for this hull. VectorSubtract( p, offset, test ); if( (pe->model->flags & MODEL_HAS_ORIGIN) && !VectorIsNull( pe->angles )) { matrix4x4 matrix; Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f ); Matrix4x4_VectorITransform( matrix, p, test ); }; // test hull for intersection with this model if( PM_HullPointContents( hull, hull->firstclipnode, test ) == CONTENTS_EMPTY ) continue; // compare contents ranking if( RankForContents( pe->skin ) > RankForContents( contents )) contents = pe->skin; // new content has more priority }; return contents; }
/* ============= CL_WaterEntity ============= */ int CL_WaterEntity( const float *rgflPos ) { physent_t *pe; hull_t *hull; vec3_t test, offset; int i, oldhull; if( !rgflPos ) return -1; oldhull = clgame.pmove->usehull; for( i = 0; i < clgame.pmove->nummoveent; i++ ) { pe = &clgame.pmove->moveents[i]; if( pe->solid != SOLID_NOT ) // disabled ? continue; // only brushes can have special contents if( !pe->model || pe->model->type != mod_brush ) continue; // check water brushes accuracy clgame.pmove->usehull = 2; hull = PM_HullForBsp( pe, clgame.pmove, offset ); clgame.pmove->usehull = oldhull; // offset the test point appropriately for this hull. VectorSubtract( rgflPos, offset, test ); if( (pe->model->flags & MODEL_HAS_ORIGIN) && !VectorIsNull( pe->angles )) { matrix4x4 matrix; Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f ); Matrix4x4_VectorITransform( matrix, rgflPos, test ); }; // test hull for intersection with this model if( PM_HullPointContents( hull, hull->firstclipnode, test ) == CONTENTS_EMPTY ) continue; // found water entity return pe->info; } return -1; }
static float pfnTraceModel( physent_t *pe, float *start, float *end, trace_t *trace ) { int old_usehull; vec3_t start_l, end_l; vec3_t offset, temp; qboolean rotated; matrix4x4 matrix; hull_t *hull; old_usehull = clgame.pmove->usehull; clgame.pmove->usehull = 2; hull = PM_HullForBsp( pe, clgame.pmove, offset ); clgame.pmove->usehull = old_usehull; if( pe->solid == SOLID_BSP && !VectorIsNull( pe->angles )) rotated = true; else rotated = false; if( rotated ) { Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f ); Matrix4x4_VectorITransform( matrix, start, start_l ); Matrix4x4_VectorITransform( matrix, end, end_l ); } else { VectorSubtract( start, offset, start_l ); VectorSubtract( end, offset, end_l ); } SV_RecursiveHullCheck( hull, hull->firstclipnode, 0, 1, start_l, end_l, trace ); trace->ent = NULL; if( rotated ) { VectorCopy( trace->plane.normal, temp ); Matrix4x4_TransformPositivePlane( matrix, temp, trace->plane.dist, trace->plane.normal, &trace->plane.dist ); } VectorLerp( start, trace->fraction, end, trace->endpos ); return trace->fraction; }
static hull_t *pfnHullForBsp( physent_t *pe, float *offset ) { return PM_HullForBsp( pe, clgame.pmove, offset ); }