trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask);
trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask);
int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts);
+int SV_EntitiesInBoxNearLine(const vec3_t mins, const vec3_t maxs, const vec3_t start, const vec3_t end, vec_t distance, int maxedicts, prvm_edict_t **resultedicts);
qboolean SV_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs);
// clip to entities
// because this uses World_EntitiestoBox, we know all entity boxes overlap
// the clip region, so we can skip culling checks in the loop below
- numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+ numtouchedicts = SV_EntitiesInBoxNearLine(clipboxmins, clipboxmaxs, clipstart, clipend, 0, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
// this never happens
return World_EntitiesInBox(&sv.world, paddedmins, paddedmaxs, maxedicts, resultedicts);
}
+int SV_EntitiesInBoxNearLine(const vec3_t mins, const vec3_t maxs, const vec3_t start, const vec3_t end, vec_t distance, int maxedicts, prvm_edict_t **resultedicts)
+{
+ prvm_prog_t *prog = SVVM_prog;
+ vec3_t paddedmins, paddedmaxs;
+ if (sv_areadebug.integer)
+ return SV_EntitiesInBox(mins, maxs, maxedicts, resultedicts);
+ if (maxedicts < 1 || resultedicts == NULL)
+ return 0;
+ // LordHavoc: discovered this actually causes its own bugs (dm6 teleporters being too close to info_teleport_destination)
+ //VectorSet(paddedmins, mins[0] - 10, mins[1] - 10, mins[2] - 1);
+ //VectorSet(paddedmaxs, maxs[0] + 10, maxs[1] + 10, maxs[2] + 1);
+ VectorCopy(mins, paddedmins);
+ VectorCopy(maxs, paddedmaxs);
+ return World_EntitiesInBoxNearLine(&sv.world, paddedmins, paddedmaxs, start, end, distance, maxedicts, resultedicts);
+}
+
void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
{
prvm_prog_t *prog = SVVM_prog;
return numlist;
}
-qboolean IsNearLine(vec3_t mins, vec3_t maxs, vec3_t linestart, vec3_t lineend, vec_t distance)
+static qboolean IsNearLine(const vec3_t mins, const vec3_t maxs, const vec3_t linestart, const vec3_t lineend, vec_t distance)
{
+ vec3_t center, linedirection, center_to_start, center_to_start_projection;
+ vec_t radius, center_to_start_projection_length, line_center_distance;
// This tests only the infinite length line - linestart and lineend
// themselves don't matter as long as they are on the line.
// Also, we approximate even more:
// we just test whether distance between center of mins, maxs is and
// the line is smaller or equal the distance + the radius of the mins,
// maxs.
- return true;
+ VectorMAM(0.5, mins, 0.5, maxs, center);
+
+ radius = VectorDistance(center, mins) + distance;
+
+ VectorSubtract(lineend, linestart, linedirection);
+ VectorNormalize(linedirection);
+
+ VectorSubtract(linestart, center, center_to_start);
+
+ center_to_start_projection_length = DotProduct(center_to_start, linedirection);
+
+ VectorScale(linedirection, center_to_start_projection_length, center_to_start_projection);
+
+ line_center_distance = VectorDistance(center_to_start_projection, center_to_start);
+
+ return line_center_distance <= radius;
}
int World_EntitiesInBoxNearLine(world_t *world, const vec3_t requestmins, const vec3_t requestmaxs, const vec3_t requeststart, const vec3_t requestend, vec_t requestdistance, int maxlist, prvm_edict_t **list)
/// \returns list of entities touching a box
int World_EntitiesInBox(world_t *world, const vec3_t mins, const vec3_t maxs, int maxlist, struct prvm_edict_s **list);
+int World_EntitiesInBoxNearLine(world_t *world, const vec3_t mins, const vec3_t maxs, const vec3_t start, const vec3_t end, vec_t distance, int maxlist, struct prvm_edict_s **list);
void World_Start(world_t *world);
void World_End(world_t *world);