]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
Implemented.
authorRudolf Polzer <divverent@xonotic.org>
Fri, 3 Jan 2014 11:47:37 +0000 (12:47 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Fri, 3 Jan 2014 11:47:37 +0000 (12:47 +0100)
server.h
sv_phys.c
world.c
world.h

index 0dfaf0342255f5ba4f567576026d81f17b85849e..b7714cd6cb96d8f26bb1d4445e8181a480266aaf 100644 (file)
--- a/server.h
+++ b/server.h
@@ -581,6 +581,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 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);
 
index e88baa2578c7e575dabdc0af5c74b45922ad988f..37d63575d2dc413d1a81c7ad7dab9100eba3f4be 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -350,7 +350,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
        // 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
@@ -749,6 +749,22 @@ int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_e
                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;
diff --git a/world.c b/world.c
index 553cabefd8cba570cce3d34a518843aefdea9fb4..376fc997ba9b4714fd840dd2b239ab33982180c0 100644 (file)
--- a/world.c
+++ b/world.c
@@ -263,15 +263,32 @@ int World_EntitiesInBox(world_t *world, const vec3_t requestmins, const vec3_t r
        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)
diff --git a/world.h b/world.h
index e43ebd142c6ffc99f7fcfa01a5badb0baa86966d..afbe57cfa98a91a00be33d5f0283824fec73799f 100644 (file)
--- a/world.h
+++ b/world.h
@@ -115,6 +115,7 @@ void World_LinkEdict(world_t *world, struct prvm_edict_s *ent, const vec3_t mins
 
 /// \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);