no time to explain, more changes on the path to q3bsp support
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 13 Aug 2003 23:08:58 +0000 (23:08 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 13 Aug 2003 23:08:58 +0000 (23:08 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3394 d7cf8633-e32d-0410-b094-e92efae38249

16 files changed:
cl_particles.c
collision.c
collision.h
gl_rmain.c
gl_rsurf.c
model_brush.c
model_shared.h
pr_cmds.c
r_light.c
r_shadow.c
r_shadow.h
render.h
snd_dma.c
sv_main.c
todo
world.c

index 0874519..e03b0e3 100644 (file)
@@ -163,9 +163,9 @@ float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int
        trace.fraction = 1;
        VectorCopy (end, trace.endpos);
 #if QW
-       PM_RecursiveHullCheck (cl.model_precache[1]->brushq1.hulls, 0, 0, 1, start, end, &trace);
+       PM_RecursiveHullCheck (cl.model_precache[1]->hulls, 0, 0, 1, start, end, &trace);
 #else
-       RecursiveHullCheck (cl.worldmodel->brushq1.hulls, 0, 0, 1, start, end, &trace);
+       RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
 #endif
        VectorCopy(trace.endpos, impact);
        VectorCopy(trace.plane.normal, normal);
index ef8e06f..4936e2d 100644 (file)
@@ -206,39 +206,6 @@ static void RecursiveHullCheckPoint (RecursiveHullCheckTraceInfo_t *t, int num)
 }
 #endif
 
-void Collision_RoundUpToHullSize(const model_t *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs)
-{
-       vec3_t size;
-       const hull_t *hull;
-
-       VectorSubtract(inmaxs, inmins, size);
-       if (cmodel->brushq1.ishlbsp)
-       {
-               if (size[0] < 3)
-                       hull = &cmodel->brushq1.hulls[0]; // 0x0x0
-               else if (size[0] <= 32)
-               {
-                       if (size[2] < 54) // pick the nearest of 36 or 72
-                               hull = &cmodel->brushq1.hulls[3]; // 32x32x36
-                       else
-                               hull = &cmodel->brushq1.hulls[1]; // 32x32x72
-               }
-               else
-                       hull = &cmodel->brushq1.hulls[2]; // 64x64x64
-       }
-       else
-       {
-               if (size[0] < 3)
-                       hull = &cmodel->brushq1.hulls[0]; // 0x0x0
-               else if (size[0] <= 32)
-                       hull = &cmodel->brushq1.hulls[1]; // 32x32x56
-               else
-                       hull = &cmodel->brushq1.hulls[2]; // 64x64x88
-       }
-       VectorCopy(inmins, outmins);
-       VectorAdd(inmins, hull->clip_size, outmaxs);
-}
-
 static hull_t box_hull;
 static dclipnode_t box_clipnodes[6];
 static mplane_t box_planes[6];
@@ -562,301 +529,6 @@ void Collision_TraceBrushPolygonTransformFloat(trace_t *trace, const colbrushf_t
        Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, &polyf_brushstart, &polyf_brushend);
 }
 
-colbrushd_t *Collision_AllocBrushDouble(mempool_t *mempool, int numpoints, int numplanes)
-{
-       colbrushd_t *brush;
-       brush = Mem_Alloc(mempool, sizeof(colbrushd_t) + sizeof(colpointd_t) * numpoints + sizeof(colplaned_t) * numplanes);
-       brush->numpoints = numpoints;
-       brush->numplanes = numplanes;
-       brush->planes = (void *)(brush + 1);
-       brush->points = (void *)(brush->planes + brush->numplanes);
-       return brush;
-}
-
-void Collision_CalcPlanesForPolygonBrushDouble(colbrushd_t *brush)
-{
-       int i;
-       double edge0[3], edge1[3], normal[3], dist, bestdist;
-       colpointd_t *p, *p2;
-
-       // choose best surface normal for polygon's plane
-       bestdist = 0;
-       for (i = 2, p = brush->points + 2;i < brush->numpoints;i++, p++)
-       {
-               VectorSubtract(p[-1].v, p[0].v, edge0);
-               VectorSubtract(p[1].v, p[0].v, edge1);
-               CrossProduct(edge0, edge1, normal);
-               dist = DotProduct(normal, normal);
-               if (i == 2 || bestdist < dist)
-               {
-                       bestdist = dist;
-                       VectorCopy(normal, brush->planes->normal);
-               }
-       }
-
-       VectorNormalize(brush->planes->normal);
-       brush->planes->dist = DotProduct(brush->points->v, brush->planes->normal);
-
-       // negate plane to create other side
-       VectorNegate(brush->planes[0].normal, brush->planes[1].normal);
-       brush->planes[1].dist = -brush->planes[0].dist;
-       for (i = 0, p = brush->points + (brush->numpoints - 1), p2 = brush->points + 2;i < brush->numpoints;i++, p = p2, p2++)
-       {
-               VectorSubtract(p->v, p2->v, edge0);
-               CrossProduct(edge0, brush->planes->normal, brush->planes[i].normal);
-               VectorNormalize(brush->planes[i].normal);
-               brush->planes[i].dist = DotProduct(p->v, brush->planes[i].normal);
-       }
-
-#if 1
-       // validity check - will be disabled later
-       for (i = 0;i < brush->numplanes;i++)
-       {
-               int j;
-               for (j = 0, p = brush->points;j < brush->numpoints;j++, p++)
-                       if (DotProduct(p->v, brush->planes[i].normal) > brush->planes[i].dist + (1.0 / 32.0))
-                               Con_Printf("Error in brush plane generation, plane %i\n");
-       }
-#endif
-}
-
-colbrushd_t *Collision_AllocBrushFromPermanentPolygonDouble(mempool_t *mempool, int numpoints, double *points)
-{
-       colbrushd_t *brush;
-       brush = Mem_Alloc(mempool, sizeof(colbrushd_t) + sizeof(colplaned_t) * (numpoints + 2));
-       brush->numpoints = numpoints;
-       brush->numplanes = numpoints + 2;
-       brush->planes = (void *)(brush + 1);
-       brush->points = (colpointd_t *)points;
-       return brush;
-}
-
-
-double nearestplanedist_double(const double *normal, const colpointd_t *points, int numpoints)
-{
-       double dist, bestdist;
-       bestdist = DotProduct(points->v, normal);
-       points++;
-       while(--numpoints)
-       {
-               dist = DotProduct(points->v, normal);
-               if (bestdist > dist)
-                       bestdist = dist;
-               points++;
-       }
-       return bestdist;
-}
-
-double furthestplanedist_double(const double *normal, const colpointd_t *points, int numpoints)
-{
-       double dist, bestdist;
-       bestdist = DotProduct(points->v, normal);
-       points++;
-       while(--numpoints)
-       {
-               dist = DotProduct(points->v, normal);
-               if (bestdist < dist)
-                       bestdist = dist;
-               points++;
-       }
-       return bestdist;
-}
-
-// NOTE: start and end of each brush pair must have same numplanes/numpoints
-void Collision_TraceBrushBrushDouble(trace_t *trace, const colbrushd_t *thisbrush_start, const colbrushd_t *thisbrush_end, const colbrushd_t *thatbrush_start, const colbrushd_t *thatbrush_end)
-{
-       int nplane, nplane2, fstartsolid, fendsolid;
-       double enterfrac, leavefrac, d1, d2, f, newimpactnormal[3];
-       const colplaned_t *startplane, *endplane;
-
-       enterfrac = -1;
-       leavefrac = 1;
-       fstartsolid = true;
-       fendsolid = true;
-
-       for (nplane = 0;nplane < thatbrush_start->numplanes + thisbrush_start->numplanes;nplane++)
-       {
-               nplane2 = nplane;
-               if (nplane2 >= thatbrush_start->numplanes)
-               {
-                       nplane2 -= thatbrush_start->numplanes;
-                       startplane = thisbrush_start->planes + nplane2;
-                       endplane = thisbrush_end->planes + nplane2;
-               }
-               else
-               {
-                       startplane = thatbrush_start->planes + nplane2;
-                       endplane = thatbrush_end->planes + nplane2;
-               }
-               d1 = nearestplanedist_double(startplane->normal, thisbrush_start->points, thisbrush_start->numpoints) - furthestplanedist_double(startplane->normal, thatbrush_start->points, thatbrush_start->numpoints);
-               d2 = nearestplanedist_double(endplane->normal, thisbrush_end->points, thisbrush_end->numpoints) - furthestplanedist_double(endplane->normal, thatbrush_end->points, thatbrush_end->numpoints) - COLLISIONEPSILON2;
-               //Con_Printf("%c%i: d1 = %f, d2 = %f, d1 / (d1 - d2) = %f\n", nplane2 != nplane ? 'b' : 'a', nplane2, d1, d2, d1 / (d1 - d2));
-
-               f = d1 - d2;
-               if (f >= 0)
-               {
-                       // moving into brush
-                       if (d2 > 0)
-                               return;
-                       if (d1 < 0)
-                               continue;
-                       // enter
-                       fstartsolid = false;
-                       f = (d1 - COLLISIONEPSILON) / f;
-                       f = bound(0, f, 1);
-                       if (enterfrac < f)
-                       {
-                               enterfrac = f;
-                               VectorBlend(startplane->normal, endplane->normal, enterfrac, newimpactnormal);
-                       }
-               }
-               else if (f < 0)
-               {
-                       // moving out of brush
-                       if (d1 > 0)
-                               return;
-                       if (d2 < 0)
-                               continue;
-                       // leave
-                       fendsolid = false;
-                       f = (d1 + COLLISIONEPSILON) / f;
-                       f = bound(0, f, 1);
-                       if (leavefrac > f)
-                               leavefrac = f;
-               }
-       }
-
-       if (fstartsolid)
-       {
-               trace->startsolid = true;
-               if (fendsolid)
-                       trace->allsolid = true;
-       }
-
-       // LordHavoc: we need an epsilon nudge here because for a point trace the
-       // penetrating line segment is normally zero length if this brush was
-       // generated from a polygon (infinitely thin), and could even be slightly
-       // positive or negative due to rounding errors in that case.
-       if (enterfrac > -1 && enterfrac < trace->fraction && enterfrac - (1.0f / 1024.0f) <= leavefrac)
-       {
-               trace->fraction = bound(0, enterfrac, 1);
-               VectorCopy(newimpactnormal, trace->plane.normal);
-       }
-}
-
-static colplaned_t polyd_planes[256 + 2];
-static colbrushd_t polyd_brush;
-void Collision_TraceBrushPolygonDouble(trace_t *trace, const colbrushd_t *thisbrush_start, const colbrushd_t *thisbrush_end, int numpoints, const double *points)
-{
-       if (numpoints > 256)
-       {
-               Con_Printf("Polygon with more than 256 points not supported yet (fixme!)\n");
-               return;
-       }
-       polyd_brush.numpoints = numpoints;
-       polyd_brush.numplanes = numpoints + 2;
-       polyd_brush.points = (colpointd_t *)points;
-       polyd_brush.planes = polyd_planes;
-       Collision_CalcPlanesForPolygonBrushDouble(&polyd_brush);
-       Collision_TraceBrushBrushDouble(trace, thisbrush_start, thisbrush_end, &polyd_brush, &polyd_brush);
-}
-
-
-
-
-typedef struct colbrushbmodelinfo_s
-{
-       model_t *model;
-       trace_t *trace;
-       const matrix4x4_t *modelmatrixstart;
-       const matrix4x4_t *modelmatrixend;
-       const colbrushf_t *thisbrush_start;
-       const colbrushf_t *thisbrush_end;
-}
-colbrushbmodelinfo_t;
-
-static int colframecount = 1;
-
-void Collision_RecursiveTraceBrushNode(colbrushbmodelinfo_t *info, mnode_t *node)
-{
-       if (node->contents)
-       {
-               // collide with surfaces marked by this leaf
-               int i, *mark;
-               mleaf_t *leaf = (mleaf_t *)node;
-               msurface_t *surf;
-               for (i = 0, mark = leaf->firstmarksurface;i < leaf->nummarksurfaces;i++, mark++)
-               {
-                       surf = info->model->brushq1.surfaces + *mark;
-                       // don't check a surface twice
-                       if (surf->colframe != colframecount)
-                       {
-                               surf->colframe = colframecount;
-                               if (surf->flags & SURF_SOLIDCLIP)
-                               {
-                                       Collision_TraceBrushPolygonFloat(info->trace, info->thisbrush_start, info->thisbrush_end, surf->poly_numverts, surf->poly_verts);
-                                       //Collision_TraceBrushPolygonTransformFloat(info->trace, info->thisbrush_start, info->thisbrush_end, surf->poly_numverts, surf->poly_verts, info->modelmatrixstart, info->modelmatrixend);
-                               }
-                       }
-               }
-       }
-       else
-       {
-               // recurse down node sides
-               int i;
-               float dist;
-               colpointf_t *ps, *pe;
-               // FIXME? if TraceBrushPolygonTransform were to be made usable, the
-               // node planes would need to be transformed too
-               dist = node->plane->dist - (1.0f / 8.0f);
-               for (i = 0, ps = info->thisbrush_start->points, pe = info->thisbrush_end->points;i < info->thisbrush_start->numpoints;i++, ps++, pe++)
-               {
-                       if (DotProduct(ps->v, node->plane->normal) > dist || DotProduct(pe->v, node->plane->normal) > dist)
-                       {
-                               Collision_RecursiveTraceBrushNode(info, node->children[0]);
-                               break;
-                       }
-               }
-               dist = node->plane->dist + (1.0f / 8.0f);
-               for (i = 0, ps = info->thisbrush_start->points, pe = info->thisbrush_end->points;i < info->thisbrush_start->numpoints;i++, ps++, pe++)
-               {
-                       if (DotProduct(ps->v, node->plane->normal) < dist || DotProduct(pe->v, node->plane->normal) < dist)
-                       {
-                               Collision_RecursiveTraceBrushNode(info, node->children[1]);
-                               break;
-                       }
-               }
-       }
-}
-
-void Collision_TraceBrushBModel(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, model_t *model)
-{
-       colbrushbmodelinfo_t info;
-       colframecount++;
-       memset(trace, 0, sizeof(*trace));
-       trace->fraction = 1;
-       info.trace = trace;
-       info.model = model;
-       info.thisbrush_start = thisbrush_start;
-       info.thisbrush_end = thisbrush_end;
-       Collision_RecursiveTraceBrushNode(&info, model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode);
-}
-
-void Collision_TraceBrushBModelTransform(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, model_t *model, const matrix4x4_t *modelmatrixstart, const matrix4x4_t *modelmatrixend)
-{
-       colbrushbmodelinfo_t info;
-       colframecount++;
-       memset(trace, 0, sizeof(*trace));
-       trace->fraction = 1;
-       info.trace = trace;
-       info.model = model;
-       info.modelmatrixstart = modelmatrixstart;
-       info.modelmatrixend = modelmatrixend;
-       info.thisbrush_start = thisbrush_start;
-       info.thisbrush_end = thisbrush_end;
-       Collision_RecursiveTraceBrushNode(&info, model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode);
-}
-
 
 
 #define MAX_BRUSHFORBOX 16
@@ -905,60 +577,6 @@ colbrushf_t *Collision_BrushForBox(const matrix4x4_t *matrix, const vec3_t mins,
        return brush;
 }
 
-void Collision_PolygonClipTrace (trace_t *trace, const void *cent, model_t *cmodel, const vec3_t corigin, const vec3_t cangles, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end)
-{
-       vec3_t impactnormal;
-       //vec3_t mins2, maxs2;
-       matrix4x4_t cmatrix, cimatrix, startmatrix, endmatrix;
-       matrix4x4_t mstartmatrix, mendmatrix, identitymatrix;
-       colbrushf_t *thisbrush_start, *thisbrush_end, *cbrush;
-
-       Matrix4x4_CreateFromQuakeEntity(&cmatrix, corigin[0], corigin[1], corigin[2], cangles[0], cangles[1], cangles[2], 1);
-       Matrix4x4_Invert_Simple(&cimatrix, &cmatrix);
-       Matrix4x4_CreateTranslate(&startmatrix, start[0], start[1], start[2]);
-       Matrix4x4_CreateTranslate(&endmatrix, end[0], end[1], end[2]);
-
-       Matrix4x4_CreateIdentity(&identitymatrix);
-       Matrix4x4_Concat(&mstartmatrix, &cimatrix, &startmatrix);
-       Matrix4x4_Concat(&mendmatrix, &cimatrix, &endmatrix);
-       thisbrush_start = Collision_BrushForBox(&mstartmatrix, mins, maxs);
-       //mins2[0] = mins[0] - 0.0625;mins2[1] = mins[1] - 0.0625;mins2[2] = mins[2] - 0.0625;
-       //maxs2[0] = maxs[0] + 0.0625;maxs2[1] = maxs[1] + 0.0625;maxs2[2] = maxs[2] + 0.0625;
-       thisbrush_end = Collision_BrushForBox(&mendmatrix, mins, maxs);
-
-       //Collision_PrintBrushAsQHull(thisbrush_start, "thisbrush_start");
-       //Collision_PrintBrushAsQHull(thisbrush_end, "thisbrush_end");
-       memset (trace, 0, sizeof(trace_t));
-       if (cmodel && cmodel->type == mod_brush)
-       {
-               // brush model
-               Collision_TraceBrushBModel(trace, thisbrush_start, thisbrush_end, cmodel);
-               //Collision_TraceBrushBModelTransform(trace, thisbrush_start, thisbrush_end, cmodel, &cmatrix, &cmatrix);
-       }
-       else
-       {
-               // bounding box
-               cbrush = Collision_BrushForBox(&identitymatrix, cmins, cmaxs);
-               Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, cbrush, cbrush);
-               //cbrush = Collision_BrushForBox(&cmatrix, cmins, cmaxs);
-               //trace->fraction = Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, cbrush, cbrush);
-       }
-
-       if (trace->fraction < 0 || trace->fraction > 1)
-               Con_Printf("fraction out of bounds %f %s:%d\n", trace->fraction, __FILE__, __LINE__);
-
-       VectorBlend(start, end, trace->fraction, trace->endpos);
-       if (trace->fraction < 1)
-       {
-               trace->ent = (void *) cent;
-               VectorCopy(trace->plane.normal, impactnormal);
-               Matrix4x4_Transform(&cmatrix, impactnormal, trace->plane.normal);
-               VectorNormalize(trace->plane.normal);
-               //Con_Printf("fraction %f normal %f %f %f\n", trace->fraction, trace->plane.normal[0], trace->plane.normal[1], trace->plane.normal[2]);
-       }
-}
-
-
 // LordHavoc: currently unused and not yet tested
 // note: this can be used for tracing a moving sphere vs a stationary sphere,
 // by simply adding the moving sphere's radius to the sphereradius parameter,
index 0e746e4..dfc02ff 100644 (file)
@@ -36,7 +36,6 @@ typedef struct trace_s
 }
 trace_t;
 
-void Collision_RoundUpToHullSize(const model_t *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs);
 void Collision_Init(void);
 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);
 
@@ -69,39 +68,6 @@ void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *thisbrush
 void Collision_TraceBrushPolygonFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int numpoints, const float *points);
 void Collision_TraceBrushPolygonTransformFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int numpoints, const float *points, const matrix4x4_t *polygonmatrixstart, const matrix4x4_t *polygonmatrixend);
 
-typedef struct colpointd_s
-{
-       double v[3];
-}
-colpointd_t;
-
-typedef struct colplaned_s
-{
-       double normal[3];
-       double dist;
-}
-colplaned_t;
-
-typedef struct colbrushd_s
-{
-       int numplanes;
-       int numpoints;
-       colplaned_t *planes;
-       colpointd_t *points;
-}
-colbrushd_t;
-
-colbrushd_t *Collision_AllocBrushDouble(mempool_t *mempool, int numpoints, int numplanes);
-void Collision_CalcPlanesForPolygonBrushDouble(colbrushd_t *brush);
-colbrushd_t *Collision_AllocBrushFromPermanentPolygonDouble(mempool_t *mempool, int numpoints, double *points);
-void Collision_TraceBrushBrushDouble(trace_t *trace, const colbrushd_t *thisbrush_start, const colbrushd_t *thisbrush_end, const colbrushd_t *thatbrush_start, const colbrushd_t *thatbrush_end);
-void Collision_TraceBrushPolygonDouble(trace_t *trace, const colbrushd_t *thisbrush_start, const colbrushd_t *thisbrush_end, int numpoints, const double *points);
-
-void Collision_TraceBrushBModel(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, model_t *model);
-void Collision_TraceBrushBModelTransform(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, model_t *model, const matrix4x4_t *modelmatrixstart, const matrix4x4_t *modelmatrixend);
-
-void Collision_PolygonClipTrace(trace_t *trace, const void *cent, model_t *cmodel, const vec3_t corigin, const vec3_t cangles, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end);
-
 colbrushf_t *Collision_BrushForBox(const matrix4x4_t *matrix, const vec3_t mins, const vec3_t maxs);
 
 #endif
index 8c24694..5df0849 100644 (file)
@@ -24,6 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // used for dlight push checking and other things
 int r_framecount;
 
+// used for visibility checking
+qbyte r_pvsbits[(MAX_MAP_LEAFS+7)>>3];
+
 mplane_t frustum[4];
 
 matrix4x4_t r_identitymatrix;
@@ -397,132 +400,7 @@ int R_CullBox(const vec3_t mins, const vec3_t maxs)
        return false;
 }
 
-int PVS_CullBox(const vec3_t mins, const vec3_t maxs)
-{
-       int stackpos, sides;
-       mnode_t *node, *stack[4096];
-       if (cl.worldmodel == NULL)
-               return false;
-       stackpos = 0;
-       stack[stackpos++] = cl.worldmodel->brushq1.nodes;
-       while (stackpos)
-       {
-               node = stack[--stackpos];
-               if (node->contents < 0)
-               {
-                       if (((mleaf_t *)node)->pvsframe == cl.worldmodel->brushq1.pvsframecount)
-                               return false;
-               }
-               else
-               {
-                       sides = BoxOnPlaneSide(mins, maxs, node->plane);
-                       if (sides & 2 && stackpos < 4096)
-                               stack[stackpos++] = node->children[1];
-                       if (sides & 1 && stackpos < 4096)
-                               stack[stackpos++] = node->children[0];
-               }
-       }
-       return true;
-}
-
-int VIS_CullBox(const vec3_t mins, const vec3_t maxs)
-{
-       int stackpos, sides;
-       mnode_t *node, *stack[4096];
-       if (R_CullBox(mins, maxs))
-               return true;
-       if (cl.worldmodel == NULL)
-               return false;
-       stackpos = 0;
-       stack[stackpos++] = cl.worldmodel->brushq1.nodes;
-       while (stackpos)
-       {
-               node = stack[--stackpos];
-               if (node->contents < 0)
-               {
-                       if (((mleaf_t *)node)->visframe == r_framecount)
-                               return false;
-               }
-               else
-               {
-                       sides = BoxOnPlaneSide(mins, maxs, node->plane);
-                       if (sides & 2 && stackpos < 4096)
-                               stack[stackpos++] = node->children[1];
-                       if (sides & 1 && stackpos < 4096)
-                               stack[stackpos++] = node->children[0];
-               }
-       }
-       return true;
-}
-
-int R_CullSphere(const vec3_t origin, vec_t radius)
-{
-       return (DotProduct(frustum[0].normal, origin) + radius < frustum[0].dist
-            || DotProduct(frustum[1].normal, origin) + radius < frustum[1].dist
-            || DotProduct(frustum[2].normal, origin) + radius < frustum[2].dist
-            || DotProduct(frustum[3].normal, origin) + radius < frustum[3].dist);
-}
-
-int PVS_CullSphere(const vec3_t origin, vec_t radius)
-{
-       int stackpos;
-       mnode_t *node, *stack[4096];
-       float dist;
-       if (cl.worldmodel == NULL)
-               return false;
-       stackpos = 0;
-       stack[stackpos++] = cl.worldmodel->brushq1.nodes;
-       while (stackpos)
-       {
-               node = stack[--stackpos];
-               if (node->contents < 0)
-               {
-                       if (((mleaf_t *)node)->pvsframe == cl.worldmodel->brushq1.pvsframecount)
-                               return false;
-               }
-               else
-               {
-                       dist = PlaneDiff(origin, node->plane);
-                       if (dist <= radius)
-                               stack[stackpos++] = node->children[1];
-                       if (dist >= -radius)
-                               stack[stackpos++] = node->children[0];
-               }
-       }
-       return true;
-}
-
-int VIS_CullSphere(const vec3_t origin, vec_t radius)
-{
-       int stackpos;
-       mnode_t *node, *stack[4096];
-       float dist;
-       if (R_CullSphere(origin, radius))
-               return true;
-       if (cl.worldmodel == NULL)
-               return false;
-       stackpos = 0;
-       stack[stackpos++] = cl.worldmodel->brushq1.nodes;
-       while (stackpos)
-       {
-               node = stack[--stackpos];
-               if (node->contents < 0)
-               {
-                       if (((mleaf_t *)node)->visframe == r_framecount)
-                               return false;
-               }
-               else
-               {
-                       dist = PlaneDiff(origin, node->plane);
-                       if (dist <= radius)
-                               stack[stackpos++] = node->children[1];
-                       if (dist >= -radius)
-                               stack[stackpos++] = node->children[0];
-               }
-       }
-       return true;
-}
-
+#define VIS_CullBox(mins,maxs) (R_CullBox((mins), (maxs)) || (cl.worldmodel && cl.worldmodel->brush.BoxTouchingPVS && !cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, r_pvsbits, (mins), (maxs))))
 
 //==================================================================================
 
@@ -552,7 +430,6 @@ static void R_MarkEntities (void)
                R_LerpAnimation(ent);
                R_UpdateEntLights(ent);
                if ((chase_active.integer || !(ent->flags & RENDER_EXTERIORMODEL))
-                && !VIS_CullSphere(ent->origin, (ent->model != NULL ? ent->model->radius : 16) * ent->scale)
                 && !VIS_CullBox(ent->mins, ent->maxs))
                {
                        ent->visframe = r_framecount;
@@ -652,182 +529,21 @@ void R_DrawFakeShadows (void)
 
 int shadowframecount = 0;
 
-int Light_CullBox(const vec3_t mins, const vec3_t maxs)
-{
-       int stackpos, sides;
-       mnode_t *node, *stack[4096];
-       if (cl.worldmodel == NULL)
-               return false;
-       stackpos = 0;
-       stack[stackpos++] = cl.worldmodel->brushq1.nodes;
-       while (stackpos)
-       {
-               node = stack[--stackpos];
-               if (node->contents < 0)
-               {
-                       if (((mleaf_t *)node)->worldnodeframe == shadowframecount)
-                               return false;
-               }
-               else
-               {
-                       sides = BoxOnPlaneSide(mins, maxs, node->plane);
-                       if (sides & 2 && stackpos < 4096)
-                               stack[stackpos++] = node->children[1];
-                       if (sides & 1 && stackpos < 4096)
-                               stack[stackpos++] = node->children[0];
-               }
-       }
-       return true;
-}
-
-int LightAndVis_CullBox(const vec3_t mins, const vec3_t maxs)
-{
-       int stackpos, sides;
-       mnode_t *node, *stack[4096];
-       if (R_CullBox(mins, maxs))
-               return true;
-       if (cl.worldmodel == NULL)
-               return false;
-       stackpos = 0;
-       stack[stackpos++] = cl.worldmodel->brushq1.nodes;
-       while (stackpos)
-       {
-               node = stack[--stackpos];
-               if (node->contents < 0)
-               {
-                       if (((mleaf_t *)node)->visframe == r_framecount && ((mleaf_t *)node)->worldnodeframe == shadowframecount)
-                               return false;
-               }
-               else
-               {
-                       sides = BoxOnPlaneSide(mins, maxs, node->plane);
-                       if (sides & 2 && stackpos < 4096)
-                               stack[stackpos++] = node->children[1];
-                       if (sides & 1 && stackpos < 4096)
-                               stack[stackpos++] = node->children[0];
-               }
-       }
-       return true;
-}
-
-int LightAndVis_CullPointCloud(int numpoints, const float *points)
-{
-       int i;
-       const float *p;
-       int stackpos, sides;
-       mnode_t *node, *stack[4096];
-       //if (R_CullBox(mins, maxs))
-       //      return true;
-       if (cl.worldmodel == NULL)
-               return false;
-       stackpos = 0;
-       stack[stackpos++] = cl.worldmodel->brushq1.nodes;
-       while (stackpos)
-       {
-               node = stack[--stackpos];
-               if (node->contents < 0)
-               {
-                       if (((mleaf_t *)node)->visframe == r_framecount && ((mleaf_t *)node)->worldnodeframe == shadowframecount)
-                               return false;
-               }
-               else
-               {
-                       sides = 0;
-                       for (i = 0, p = points;i < numpoints && sides != 3;i++, p += 3)
-                       {
-                               if (DotProduct(p, node->plane->normal) < node->plane->dist)
-                                       sides |= 1;
-                               else
-                                       sides |= 2;
-                       }
-                       if (sides & 2 && stackpos < 4096)
-                               stack[stackpos++] = node->children[1];
-                       if (sides & 1 && stackpos < 4096)
-                               stack[stackpos++] = node->children[0];
-               }
-       }
-       return true;
-}
-
-
 void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float cullradius, float lightradius, vec3_t lightmins, vec3_t lightmaxs, vec3_t clipmins, vec3_t clipmaxs, int lightmarked)
 {
        vec3_t relativelightorigin;
-       #if 0
-       int i;
-       vec3_t temp;
-       float dist, projectdistance;
-       float points[16][3];
-       #endif
        // rough checks
-       if (!(ent->flags & RENDER_SHADOW) || ent->model == NULL || ent->model->DrawShadowVolume == NULL)
-               return;
-       if (r_shadow_cull.integer)
+       if ((ent->flags & RENDER_SHADOW) && ent->model && ent->model->DrawShadowVolume && !(r_shadow_cull.integer && (ent->maxs[0] < lightmins[0] || ent->mins[0] > lightmaxs[0] || ent->maxs[1] < lightmins[1] || ent->mins[1] > lightmaxs[1] || ent->maxs[2] < lightmins[2] || ent->mins[2] > lightmaxs[2])))
        {
-               if (ent->maxs[0] < lightmins[0] || ent->mins[0] > lightmaxs[0]
-                || ent->maxs[1] < lightmins[1] || ent->mins[1] > lightmaxs[1]
-                || ent->maxs[2] < lightmins[2] || ent->mins[2] > lightmaxs[2]
-                || (lightmarked && Light_CullBox(ent->mins, ent->maxs)))
-                       return;
+               Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin);
+               ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius);
        }
-       #if 0
-       if (r_shadow_cull.integer)
-       {
-               projectdistance = cullradius;
-               // calculate projected bounding box and decide if it is on-screen
-               for (i = 0;i < 8;i++)
-               {
-                       temp[0] = i & 1 ? ent->model->normalmaxs[0] : ent->model->normalmins[0];
-                       temp[1] = i & 2 ? ent->model->normalmaxs[1] : ent->model->normalmins[1];
-                       temp[2] = i & 4 ? ent->model->normalmaxs[2] : ent->model->normalmins[2];
-                       Matrix4x4_Transform(&ent->matrix, temp, points[i]);
-                       VectorSubtract(points[i], lightorigin, temp);
-                       dist = projectdistance / sqrt(DotProduct(temp, temp));
-                       VectorMA(lightorigin, dist, temp, points[i+8]);
-               }
-               if (LightAndVis_CullPointCloud(16, points[0]))
-                       return;
-               /*
-               for (i = 0;i < 8;i++)
-               {
-                       p2[0] = i & 1 ? ent->model->normalmaxs[0] : ent->model->normalmins[0];
-                       p2[1] = i & 2 ? ent->model->normalmaxs[1] : ent->model->normalmins[1];
-                       p2[2] = i & 4 ? ent->model->normalmaxs[2] : ent->model->normalmins[2];
-                       Matrix4x4_Transform(&ent->matrix, p2, p);
-                       VectorSubtract(p, lightorigin, temp);
-                       dist = projectdistance / sqrt(DotProduct(temp, temp));
-                       VectorMA(p, dist, temp, p2);
-                       if (i)
-                       {
-                               if (mins[0] > p[0]) mins[0] = p[0];if (maxs[0] < p[0]) maxs[0] = p[0];
-                               if (mins[1] > p[1]) mins[1] = p[1];if (maxs[1] < p[1]) maxs[1] = p[1];
-                               if (mins[2] > p[2]) mins[2] = p[2];if (maxs[2] < p[2]) maxs[2] = p[2];
-                       }
-                       else
-                       {
-                               VectorCopy(p, mins);
-                               VectorCopy(p, maxs);
-                       }
-                       if (mins[0] > p2[0]) mins[0] = p2[0];if (maxs[0] < p2[0]) maxs[0] = p2[0];
-                       if (mins[1] > p2[1]) mins[1] = p2[1];if (maxs[1] < p2[1]) maxs[1] = p2[1];
-                       if (mins[2] > p2[2]) mins[2] = p2[2];if (maxs[2] < p2[2]) maxs[2] = p2[2];
-               }
-               if (mins[0] >= clipmaxs[0] || maxs[0] <= clipmins[0]
-                || mins[1] >= clipmaxs[1] || maxs[1] <= clipmins[1]
-                || mins[2] >= clipmaxs[2] || maxs[2] <= clipmins[2]
-                || LightAndVis_CullBox(mins, maxs))
-                       return;
-               */
-       }
-       #endif
-       Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin);
-       ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius);
 }
 
 void R_Shadow_DrawWorldLightShadowVolume(matrix4x4_t *matrix, worldlight_t *light);
 
 extern void R_Model_Brush_DrawLightForSurfaceList(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, msurface_t **surflist, int numsurfaces, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
-void R_ShadowVolumeLighting (int visiblevolumes)
+void R_ShadowVolumeLighting(int visiblevolumes)
 {
        int i;
        entity_render_t *ent;
@@ -837,7 +553,6 @@ void R_ShadowVolumeLighting (int visiblevolumes)
        worldlight_t *wl;
        rdlight_t *rd;
        rmeshstate_t m;
-       mleaf_t *leaf;
        matrix4x4_t matrix;
        matrix4x4_t matrix_worldtofilter, matrix_worldtoattenuationxyz, matrix_worldtoattenuationz;
        matrix4x4_t matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz;
@@ -863,63 +578,17 @@ void R_ShadowVolumeLighting (int visiblevolumes)
                {
                        if (d_lightstylevalue[wl->style] <= 0)
                                continue;
-                       if (R_CullBox(wl->mins, wl->maxs))
-                       //if (R_CullSphere(wl->origin, cullradius))
+                       if (VIS_CullBox(wl->mins, wl->maxs))
                                continue;
-                       //if (R_CullBox(wl->mins, wl->maxs) || R_CullSphere(wl->origin, lightradius))
-                       //      continue;
-                       //if (VIS_CullBox(wl->mins, wl->maxs) || VIS_CullSphere(wl->origin, lightradius))
-                       //      continue;
                        if (r_shadow_debuglight.integer >= 0 && lnum != r_shadow_debuglight.integer)
                                continue;
+                       if (R_Shadow_ScissorForBBox(wl->mins, wl->maxs))
+                               continue;
 
                        cullradius = wl->cullradius;
                        lightradius = wl->lightradius;
-
-                       if (cl.worldmodel != NULL)
-                       {
-                               for (i = 0;i < wl->numleafs;i++)
-                                       if (wl->leafs[i]->visframe == r_framecount)
-                                               break;
-                               if (i == wl->numleafs)
-                                       continue;
-                               leaf = wl->leafs[i++];
-                               VectorCopy(leaf->mins, clipmins);
-                               VectorCopy(leaf->maxs, clipmaxs);
-                               for (;i < wl->numleafs;i++)
-                               {
-                                       leaf = wl->leafs[i];
-                                       if (leaf->visframe == r_framecount)
-                                       {
-                                               if (clipmins[0] > leaf->mins[0]) clipmins[0] = leaf->mins[0];
-                                               if (clipmaxs[0] < leaf->maxs[0]) clipmaxs[0] = leaf->maxs[0];
-                                               if (clipmins[1] > leaf->mins[1]) clipmins[1] = leaf->mins[1];
-                                               if (clipmaxs[1] < leaf->maxs[1]) clipmaxs[1] = leaf->maxs[1];
-                                               if (clipmins[2] > leaf->mins[2]) clipmins[2] = leaf->mins[2];
-                                               if (clipmaxs[2] < leaf->maxs[2]) clipmaxs[2] = leaf->maxs[2];
-                                       }
-                               }
-                               if (clipmins[0] < wl->mins[0]) clipmins[0] = wl->mins[0];
-                               if (clipmaxs[0] > wl->maxs[0]) clipmaxs[0] = wl->maxs[0];
-                               if (clipmins[1] < wl->mins[1]) clipmins[1] = wl->mins[1];
-                               if (clipmaxs[1] > wl->maxs[1]) clipmaxs[1] = wl->maxs[1];
-                               if (clipmins[2] < wl->mins[2]) clipmins[2] = wl->mins[2];
-                               if (clipmaxs[2] > wl->maxs[2]) clipmaxs[2] = wl->maxs[2];
-                       }
-                       else
-                       {
-                               VectorCopy(wl->mins, clipmins);
-                               VectorCopy(wl->maxs, clipmaxs);
-                       }
-
-                       //if (R_Shadow_ScissorForBBoxAndSphere(clipmins, clipmaxs, wl->origin, wl->cullradius))
-                       if (R_CullBox(clipmins, clipmaxs) || R_Shadow_ScissorForBBox(clipmins, clipmaxs))
-                               continue;
-
-                       // mark the leafs we care about so only things in those leafs will matter
-                       if (cl.worldmodel != NULL)
-                               for (i = 0;i < wl->numleafs;i++)
-                                       wl->leafs[i]->worldnodeframe = shadowframecount;
+                       VectorCopy(wl->mins, clipmins);
+                       VectorCopy(wl->maxs, clipmaxs);
 
                        f = d_lightstylevalue[wl->style] * (1.0f / 256.0f);
                        VectorScale(wl->light, f, lightcolor);
@@ -1213,6 +882,9 @@ void R_RenderView (void)
        R_BuildLightList();
        R_TimeReport("setup");
 
+       if (cl.worldmodel && cl.worldmodel->brush.FatPVS)
+               cl.worldmodel->brush.FatPVS(cl.worldmodel, r_origin, 2, r_pvsbits, sizeof(r_pvsbits));
+
        R_WorldVisibility(world);
        R_TimeReport("worldvis");
 
index fe81def..4582d8c 100644 (file)
@@ -729,7 +729,7 @@ static void RSurfShader_Sky(const entity_render_t *ent, const texture_t *texture
        rmeshstate_t m;
 
        // LordHavoc: HalfLife maps have freaky skypolys...
-       if (ent->model->brushq1.ishlbsp)
+       if (ent->model->brush.ishlbsp)
                return;
 
        if (skyrendernow)
@@ -1528,6 +1528,7 @@ static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
        R_Mesh_Draw(portal->numpoints, portal->numpoints - 2, polygonelements);
 }
 
+// LordHavoc: this is just a nice debugging tool, very slow
 static void R_DrawPortals(entity_render_t *ent)
 {
        int i;
@@ -1537,7 +1538,7 @@ static void R_DrawPortals(entity_render_t *ent)
                return;
        for (portal = ent->model->brushq1.portals, endportal = portal + ent->model->brushq1.numportals;portal < endportal;portal++)
        {
-               if ((portal->here->pvsframe == ent->model->brushq1.pvsframecount || portal->past->pvsframe == ent->model->brushq1.pvsframecount) && portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
+               if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
                {
                        VectorClear(temp);
                        for (i = 0;i < portal->numpoints;i++)
@@ -1639,7 +1640,7 @@ void R_SurfaceWorldNode (entity_render_t *ent)
 
 static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
 {
-       int c, leafstackpos, *mark, *surfacevisframes;
+       int c, leafstackpos, *mark, *surfacevisframes, bitnum;
 #if WORLDNODECULLBACKFACES
        int n;
        msurface_t *surf;
@@ -1703,7 +1704,8 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
                                {
                                        leaf->worldnodeframe = r_framecount;
                                        // FIXME: R_CullBox is absolute, should be done relative
-                                       if (leaf->pvsframe == ent->model->brushq1.pvsframecount && !R_CullBox(leaf->mins, leaf->maxs))
+                                       bitnum = (leaf - ent->model->brushq1.leafs) - 1;
+                                       if ((r_pvsbits[bitnum >> 3] & (1 << (bitnum & 7))) && !R_CullBox(leaf->mins, leaf->maxs))
                                                leafstack[leafstackpos++] = leaf;
                                }
                        }
@@ -1715,7 +1717,6 @@ void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf)
 {
        int j, c, *surfacepvsframes, *mark;
        mleaf_t *leaf;
-       qbyte *pvs;
        model_t *model;
 
        model = ent->model;
@@ -1728,11 +1729,10 @@ void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf)
                model->brushq1.pvssurflistlength = 0;
                if (viewleaf)
                {
-                       pvs = viewleaf->pvsdata;
                        surfacepvsframes = model->brushq1.surfacepvsframes;
-                       for (j = 0;j < model->brushq1.numleafs-1;j++)
+                       for (j = 0;j < model->brushq1.visleafs;j++)
                        {
-                               if (pvs[j >> 3] & (1 << (j & 7)))
+                               if (r_pvsbits[j >> 3] & (1 << (j & 7)))
                                {
                                        leaf = model->brushq1.leafs + j + 1;
                                        leaf->pvsframe = model->brushq1.pvsframecount;
@@ -1897,6 +1897,34 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
        }
 }
 
+/*
+void R_Q3BSP_DrawSky(entity_render_t *ent)
+{
+}
+*/
+
+void R_Q3BSP_Draw(entity_render_t *ent)
+{
+}
+
+/*
+void R_Q3BSP_DrawFakeShadow(entity_render_t *ent)
+{
+}
+*/
+
+/*
+void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
+{
+}
+*/
+
+/*
+void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
+{
+}
+*/
+
 static void gl_surf_start(void)
 {
 }
index e20c570..a1bcd56 100644 (file)
@@ -64,6 +64,25 @@ static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p)
        return (mleaf_t *)node;
 }
 
+static void Mod_Q1BSP_AmbientSoundLevelsForPoint(model_t *model, const vec3_t p, qbyte *out, int outsize)
+{
+       int i;
+       mleaf_t *leaf;
+       leaf = Mod_Q1BSP_PointInLeaf(model, p);
+       if (leaf)
+       {
+               i = min(outsize, (int)sizeof(leaf->ambient_sound_level));;
+               if (i)
+               {
+                       memcpy(out, leaf->ambient_sound_level, i);
+                       out += i;
+                       outsize -= i;
+               }
+       }
+       if (outsize)
+               memset(out, 0, outsize);
+}
+
 
 static int Mod_Q1BSP_BoxTouchingPVS_RecursiveBSPNode(const model_t *model, const mnode_t *node, const qbyte *pvs, const vec3_t mins, const vec3_t maxs)
 {
@@ -478,7 +497,7 @@ static void Mod_Q1BSP_TraceBox(struct model_s *model, trace_t *trace, const vec3
        VectorSubtract(boxstartmaxs, boxstartmins, boxsize);
        if (boxsize[0] < 3)
                rhc.hull = &model->brushq1.hulls[0]; // 0x0x0
-       else if (model->brushq1.ishlbsp)
+       else if (model->brush.ishlbsp)
        {
                if (boxsize[0] <= 32)
                {
@@ -766,7 +785,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                }
 
                // LordHavoc: HL sky textures are entirely different than quake
-               if (!loadmodel->brushq1.ishlbsp && !strncmp(tx->name, "sky", 3) && mtwidth == 256 && mtheight == 128)
+               if (!loadmodel->brush.ishlbsp && !strncmp(tx->name, "sky", 3) && mtwidth == 256 && mtheight == 128)
                {
                        if (loadmodel->isworldmodel)
                        {
@@ -795,7 +814,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                        if (!Mod_LoadSkinFrame(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true))
                        {
                                // did not find external texture, load it from the bsp or wad3
-                               if (loadmodel->brushq1.ishlbsp)
+                               if (loadmodel->brush.ishlbsp)
                                {
                                        // internal texture overrides wad
                                        qbyte *pixels, *freepixels, *fogpixels;
@@ -977,7 +996,7 @@ static void Mod_Q1BSP_LoadLighting(lump_t *l)
        qbyte *in, *out, *data, d;
        char litfilename[1024];
        loadmodel->brushq1.lightdata = NULL;
-       if (loadmodel->brushq1.ishlbsp) // LordHavoc: load the colored lighting data straight
+       if (loadmodel->brush.ishlbsp) // LordHavoc: load the colored lighting data straight
        {
                loadmodel->brushq1.lightdata = Mem_Alloc(loadmodel->mempool, l->filelen);
                memcpy(loadmodel->brushq1.lightdata, mod_base + l->fileofs, l->filelen);
@@ -1094,265 +1113,6 @@ static void Mod_Q1BSP_LoadLightList(void)
        }
 }
 
-/*
-static int castshadowcount = 0;
-static void Mod_Q1BSP_ProcessLightList(void)
-{
-       int j, k, l, *mark, lnum;
-       mlight_t *e;
-       msurface_t *surf;
-       float dist;
-       mleaf_t *leaf;
-       qbyte *pvs;
-       vec3_t temp;
-       float *v, radius2;
-       for (lnum = 0, e = loadmodel->brushq1.lights;lnum < loadmodel->brushq1.numlights;lnum++, e++)
-       {
-               e->cullradius2 = DotProduct(e->light, e->light) / (e->falloff * e->falloff * 8192.0f * 8192.0f * 2.0f * 2.0f);// + 4096.0f;
-               if (e->cullradius2 > 4096.0f * 4096.0f)
-                       e->cullradius2 = 4096.0f * 4096.0f;
-               e->cullradius = e->lightradius = sqrt(e->cullradius2);
-               leaf = Mod_Q1BSP_PointInLeaf(e->origin, loadmodel);
-               if (leaf->compressed_vis)
-                       pvs = Mod_Q1BSP_DecompressVis(leaf->compressed_vis, loadmodel);
-               else
-                       pvs = mod_q1bsp_novis;
-               for (j = 0;j < loadmodel->brushq1.numsurfaces;j++)
-                       loadmodel->brushq1.surfacevisframes[j] = -1;
-               for (j = 0, leaf = loadmodel->brushq1.leafs + 1;j < loadmodel->brushq1.numleafs - 1;j++, leaf++)
-               {
-                       if (pvs[j >> 3] & (1 << (j & 7)))
-                       {
-                               for (k = 0, mark = leaf->firstmarksurface;k < leaf->nummarksurfaces;k++, mark++)
-                               {
-                                       surf = loadmodel->brushq1.surfaces + *mark;
-                                       if (surf->number != *mark)
-                                               Con_Printf("%d != %d\n", surf->number, *mark);
-                                       dist = DotProduct(e->origin, surf->plane->normal) - surf->plane->dist;
-                                       if (surf->flags & SURF_PLANEBACK)
-                                               dist = -dist;
-                                       if (dist > 0 && dist < e->cullradius)
-                                       {
-                                               temp[0] = bound(surf->poly_mins[0], e->origin[0], surf->poly_maxs[0]) - e->origin[0];
-                                               temp[1] = bound(surf->poly_mins[1], e->origin[1], surf->poly_maxs[1]) - e->origin[1];
-                                               temp[2] = bound(surf->poly_mins[2], e->origin[2], surf->poly_maxs[2]) - e->origin[2];
-                                               if (DotProduct(temp, temp) < lightradius2)
-                                                       loadmodel->brushq1.surfacevisframes[*mark] = -2;
-                                       }
-                               }
-                       }
-               }
-               // build list of light receiving surfaces
-               e->numsurfaces = 0;
-               for (j = 0;j < loadmodel->brushq1.numsurfaces;j++)
-                       if (loadmodel->brushq1.surfacevisframes[j] == -2)
-                               e->numsurfaces++;
-               e->surfaces = NULL;
-               if (e->numsurfaces > 0)
-               {
-                       e->surfaces = Mem_Alloc(loadmodel->mempool, sizeof(msurface_t *) * e->numsurfaces);
-                       e->numsurfaces = 0;
-                       for (j = 0;j < loadmodel->brushq1.numsurfaces;j++)
-                               if (loadmodel->brushq1.surfacevisframes[j] == -2)
-                                       e->surfaces[e->numsurfaces++] = loadmodel->brushq1.surfaces + j;
-               }
-               // find bounding box and sphere of lit surfaces
-               // (these will be used for creating a shape to clip the light)
-               radius2 = 0;
-               for (j = 0;j < e->numsurfaces;j++)
-               {
-                       surf = e->surfaces[j];
-                       if (j == 0)
-                       {
-                               VectorCopy(surf->poly_verts, e->mins);
-                               VectorCopy(surf->poly_verts, e->maxs);
-                       }
-                       for (k = 0, v = surf->poly_verts;k < surf->poly_numverts;k++, v += 3)
-                       {
-                               if (e->mins[0] > v[0]) e->mins[0] = v[0];if (e->maxs[0] < v[0]) e->maxs[0] = v[0];
-                               if (e->mins[1] > v[1]) e->mins[1] = v[1];if (e->maxs[1] < v[1]) e->maxs[1] = v[1];
-                               if (e->mins[2] > v[2]) e->mins[2] = v[2];if (e->maxs[2] < v[2]) e->maxs[2] = v[2];
-                               VectorSubtract(v, e->origin, temp);
-                               dist = DotProduct(temp, temp);
-                               if (radius2 < dist)
-                                       radius2 = dist;
-                       }
-               }
-               if (e->cullradius2 > radius2)
-               {
-                       e->cullradius2 = radius2;
-                       e->cullradius = sqrt(e->cullradius2);
-               }
-               if (e->mins[0] < e->origin[0] - e->lightradius) e->mins[0] = e->origin[0] - e->lightradius;
-               if (e->maxs[0] > e->origin[0] + e->lightradius) e->maxs[0] = e->origin[0] + e->lightradius;
-               if (e->mins[1] < e->origin[1] - e->lightradius) e->mins[1] = e->origin[1] - e->lightradius;
-               if (e->maxs[1] > e->origin[1] + e->lightradius) e->maxs[1] = e->origin[1] + e->lightradius;
-               if (e->mins[2] < e->origin[2] - e->lightradius) e->mins[2] = e->origin[2] - e->lightradius;
-               if (e->maxs[2] > e->origin[2] + e->lightradius) e->maxs[2] = e->origin[2] + e->lightradius;
-               // clip shadow volumes against eachother to remove unnecessary
-               // polygons(and sections of polygons)
-               {
-                       //vec3_t polymins, polymaxs;
-                       int maxverts = 4;
-                       float *verts = Mem_Alloc(loadmodel->mempool, maxverts * sizeof(float[3]));
-                       float f, *v0, *v1, projectdistance;
-
-                       e->shadowvolume = Mod_ShadowMesh_Begin(loadmodel->mempool, 1024);
-#if 0
-                       {
-                       vec3_t outermins, outermaxs, innermins, innermaxs;
-                       innermins[0] = e->mins[0] - 1;
-                       innermins[1] = e->mins[1] - 1;
-                       innermins[2] = e->mins[2] - 1;
-                       innermaxs[0] = e->maxs[0] + 1;
-                       innermaxs[1] = e->maxs[1] + 1;
-                       innermaxs[2] = e->maxs[2] + 1;
-                       outermins[0] = loadmodel->normalmins[0] - 1;
-                       outermins[1] = loadmodel->normalmins[1] - 1;
-                       outermins[2] = loadmodel->normalmins[2] - 1;
-                       outermaxs[0] = loadmodel->normalmaxs[0] + 1;
-                       outermaxs[1] = loadmodel->normalmaxs[1] + 1;
-                       outermaxs[2] = loadmodel->normalmaxs[2] + 1;
-                       // add bounding box around the whole shadow volume set,
-                       // facing inward to limit light area, with an outer bounding box
-                       // facing outward (this is needed by the shadow rendering method)
-                       // X major
-                       verts[ 0] = innermaxs[0];verts[ 1] = innermins[1];verts[ 2] = innermaxs[2];
-                       verts[ 3] = innermaxs[0];verts[ 4] = innermins[1];verts[ 5] = innermins[2];
-                       verts[ 6] = innermaxs[0];verts[ 7] = innermaxs[1];verts[ 8] = innermins[2];
-                       verts[ 9] = innermaxs[0];verts[10] = innermaxs[1];verts[11] = innermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       verts[ 0] = outermaxs[0];verts[ 1] = outermaxs[1];verts[ 2] = outermaxs[2];
-                       verts[ 3] = outermaxs[0];verts[ 4] = outermaxs[1];verts[ 5] = outermins[2];
-                       verts[ 6] = outermaxs[0];verts[ 7] = outermins[1];verts[ 8] = outermins[2];
-                       verts[ 9] = outermaxs[0];verts[10] = outermins[1];verts[11] = outermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       // X minor
-                       verts[ 0] = innermins[0];verts[ 1] = innermaxs[1];verts[ 2] = innermaxs[2];
-                       verts[ 3] = innermins[0];verts[ 4] = innermaxs[1];verts[ 5] = innermins[2];
-                       verts[ 6] = innermins[0];verts[ 7] = innermins[1];verts[ 8] = innermins[2];
-                       verts[ 9] = innermins[0];verts[10] = innermins[1];verts[11] = innermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       verts[ 0] = outermins[0];verts[ 1] = outermins[1];verts[ 2] = outermaxs[2];
-                       verts[ 3] = outermins[0];verts[ 4] = outermins[1];verts[ 5] = outermins[2];
-                       verts[ 6] = outermins[0];verts[ 7] = outermaxs[1];verts[ 8] = outermins[2];
-                       verts[ 9] = outermins[0];verts[10] = outermaxs[1];verts[11] = outermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       // Y major
-                       verts[ 0] = innermaxs[0];verts[ 1] = innermaxs[1];verts[ 2] = innermaxs[2];
-                       verts[ 3] = innermaxs[0];verts[ 4] = innermaxs[1];verts[ 5] = innermins[2];
-                       verts[ 6] = innermins[0];verts[ 7] = innermaxs[1];verts[ 8] = innermins[2];
-                       verts[ 9] = innermins[0];verts[10] = innermaxs[1];verts[11] = innermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       verts[ 0] = outermins[0];verts[ 1] = outermaxs[1];verts[ 2] = outermaxs[2];
-                       verts[ 3] = outermins[0];verts[ 4] = outermaxs[1];verts[ 5] = outermins[2];
-                       verts[ 6] = outermaxs[0];verts[ 7] = outermaxs[1];verts[ 8] = outermins[2];
-                       verts[ 9] = outermaxs[0];verts[10] = outermaxs[1];verts[11] = outermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       // Y minor
-                       verts[ 0] = innermins[0];verts[ 1] = innermins[1];verts[ 2] = innermaxs[2];
-                       verts[ 3] = innermins[0];verts[ 4] = innermins[1];verts[ 5] = innermins[2];
-                       verts[ 6] = innermaxs[0];verts[ 7] = innermins[1];verts[ 8] = innermins[2];
-                       verts[ 9] = innermaxs[0];verts[10] = innermins[1];verts[11] = innermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       verts[ 0] = outermaxs[0];verts[ 1] = outermins[1];verts[ 2] = outermaxs[2];
-                       verts[ 3] = outermaxs[0];verts[ 4] = outermins[1];verts[ 5] = outermins[2];
-                       verts[ 6] = outermins[0];verts[ 7] = outermins[1];verts[ 8] = outermins[2];
-                       verts[ 9] = outermins[0];verts[10] = outermins[1];verts[11] = outermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       // Z major
-                       verts[ 0] = innermaxs[0];verts[ 1] = innermins[1];verts[ 2] = innermaxs[2];
-                       verts[ 3] = innermaxs[0];verts[ 4] = innermaxs[1];verts[ 5] = innermaxs[2];
-                       verts[ 6] = innermins[0];verts[ 7] = innermaxs[1];verts[ 8] = innermaxs[2];
-                       verts[ 9] = innermins[0];verts[10] = innermins[1];verts[11] = innermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       verts[ 0] = outermaxs[0];verts[ 1] = outermaxs[1];verts[ 2] = outermaxs[2];
-                       verts[ 3] = outermaxs[0];verts[ 4] = outermins[1];verts[ 5] = outermaxs[2];
-                       verts[ 6] = outermins[0];verts[ 7] = outermins[1];verts[ 8] = outermaxs[2];
-                       verts[ 9] = outermins[0];verts[10] = outermaxs[1];verts[11] = outermaxs[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       // Z minor
-                       verts[ 0] = innermaxs[0];verts[ 1] = innermaxs[1];verts[ 2] = innermins[2];
-                       verts[ 3] = innermaxs[0];verts[ 4] = innermins[1];verts[ 5] = innermins[2];
-                       verts[ 6] = innermins[0];verts[ 7] = innermins[1];verts[ 8] = innermins[2];
-                       verts[ 9] = innermins[0];verts[10] = innermaxs[1];verts[11] = innermins[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       verts[ 0] = outermaxs[0];verts[ 1] = outermins[1];verts[ 2] = outermins[2];
-                       verts[ 3] = outermaxs[0];verts[ 4] = outermaxs[1];verts[ 5] = outermins[2];
-                       verts[ 6] = outermins[0];verts[ 7] = outermaxs[1];verts[ 8] = outermins[2];
-                       verts[ 9] = outermins[0];verts[10] = outermins[1];verts[11] = outermins[2];
-                       Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                       }
-#endif
-                       castshadowcount++;
-                       for (j = 0;j < e->numsurfaces;j++)
-                       {
-                               surf = e->surfaces[j];
-                               if (surf->flags & SURF_SHADOWCAST)
-                                       surf->castshadow = castshadowcount;
-                       }
-                       for (j = 0;j < e->numsurfaces;j++)
-                       {
-                               surf = e->surfaces[j];
-                               if (surf->castshadow != castshadowcount)
-                                       continue;
-                               f = DotProduct(e->origin, surf->plane->normal) - surf->plane->dist;
-                               if (surf->flags & SURF_PLANEBACK)
-                                       f = -f;
-                               projectdistance = e->lightradius;
-                               if (maxverts < surf->poly_numverts)
-                               {
-                                       maxverts = surf->poly_numverts;
-                                       if (verts)
-                                               Mem_Free(verts);
-                                       verts = Mem_Alloc(loadmodel->mempool, maxverts * sizeof(float[3]));
-                               }
-                               // copy the original polygon, for the front cap of the volume
-                               for (k = 0, v0 = surf->poly_verts, v1 = verts;k < surf->poly_numverts;k++, v0 += 3, v1 += 3)
-                                       VectorCopy(v0, v1);
-                               Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, surf->poly_numverts, verts);
-                               // project the original polygon, reversed, for the back cap of the volume
-                               for (k = 0, v0 = surf->poly_verts + (surf->poly_numverts - 1) * 3, v1 = verts;k < surf->poly_numverts;k++, v0 -= 3, v1 += 3)
-                               {
-                                       VectorSubtract(v0, e->origin, temp);
-                                       VectorNormalize(temp);
-                                       VectorMA(v0, projectdistance, temp, v1);
-                               }
-                               Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, surf->poly_numverts, verts);
-                               // project the shadow volume sides
-                               for (l = surf->poly_numverts - 1, k = 0, v0 = surf->poly_verts + (surf->poly_numverts - 1) * 3, v1 = surf->poly_verts;k < surf->poly_numverts;l = k, k++, v0 = v1, v1 += 3)
-                               {
-                                       if (!surf->neighborsurfaces[l] || surf->neighborsurfaces[l]->castshadow != castshadowcount)
-                                       {
-                                               VectorCopy(v1, &verts[0]);
-                                               VectorCopy(v0, &verts[3]);
-                                               VectorCopy(v0, &verts[6]);
-                                               VectorCopy(v1, &verts[9]);
-                                               VectorSubtract(&verts[6], e->origin, temp);
-                                               VectorNormalize(temp);
-                                               VectorMA(&verts[6], projectdistance, temp, &verts[6]);
-                                               VectorSubtract(&verts[9], e->origin, temp);
-                                               VectorNormalize(temp);
-                                               VectorMA(&verts[9], projectdistance, temp, &verts[9]);
-                                               Mod_ShadowMesh_AddPolygon(loadmodel->mempool, e->shadowvolume, 4, verts);
-                                       }
-                               }
-                       }
-                       // build the triangle mesh
-                       e->shadowvolume = Mod_ShadowMesh_Finish(loadmodel->mempool, e->shadowvolume);
-                       {
-                               shadowmesh_t *mesh;
-                               l = 0;
-                               for (mesh = e->shadowvolume;mesh;mesh = mesh->next)
-                                       l += mesh->numtriangles;
-                               Con_Printf("light %i shadow volume built containing %i triangles\n", lnum, l);
-                       }
-               }
-       }
-}
-*/
-
-
 static void Mod_Q1BSP_LoadVisibility(lump_t *l)
 {
        loadmodel->brushq1.num_compressedpvs = 0;
@@ -1393,7 +1153,7 @@ static void Mod_Q1BSP_ParseWadsFromEntityLump(const char *data)
                strcpy(value, com_token);
                if (!strcmp("wad", key)) // for HalfLife maps
                {
-                       if (loadmodel->brushq1.ishlbsp)
+                       if (loadmodel->brush.ishlbsp)
                        {
                                j = 0;
                                for (i = 0;i < 4096;i++)
@@ -1431,7 +1191,7 @@ static void Mod_Q1BSP_LoadEntities(lump_t *l)
                return;
        loadmodel->brush.entities = Mem_Alloc(loadmodel->mempool, l->filelen);
        memcpy(loadmodel->brush.entities, mod_base + l->fileofs, l->filelen);
-       if (loadmodel->brushq1.ishlbsp)
+       if (loadmodel->brush.ishlbsp)
                Mod_Q1BSP_ParseWadsFromEntityLump(loadmodel->brush.entities);
 }
 
@@ -1472,7 +1232,7 @@ static void Mod_Q1BSP_LoadSubmodels(lump_t *l)
        out = Mem_Alloc(loadmodel->mempool, count*sizeof(*out));
 
        loadmodel->brushq1.submodels = out;
-       loadmodel->brushq1.numsubmodels = count;
+       loadmodel->brush.numsubmodels = count;
 
        for ( i=0 ; i<count ; i++, in++, out++)
        {
@@ -1850,7 +1610,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
                i = LittleLong(in->lightofs);
                if (i == -1)
                        surf->samples = NULL;
-               else if (loadmodel->brushq1.ishlbsp) // LordHavoc: HalfLife map (bsp version 30)
+               else if (loadmodel->brush.ishlbsp) // LordHavoc: HalfLife map (bsp version 30)
                        surf->samples = loadmodel->brushq1.lightdata + i;
                else // LordHavoc: white lighting (bsp version 29)
                        surf->samples = loadmodel->brushq1.lightdata + (i * 3);
@@ -2018,7 +1778,7 @@ static void Mod_Q1BSP_LoadLeafs(lump_t *l)
 
        loadmodel->brushq1.leafs = out;
        loadmodel->brushq1.numleafs = count;
-       pvschainbytes = ((loadmodel->brushq1.num_leafs - 1)+7)>>3;
+       pvschainbytes = ((loadmodel->brushq1.numleafs - 1)+7)>>3;
        loadmodel->brushq1.data_decompressedpvs = pvs = Mem_Alloc(loadmodel->mempool, loadmodel->brushq1.numleafs * pvschainbytes);
 
        for ( i=0 ; i<count ; i++, in++, out++)
@@ -2067,7 +1827,7 @@ static void Mod_Q1BSP_LoadClipnodes(lump_t *l)
        loadmodel->brushq1.clipnodes = out;
        loadmodel->brushq1.numclipnodes = count;
 
-       if (loadmodel->brushq1.ishlbsp)
+       if (loadmodel->brush.ishlbsp)
        {
                hull = &loadmodel->brushq1.hulls[1];
                hull->clipnodes = out;
@@ -3072,13 +2832,46 @@ void Mod_Q1BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, vec_t r
 //of the given point.
 int Mod_Q1BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbufferlength)
 {
-       int bytes = ((model->brushq1.num_leafs - 1) + 7) >> 3;
+       int bytes = ((model->brushq1.numleafs - 1) + 7) >> 3;
        bytes = min(bytes, pvsbufferlength);
        memset(pvsbuffer, 0, bytes);
        Mod_Q1BSP_FatPVS_RecursiveBSPNode(model, org, radius, pvsbuffer, bytes, sv.worldmodel->brushq1.nodes);
        return bytes;
 }
 
+static void Mod_Q1BSP_RoundUpToHullSize(model_t *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs)
+{
+       vec3_t size;
+       const hull_t *hull;
+
+       VectorSubtract(inmaxs, inmins, size);
+       if (cmodel->brush.ishlbsp)
+       {
+               if (size[0] < 3)
+                       hull = &cmodel->brushq1.hulls[0]; // 0x0x0
+               else if (size[0] <= 32)
+               {
+                       if (size[2] < 54) // pick the nearest of 36 or 72
+                               hull = &cmodel->brushq1.hulls[3]; // 32x32x36
+                       else
+                               hull = &cmodel->brushq1.hulls[1]; // 32x32x72
+               }
+               else
+                       hull = &cmodel->brushq1.hulls[2]; // 64x64x64
+       }
+       else
+       {
+               if (size[0] < 3)
+                       hull = &cmodel->brushq1.hulls[0]; // 0x0x0
+               else if (size[0] <= 32)
+                       hull = &cmodel->brushq1.hulls[1]; // 32x32x56
+               else
+                       hull = &cmodel->brushq1.hulls[2]; // 64x64x88
+       }
+       VectorCopy(inmins, outmins);
+       VectorAdd(inmins, hull->clip_size, outmaxs);
+}
+
 extern void R_Model_Brush_DrawSky(entity_render_t *ent);
 extern void R_Model_Brush_Draw(entity_render_t *ent);
 extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
@@ -3102,19 +2895,21 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer)
        i = LittleLong(header->version);
        if (i != BSPVERSION && i != 30)
                Host_Error("Mod_Q1BSP_Load: %s has wrong version number(%i should be %i(Quake) or 30(HalfLife))", mod->name, i, BSPVERSION);
-       mod->brushq1.ishlbsp = i == 30;
+       mod->brush.ishlbsp = i == 30;
 
+       mod->brush.AmbientSoundLevelsForPoint = Mod_Q1BSP_AmbientSoundLevelsForPoint;
        mod->brush.FatPVS = Mod_Q1BSP_FatPVS;
        mod->brush.BoxTouchingPVS = Mod_Q1BSP_BoxTouchingPVS;
        mod->brush.LightPoint = Mod_Q1BSP_LightPoint;
        mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation;
        mod->brush.TraceBox = Mod_Q1BSP_TraceBox;
+       mod->brush.RoundUpToHullSize = Mod_Q1BSP_RoundUpToHullSize;
        mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
        mod->brushq1.BuildPVSTextureChains = Mod_Q1BSP_BuildPVSTextureChains;
 
        if (loadmodel->isworldmodel)
        {
-               Cvar_SetValue("halflifebsp", mod->brushq1.ishlbsp);
+               Cvar_SetValue("halflifebsp", mod->brush.ishlbsp);
                // until we get a texture for it...
                R_ResetQuakeSky();
        }
@@ -3155,7 +2950,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer)
        Mod_Q1BSP_MakePortals();
 
        if (developer.integer)
-               Con_Printf("Some stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals\n", loadmodel->name, loadmodel->brushq1.numsurfaces, loadmodel->brushq1.numnodes, loadmodel->brushq1.numleafs, loadmodel->brushq1.num_leafs - 1, loadmodel->brushq1.numportals);
+               Con_Printf("Some stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals\n", loadmodel->name, loadmodel->brushq1.numsurfaces, loadmodel->brushq1.numnodes, loadmodel->brushq1.numleafs, loadmodel->brushq1.numleafs - 1, loadmodel->brushq1.numportals);
 
        mod->numframes = 2;             // regular and alternate animation
 
@@ -3168,7 +2963,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer)
 //
 // set up the submodels(FIXME: this is confusing)
 //
-       for (i = 0;i < mod->brushq1.numsubmodels;i++)
+       for (i = 0;i < mod->brush.numsubmodels;i++)
        {
                bm = &mod->brushq1.submodels[i];
 
@@ -3206,7 +3001,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer)
                                if (surf->texinfo->texture->shader == &Cshader_sky)
                                        mod->DrawSky = R_Model_Brush_DrawSky;
                                // LordHavoc: submodels always clip, even if water
-                               if (mod->brushq1.numsubmodels - 1)
+                               if (mod->brush.numsubmodels - 1)
                                        surf->flags |= SURF_SOLIDCLIP;
                                // calculate bounding shapes
                                for (mesh = surf->mesh;mesh;mesh = mesh->chain)
@@ -3245,11 +3040,11 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer)
                }
                Mod_Q1BSP_BuildSurfaceNeighbors(mod->brushq1.surfaces + mod->brushq1.firstmodelsurface, mod->brushq1.nummodelsurfaces, originalloadmodel->mempool);
 
-               mod->brushq1.numleafs = bm->visleafs;
+               mod->brushq1.visleafs = bm->visleafs;
 
                // LordHavoc: only register submodels if it is the world
                // (prevents bsp models from replacing world submodels)
-               if (loadmodel->isworldmodel && i < (mod->brushq1.numsubmodels - 1))
+               if (loadmodel->isworldmodel && i < (mod->brush.numsubmodels - 1))
                {
                        char    name[10];
                        // duplicate the basic information
@@ -3660,10 +3455,10 @@ void Mod_Q2BSP_Load(model_t *mod, void *buffer)
        i = LittleLong(header->version);
        if (i != Q2BSPVERSION)
                Host_Error("Mod_Q2BSP_Load: %s has wrong version number (%i, should be %i)", mod->name, i, Q2BSPVERSION);
-       mod->brushq1.ishlbsp = false;
+       mod->brush.ishlbsp = false;
        if (loadmodel->isworldmodel)
        {
-               Cvar_SetValue("halflifebsp", mod->brushq1.ishlbsp);
+               Cvar_SetValue("halflifebsp", mod->brush.ishlbsp);
                // until we get a texture for it...
                R_ResetQuakeSky();
        }
@@ -4532,6 +4327,11 @@ int Mod_Q3BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsb
        return pvsbufferlength;
 }
 
+//extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
+extern void R_Q3BSP_Draw(struct entity_render_s *ent);
+//extern void R_Q3BSP_DrawFakeShadow(struct entity_render_s *ent);
+//extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
+//extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
 void Mod_Q3BSP_Load(model_t *mod, void *buffer)
 {
        int i;
@@ -4556,8 +4356,11 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer)
        mod->brush.LightPoint = Mod_Q3BSP_LightPoint;
        mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation;
        mod->brush.TraceBox = Mod_Q3BSP_TraceBox;
-       //mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
-       //mod->brushq1.BuildPVSTextureChains = Mod_Q1BSP_BuildPVSTextureChains;
+       //mod->DrawSky = R_Q3BSP_DrawSky;
+       mod->Draw = R_Q3BSP_Draw;
+       //mod->DrawFakeShadow = R_Q3BSP_DrawFakeShadow;
+       //mod->DrawShadowVolume = R_Q3BSP_DrawShadowVolume;
+       //mod->DrawLight = R_Q3BSP_DrawLight;
 
        mod_base = (qbyte *)header;
 
index 7023822..3dbbb0c 100644 (file)
@@ -144,33 +144,41 @@ struct trace_s;
 
 typedef struct model_brush_s
 {
+       // true if this model is a HalfLife .bsp file
+       qboolean ishlbsp;
+       // string of entity definitions (.map format)
        char *entities;
+       // number of submodels in this map (just used by server to know how many
+       // submodels to load)
+       int numsubmodels;
+       // common functions
+       void (*AmbientSoundLevelsForPoint)(struct model_s *model, const vec3_t p, qbyte *out, int outsize);
        int (*FatPVS)(struct model_s *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbufferlength);
        int (*BoxTouchingPVS)(struct model_s *model, const qbyte *pvs, const vec3_t mins, const vec3_t maxs);
        void (*LightPoint)(struct model_s *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal);
        void (*FindNonSolidLocation)(struct model_s *model, const vec3_t in, vec3_t out, vec_t radius);
        void (*TraceBox)(struct model_s *model, struct trace_s *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs);
+       // this is actually only found on brushq1, but NULL is handled gracefully
+       void (*RoundUpToHullSize)(struct model_s *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs);
 }
 model_brush_t;
 
 typedef struct model_brushq1_s
 {
-       // true if this model is a HalfLife .bsp file
-       qboolean                ishlbsp;
-
        int                             firstmodelsurface, nummodelsurfaces;
 
        // lightmap format, set to r_lightmaprgba when model is loaded
        int                             lightmaprgba;
 
-       int                             numsubmodels;
        dmodel_t                *submodels;
 
        int                             numplanes;
        mplane_t                *planes;
 
-       // number of visible leafs, not counting 0 (solid)
+       // number of actual leafs (including 0 which is solid)
        int                             numleafs;
+       // visible leafs, not counting 0 (solid)
+       int                             visleafs;
        mleaf_t                 *leafs;
 
        int                             numvertexes;
index c0d6e44..0f801f8 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -1297,7 +1297,7 @@ void PF_precache_model (void)
                Host_Error ("PF_Precache_*: Precache can only be done in spawn functions");
 
        s = G_STRING(OFS_PARM0);
-       if (sv.worldmodel->brushq1.ishlbsp && ((!s) || (!s[0])))
+       if (sv.worldmodel->brush.ishlbsp && ((!s) || (!s[0])))
                return;
        G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
        PR_CheckEmptyString (s);
index 9fd7478..5cc2697 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -275,7 +275,7 @@ void R_MarkLights(entity_render_t *ent)
                        lightpvsbytes = 0;
                        if (r_vismarklights.integer && ent->model->brush.FatPVS)
                                lightpvsbytes = ent->model->brush.FatPVS(ent->model, lightorigin, 0, lightpvs, sizeof(lightpvs));
-                       R_RecursiveMarkLights(ent, lightorigin, rd, bit, bitindex, ent->model->brushq1.nodes + ent->model->brushq1.hulls[0].firstclipnode, lightpvs, min(lightpvsbytes * 8, ent->model->brushq1.num_leafs - 1));
+                       R_RecursiveMarkLights(ent, lightorigin, rd, bit, bitindex, ent->model->brushq1.nodes + ent->model->brushq1.hulls[0].firstclipnode, lightpvs, min(lightpvsbytes * 8, ent->model->brushq1.visleafs));
                }
        }
 }
@@ -301,16 +301,6 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
        else
                VectorSet(ambientcolor, 1, 1, 1);
 
-       /*
-       if (leaf == NULL && cl.worldmodel != NULL)
-               leaf = cl.worldmodel->brushq1.PointInLeaf(cl.worldmodel, p);
-       if (!leaf || leaf->contents == CONTENTS_SOLID || !cl.worldmodel->brushq1.lightdata)
-       {
-               VectorSet(ambientcolor, 1, 1, 1);
-               return;
-       }
-       */
-
        // FIXME: this .lights related stuff needs to be ported into the Mod_Q1BSP code
        if (cl.worldmodel->brushq1.numlights)
        {
index 3995057..4234f96 100644 (file)
@@ -772,7 +772,6 @@ void R_Shadow_Stage_Begin(void)
        if (r_shadow_texture3d.integer && !gl_texture3d)
                Cvar_SetValueQuick(&r_shadow_texture3d, 0);
 
-       //cl.worldmodel->brushq1.numlights = min(cl.worldmodel->brushq1.numlights, 1);
        if (!r_shadow_attenuation2dtexture
         || (!r_shadow_attenuation3dtexture && r_shadow_texture3d.integer)
         || r_shadow_lightattenuationpower.value != r_shadow_attenpower
@@ -901,147 +900,6 @@ void R_Shadow_Stage_End(void)
        r_shadowstage = SHADOWSTAGE_NONE;
 }
 
-#if 0
-int R_Shadow_ScissorForBBoxAndSphere(const float *mins, const float *maxs, const float *origin, float radius)
-{
-       int i, ix1, iy1, ix2, iy2;
-       float x1, y1, x2, y2, x, y;
-       vec3_t smins, smaxs;
-       vec4_t v, v2;
-       if (!r_shadow_scissor.integer)
-               return false;
-       // if view is inside the box, just say yes it's visible
-       if (r_origin[0] >= mins[0] && r_origin[0] <= maxs[0]
-        && r_origin[1] >= mins[1] && r_origin[1] <= maxs[1]
-        && r_origin[2] >= mins[2] && r_origin[2] <= maxs[2])
-       {
-               qglDisable(GL_SCISSOR_TEST);
-               return false;
-       }
-       VectorSubtract(r_origin, origin, v);
-       if (DotProduct(v, v) < radius * radius)
-       {
-               qglDisable(GL_SCISSOR_TEST);
-               return false;
-       }
-       // create viewspace bbox
-       for (i = 0;i < 8;i++)
-       {
-               v[0] = ((i & 1) ? mins[0] : maxs[0]) - r_origin[0];
-               v[1] = ((i & 2) ? mins[1] : maxs[1]) - r_origin[1];
-               v[2] = ((i & 4) ? mins[2] : maxs[2]) - r_origin[2];
-               v2[0] = DotProduct(v, vright);
-               v2[1] = DotProduct(v, vup);
-               v2[2] = DotProduct(v, vpn);
-               if (i)
-               {
-                       if (smins[0] > v2[0]) smins[0] = v2[0];
-                       if (smaxs[0] < v2[0]) smaxs[0] = v2[0];
-                       if (smins[1] > v2[1]) smins[1] = v2[1];
-                       if (smaxs[1] < v2[1]) smaxs[1] = v2[1];
-                       if (smins[2] > v2[2]) smins[2] = v2[2];
-                       if (smaxs[2] < v2[2]) smaxs[2] = v2[2];
-               }
-               else
-               {
-                       smins[0] = smaxs[0] = v2[0];
-                       smins[1] = smaxs[1] = v2[1];
-                       smins[2] = smaxs[2] = v2[2];
-               }
-       }
-       // now we have a bbox in viewspace
-       // clip it to the viewspace version of the sphere
-       v[0] = origin[0] - r_origin[0];
-       v[1] = origin[1] - r_origin[1];
-       v[2] = origin[2] - r_origin[2];
-       v2[0] = DotProduct(v, vright);
-       v2[1] = DotProduct(v, vup);
-       v2[2] = DotProduct(v, vpn);
-       if (smins[0] < v2[0] - radius) smins[0] = v2[0] - radius;
-       if (smaxs[0] < v2[0] - radius) smaxs[0] = v2[0] + radius;
-       if (smins[1] < v2[1] - radius) smins[1] = v2[1] - radius;
-       if (smaxs[1] < v2[1] - radius) smaxs[1] = v2[1] + radius;
-       if (smins[2] < v2[2] - radius) smins[2] = v2[2] - radius;
-       if (smaxs[2] < v2[2] - radius) smaxs[2] = v2[2] + radius;
-       // clip it to the view plane
-       if (smins[2] < 1)
-               smins[2] = 1;
-       // return true if that culled the box
-       if (smins[2] >= smaxs[2])
-               return true;
-       // ok some of it is infront of the view, transform each corner back to
-       // worldspace and then to screenspace and make screen rect
-       // initialize these variables just to avoid compiler warnings
-       x1 = y1 = x2 = y2 = 0;
-       for (i = 0;i < 8;i++)
-       {
-               v2[0] = (i & 1) ? smins[0] : smaxs[0];
-               v2[1] = (i & 2) ? smins[1] : smaxs[1];
-               v2[2] = (i & 4) ? smins[2] : smaxs[2];
-               v[0] = v2[0] * vright[0] + v2[1] * vup[0] + v2[2] * vpn[0] + r_origin[0];
-               v[1] = v2[0] * vright[1] + v2[1] * vup[1] + v2[2] * vpn[1] + r_origin[1];
-               v[2] = v2[0] * vright[2] + v2[1] * vup[2] + v2[2] * vpn[2] + r_origin[2];
-               v[3] = 1.0f;
-               GL_TransformToScreen(v, v2);
-               //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
-               x = v2[0];
-               y = v2[1];
-               if (i)
-               {
-                       if (x1 > x) x1 = x;
-                       if (x2 < x) x2 = x;
-                       if (y1 > y) y1 = y;
-                       if (y2 < y) y2 = y;
-               }
-               else
-               {
-                       x1 = x2 = x;
-                       y1 = y2 = y;
-               }
-       }
-       /*
-       // this code doesn't handle boxes with any points behind view properly
-       x1 = 1000;x2 = -1000;
-       y1 = 1000;y2 = -1000;
-       for (i = 0;i < 8;i++)
-       {
-               v[0] = (i & 1) ? mins[0] : maxs[0];
-               v[1] = (i & 2) ? mins[1] : maxs[1];
-               v[2] = (i & 4) ? mins[2] : maxs[2];
-               v[3] = 1.0f;
-               GL_TransformToScreen(v, v2);
-               //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
-               if (v2[2] > 0)
-               {
-                       x = v2[0];
-                       y = v2[1];
-
-                       if (x1 > x) x1 = x;
-                       if (x2 < x) x2 = x;
-                       if (y1 > y) y1 = y;
-                       if (y2 < y) y2 = y;
-               }
-       }
-       */
-       ix1 = x1 - 1.0f;
-       iy1 = y1 - 1.0f;
-       ix2 = x2 + 1.0f;
-       iy2 = y2 + 1.0f;
-       //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
-       if (ix1 < r_refdef.x) ix1 = r_refdef.x;
-       if (iy1 < r_refdef.y) iy1 = r_refdef.y;
-       if (ix2 > r_refdef.x + r_refdef.width) ix2 = r_refdef.x + r_refdef.width;
-       if (iy2 > r_refdef.y + r_refdef.height) iy2 = r_refdef.y + r_refdef.height;
-       if (ix2 <= ix1 || iy2 <= iy1)
-               return true;
-       // set up the scissor rectangle
-       qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);
-       qglEnable(GL_SCISSOR_TEST);
-       c_rt_scissored++;
-       return false;
-}
-#endif
-
 int R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
 {
        int i, ix1, iy1, ix2, iy2;
@@ -1847,8 +1705,8 @@ static qbyte lightpvs[(MAX_MAP_LEAFS + 7)/ 8];
 static int castshadowcount = 1;
 void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style, const char *cubemapname, int castshadow)
 {
-       int i, j, k, l, maxverts = 256, *mark, tris;
-       float *vertex3f = NULL;
+       int i, j, k, l, maxverts = 256, *mark, tris, numsurfaces;
+       float *vertex3f = NULL, mins[3], maxs[3];
        worldlight_t *e;
        shadowmesh_t *mesh, *castmesh;
        mleaf_t *leaf;
@@ -1876,8 +1734,8 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
        e->cullradius = e->lightradius;
        for (k = 0;k < 3;k++)
        {
-               e->mins[k] = e->origin[k] - e->lightradius;
-               e->maxs[k] = e->origin[k] + e->lightradius;
+               mins[k] = e->origin[k] - e->lightradius;
+               maxs[k] = e->origin[k] + e->lightradius;
        }
 
        e->next = r_shadow_worldlightchain;
@@ -1891,6 +1749,8 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
        if (cl.worldmodel)
        {
                castshadowcount++;
+               VectorCopy(e->origin, e->mins);
+               VectorCopy(e->origin, e->maxs);
                i = CL_PointContents(e->origin);
                if (r_shadow_portallight.integer && i != CONTENTS_SOLID && i != CONTENTS_SKY)
                {
@@ -1903,11 +1763,19 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                        Portal_Visibility(cl.worldmodel, e->origin, byteleafpvs, bytesurfacepvs, NULL, 0, true, RadiusFromBoundsAndOrigin(e->mins, e->maxs, e->origin));
 
                        for (i = 0, leaf = cl.worldmodel->brushq1.leafs;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
-                               if (byteleafpvs[i] && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
-                                       leaf->worldnodeframe = castshadowcount;
+                       {
+                               if (byteleafpvs[i] && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
+                               {
+                                       for (k = 0;k < 3;k++)
+                                       {
+                                               if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
+                                               if (e->maxs[k] < leaf->maxs[k]) e->maxs[k] = leaf->maxs[k];
+                                       }
+                               }
+                       }
 
                        for (i = 0, surf = cl.worldmodel->brushq1.surfaces;i < cl.worldmodel->brushq1.numsurfaces;i++, surf++)
-                               if (bytesurfacepvs[i] && BoxesOverlap(surf->poly_mins, surf->poly_maxs, e->mins, e->maxs))
+                               if (bytesurfacepvs[i] && BoxesOverlap(surf->poly_mins, surf->poly_maxs, mins, maxs))
                                        surf->castshadow = castshadowcount;
 
                        Mem_Free(byteleafpvs);
@@ -1916,56 +1784,25 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                else
                {
                        lightpvsbytes = cl.worldmodel->brush.FatPVS(cl.worldmodel, origin, 0, lightpvs, sizeof(lightpvs));
-                       for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs - 1;i++, leaf++)
+                       for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.visleafs;i++, leaf++)
                        {
-                               if (lightpvs[i >> 3] & (1 << (i & 7)) && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
+                               if (lightpvs[i >> 3] & (1 << (i & 7)) && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
                                {
-                                       leaf->worldnodeframe = castshadowcount;
+                                       for (k = 0;k < 3;k++)
+                                       {
+                                               if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
+                                               if (e->maxs[k] < leaf->maxs[k]) e->maxs[k] = leaf->maxs[k];
+                                       }
                                        for (j = 0, mark = leaf->firstmarksurface;j < leaf->nummarksurfaces;j++, mark++)
                                        {
                                                surf = cl.worldmodel->brushq1.surfaces + *mark;
-                                               if (surf->castshadow != castshadowcount && BoxesOverlap(surf->poly_mins, surf->poly_maxs, e->mins, e->maxs))
+                                               if (surf->castshadow != castshadowcount && BoxesOverlap(surf->poly_mins, surf->poly_maxs, mins, maxs))
                                                        surf->castshadow = castshadowcount;
                                        }
                                }
                        }
                }
 
-               e->numleafs = 0;
-               for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
-                       if (leaf->worldnodeframe == castshadowcount)
-                               e->numleafs++;
-               e->numsurfaces = 0;
-               for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
-                       if (surf->castshadow == castshadowcount)
-                               e->numsurfaces++;
-
-               if (e->numleafs)
-                       e->leafs = Mem_Alloc(r_shadow_mempool, e->numleafs * sizeof(mleaf_t *));
-               if (e->numsurfaces)
-                       e->surfaces = Mem_Alloc(r_shadow_mempool, e->numsurfaces * sizeof(msurface_t *));
-               e->numleafs = 0;
-               for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
-                       if (leaf->worldnodeframe == castshadowcount)
-                               e->leafs[e->numleafs++] = leaf;
-               e->numsurfaces = 0;
-               for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
-                       if (surf->castshadow == castshadowcount)
-                               e->surfaces[e->numsurfaces++] = surf;
-
-               // find bounding box of lit leafs
-               VectorCopy(e->origin, e->mins);
-               VectorCopy(e->origin, e->maxs);
-               for (j = 0;j < e->numleafs;j++)
-               {
-                       leaf = e->leafs[j];
-                       for (k = 0;k < 3;k++)
-                       {
-                               if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
-                               if (e->maxs[k] < leaf->maxs[k]) e->maxs[k] = leaf->maxs[k];
-                       }
-               }
-
                for (k = 0;k < 3;k++)
                {
                        if (e->mins[k] < e->origin[k] - e->lightradius) e->mins[k] = e->origin[k] - e->lightradius;
@@ -1973,6 +1810,17 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                }
                e->cullradius = RadiusFromBoundsAndOrigin(e->mins, e->maxs, e->origin);
 
+               numsurfaces = 0;
+               for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
+                       if (surf->castshadow == castshadowcount)
+                               numsurfaces++;
+               if (numsurfaces)
+                       e->surfaces = Mem_Alloc(r_shadow_mempool, numsurfaces * sizeof(msurface_t *));
+               e->numsurfaces = 0;
+               for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
+                       if (surf->castshadow == castshadowcount)
+                               e->surfaces[e->numsurfaces++] = surf;
+
                if (e->castshadows)
                {
                        castshadowcount++;
@@ -2026,7 +1874,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
                        Con_Printf("static shadow volume built containing %i triangles\n", l);
                }
        }
-       Con_Printf("%f %f %f, %f %f %f, %f, %f, %d, %d\n", e->mins[0], e->mins[1], e->mins[2], e->maxs[0], e->maxs[1], e->maxs[2], e->cullradius, e->lightradius, e->numleafs, e->numsurfaces);
+       Con_Printf("%f %f %f, %f %f %f, %f, %f, %d\n", e->mins[0], e->mins[1], e->mins[2], e->maxs[0], e->maxs[1], e->maxs[2], e->cullradius, e->lightradius, e->numsurfaces);
 }
 
 void R_Shadow_FreeWorldLight(worldlight_t *light)
@@ -2042,8 +1890,6 @@ void R_Shadow_FreeWorldLight(worldlight_t *light)
                Mod_ShadowMesh_Free(light->shadowvolume);
        if (light->surfaces)
                Mem_Free(light->surfaces);
-       if (light->leafs)
-               Mem_Free(light->leafs);
        Mem_Free(light);
 }
 
index 20a3f36..449c62e 100644 (file)
@@ -25,7 +25,6 @@ void R_Shadow_Stage_ShadowVolumes(void);
 void R_Shadow_Stage_LightWithShadows(void);
 void R_Shadow_Stage_LightWithoutShadows(void);
 void R_Shadow_Stage_End(void);
-//int R_Shadow_ScissorForBBoxAndSphere(const float *mins, const float *maxs, const float *origin, float radius);
 int R_Shadow_ScissorForBBox(const float *mins, const float *maxs);
 
 typedef struct worldlight_s
@@ -57,8 +56,6 @@ typedef struct worldlight_s
        struct worldlight_s *next;
        msurface_t **surfaces;
        int numsurfaces;
-       mleaf_t **leafs;
-       int numleafs;
        rtexture_t *cubemap;
        int style;
        shadowmesh_t *shadowvolume;
index 2bd3e24..f523fe4 100644 (file)
--- a/render.h
+++ b/render.h
@@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #ifndef RENDER_H
 #define RENDER_H
 
+extern qbyte r_pvsbits[(MAX_MAP_LEAFS+7)>>3];
+
 extern matrix4x4_t r_identitymatrix;
 
 // 1.0f / N table
@@ -122,9 +124,6 @@ void R_DrawExplosions(void);
 //#define PARANOID 1
 
 int R_CullBox(const vec3_t mins, const vec3_t maxs);
-int PVS_CullBox(const vec3_t mins, const vec3_t maxs);
-int R_CullSphere(const vec3_t origin, vec_t radius);
-int PVS_CullSphere(const vec3_t origin, vec_t radius);
 
 extern qboolean fogenabled;
 extern vec3_t fogcolor;
index 6de3389..89cf157 100644 (file)
--- a/snd_dma.c
+++ b/snd_dma.c
@@ -680,18 +680,20 @@ S_UpdateAmbientSounds
 */
 void S_UpdateAmbientSounds (void)
 {
-       mleaf_t         *l;
        float           vol;
        int                     ambient_channel;
        channel_t       *chan;
+       qbyte           ambientlevels[NUM_AMBIENTS];
 
        // LordHavoc: kill ambient sounds until proven otherwise
        for (ambient_channel = 0 ; ambient_channel < NUM_AMBIENTS;ambient_channel++)
                channels[ambient_channel].sfx = NULL;
 
-       if (!snd_ambient || ambient_level.value <= 0 || !cl.worldmodel || !cl.worldmodel->brushq1.PointInLeaf || (l = cl.worldmodel->brushq1.PointInLeaf(cl.worldmodel, listener_origin)) == NULL)
+       if (!snd_ambient || ambient_level.value <= 0 || !cl.worldmodel || !cl.worldmodel->brush.AmbientSoundLevelsForPoint)
                return;
 
+       cl.worldmodel->brush.AmbientSoundLevelsForPoint(cl.worldmodel, listener_origin, ambientlevels, sizeof(ambientlevels));
+
 // calc ambient sound levels
        for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
        {
@@ -701,7 +703,7 @@ void S_UpdateAmbientSounds (void)
                chan->forceloop = true;
                chan->sfx = ambient_sfx[ambient_channel];
 
-               vol = ambient_level.value * l->ambient_sound_level[ambient_channel];
+               vol = ambient_level.value * ambientlevels[ambient_channel];
                if (vol < 8)
                        vol = 0;
 
index 310a726..e9f1c33 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -20,10 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // sv_main.c -- server main program
 
 #include "quakedef.h"
-#include "portals.h"
 
 static cvar_t sv_cullentities_pvs = {0, "sv_cullentities_pvs", "0"}; // fast but loose
-static cvar_t sv_cullentities_portal = {0, "sv_cullentities_portal", "0"}; // extremely accurate visibility checking, but too slow
 static cvar_t sv_cullentities_trace = {0, "sv_cullentities_trace", "1"}; // tends to get false negatives, uses a timeout to keep entities visible a short time after becoming hidden
 static cvar_t sv_cullentities_stats = {0, "sv_cullentities_stats", "0"};
 static cvar_t sv_entpatch = {0, "sv_entpatch", "1"};
@@ -62,7 +60,6 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_nostep);
        Cvar_RegisterVariable (&sv_deltacompress);
        Cvar_RegisterVariable (&sv_cullentities_pvs);
-       Cvar_RegisterVariable (&sv_cullentities_portal);
        Cvar_RegisterVariable (&sv_cullentities_trace);
        Cvar_RegisterVariable (&sv_cullentities_stats);
        Cvar_RegisterVariable (&sv_entpatch);
@@ -387,7 +384,7 @@ SV_WriteEntitiesToClient
 void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
 {
        int e, clentnum, bits, alpha, glowcolor, glowsize, scale, effects, lightsize;
-       int culled_pvs, culled_portal, culled_trace, visibleentities, totalentities;
+       int culled_pvs, culled_trace, visibleentities, totalentities;
        qbyte *pvs;
        vec3_t origin, angles, entmins, entmaxs, testorigin, testeye;
        float nextfullupdate, alphaf;
@@ -405,7 +402,6 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                fatbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, testeye, 8, sv_writeentitiestoclient_pvs, sizeof(sv_writeentitiestoclient_pvs));
 
        culled_pvs = 0;
-       culled_portal = 0;
        culled_trace = 0;
        visibleentities = 0;
        totalentities = 0;
@@ -509,13 +505,6 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                                continue;
                        }
 
-                       // or not visible through the portals
-                       if (sv_cullentities_portal.integer && !Portal_CheckBox(sv.worldmodel, testeye, entmins, entmaxs))
-                       {
-                               culled_portal++;
-                               continue;
-                       }
-
                        // don't try to cull embedded brush models with this, they're sometimes huge (spanning several rooms)
                        if (sv_cullentities_trace.integer && (model == NULL || model->type != mod_brush || model->name[0] != '*'))
                        {
@@ -713,7 +702,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
        }
 
        if (sv_cullentities_stats.integer)
-               Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d portal %d trace\n", client->name, totalentities, visibleentities, culled_pvs + culled_portal + culled_trace, culled_pvs, culled_portal, culled_trace);
+               Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, totalentities, visibleentities, culled_pvs + culled_trace, culled_pvs, culled_trace);
 }
 #else
 static int numsendentities;
@@ -833,7 +822,6 @@ static int sententitiesmark = 0;
 static int sententities[MAX_EDICTS];
 static int sententitiesconsideration[MAX_EDICTS];
 static int sv_writeentitiestoclient_culled_pvs;
-static int sv_writeentitiestoclient_culled_portal;
 static int sv_writeentitiestoclient_culled_trace;
 static int sv_writeentitiestoclient_visibleentities;
 static int sv_writeentitiestoclient_totalentities;
@@ -924,12 +912,6 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                                sv_writeentitiestoclient_culled_pvs++;
                                return;
                        }
-                       // or not visible through the portals
-                       if (sv_cullentities_portal.integer && !Portal_CheckBox(sv.worldmodel, sv_writeentitiestoclient_testeye, lightmins, lightmaxs))
-                       {
-                               sv_writeentitiestoclient_culled_portal++;
-                               return;
-                       }
                        // or not seen by random tracelines
                        if (sv_cullentities_trace.integer)
                        {
@@ -1000,7 +982,6 @@ void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg)
        sv_writeentitiestoclient_client = client;
 
        sv_writeentitiestoclient_culled_pvs = 0;
-       sv_writeentitiestoclient_culled_portal = 0;
        sv_writeentitiestoclient_culled_trace = 0;
        sv_writeentitiestoclient_visibleentities = 0;
        sv_writeentitiestoclient_totalentities = 0;
@@ -1109,7 +1090,7 @@ void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg)
        d->currentcommit = NULL;
 
        if (sv_cullentities_stats.integer)
-               Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d portal %d trace\n", client->name, sv_writeentitiestoclient_totalentities, sv_writeentitiestoclient_visibleentities, sv_writeentitiestoclient_culled_pvs + sv_writeentitiestoclient_culled_portal + sv_writeentitiestoclient_culled_trace, sv_writeentitiestoclient_culled_pvs, sv_writeentitiestoclient_culled_portal, sv_writeentitiestoclient_culled_trace);
+               Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, sv_writeentitiestoclient_totalentities, sv_writeentitiestoclient_visibleentities, sv_writeentitiestoclient_culled_pvs + sv_writeentitiestoclient_culled_trace, sv_writeentitiestoclient_culled_pvs, sv_writeentitiestoclient_culled_trace);
 }
 #endif
 
@@ -1836,7 +1817,7 @@ void SV_SpawnServer (const char *server)
 
        sv.model_precache[0] = "";
        sv.model_precache[1] = sv.modelname;
-       for (i = 1;i < sv.worldmodel->brushq1.numsubmodels;i++)
+       for (i = 1;i < sv.worldmodel->brush.numsubmodels;i++)
        {
                sv.model_precache[i+1] = localmodels[i];
                sv.models[i+1] = Mod_ForName (localmodels[i], false, false, false);
diff --git a/todo b/todo
index 404c2e6..a554256 100644 (file)
--- a/todo
+++ b/todo
@@ -1,48 +1,6 @@
 - todo: difficulty ratings are: 0 = trivial, 1 = easy, 2 = easy-moderate, 3 = moderate, 4 = moderate-hard, 5 = hard, 6 = hard++, 7 = nightmare, d = done, -n = done but have not notified the people who asked for it, f = failed
-d darkplaces: finish the partial update support in protocol.[ch] and reduce packet size to 1k to fix NAT routers (yummyluv, Vermeulen, Elric)
-d darkplaces: fix server crashing from client timeouts (Moz)
-d darkplaces: fix server list only querying the master to reply (Rick)
-d darkplaces: fix sounds not following entities (yummyluv, SeienAbunae)
+-n darkplaces: revert noclip movement to match nq for compatibility with mods that trap movement as input (MauveBib)
 -n dpmod: make grapple off-hand (joe hill)
-0 dpmod: add a "monsterwander" cvar and default it off, this would enable the spawnwanderpath code (Zombie13)
-0 darkplaces: stuttering movement when walking over steps or monsters (romi)
-0 darkplaces: bullets don't hit walls at steep angles in id1
-0 darkplaces: hack PF_nextent to skip inaccessible client slots depending on maxplayers - but always report ones that are active at the time (FrikaC)
-0 darkplaces: client colors being reset to "15 15" each level in prydon gate (FrikaC)
-0 darkplaces: make lightning work without bolt models persent (Vermeulen)
-0 darkplaces: make the WriteEntitiesToClient code call TraceBox directly instead of SV_Move because checking all the entities is far too slow in helm18 (banshee21)
-0 darkplaces: add te_flamejet builtin and add extension (Supajoe)
-0 darkplaces: pointcontents crash when building harvester in gvb2? (yummyluv)
-0 darkplaces: integrate zinx's psycho.c gamma hack as an easteregg
-0 dpmod: crash when dog attacks you in dpdm2 deathmatch 7 with bots present (Zombie13)
-0 dpmod: identify what could cause huge angles values (1187488512.0000) on a dog entity, may be related to anglemod, FacingIdeal, ai_run, or dog_run2 (Zombie13)
-0 dpmod: modify anglemod to be able to recover from extremely large angles numbers (Zombie13)
-0 darkplaces: add error messages to LHNET_OpenSocket_Connectionless or its callers (Zombie13)
-0 dpmod: find a way to make deathmatch 7 get more difficulty as kills increase?  (Zombie13)
-0 darkplaces: can't move when stuck in a monster (SeienAbunae)
-0 dpmod: monsters falling out of level? (SeienAbunae)
-0 dpmod: add killing spree reporting; how many kills since spawn when you die, as well as announcing when you hit certain numbers of kills (SeienAbunae)
-0 dpmod: add combo kill detection; rapid burst of kills (SeienAbunae)
-0 darkplaces: may be reading md3 tag matrices wrong (Electro)
-d dpmod: add back charge-up on plasma rifle alt-fire and increase the max charge to 50 cells
-0 darkplaces: make sure that disappearing entities are removed on the client in quake demos, they aren't currently
-0 darkplaces: scrags frequently fly through ceilings - this needs to be fixed
-0 dpmod: set oldorigin when spawning to prevent being stuck at the spawn from causing an instant teleport back to where you died (SeienAbunae)
-0 darkplaces: model interpolation off crashes?  (SeienAbunae)
-0 dpmod: impulse 102 isn't removing the bots (SeienAbunae)
-d dpmod: make enforcers drop more cells for plasma gun (SeienAbunae)
-d dpmod: make tarbabies easier to kill?  (SeienAbunae)
-f dpmod: make tarbabies have a self.resist_explosive = 3; like zombies (SeienAbunae)
-d dpmod: make tarbabies explode larger (SeienAbunae)
-0 darkplaces: make sure that sound engine does not remove sounds when volume drops to 0 due to going out of range (SeienAbunae)
-0 darkplaces: crashes if you type too long a command line in the console (SeienAbunae)
-0 darkplaces: fix 'wall hugging' stuttering (romi)
-0 darkplaces: fix intermission failing to move view to intermission camera (romi, Zombie_13)
-0 darkplaces: fix key based turning being affected by slowmo - it should not be
-0 darkplaces: add view height to chase_active again (yummyluv)
-0 darkplaces: examine the surface rendering code to make sure it has no bugs regarding texture selection for any of the passes (sublim3)
-1 darkplaces: add rate command (and _cl_rate cvar to save to config) to control client rate (send to server on connect as a command, like other properties) (Transfusion)
-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)
 0 darkplaces: ability to disable fopen builtin access to read /, read data/, write data/, or disable fopen builtin entirely
 0 darkplaces: add DP_GFX_QUAKE3MODELTAGS, DP_GFX_SKINFILES, and any other new extensions to the wiki
 0 darkplaces: add DP_LITSUPPORT extension
@@ -54,34 +12,47 @@ d dpmod: make tarbabies explode larger (SeienAbunae)
 0 darkplaces: add bullet hole decals to the particlefont (Vermeulen)
 0 darkplaces: add cl_particles_quality cvar (1-10) which would scale count of particles and inversely scale alpha of particles (TheBeast)
 0 darkplaces: add cvars for sbar alpha (background and foreground) (Throvold@uboot.com)
+0 darkplaces: add error messages to LHNET_OpenSocket_Connectionless or its callers (Zombie13)
 0 darkplaces: add lightning beam settings to menu (romi)
 0 darkplaces: add svc_setanglefloat and DP_SVC_SETANGLEFLOAT extension (FrikaC, SeienAbunae)
+0 darkplaces: add te_flamejet builtin and add extension (Supajoe)
+0 darkplaces: add view height to chase_active again (yummyluv)
+0 darkplaces: bullets don't hit walls at steep angles in id1
+0 darkplaces: can't move when stuck in a monster (SeienAbunae)
 0 darkplaces: change particle() macro in cl_particles.c to have a do{}while(0) to eat the ;
 0 darkplaces: check out qe1 textures and make sure they load in all the e1 maps, report of crashing in most but not all maps (Linny Amore)
 0 darkplaces: cl_particles_maximum cvar (default 32768) which would change number of particles allowed at once (TheBeast)
+0 darkplaces: client colors being reset to "15 15" each level in prydon gate (FrikaC)
+0 darkplaces: crashes if you type too long a command line in the console (SeienAbunae)
 0 darkplaces: darkplaces-glx -path transfusion crashes, fix the crash even though it's not going to work anyway (Todd)
 0 darkplaces: default to 32bit color
 0 darkplaces: delay "connect" and "playdemo" and "timedemo" until after video init to cause quicker video startup (KrimZon)
 0 darkplaces: document how polygon collision works in the code (KrimZon)
 0 darkplaces: document the TEI stuff used in Nexuiz?  check telejano site first (SeienAbunae)
+0 darkplaces: examine the surface rendering code to make sure it has no bugs regarding texture selection for any of the passes (sublim3)
 0 darkplaces: figure out and fix the 'rubbing against a moving door causes block' bug (Static_Fiend)
 0 darkplaces: figure out random crashes on map changes (Uffe, QorpsE)
 0 darkplaces: figure out what's wrong with gloss rendering vertex calculations, which may be GF2 related (QorpsE)
 0 darkplaces: figure out why monsters keep making fall pain sound after they've landed in dpmod (Cruaich)
+0 darkplaces: fix 'wall hugging' stuttering (romi)
 0 darkplaces: fix a crash when changing level while using qe1 textures (Todd)
 0 darkplaces: fix con_notify (should control number of lines)
+0 darkplaces: fix intermission failing to move view to intermission camera (romi, Zombie_13)
+0 darkplaces: fix key based turning being affected by slowmo - it should not be
 0 darkplaces: fix skybox geometry (SeienAbunae)
 0 darkplaces: fix the fact singleplayer is using maxplayers 8
 0 darkplaces: fix view blends slightly lingering as time goes on, they should go away completely (Cruaich)
-2 darkplaces: frikbot scores don't update - discovered this is because of the fact they have no client (Todd)
 0 darkplaces: get rid of stencil options and make 32bit color automatically use stencil
+0 darkplaces: hack PF_nextent to skip inaccessible client slots depending on maxplayers - but always report ones that are active at the time (FrikaC)
 0 darkplaces: identify weird lightmap texturing bug on TNT cards - goes away in r_textureunits 1 (NotoriousRay, Uffe)
+0 darkplaces: integrate zinx's psycho.c gamma hack as an easteregg
 0 darkplaces: make Com_HexDumpToConsole not use color
 0 darkplaces: make DP_EF_FULLBRIGHT extension (FrikaC)
 0 darkplaces: make S_Update take a matrix4x4_t *
 0 darkplaces: make a flag for rtlights that makes them appear in normal mode (not just r_shadow_realtime_world mode) (Vermeulen)
 0 darkplaces: make dedicated server not load images (maybe all fail?)
 0 darkplaces: make fopen builtin check / as well as data/ when reading (writing would always go in data/)
+0 darkplaces: make lightning work without bolt models persent (Vermeulen)
 0 darkplaces: make memory pools have a flag to print them as temporary pools (I.E. consider them leaks if anything is in them) (Vicious)
 0 darkplaces: make server queries use a queue to avoid flooding out queries too fast, and then change the reply receive code drop packets from servers not in the list (Willis)
 0 darkplaces: make sure EF_FULLBRIGHT works on bmodels (FrikaC)
@@ -90,22 +61,39 @@ d dpmod: make tarbabies explode larger (SeienAbunae)
 0 darkplaces: make sure PR_SetString points NULL strings at pr_strings (which would be an offset of 0) (Fuh)
 0 darkplaces: make sure QuakeDoneQuick works (Chris Kemp)
 0 darkplaces: make sure r_fullbright works - need to fix maxplayers checking
+0 darkplaces: make sure that disappearing entities are removed on the client in quake demos, they aren't currently
 0 darkplaces: make sure that sky works without a valid size (just treat it as single layer clouds or non-animated) (tell Vermeulen)
+0 darkplaces: make sure that sound engine does not remove sounds when volume drops to 0 due to going out of range (SeienAbunae)
+0 darkplaces: make the WriteEntitiesToClient code call TraceBox directly instead of SV_Move because checking all the entities is far too slow in helm18 (banshee21)
+0 darkplaces: may be reading md3 tag matrices wrong (Electro)
+0 darkplaces: model interpolation off crashes?  (SeienAbunae)
+0 darkplaces: pointcontents crash when building harvester in gvb2? (yummyluv)
 0 darkplaces: r_shadow should load .ent when importing light entities
 0 darkplaces: r_skyscroll1 and r_skyscroll2 cvars (SeienAbunae)
 0 darkplaces: rename r_picmip and r_max_size and such to glquake names
 0 darkplaces: reset zoom on connect (Rick)
--n darkplaces: revert noclip movement to match nq for compatibility with mods that trap movement as input (MauveBib)
+0 darkplaces: scrags frequently fly through ceilings - this needs to be fixed
 0 darkplaces: segfault reading memory in windows when starting a new server from menu (yummyluv)
+0 darkplaces: stuttering movement when walking over steps or monsters (romi)
 0 darkplaces: test TecnoX and find the frikbot crash in SV_Physics (KrimZon)
 0 darkplaces: test zlib support with entirely pk3'd id1 data (should crash because of zlib not being setup early enough - fix this) (Mabus)
 0 darkplaces: the new sound engine should have a cvar for random variations of pitch on sounds like in doom (RenegadeC)
 0 darkplaces: try not adding gravity when onground to see if it gets rid of ramp sliding (Midgar)
 0 darkplaces: tweak the blood decals in the particlefont to make them look more like the q2e_blood.avi video (Vermeulen)
+0 dpmod: add a "monsterwander" cvar and default it off, this would enable the spawnwanderpath code (Zombie13)
+0 dpmod: add combo kill detection; rapid burst of kills (SeienAbunae)
 0 dpmod: add flame thrower enforcers back (scar3crow)
 0 dpmod: add flame thrower weapon, and make its altfire drop a canister of fuel (10 fuel units?), which can be ignited to set off as a bomb about the size of a rocket blast, plus some fireballs raining down (scar3crow)
+0 dpmod: add killing spree reporting; how many kills since spawn when you die, as well as announcing when you hit certain numbers of kills (SeienAbunae)
+0 dpmod: crash when dog attacks you in dpdm2 deathmatch 7 with bots present (Zombie13)
+0 dpmod: find a way to make deathmatch 7 get more difficulty as kills increase?  (Zombie13)
+0 dpmod: identify what could cause huge angles values (1187488512.0000) on a dog entity, may be related to anglemod, FacingIdeal, ai_run, or dog_run2 (Zombie13)
+0 dpmod: impulse 102 isn't removing the bots (SeienAbunae)
 0 dpmod: impulse 154 should cycle to deathmatch 7 (Rick)
 0 dpmod: items aren't respawning in coop, they should
+0 dpmod: modify anglemod to be able to recover from extremely large angles numbers (Zombie13)
+0 dpmod: monsters falling out of level? (SeienAbunae)
+0 dpmod: set oldorigin when spawning to prevent being stuck at the spawn from causing an instant teleport back to where you died (SeienAbunae)
 0 dpmod: try making ball lightning mortar shamblers (scar3crow)
 0 dpmod: up nail limit to 500 (scar3crow)
 0 dpzoo: colored lighting
@@ -140,6 +128,7 @@ d dpmod: make tarbabies explode larger (SeienAbunae)
 1 darkplaces: add log cvar to set console logging target (default "", or default "qconsole.log" if -condebug is used)
 1 darkplaces: add r_displayrefresh cvar for windows video refresh settings (Willis)
 1 darkplaces: add r_waterwarp to allow disabling view squishing underwater
+1 darkplaces: add rate command (and _cl_rate cvar to save to config) to control client rate (send to server on connect as a command, like other properties) (Transfusion)
 1 darkplaces: add some particles to teleportsplash (Uffe)
 1 darkplaces: check out QMB lightning and lava effects (jeremy janzen)
 1 darkplaces: clear stainmaps on map restart/change based on cl_stainmapsclearonload cvar (John Truex, Electro)
@@ -185,6 +174,7 @@ d dpmod: make tarbabies explode larger (SeienAbunae)
 2 darkplaces: add stats to slist menu displaying how many masters/servers have been queried and replied (tell yummyluv)
 2 darkplaces: figure out how to prevent "alias a a" - infinite loop when executed, this should be detected when executing it (Vicious)
 2 darkplaces: figure out why -sndspeed 22050, 44100 and 16000 are choppy in windows? (cheapalert)
+2 darkplaces: frikbot scores don't update - discovered this is because of the fact they have no client (Todd)
 2 darkplaces: implement menu_clearkeyconfig and menu_keyconfig and the corresponding menu (diGGer)
 2 darkplaces: lerp lightstyles (Mitchell)
 2 darkplaces: locked console scrollback (sublim3)
@@ -211,6 +201,7 @@ d dpmod: make tarbabies explode larger (SeienAbunae)
 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 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)
 3 darkplaces: dpshaders (when supported) should have support for envmaps, and should support being lit by diffuse lighting as a fake gloss effect for normal mode (Vermeulen)
 3 darkplaces: dsound broken, needs to be managed as part of video system (jeremy janzen)
@@ -288,6 +279,7 @@ d darkplaces: figure out what is wrong with loading _glow/_luma textures on md3
 d darkplaces: figure out why disconnections are showing up as " disconnected"
 d darkplaces: figure out why quad is creating two coronas, one at player and one at 0 0 0 - answer: viewmodel dlight (Tomaz)
 d darkplaces: finish new udp networking code (yummyluv)
+d darkplaces: finish the partial update support in protocol.[ch] and reduce packet size to 1k to fix NAT routers (yummyluv, Vermeulen, Elric)
 d darkplaces: fix PF_substring's mishandling of the end variable (Fuh)
 d darkplaces: fix Short format entity origins to fix shell casings sitting in floor/above floor (Tomaz)
 d darkplaces: fix bounding box bugs with viewmodelforclient (diGGer)
@@ -300,7 +292,10 @@ d darkplaces: fix md3 shadow volumes
 d darkplaces: fix network timeouts
 d darkplaces: fix non-polygonal lightning beam model pitch (it was backwards) (thanks Eksess for reporting this)
 d darkplaces: fix particle trails (I think trail start is identical to trail end) (Supajoe, SeienAbunae)
+d darkplaces: fix server crashing from client timeouts (Moz)
 d darkplaces: fix server list not working until you set maxplayers above 1 (Rick)
+d darkplaces: fix server list only querying the master to reply (Rick)
+d darkplaces: fix sounds not following entities (yummyluv, SeienAbunae)
 d darkplaces: fix starting non-existent maps.  (drops to console with an error like it should)
 d darkplaces: fix startup on multiplayer games so they don't start a game when executing startdemos unless -listen or -dedicated was used (yummyluv)
 d darkplaces: fix toggling decals in menu
@@ -325,10 +320,14 @@ d darkplaces: release new hmap (fixes compilation of TF entities for one person,
 d darkplaces: release new hqbsp with -wadpath support (also searchs in map's directory and map's parent directory)
 d darkplaces: remove frags per hour rating from scoreboard because it depends on cl.scores[i]->entertime (which is never set)
 d darkplaces: tags support on md3 (Electro needs this urgently)
+d dpmod: add back charge-up on plasma rifle alt-fire and increase the max charge to 50 cells
 d dpmod: add back tarbaby gibs (scar3crow)
 d dpmod: add frags for killing monsters in dpmod (scar3crow)
 d dpmod: change weapons 8-10 to lightning, plasma, plasma wave (joe hill)
 d dpmod: fix backpacks (giving no ammo)
+d dpmod: make enforcers drop more cells for plasma gun (SeienAbunae)
+d dpmod: make tarbabies easier to kill?  (SeienAbunae)
+d dpmod: make tarbabies explode larger (SeienAbunae)
 d dpmod: post new dpmod build.
 d dpmod: switch to new Tomaz weapon models
 d dpmod: why can't I pick up nails when I have no nailguns?  and other similar pickup problems with weapons
@@ -338,4 +337,5 @@ d lmp2pcx: post new lmp2pcx build.
 f darkplaces: add _0.tga support (per texture) to bsp/md2/md3 loaders
 f darkplaces: examine proquake code to find nat fix and implement similar in darkplaces
 f darkplaces: look at and integrate Vic's updated zone.[ch] (Vic)
+f dpmod: make tarbabies have a self.resist_explosive = 3; like zombies (SeienAbunae)
 
diff --git a/world.c b/world.c
index fe82505..373ac3e 100644 (file)
--- a/world.c
+++ b/world.c
@@ -30,7 +30,6 @@ line of sight checks trace->inopen and trace->inwater, but bullets don't
 */
 
 cvar_t sv_debugmove = {CVAR_NOTIFY, "sv_debugmove", "0"};
-cvar_t sv_polygoncollisions = {CVAR_NOTIFY, "sv_polygoncollisions", "0"};
 cvar_t sv_areagrid_mingridsize = {CVAR_NOTIFY, "sv_areagrid_mingridsize", "64"};
 
 void SV_AreaStats_f(void);
@@ -38,7 +37,6 @@ void SV_AreaStats_f(void);
 void SV_World_Init(void)
 {
        Cvar_RegisterVariable(&sv_debugmove);
-       Cvar_RegisterVariable(&sv_polygoncollisions);
        Cvar_RegisterVariable(&sv_areagrid_mingridsize);
        Cmd_AddCommand("sv_areastats", SV_AreaStats_f);
        Collision_Init();
@@ -491,10 +489,7 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
        VectorAdd(starttransformed, mins, starttransformedmins);
        VectorAdd(endtransformed, mins, endtransformedmins);
 
-       // FIXME: the PolygonClipTrace should go away (should all be done in model code)
-       if (sv_polygoncollisions.integer == 1)
-               Collision_PolygonClipTrace(&trace, ent, model, vec3_origin, vec3_origin, ent->v->mins, ent->v->maxs, starttransformed, mins, maxs, endtransformed);
-       else if (model && model->brush.TraceBox)
+       if (model && model->brush.TraceBox)
                model->brush.TraceBox(model, &trace, starttransformedmins, starttransformedmaxs, endtransformedmins, endtransformedmaxs);
        else
                Collision_ClipTrace_Box(&trace, ent->v->mins, ent->v->maxs, starttransformed, mins, maxs, endtransformed);
@@ -626,7 +621,8 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        clip.type = type;
        clip.passedict = passedict;
 
-       Collision_RoundUpToHullSize(sv.worldmodel, clip.mins, clip.maxs, clip.hullmins, clip.hullmaxs);
+       if (sv.worldmodel && sv.worldmodel->brush.RoundUpToHullSize)
+               sv.worldmodel->brush.RoundUpToHullSize(sv.worldmodel, clip.mins, clip.maxs, clip.hullmins, clip.hullmaxs);
 
        // clip to world
        clip.trace = SV_ClipMoveToEntity(sv.edicts, clip.start, clip.hullmins, clip.hullmaxs, clip.end);