Ejemplo n.º 1
0
int SV_PointContents(const CVec3 &p)
{
	guard(SV_PointContents);

	// get base contents from world
	unsigned contents = CM_PointContents(p, 0);
	contents |= CM_PointModelContents(p);

	edict_t	*list[MAX_EDICTS];
	int num = SV_AreaEdicts(p, p, ARRAY_ARG(list), AREA_SOLID);

	for (int i = 0; i < num; i++)
	{
		edict_t *edict = list[i];
		entityHull_t &ent = ents[NUM_FOR_EDICT(edict)];

		if (ent.model)
			contents |= CM_TransformedPointContents(p, ent.model->headnode, edict->s.origin, ent.axis);
		else
			contents |= CM_TransformedPointContents(p, CM_HeadnodeForBox(ent.bounds), edict->s.origin, nullVec3);
	}
	return contents;

	unguard;
}
Ejemplo n.º 2
0
/*
================
SV_HullForEntity

Returns a headnode that can be used for testing or clipping an
object of mins/maxs size.
================
*/
static mnode_t *SV_HullForEntity(edict_t *ent)
{
    if (ent->solid == SOLID_BSP) {
        int i = ent->s.modelindex - 1;

        // explicit hulls in the BSP model
        if (i <= 0 || i >= sv.cm.cache->nummodels)
            Com_Error(ERR_DROP, "%s: inline model %d out of range", __func__, i);

        return sv.cm.cache->models[i].headnode;
    }

    // create a temp hull from bounding box sizes
    return CM_HeadnodeForBox(ent->mins, ent->maxs);
}
Ejemplo n.º 3
0
Archivo: sv_world.c Proyecto: ZwS/qudos
/*
 * ================ SV_HullForEntity
 *
 * Returns a headnode 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. ================
 */
int
SV_HullForEntity(edict_t * ent)
{
	cmodel_t       *model;

	/* decide which clipping hull to use, based on the size */
	if (ent->solid == SOLID_BSP) {	/* explicit hulls in the BSP model */
		model = sv.models[ent->s.modelindex];

		if (!model)
			Com_Error(ERR_FATAL, "MOVETYPE_PUSH with a non bsp model");

		return model->headnode;
	}
	/* create a temp hull from bounding box sizes */

	return CM_HeadnodeForBox(ent->mins, ent->maxs);
}
Ejemplo n.º 4
0
/**
 * @brief Returns a headnode 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.
 * @param[in] le The local entity to get the bmodel from
 * @param[out] tile The maptile the bmodel belongs, too
 * @param[out] rmaShift the shift vector in case of an RMA (needed for doors)
 * @param[out] angles The rotation of the entity (in case of bmodels)
 * @return The headnode for the local entity
 * @sa SV_HullForEntity
 */
static int32_t CL_HullForEntity (const le_t* le, int* tile, vec3_t rmaShift, vec3_t angles)
{
	/* special case for bmodels */
	if (le->contents & CONTENTS_SOLID) {
		const cBspModel_t* model = LE_GetClipModel(le);
		/* special value for bmodel */
		if (!model)
			Com_Error(ERR_DROP, "CL_HullForEntity: Error - le with nullptr bmodel (%i)\n", le->type);
		*tile = model->tile;
		VectorCopy(le->angles, angles);
		VectorCopy(model->shift, rmaShift);
		return model->headnode;
	} else {
		/* might intersect, so do an exact clip */
		*tile = 0;
		VectorCopy(vec3_origin, angles);
		VectorCopy(vec3_origin, rmaShift);
		return CM_HeadnodeForBox(cl.mapTiles->mapTiles[*tile], le->aabb);
	}
}
Ejemplo n.º 5
0
static void SV_ClipMoveToEntities(trace_t &trace, const CVec3 &start, const CVec3 &end, const CBox &bounds, edict_t *passedict, int contentmask)
{
	guard(SV_ClipMoveToEntities);

	if (trace.allsolid) return;

	int		i;

	CVec3 amins, amaxs;
	for (i = 0; i < 3; i++)
	{
		if (start[i] < end[i])
		{
			amins[i] = bounds.mins[i] + start[i];
			amaxs[i] = bounds.maxs[i] + end[i];
		}
		else
		{
			amins[i] = bounds.mins[i] + end[i];
			amaxs[i] = bounds.maxs[i] + start[i];
		}
	}
	edict_t	*list[MAX_EDICTS];
	int num = SV_AreaEdicts(amins, amaxs, ARRAY_ARG(list), AREA_SOLID);
	if (!num) return;

	float b1 = dot(bounds.mins, bounds.mins);
	float b2 = dot(bounds.maxs, bounds.maxs);
	float t = max(b1, b2);
	float traceWidth = SQRTFAST(t);
	CVec3 traceDir;
	VectorSubtract(end, start, traceDir);
	float traceLen = traceDir.Normalize() + traceWidth;

	for (i = 0; i < num; i++)
	{
		edict_t *edict = list[i];
		entityHull_t &ent = ents[NUM_FOR_EDICT(edict)];
//		if (!ent->linked) continue;

		if (edict->solid == SOLID_NOT || edict == passedict) continue;
		if (passedict)
		{
		 	if (edict->owner == passedict)
				continue;	// don't clip against own missiles
			if (passedict->owner == edict)
				continue;	// don't clip against owner
		}
		if (!(contentmask & CONTENTS_DEADMONSTER) && (edict->svflags & SVF_DEADMONSTER))
			continue;

		CVec3 eCenter;
		VectorSubtract(ent.center, start, eCenter);
		// check position of point projection on line
		float entPos = dot(eCenter, traceDir);
		if (entPos < -traceWidth - ent.radius || entPos > traceLen + ent.radius)
			continue;		// too near / too far

		// check distance between point and line
		CVec3 tmp;
		VectorMA(eCenter, -entPos, traceDir, tmp);
		float dist2 = dot(tmp, tmp);
		float dist0 = ent.radius + traceWidth;
		if (dist2 >= dist0 * dist0) continue;

		trace_t	tr;
		if (ent.model)
			CM_TransformedBoxTrace(tr, start, end, bounds, ent.model->headnode, contentmask, edict->s.origin, ent.axis);
		else
			CM_TransformedBoxTrace(tr, start, end, bounds, CM_HeadnodeForBox(ent.bounds), contentmask, edict->s.origin, nullVec3);
		if (CM_CombineTrace(trace, tr))
			trace.ent = edict;
		if (trace.allsolid) return;
	}

	unguard;
}