示例#1
0
/*
================
PM_TestPlayerPosition

Returns false if the given player position is not valid (in solid)
================
*/
qbool PM_TestPlayerPosition (playermove_t *pm, vec3_t pos)
{
	int			i;
	physent_t	*pe;
	vec3_t		mins, maxs, offset, test;
	hull_t		*hull;

	for (i=0 ; i< pm->numphysent ; i++)
	{
		pe = &pm->physents[i];
	// get the clipping hull
		if (pe->model)
		{
			hull = &pm->physents[i].model->hulls[1];
			VectorSubtract (hull->clip_mins, player_mins, offset);
			VectorAdd (offset, pe->origin, offset);
		}
		else
		{
			VectorSubtract (pe->mins, player_maxs, mins);
			VectorSubtract (pe->maxs, player_mins, maxs);
			hull = CM_HullForBox (mins, maxs);
			VectorCopy (pe->origin, offset);
		}

		VectorSubtract (pos, offset, test);

		if (CM_HullPointContents (hull, hull->firstclipnode, test) == CONTENTS_SOLID)
			return false;
	}

	return true;
}
示例#2
0
/*
================
PM_TraceLine
================
*/
trace_t PM_TraceLine (playermove_t *pm, vec3_t start, vec3_t end)
{
	trace_t		trace, total;
	vec3_t		offset;
	vec3_t		start_l, end_l;
	hull_t		*hull;
	int			i;
	physent_t	*pe;

// fill in a default trace
	memset (&total, 0, sizeof(trace_t));
	total.fraction = 1;
	total.e.entnum = -1;
	VectorCopy (end, total.endpos);

	for (i=0 ; i< pm->numphysent ; i++)
	{
		pe = &pm->physents[i];
	// get the clipping hull
		if (pe->model)
			hull = &pm->physents[i].model->hulls[0];
		else
			hull = CM_HullForBox (pe->mins, pe->maxs);

	// PM_HullForEntity (ent, mins, maxs, offset);
	VectorCopy (pe->origin, offset);

		VectorSubtract (start, offset, start_l);
		VectorSubtract (end, offset, end_l);

		// trace a line through the apropriate clipping hull
		trace = CM_HullTrace (hull, start_l, end_l);

		// fix trace up by the offset
		VectorAdd (trace.endpos, offset, trace.endpos);

		if (trace.allsolid)
			trace.startsolid = true;
		if (trace.startsolid)
			trace.fraction = 0;

		// did we clip the move?
		if (trace.fraction < total.fraction)
		{
			total = trace;
			total.e.entnum = i;
		}

	}

	return total;
}
示例#3
0
文件: sv_world.cpp 项目: luaman/zq
/*
================
SV_HullForEntity

Returns a hull that can be used for testing or clipping an object of mins/maxs
size.
Offset is filled in to contain the adjustment that must be added to the
testing object's origin to get a point to use with the returned hull.
================
*/
hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
{
	cmodel_t	*model;
	vec3_t		size;
	vec3_t		hullmins, hullmaxs;
	hull_t		*hull;

// decide which clipping hull to use, based on the size
	if (ent->v.solid == SOLID_BSP)
	{	// explicit hulls in the BSP model
		if (ent->v.movetype != MOVETYPE_PUSH)
			Host_Error ("SOLID_BSP without MOVETYPE_PUSH");

		if ((unsigned)ent->v.modelindex >= MAX_MODELS)
			Host_Error ("SV_HullForEntity: ent.modelindex >= MAX_MODELS");

		model = sv.models[(int)ent->v.modelindex];
		if (!model)
			Host_Error ("SOLID_BSP with a non-bsp model");

		VectorSubtract (maxs, mins, size);
		if (size[0] < 3)
			hull = &model->hulls[0];
		else if (size[0] <= 32)
			hull = &model->hulls[1];
		else
			hull = &model->hulls[2];

// calculate an offset value to center the origin
		VectorSubtract (hull->clip_mins, mins, offset);
		VectorAdd (offset, ent->v.origin, offset);
	}
	else
	{	// create a temp hull from bounding box sizes

		VectorSubtract (ent->v.mins, maxs, hullmins);
		VectorSubtract (ent->v.maxs, mins, hullmaxs);
		hull = CM_HullForBox (hullmins, hullmaxs);
		
		VectorCopy (ent->v.origin, offset);
	}


	return hull;
}
示例#4
0
/*
================
PM_PlayerTrace
================
*/
trace_t PM_PlayerTrace (playermove_t *pm, vec3_t start, vec3_t end)
{
	trace_t		trace, total;
	vec3_t		offset;
	vec3_t		start_l, end_l;
	hull_t		*hull;
	int			i;
	physent_t	*pe;
	vec3_t		mins, maxs, tracemins, tracemaxs;

	// fill in a default trace
	memset (&total, 0, sizeof(trace_t));
	total.fraction = 1;
	total.e.entnum = -1;
	VectorCopy (end, total.endpos);

	PM_TraceBounds(start, end, tracemins, tracemaxs);

	for (i=0 ; i< pm->numphysent ; i++)
	{
		pe = &pm->physents[i];

		// get the clipping hull
		if (pe->model)
		{
			hull = &pm->physents[i].model->hulls[1];

			if (i > 0 && PM_CullTraceBox(tracemins, tracemaxs, pe->origin, pe->model->mins, pe->model->maxs, hull->clip_mins, hull->clip_maxs))
				continue;

			VectorSubtract (hull->clip_mins, player_mins, offset);
			VectorAdd (offset, pe->origin, offset);
		}
		else
		{
			VectorSubtract (pe->mins, player_maxs, mins);
			VectorSubtract (pe->maxs, player_mins, maxs);

			if (PM_CullTraceBox(tracemins, tracemaxs, pe->origin, mins, maxs, vec3_origin, vec3_origin))
				continue;

			hull = CM_HullForBox (mins, maxs);
			VectorCopy (pe->origin, offset);
		}

		VectorSubtract (start, offset, start_l);
		VectorSubtract (end, offset, end_l);

		// rotate start and end into the models frame of reference
		if (pe->solid == 4 /*SOLID_BSP*/ && (pe->angles[0] || pe->angles[1] || pe->angles[2]))
		{
			vec3_t   forward, right, up;
			vec3_t   temp;

			AngleVectors (pe->angles, forward, right, up);

			VectorCopy (start_l, temp);
			start_l[0] = DotProduct (temp, forward);
			start_l[1] = -DotProduct (temp, right);
			start_l[2] = DotProduct (temp, up);

			VectorCopy (end_l, temp);
			end_l[0] = DotProduct (temp, forward);
			end_l[1] = -DotProduct (temp, right);
			end_l[2] = DotProduct (temp, up);
		}

		// trace a line through the apropriate clipping hull
		trace = CM_HullTrace (hull, start_l, end_l);

		// rotate endpos back to world frame of reference
		if (pe->solid == 4 /*SOLID_BSP*/ && (pe->angles[0] || pe->angles[1] || pe->angles[2]))
		{
			vec3_t   a;
			vec3_t   forward, right, up;
			vec3_t   temp;

			if (trace.fraction != 1)
			{
				VectorSubtract (vec3_origin, pe->angles, a);
				AngleVectors (a, forward, right, up);

				VectorCopy (trace.endpos, temp);
				trace.endpos[0] = DotProduct (temp, forward);
				trace.endpos[1] = -DotProduct (temp, right);
				trace.endpos[2] = DotProduct (temp, up);

				VectorCopy (trace.plane.normal, temp);
				trace.plane.normal[0] = DotProduct (temp, forward);
				trace.plane.normal[1] = -DotProduct (temp, right);
				trace.plane.normal[2] = DotProduct (temp, up);
			}
		}

		// fix trace up by the offset
		VectorAdd (trace.endpos, offset, trace.endpos);

		if (trace.allsolid)
			trace.startsolid = true;
		if (trace.startsolid)
			trace.fraction = 0;

		// did we clip the move?
		if (trace.fraction < total.fraction)
		{
			total = trace;
			total.e.entnum = i;
		}
	}

	return total;
}