#include "quakedef.h"
#include "winding.h"
+// 1/32 epsilon to keep floating point happy
+#define DIST_EPSILON (0.03125)
+
+#if 0
typedef struct
{
// the hull we're tracing through
}
RecursiveHullCheckTraceInfo_t;
-// 1/32 epsilon to keep floating point happy
-#define DIST_EPSILON (0.03125)
-
#define HULLCHECKSTATE_EMPTY 0
#define HULLCHECKSTATE_SOLID 1
#define HULLCHECKSTATE_DONE 2
// check for empty
if (num < 0)
{
- // translate the fake CONTENTS values in the box bsp tree
- if (num == CONTENTS_SOLID)
- num = t->boxsupercontents;
- else
- num = 0;
+ num = Mod_Q1BSP_SuperContentsFromNativeContents(NULL, num);
if (!t->trace->startfound)
{
t->trace->startfound = true;
t->trace->startsupercontents |= num;
}
+ if (num & SUPERCONTENTS_LIQUIDSMASK)
+ t->trace->inwater = true;
+ if (num == 0)
+ t->trace->inopen = true;
if (num & t->trace->hitsupercontentsmask)
{
// if the first leaf is solid, set startsolid
if (t->trace->allsolid)
t->trace->startsolid = true;
+#if COLLISIONPARANOID >= 3
+ Con_Printf("S");
+#endif
return HULLCHECKSTATE_SOLID;
}
else
{
t->trace->allsolid = false;
+#if COLLISIONPARANOID >= 3
+ Con_Printf("E");
+#endif
return HULLCHECKSTATE_EMPTY;
}
}
{
if (t2 < 0)
{
+#if COLLISIONPARANOID >= 3
+ Con_Printf("<");
+#endif
num = node->children[1];
goto loc0;
}
{
if (t2 >= 0)
{
+#if COLLISIONPARANOID >= 3
+ Con_Printf(">");
+#endif
num = node->children[0];
goto loc0;
}
// the line intersects, find intersection point
// LordHavoc: this uses the original trace for maximum accuracy
+#if COLLISIONPARANOID >= 3
+ Con_Printf("M");
+#endif
if (plane->type < 3)
{
t1 = t->start[plane->type] - plane->dist;
midf = t1 / (t1 - t2);
t->trace->fraction = bound(0.0f, midf, 1.0);
+#if COLLISIONPARANOID >= 3
+ Con_Printf("D");
+#endif
return HULLCHECKSTATE_DONE;
}
static dclipnode_t box_clipnodes[6];
static mplane_t box_planes[6];
-void Collision_Init (void)
+void Mod_Q1BSP_Collision_Init (void)
{
int i;
int side;
VectorCopy(start, rhc.start);
VectorCopy(end, rhc.end);
VectorSubtract(rhc.end, rhc.start, rhc.dist);
- RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
+ Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
VectorMA(rhc.start, rhc.trace->fraction, rhc.dist, rhc.trace->endpos);
+ if (rhc.trace->startsupercontents)
+ rhc.trace->startsupercontents = boxsupercontents;
}
+#endif
+void Collision_Init (void)
+{
+}
Con_Printf("Collision_TraceLineBrushFloat: degenerate plane!\n");
return;
}
- f = furthestplanedist_float(startplane->normal, thatbrush_start->points, thatbrush_start->numpoints);
- if (fabs(f - startplane->dist) > 0.01f)
- Con_Printf("startplane->dist %f != calculated %f\n", startplane->dist, f);
+ if (thatbrush_start->numpoints)
+ {
+ f = furthestplanedist_float(startplane->normal, thatbrush_start->points, thatbrush_start->numpoints);
+ if (fabs(f - startplane->dist) > 0.01f)
+ Con_Printf("startplane->dist %f != calculated %f\n", startplane->dist, f);
+ }
}
f = d1 - d2;
void Collision_BoundingBoxOfBrushTraceSegment(const colbrushf_t *start, const colbrushf_t *end, vec3_t mins, vec3_t maxs, float startfrac, float endfrac);
+// this enables rather large debugging spew!
+// settings:
+// 0 = no spew
+// 1 = spew trace calls if something odd is happening
+// 2 = spew trace calls always
+// 3 = spew detailed trace flow (bsp tree recursion info)
+#define COLLISIONPARANOID 0
+
#endif
cvar_t mod_q3bsp_curves_collisions = {0, "mod_q3bsp_curves_collisions", "1"};
cvar_t mod_q3bsp_optimizedtraceline = {0, "mod_q3bsp_optimizedtraceline", "0"};
+static void Mod_Q1BSP_Collision_Init (void);
void Mod_BrushInit(void)
{
// Cvar_RegisterVariable(&r_subdivide_size);
Cvar_RegisterVariable(&mod_q3bsp_curves_collisions);
Cvar_RegisterVariable(&mod_q3bsp_optimizedtraceline);
memset(mod_q1bsp_novis, 0xff, sizeof(mod_q1bsp_novis));
+ Mod_Q1BSP_Collision_Init();
}
static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p)
// if the first leaf is solid, set startsolid
if (t->trace->allsolid)
t->trace->startsolid = true;
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf("S");
#endif
return HULLCHECKSTATE_SOLID;
else
{
t->trace->allsolid = false;
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf("E");
#endif
return HULLCHECKSTATE_EMPTY;
{
if (t2 < 0)
{
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf("<");
#endif
num = node->children[1];
{
if (t2 >= 0)
{
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf(">");
#endif
num = node->children[0];
// the line intersects, find intersection point
// LordHavoc: this uses the original trace for maximum accuracy
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf("M");
#endif
if (plane->type < 3)
midf = t1 / (t1 - t2);
t->trace->fraction = bound(0.0f, midf, 1.0);
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf("D");
#endif
return HULLCHECKSTATE_DONE;
}
-#ifndef COLLISIONPARANOID
+#if COLLISIONPARANOID < 2
static int Mod_Q1BSP_RecursiveHullCheckPoint(RecursiveHullCheckTraceInfo_t *t, int num)
{
while (num >= 0)
VectorSubtract(boxstartmins, rhc.hull->clip_mins, rhc.start);
VectorSubtract(boxendmins, rhc.hull->clip_mins, rhc.end);
VectorSubtract(rhc.end, rhc.start, rhc.dist);
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 2
Con_Printf("t(%f %f %f,%f %f %f,%i %f %f %f)", rhc.start[0], rhc.start[1], rhc.start[2], rhc.end[0], rhc.end[1], rhc.end[2], rhc.hull - model->brushq1.hulls, rhc.hull->clip_mins[0], rhc.hull->clip_mins[1], rhc.hull->clip_mins[2]);
Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
Con_Printf("\n");
#endif
}
+static hull_t box_hull;
+static dclipnode_t box_clipnodes[6];
+static mplane_t box_planes[6];
+
+static void Mod_Q1BSP_Collision_Init (void)
+{
+ int i;
+ int side;
+
+ //Set up the planes and clipnodes so that the six floats of a bounding box
+ //can just be stored out and get a proper hull_t structure.
+
+ box_hull.clipnodes = box_clipnodes;
+ box_hull.planes = box_planes;
+ box_hull.firstclipnode = 0;
+ box_hull.lastclipnode = 5;
+
+ for (i = 0;i < 6;i++)
+ {
+ box_clipnodes[i].planenum = i;
+
+ side = i&1;
+
+ box_clipnodes[i].children[side] = CONTENTS_EMPTY;
+ if (i != 5)
+ box_clipnodes[i].children[side^1] = i + 1;
+ else
+ box_clipnodes[i].children[side^1] = CONTENTS_SOLID;
+
+ box_planes[i].type = i>>1;
+ box_planes[i].normal[i>>1] = 1;
+ }
+}
+
+void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int boxsupercontents)
+{
+#if 1
+ colbrushf_t cbox;
+ colplanef_t cbox_planes[6];
+ cbox.supercontents = boxsupercontents;
+ cbox.numplanes = 6;
+ cbox.numpoints = 0;
+ cbox.numtriangles = 0;
+ cbox.planes = cbox_planes;
+ cbox.points = NULL;
+ cbox.elements = NULL;
+ cbox.markframe = 0;
+ cbox.mins[0] = 0;
+ cbox.mins[1] = 0;
+ cbox.mins[2] = 0;
+ cbox.maxs[0] = 0;
+ cbox.maxs[1] = 0;
+ cbox.maxs[2] = 0;
+ cbox_planes[0].normal[0] = 1;cbox_planes[0].normal[1] = 0;cbox_planes[0].normal[2] = 0;cbox_planes[0].dist = cmaxs[0] - mins[0];
+ cbox_planes[1].normal[0] = -1;cbox_planes[1].normal[1] = 0;cbox_planes[1].normal[2] = 0;cbox_planes[1].dist = maxs[0] - cmins[0];
+ cbox_planes[2].normal[0] = 0;cbox_planes[2].normal[1] = 1;cbox_planes[2].normal[2] = 0;cbox_planes[2].dist = cmaxs[1] - mins[1];
+ cbox_planes[3].normal[0] = 0;cbox_planes[3].normal[1] = -1;cbox_planes[3].normal[2] = 0;cbox_planes[3].dist = maxs[1] - cmins[1];
+ cbox_planes[4].normal[0] = 0;cbox_planes[4].normal[1] = 0;cbox_planes[4].normal[2] = 1;cbox_planes[4].dist = cmaxs[2] - mins[2];
+ cbox_planes[5].normal[0] = 0;cbox_planes[5].normal[1] = 0;cbox_planes[5].normal[2] = -1;cbox_planes[5].dist = maxs[2] - cmins[2];
+ memset(trace, 0, sizeof(trace_t));
+ trace->hitsupercontentsmask = hitsupercontentsmask;
+ trace->fraction = 1;
+ Collision_TraceLineBrushFloat(trace, start, end, &cbox, &cbox);
+#else
+ RecursiveHullCheckTraceInfo_t rhc;
+ // fill in a default trace
+ memset(&rhc, 0, sizeof(rhc));
+ memset(trace, 0, sizeof(trace_t));
+ //To keep everything totally uniform, bounding boxes are turned into small
+ //BSP trees instead of being compared directly.
+ // create a temp hull from bounding box sizes
+ box_planes[0].dist = cmaxs[0] - mins[0];
+ box_planes[1].dist = cmins[0] - maxs[0];
+ box_planes[2].dist = cmaxs[1] - mins[1];
+ box_planes[3].dist = cmins[1] - maxs[1];
+ box_planes[4].dist = cmaxs[2] - mins[2];
+ box_planes[5].dist = cmins[2] - maxs[2];
+ Con_Printf("box_planes %f:%f %f:%f %f:%f\ncbox %f %f %f:%f %f %f\nbox %f %f %f:%f %f %f\n", box_planes[0].dist, box_planes[1].dist, box_planes[2].dist, box_planes[3].dist, box_planes[4].dist, box_planes[5].dist, cmins[0], cmins[1], cmins[2], cmaxs[0], cmaxs[1], cmaxs[2], mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]);
+ // trace a line through the generated clipping hull
+ //rhc.boxsupercontents = boxsupercontents;
+ rhc.hull = &box_hull;
+ rhc.trace = trace;
+ rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+ rhc.trace->fraction = 1;
+ rhc.trace->allsolid = true;
+ VectorCopy(start, rhc.start);
+ VectorCopy(end, rhc.end);
+ VectorSubtract(rhc.end, rhc.start, rhc.dist);
+ Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
+ VectorMA(rhc.start, rhc.trace->fraction, rhc.dist, rhc.trace->endpos);
+ if (rhc.trace->startsupercontents)
+ rhc.trace->startsupercontents = boxsupercontents;
+#endif
+}
+
static int Mod_Q1BSP_LightPoint_RecursiveBSPNode(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const mnode_t *node, float x, float y, float startz, float endz)
{
int side, distz = endz - startz;
neworg[2] += 8;
}
trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, neworg, MOVE_NORMAL, ent);
+#if COLLISIONPARANOID >= 1
+ {
+ int endstuck;
+ vec3_t temp;
+ VectorCopy(trace.endpos, temp);
+ endstuck = SV_Move(temp, ent->v->mins, ent->v->maxs, temp, MOVE_WORLDONLY, ent).startsolid;
+#if COLLISIONPARANOID < 2
+ if (trace.startsolid || endstuck)
+#endif
+ {
+ Con_Printf("%s{e%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "\002" : "", ent - sv.edicts, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], end[0] - ent->v->origin[0], end[1] - ent->v->origin[1], end[2] - ent->v->origin[2], trace.fraction, trace.endpos[0] - ent->v->origin[0], trace.endpos[1] - ent->v->origin[1], trace.endpos[2] - ent->v->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : "");
+ //Con_Printf("trace %f %f %f : %f : %f %f %f\n", trace.endpos[0], trace.endpos[1], trace.endpos[2], trace.fraction, trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]);
+ if (endstuck)
+ Cbuf_AddText("disconnect\n");
+ }
+ }
+#endif
if (trace.fraction == 1)
{
VectorMA(ent->v->origin, time, ent->v->velocity, end);
trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
//Con_Printf("trace %f %f %f : %f : %f %f %f\n", trace.endpos[0], trace.endpos[1], trace.endpos[2], trace.fraction, trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]);
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 1
{
int endstuck;
vec3_t temp;
VectorCopy(trace.endpos, temp);
endstuck = SV_Move(temp, ent->v->mins, ent->v->maxs, temp, MOVE_WORLDONLY, ent).startsolid;
- Con_Printf("%s{%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "\002" : "", bumpcount, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], end[0] - ent->v->origin[0], end[1] - ent->v->origin[1], end[2] - ent->v->origin[2], trace.fraction, trace.endpos[0] - ent->v->origin[0], trace.endpos[1] - ent->v->origin[1], trace.endpos[2] - ent->v->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : "");
- //Con_Printf("trace %f %f %f : %f : %f %f %f\n", trace.endpos[0], trace.endpos[1], trace.endpos[2], trace.fraction, trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]);
- if (endstuck)
- Cbuf_AddText("disconnect\n");
+#if COLLISIONPARANOID < 2
+ if (trace.startsolid || endstuck)
+#endif
+ {
+ Con_Printf("%s{e%i:%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "\002" : "", ent - sv.edicts, bumpcount, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], end[0] - ent->v->origin[0], end[1] - ent->v->origin[1], end[2] - ent->v->origin[2], trace.fraction, trace.endpos[0] - ent->v->origin[0], trace.endpos[1] - ent->v->origin[1], trace.endpos[2] - ent->v->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : "");
+ //Con_Printf("trace %f %f %f : %f : %f %f %f\n", trace.endpos[0], trace.endpos[1], trace.endpos[2], trace.fraction, trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]);
+ if (endstuck)
+ Cbuf_AddText("disconnect\n");
+ }
}
#endif
trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NOMONSTERS, ent);
else
trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+#if COLLISIONPARANOID >= 1
+ {
+ int endstuck;
+ vec3_t temp;
+ VectorCopy(trace.endpos, temp);
+ endstuck = SV_Move(temp, ent->v->mins, ent->v->maxs, temp, MOVE_WORLDONLY, ent).startsolid;
+#if COLLISIONPARANOID < 2
+ if (trace.startsolid || endstuck)
+#endif
+ {
+ Con_Printf("%s{e%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "\002" : "", ent - sv.edicts, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], end[0] - ent->v->origin[0], end[1] - ent->v->origin[1], end[2] - ent->v->origin[2], trace.fraction, trace.endpos[0] - ent->v->origin[0], trace.endpos[1] - ent->v->origin[1], trace.endpos[2] - ent->v->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : "");
+ //Con_Printf("trace %f %f %f : %f : %f %f %f\n", trace.endpos[0], trace.endpos[1], trace.endpos[2], trace.fraction, trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]);
+ if (endstuck)
+ Cbuf_AddText("disconnect\n");
+ }
+ }
+#endif
VectorCopy (trace.endpos, ent->v->origin);
// FIXME: turn players specially
if (fabs(oldorg[1] - ent->v->origin[1]) > 4
|| fabs(oldorg[0] - ent->v->origin[0]) > 4)
+ {
+ Con_DPrintf("TryUnstick - success.\n");
return clip;
+ }
// go back to the original pos and try again
VectorCopy (oldorg, ent->v->origin);
// still not moving
VectorClear (ent->v->velocity);
+ Con_Printf("TryUnstick - failure.\n");
return 7;
}
-n darkplaces: server is starting before the "port" cvar is set by commandline and scripts? (yummyluv)
-n darkplaces: typing ip in join game menu should show 'trying' and 'no response' after a while, or 'no network' if networking is not initialized (yummyluv)
-n dpmod: make grapple off-hand (joe hill)
+4 darkplaces: add qw protocol support (making darkplaces work as a qwcl client) (tell Fuh)
+0 darkplaces: add some cl_explosions_ cvars to control settings - start alpha, end alpha, start size, end size, life time (Supajoe, Mercury)
+0 darkplaces: "edict -1" and other invalid numbers cause an error, should just complain (Supajoe)
+2 darkplaces: add another TE_TELEPORT effect that spawns particles at a model's vertices (Urre)
+0 darkplaces: change sky handling to draw sky even if fog is on (Deej, C0burn)
+3 darkplaces: redesign startup script handling to simply stop execution until video inits, when it encounters certain commands (instead of delaying those commands)
+d darkplaces: physics bug: rotating bmodels stop when the player blocks them instead of pushing the player
+0 darkplaces: physics bug: fiends can leap through the player
+-n darkplaces: physics bug: bmodels (doors, etc) hurt player if player pushes against it, and sometimes gets stuck for a frame when falling onto it (Andrew A. Gilevsky)
+0 darkplaces: add gl_polyblend cvar to control amount of viewblend effect (Andrew A. Gilevsky)
+0 darkplaces: add r_waterwarp cvar to control amount of viewwarping underwater (Andrew A. Gilevsky)
+d darkplaces: add cvar_string builtin (Paul Timofeyev)
-n darkplaces: crashes if you type too long a command line in the console (SeienAbunae)
2 darkplaces: add lan searching to the server browser and related code (Vermeulen)
4 darkplaces: use larger of model box or collision box for linking into areagrid so that bullet tracing can use the model bounding box instead of the collision one? (Urre)
3 darkplaces: add anisotropic filtering options (Zombie_13, zinx)
3 darkplaces: add antialiasing options (Zombie_13)
3 darkplaces: add back r_waterripple (Vermeulen)
-3 darkplaces: add ogg music playback using optional library after adding wav music playback (Joseph Caporale, Static_Fiend)
+3 darkplaces: add ogg music playback using optional library after adding wav music playback (Joseph Caporale, Static_Fiend, Akuma)
3 darkplaces: add stainmaps to realtime lighting mode
3 darkplaces: add sv_rate cvar (limits total rate of the server - rather complicated rules to distribute rate between clients on the server, honoring their requests as best as possible) (Transfusion)
3 darkplaces: call checkvelocity (to clear NaNs) every time velocity is set in physics, to fix frikbot (tell FrikaC)
6 darkplaces: add cubemap reflections like UT2003 somehow (perhaps entities would define the reflection maps for rooms, and a water entity would take care of the rest?) (TEU, Nexuiz, SeienAbunae)
6 darkplaces: add water refraction like HalfLife2 (Mitchell)
6 darkplaces: figure out an LOD scheme for really large outdoor environments (Uffe, SeienAbunae)
-7 darkplaces: Quake3 bsp support (Vermeulen, Mitchell, SeienAbunae)
+d darkplaces: Quake3 bsp support (Vermeulen, Mitchell, SeienAbunae)
7 darkplaces: add DP_ENT_DISTORTIONFIELD which visually pulls things inward/outward around an entity (Supajoe, SeienAbunae)
7 darkplaces: add clientside quakec (KrimZon, FrikaC, SeienAbunae)
7 darkplaces: figure out what is causing invalid entity numbers in TouchAreaGrid in world.c - suspicion: problem with reallocation of edicts?
Matrix4x4_Invert_Simple(&imatrix, &matrix);
Matrix4x4_Transform(&imatrix, start, starttransformed);
Matrix4x4_Transform(&imatrix, end, endtransformed);
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf("trans(%f %f %f -> %f %f %f, %f %f %f -> %f %f %f)", start[0], start[1], start[2], starttransformed[0], starttransformed[1], starttransformed[2], end[0], end[1], end[2], endtransformed[0], endtransformed[1], endtransformed[2]);
#endif
VectorCopy(maxs, clip.maxs2);
clip.type = type;
clip.passedict = passedict;
-#ifdef COLLISIONPARANOID
+#if COLLISIONPARANOID >= 3
Con_Printf("move(%f %f %f,%f %f %f)", clip.start[0], clip.start[1], clip.start[2], clip.end[0], clip.end[1], clip.end[2]);
#endif