/* ============= 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_NudgePosition If pmove.origin is in a solid position, try nudging slightly on all axis to allow for the cut precision of the net coordinates ================= */ void CL_NudgePosition (void) { vec3_t base; int x, y; if (PM_HullPointContents (&cl.model_precache[1]->hulls[1], 0, pmove.origin) == CONTENTS_EMPTY) return; VectorCopy (pmove.origin, base); for (x=-1 ; x<=1 ; x++) { for (y=-1 ; y<=1 ; y++) { pmove.origin[0] = base[0] + x * 1.0/8; pmove.origin[1] = base[1] + y * 1.0/8; if (PM_HullPointContents (&cl.model_precache[1]->hulls[1], 0, pmove.origin) == CONTENTS_EMPTY) return; } } Con_DPrintf ("CL_NudgePosition: stuck\n"); }
/* ============= 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 int pfnHullPointContents( struct hull_s *hull, int num, float *p ) { return PM_HullPointContents( hull, num, p ); }