got rid of node->contents, leaf->contents kept (only needed temporarily during loadin...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 6 Mar 2005 14:58:54 +0000 (14:58 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 6 Mar 2005 14:58:54 +0000 (14:58 +0000)
fixed the very messed up contents translation in Q3BSP
various other cleanups

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5038 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
gl_rsurf.c
model_brush.c
model_brush.h
model_shared.h
portals.c
r_light.c
render.h

index ccf6be3..b73e5fb 100644 (file)
@@ -28,6 +28,10 @@ int r_framecount;
 // used for visibility checking
 qbyte r_pvsbits[(MAX_MAP_LEAFS+7)>>3];
 
+// TODO: dynamic resize?  65536 seems enough because q1bsp can't have more
+// than 32768, and q3bsp compilers have more like a 4096 limit
+qbyte r_worldsurfacevisible[MAX_MAP_LEAFS];
+
 mplane_t frustum[4];
 
 matrix4x4_t r_identitymatrix;
index 98b23f0..6174b9b 100644 (file)
@@ -446,7 +446,7 @@ void R_StainNode (mnode_t *node, model_t *model, const vec3_t origin, float radi
        invradius = 1.0f / radius;
 
 loc0:
-       if (node->contents < 0)
+       if (!node->plane)
                return;
        ndist = PlaneDiff(origin, node->plane);
        if (ndist > radius)
@@ -535,9 +535,9 @@ loc0:
                }
        }
 
-       if (node->children[0]->contents >= 0)
+       if (node->children[0]->plane)
        {
-               if (node->children[1]->contents >= 0)
+               if (node->children[1]->plane)
                {
                        R_StainNode(node->children[0], model, origin, radius, fcolor);
                        node = node->children[1];
@@ -549,7 +549,7 @@ loc0:
                        goto loc0;
                }
        }
-       else if (node->children[1]->contents >= 0)
+       else if (node->children[1]->plane)
        {
                node = node->children[1];
                goto loc0;
@@ -1215,7 +1215,7 @@ void R_DrawSurfaceList(entity_render_t *ent, texture_t *texture, int texturenums
 
 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
 {
-       int i, j, f, *surfacevisframes, flagsmask;
+       int i, j, f, flagsmask;
        msurface_t *surface, **surfacechain;
        texture_t *t, *texture;
        model_t *model = ent->model;
@@ -1230,15 +1230,10 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
 
        if (ent != r_refdef.worldentity)
        {
-               // because bmodels can be reused, we have to decide which things to render
-               // from scratch every time
-               int *mark = model->brushq1.surfacevisframes + model->firstmodelsurface;
+               // because bmodels can be reused, we have to clear dlightframe every time
                surface = model->brushq1.surfaces + model->firstmodelsurface;
-               for (i = 0;i < model->nummodelsurfaces;i++, mark++, surface++)
-               {
-                       *mark = r_framecount;
+               for (i = 0;i < model->nummodelsurfaces;i++, surface++)
                        surface->dlightframe = -1;
-               }
        }
 
        // update light styles
@@ -1259,14 +1254,13 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
        }
 
        R_UpdateTextureInfo(ent);
-       surfacevisframes = model->brushq1.surfacevisframes;
        flagsmask = skysurfaces ? SURF_DRAWSKY : (SURF_DRAWTURB | SURF_LIGHTMAP);
        f = 0;
        t = NULL;
        numsurfacelist = 0;
        for (i = 0, j = model->firstmodelsurface;i < model->nummodelsurfaces;i++, j++)
        {
-               if (surfacevisframes[j] == r_framecount)
+               if (ent != r_refdef.worldentity || r_worldsurfacevisible[j])
                {
                        surface = model->brushq1.surfaces + j;
                        if (t != surface->texinfo->texture)
@@ -1282,23 +1276,6 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                        }
                        if (f)
                        {
-                               // mark any backface surfaces as not visible
-                               if (PlaneDist(modelorg, surface->plane) < surface->plane->dist)
-                               {
-                                       if (!(surface->flags & SURF_PLANEBACK))
-                                       {
-                                               surfacevisframes[j] = -1;
-                                               continue;
-                                       }
-                               }
-                               else
-                               {
-                                       if ((surface->flags & SURF_PLANEBACK))
-                                       {
-                                               surfacevisframes[j] = -1;
-                                               continue;
-                                       }
-                               }
                                // add face to draw list and update lightmap if necessary
                                c_faces++;
                                if (surface->cached_dlight && surface->lightmaptexture != NULL)
@@ -1379,10 +1356,10 @@ void R_WorldVisibility(void)
        mleaf_t *leaf;
        mleaf_t *viewleaf;
        model_t *model = r_refdef.worldmodel;
-       int *surfacevisframes = model->brushq1.surfacevisframes;
        int leafstackpos;
        mportal_t *p;
        mleaf_t *leafstack[8192];
+       qbyte leafvisited[32768];
 
        if (!model || !model->brushq1.PointInLeaf)
                return;
@@ -1391,7 +1368,8 @@ void R_WorldVisibility(void)
        if (!viewleaf)
                return;
 
-       if (viewleaf->contents == CONTENTS_SOLID || r_surfaceworldnode.integer)
+       memset(r_worldsurfacevisible, 0, r_refdef.worldmodel->brushq1.numsurfaces);
+       if (viewleaf->clusterindex < 0 || r_surfaceworldnode.integer)
        {
                // equivilant to quake's RecursiveWorldNode but faster and more effective
                for (j = 0, leaf = model->brushq1.data_leafs;j < model->brushq1.num_leafs;j++, leaf++)
@@ -1399,10 +1377,9 @@ void R_WorldVisibility(void)
                        if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !R_CullBox (leaf->mins, leaf->maxs))
                        {
                                c_leafs++;
-                               leaf->visframe = r_framecount;
                                if (leaf->nummarksurfaces)
                                        for (i = 0, mark = leaf->firstmarksurface;i < leaf->nummarksurfaces;i++, mark++)
-                                               surfacevisframes[*mark] = r_framecount;
+                                               r_worldsurfacevisible[*mark] = true;
                        }
                }
        }
@@ -1414,18 +1391,19 @@ void R_WorldVisibility(void)
                // RecursiveWorldNode
                leafstack[0] = viewleaf;
                leafstackpos = 1;
+               memset(leafvisited, 0, r_refdef.worldmodel->brushq1.num_leafs);
                while (leafstackpos)
                {
                        c_leafs++;
                        leaf = leafstack[--leafstackpos];
-                       leaf->visframe = r_framecount;
+                       leafvisited[leaf - r_refdef.worldmodel->brushq1.data_leafs] = 1;
                        // draw any surfaces bounding this leaf
                        if (leaf->nummarksurfaces)
                                for (i = 0, mark = leaf->firstmarksurface;i < leaf->nummarksurfaces;i++, mark++)
-                                       surfacevisframes[*mark] = r_framecount;
+                                       r_worldsurfacevisible[*mark] = true;
                        // follow portals into other leafs
                        for (p = leaf->portals;p;p = p->next)
-                               if (DotProduct(r_vieworigin, p->plane.normal) < (p->plane.dist + 1) && p->past->visframe != r_framecount && CHECKPVSBIT(r_pvsbits, p->past->clusterindex) && !R_CullBox(p->mins, p->maxs))
+                               if (DotProduct(r_vieworigin, p->plane.normal) < (p->plane.dist + 1) && !leafvisited[p->past - r_refdef.worldmodel->brushq1.data_leafs] && CHECKPVSBIT(r_pvsbits, p->past->clusterindex) && !R_CullBox(p->mins, p->maxs))
                                        leafstack[leafstackpos++] = p->past;
                }
        }
@@ -1594,7 +1572,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t
                                if (t->flags & SURF_LIGHTMAP && t->skin.fog == NULL)
                                        Mod_ShadowMesh_AddMesh(r_shadow_mempool, r_shadow_compilingrtlight->static_meshchain_light, surface->texinfo->texture->skin.base, surface->texinfo->texture->skin.gloss, surface->texinfo->texture->skin.nmap, surface->mesh.data_vertex3f, surface->mesh.data_svector3f, surface->mesh.data_tvector3f, surface->mesh.data_normal3f, surface->mesh.data_texcoordtexture2f, surface->mesh.num_triangles, surface->mesh.data_element3i);
                        }
-                       else if (ent != r_refdef.worldentity || ent->model->brushq1.surfacevisframes[surface - ent->model->brushq1.surfaces] == r_framecount)
+                       else if (ent != r_refdef.worldentity || r_worldsurfacevisible[surface - ent->model->brushq1.surfaces])
                        {
                                t = surface->texinfo->texture->currentframe;
                                // FIXME: transparent surfaces need to be lit later
index edf6135..df45a1d 100644 (file)
@@ -84,7 +84,7 @@ static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p)
        // LordHavoc: modified to start at first clip node,
        // in other words: first node of the (sub)model
        node = model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode;
-       while (node->contents == 0)
+       while (node->plane)
                node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct(p,node->plane->normal)) < node->plane->dist];
 
        return (mleaf_t *)node;
@@ -155,26 +155,6 @@ static int Mod_Q1BSP_BoxTouchingPVS(model_t *model, const qbyte *pvs, const vec3
        return false;
 }
 
-/*
-static int Mod_Q1BSP_PointContents(model_t *model, const vec3_t p)
-{
-       mnode_t *node;
-
-       if (model == NULL)
-               return CONTENTS_EMPTY;
-
-       Mod_CheckLoaded(model);
-
-       // LordHavoc: modified to start at first clip node,
-       // in other words: first node of the (sub)model
-       node = model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode;
-       while (node->contents == 0)
-               node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct(p,node->plane->normal)) < node->plane->dist];
-
-       return ((mleaf_t *)node)->contents;
-}
-*/
-
 typedef struct findnonsolidlocationinfo_s
 {
        vec3_t center;
@@ -313,12 +293,7 @@ static void Mod_Q1BSP_FindNonSolidLocation_r_Leaf(findnonsolidlocationinfo_t *in
 
 static void Mod_Q1BSP_FindNonSolidLocation_r(findnonsolidlocationinfo_t *info, mnode_t *node)
 {
-       if (node->contents)
-       {
-               if (((mleaf_t *)node)->nummarksurfaces)
-                       Mod_Q1BSP_FindNonSolidLocation_r_Leaf(info, (mleaf_t *)node);
-       }
-       else
+       if (node->plane)
        {
                float f = PlaneDiff(info->center, node->plane);
                if (f >= -info->bestdist)
@@ -326,6 +301,11 @@ static void Mod_Q1BSP_FindNonSolidLocation_r(findnonsolidlocationinfo_t *info, m
                if (f <= info->bestdist)
                        Mod_Q1BSP_FindNonSolidLocation_r(info, node->children[1]);
        }
+       else
+       {
+               if (((mleaf_t *)node)->nummarksurfaces)
+                       Mod_Q1BSP_FindNonSolidLocation_r_Leaf(info, (mleaf_t *)node);
+       }
 }
 
 static void Mod_Q1BSP_FindNonSolidLocation(model_t *model, const vec3_t in, vec3_t out, float radius)
@@ -741,7 +721,7 @@ static int Mod_Q1BSP_LightPoint_RecursiveBSPNode(vec3_t ambientcolor, vec3_t dif
        float mid;
 
 loc0:
-       if (node->contents < 0)
+       if (!node->plane)
                return false;           // didn't hit anything
 
        switch (node->plane->type)
@@ -778,7 +758,7 @@ loc0:
        }
 
        // go down front side
-       if (node->children[side]->contents >= 0 && Mod_Q1BSP_LightPoint_RecursiveBSPNode(ambientcolor, diffusecolor, diffusenormal, node->children[side], x, y, startz, mid))
+       if (node->children[side]->plane && Mod_Q1BSP_LightPoint_RecursiveBSPNode(ambientcolor, diffusecolor, diffusenormal, node->children[side], x, y, startz, mid))
                return true;    // hit something
        else
        {
@@ -1816,7 +1796,6 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
        loadmodel->brushq1.surfaces = Mem_Alloc(loadmodel->mempool, count*sizeof(msurface_t));
 
        loadmodel->brushq1.numsurfaces = count;
-       loadmodel->brushq1.surfacevisframes = Mem_Alloc(loadmodel->mempool, count * sizeof(int));
 
        for (surfnum = 0, surf = loadmodel->brushq1.surfaces, totalverts = 0, totaltris = 0, totalmeshes = 0;surfnum < count;surfnum++, totalverts += surf->poly_numverts, totaltris += surf->poly_numverts - 2, totalmeshes++, in++, surf++)
        {
@@ -1965,10 +1944,11 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
 static void Mod_Q1BSP_SetParent(mnode_t *node, mnode_t *parent)
 {
        node->parent = parent;
-       if (node->contents < 0)
-               return;
-       Mod_Q1BSP_SetParent(node->children[0], node);
-       Mod_Q1BSP_SetParent(node->children[1], node);
+       if (node->plane)
+       {
+               Mod_Q1BSP_SetParent(node->children[0], node);
+               Mod_Q1BSP_SetParent(node->children[1], node);
+       }
 }
 
 static void Mod_Q1BSP_LoadNodes(lump_t *l)
@@ -2191,8 +2171,8 @@ static void Mod_Q1BSP_MakeHull0(void)
        for (i = 0;i < loadmodel->brushq1.numnodes;i++, out++, in++)
        {
                out->planenum = in->plane - loadmodel->brushq1.planes;
-               out->children[0] = in->children[0]->contents < 0 ? in->children[0]->contents : in->children[0] - loadmodel->brushq1.nodes;
-               out->children[1] = in->children[1]->contents < 0 ? in->children[1]->contents : in->children[1] - loadmodel->brushq1.nodes;
+               out->children[0] = in->children[0]->plane ? in->children[0] - loadmodel->brushq1.nodes : ((mleaf_t *)in->children[0])->contents;
+               out->children[1] = in->children[1]->plane ? in->children[1] - loadmodel->brushq1.nodes : ((mleaf_t *)in->children[1])->contents;
        }
 }
 
@@ -2388,11 +2368,13 @@ static void FreePortal(portal_t *p)
 
 static void Mod_Q1BSP_RecursiveRecalcNodeBBox(mnode_t *node)
 {
+       // process only nodes (leafs already had their box calculated)
+       if (!node->plane)
+               return;
+
        // calculate children first
-       if (node->children[0]->contents >= 0)
-               Mod_Q1BSP_RecursiveRecalcNodeBBox(node->children[0]);
-       if (node->children[1]->contents >= 0)
-               Mod_Q1BSP_RecursiveRecalcNodeBBox(node->children[1]);
+       Mod_Q1BSP_RecursiveRecalcNodeBBox(node->children[0]);
+       Mod_Q1BSP_RecursiveRecalcNodeBBox(node->children[1]);
 
        // make combined bounding box from children
        node->mins[0] = min(node->children[0]->mins[0], node->children[1]->mins[0]);
@@ -2451,9 +2433,7 @@ static void Mod_Q1BSP_FinalizePortals(void)
        {
                // note: this check must match the one below or it will usually corrupt memory
                // the nodes[0] != nodes[1] check is because leaf 0 is the shared solid leaf, it can have many portals inside with leaf 0 on both sides
-               if (p->numpoints >= 3 && p->nodes[0] != p->nodes[1]
-                && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID
-                && p->nodes[0]->contents != CONTENTS_SKY && p->nodes[1]->contents != CONTENTS_SKY)
+               if (p->numpoints >= 3 && p->nodes[0] != p->nodes[1] && ((mleaf_t *)p->nodes[0])->clusterindex >= 0 && ((mleaf_t *)p->nodes[1])->clusterindex >= 0)
                {
                        numportals += 2;
                        numpoints += p->numpoints * 2;
@@ -2476,60 +2456,55 @@ static void Mod_Q1BSP_FinalizePortals(void)
        {
                pnext = p->chain;
 
-               if (p->numpoints >= 3)
+               // note: this check must match the one above or it will usually corrupt memory
+               // the nodes[0] != nodes[1] check is because leaf 0 is the shared solid leaf, it can have many portals inside with leaf 0 on both sides
+               if (p->numpoints >= 3 && p->nodes[0] != p->nodes[1] && ((mleaf_t *)p->nodes[0])->clusterindex >= 0 && ((mleaf_t *)p->nodes[1])->clusterindex >= 0)
                {
-                       // note: this check must match the one above or it will usually corrupt memory
-                       // the nodes[0] != nodes[1] check is because leaf 0 is the shared solid leaf, it can have many portals inside with leaf 0 on both sides
-                       if (p->nodes[0] != p->nodes[1]
-                        && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID
-                        && p->nodes[0]->contents != CONTENTS_SKY && p->nodes[1]->contents != CONTENTS_SKY)
+                       // first make the back to front portal(forward portal)
+                       portal->points = point;
+                       portal->numpoints = p->numpoints;
+                       portal->plane.dist = p->plane.dist;
+                       VectorCopy(p->plane.normal, portal->plane.normal);
+                       portal->here = (mleaf_t *)p->nodes[1];
+                       portal->past = (mleaf_t *)p->nodes[0];
+                       // copy points
+                       for (j = 0;j < portal->numpoints;j++)
                        {
-                               // first make the back to front portal(forward portal)
-                               portal->points = point;
-                               portal->numpoints = p->numpoints;
-                               portal->plane.dist = p->plane.dist;
-                               VectorCopy(p->plane.normal, portal->plane.normal);
-                               portal->here = (mleaf_t *)p->nodes[1];
-                               portal->past = (mleaf_t *)p->nodes[0];
-                               // copy points
-                               for (j = 0;j < portal->numpoints;j++)
-                               {
-                                       VectorCopy(p->points + j*3, point->position);
-                                       point++;
-                               }
-                               BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
-                               PlaneClassify(&portal->plane);
-
-                               // link into leaf's portal chain
-                               portal->next = portal->here->portals;
-                               portal->here->portals = portal;
-
-                               // advance to next portal
-                               portal++;
-
-                               // then make the front to back portal(backward portal)
-                               portal->points = point;
-                               portal->numpoints = p->numpoints;
-                               portal->plane.dist = -p->plane.dist;
-                               VectorNegate(p->plane.normal, portal->plane.normal);
-                               portal->here = (mleaf_t *)p->nodes[0];
-                               portal->past = (mleaf_t *)p->nodes[1];
-                               // copy points
-                               for (j = portal->numpoints - 1;j >= 0;j--)
-                               {
-                                       VectorCopy(p->points + j*3, point->position);
-                                       point++;
-                               }
-                               BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
-                               PlaneClassify(&portal->plane);
+                               VectorCopy(p->points + j*3, point->position);
+                               point++;
+                       }
+                       BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
+                       PlaneClassify(&portal->plane);
+
+                       // link into leaf's portal chain
+                       portal->next = portal->here->portals;
+                       portal->here->portals = portal;
+
+                       // advance to next portal
+                       portal++;
+
+                       // then make the front to back portal(backward portal)
+                       portal->points = point;
+                       portal->numpoints = p->numpoints;
+                       portal->plane.dist = -p->plane.dist;
+                       VectorNegate(p->plane.normal, portal->plane.normal);
+                       portal->here = (mleaf_t *)p->nodes[0];
+                       portal->past = (mleaf_t *)p->nodes[1];
+                       // copy points
+                       for (j = portal->numpoints - 1;j >= 0;j--)
+                       {
+                               VectorCopy(p->points + j*3, point->position);
+                               point++;
+                       }
+                       BoxFromPoints(portal->mins, portal->maxs, portal->numpoints, portal->points->position);
+                       PlaneClassify(&portal->plane);
 
-                               // link into leaf's portal chain
-                               portal->next = portal->here->portals;
-                               portal->here->portals = portal;
+                       // link into leaf's portal chain
+                       portal->next = portal->here->portals;
+                       portal->here->portals = portal;
 
-                               // advance to next portal
-                               portal++;
-                       }
+                       // advance to next portal
+                       portal++;
                }
                FreePortal(p);
                p = pnext;
@@ -2619,7 +2594,7 @@ static void Mod_Q1BSP_RecursiveNodePortals(mnode_t *node)
        double frontpoints[3*MAX_PORTALPOINTS], backpoints[3*MAX_PORTALPOINTS];
 
        // if a leaf, we're done
-       if (node->contents)
+       if (!node->plane)
                return;
 
        plane = node->plane;
@@ -3722,8 +3697,7 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l)
                out->number = i;
                strlcpy (out->name, in->name, sizeof (out->name));
                out->surfaceflags = LittleLong(in->surfaceflags);
-               out->nativecontents = LittleLong(in->contents);
-               out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, out->nativecontents);
+               out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, LittleLong(in->contents));
                out->surfaceparms = -1;
        }
 
@@ -4472,7 +4446,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                                        invalidelements++;
                        if (invalidelements)
                        {
-                               Con_Printf("Mod_Q3BSP_LoadFaces: Warning: face #%i has %i invalid elements, type = %i, texture->name = \"%s\", texture->surfaceflags = %i, texture->nativecontents = %i, firstvertex = %i, numvertices = %i, firstelement = %i, numelements = %i, elements list:\n", i, invalidelements, type, out->texture->name, out->texture->surfaceflags, out->texture->nativecontents, firstvertex, out->mesh.num_vertices, firstelement, out->mesh.num_triangles * 3);
+                               Con_Printf("Mod_Q3BSP_LoadFaces: Warning: face #%i has %i invalid elements, type = %i, texture->name = \"%s\", texture->surfaceflags = %i, firstvertex = %i, numvertices = %i, firstelement = %i, numelements = %i, elements list:\n", i, invalidelements, type, out->texture->name, out->texture->surfaceflags, firstvertex, out->mesh.num_vertices, firstelement, out->mesh.num_triangles * 3);
                                for (j = 0;j < out->mesh.num_triangles * 3;j++)
                                {
                                        Con_Printf(" %i", out->mesh.data_element3i[j]);
@@ -5553,14 +5527,20 @@ static int Mod_Q3BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, qbyt
 static int Mod_Q3BSP_SuperContentsFromNativeContents(model_t *model, int nativecontents)
 {
        int supercontents = 0;
-       if (nativecontents & Q2CONTENTS_SOLID)
+       if (nativecontents & CONTENTSQ3_SOLID)
                supercontents |= SUPERCONTENTS_SOLID;
-       if (nativecontents & Q2CONTENTS_WATER)
+       if (nativecontents & CONTENTSQ3_WATER)
                supercontents |= SUPERCONTENTS_WATER;
-       if (nativecontents & Q2CONTENTS_SLIME)
+       if (nativecontents & CONTENTSQ3_SLIME)
                supercontents |= SUPERCONTENTS_SLIME;
-       if (nativecontents & Q2CONTENTS_LAVA)
+       if (nativecontents & CONTENTSQ3_LAVA)
                supercontents |= SUPERCONTENTS_LAVA;
+       if (nativecontents & CONTENTSQ3_BODY)
+               supercontents |= SUPERCONTENTS_BODY;
+       if (nativecontents & CONTENTSQ3_CORPSE)
+               supercontents |= SUPERCONTENTS_CORPSE;
+       if (nativecontents & CONTENTSQ3_NODROP)
+               supercontents |= SUPERCONTENTS_NODROP;
        return supercontents;
 }
 
@@ -5568,13 +5548,19 @@ static int Mod_Q3BSP_NativeContentsFromSuperContents(model_t *model, int superco
 {
        int nativecontents = 0;
        if (supercontents & SUPERCONTENTS_SOLID)
-               nativecontents |= Q2CONTENTS_SOLID;
+               nativecontents |= CONTENTSQ3_SOLID;
        if (supercontents & SUPERCONTENTS_WATER)
-               nativecontents |= Q2CONTENTS_WATER;
+               nativecontents |= CONTENTSQ3_WATER;
        if (supercontents & SUPERCONTENTS_SLIME)
-               nativecontents |= Q2CONTENTS_SLIME;
+               nativecontents |= CONTENTSQ3_SLIME;
        if (supercontents & SUPERCONTENTS_LAVA)
-               nativecontents |= Q2CONTENTS_LAVA;
+               nativecontents |= CONTENTSQ3_LAVA;
+       if (supercontents & SUPERCONTENTS_BODY)
+               nativecontents |= CONTENTSQ3_BODY;
+       if (supercontents & SUPERCONTENTS_CORPSE)
+               nativecontents |= CONTENTSQ3_CORPSE;
+       if (supercontents & SUPERCONTENTS_NODROP)
+               nativecontents |= CONTENTSQ3_NODROP;
        return nativecontents;
 }
 
index 139de2f..32e5ab6 100644 (file)
@@ -192,21 +192,16 @@ msurface_t;
 
 typedef struct mnode_s
 {
-// common with leaf
-       // always 0 in nodes
-       int contents;
-
+       //this part shared between node and leaf
+       mplane_t *plane; // != NULL
        struct mnode_s *parent;
        struct mportal_s *portals;
-
        // for bounding box culling
        vec3_t mins;
        vec3_t maxs;
 
-       mplane_t *plane; // != NULL
-// node specific
+       // this part unique to node
        struct mnode_s *children[2];
-
        unsigned short firstsurface;
        unsigned short numsurfaces;
 }
@@ -214,36 +209,21 @@ mnode_t;
 
 typedef struct mleaf_s
 {
-// common with node
-       // always negative in leafs
-       int contents;
-
+       //this part shared between node and leaf
+       mplane_t *plane; // == NULL
        struct mnode_s *parent;
        struct mportal_s *portals;
-
        // for bounding box culling
        vec3_t mins;
        vec3_t maxs;
 
-       mplane_t *plane; // == NULL
-// leaf specific
-       // next leaf in pvschain
-       struct mleaf_s *pvschain;
-       // potentially visible if current (model->pvsframecount)
-       int pvsframe;
-       // visible if marked current (r_framecount)
-       int visframe;
-       // used by certain worldnode variants to avoid processing the same leaf twice in a frame
-       int worldnodeframe;
-       // used by polygon-through-portals visibility checker
-       int portalmarkid;
-
-       // -1 is not in pvs, >= 0 is pvs bit number
-       int clusterindex;
-
+       // this part unique to leaf
+       int clusterindex; // -1 is not in pvs, >= 0 is pvs bit number
+       int contents; // TODO: remove (only used temporarily during loading when making collision hull 0)
        int *firstmarksurface;
        int nummarksurfaces;
        qbyte ambient_sound_level[NUM_AMBIENTS];
+       int portalmarkid; // used by see-polygon-through-portals visibility checker
 }
 mleaf_t;
 
@@ -268,7 +248,6 @@ typedef struct mportal_s
        mvertex_t *points;
        vec3_t mins, maxs; // culling
        mplane_t plane;
-       int visframe; // is this portal visible this frame?
 }
 mportal_t;
 
index 06e9a81..43dec61 100644 (file)
@@ -241,7 +241,6 @@ typedef struct model_brushq1_s
 
        int                             numsurfaces;
        msurface_t              *surfaces;
-       int                             *surfacevisframes;
        msurface_t              *surfacepvsnext;
 
        int                             numsurfedges;
@@ -356,7 +355,6 @@ typedef struct q3mtexture_s
        char name[Q3PATHLENGTH];
        char firstpasstexturename[Q3PATHLENGTH];
        int surfaceflags;
-       int nativecontents;
        int supercontents;
        int surfaceparms;
        int textureflags;
@@ -377,7 +375,8 @@ typedef struct q3mnode_s
        struct q3mnode_s *parent;
        vec3_t mins;
        vec3_t maxs;
-       // this part unique to nodes
+
+       // this part unique to node
        struct q3mnode_s *children[2];
 }
 q3mnode_t;
@@ -389,8 +388,9 @@ typedef struct q3mleaf_s
        struct q3mnode_s *parent;
        vec3_t mins;
        vec3_t maxs;
-       // this part unique to leafs
-       int clusterindex;
+
+       // this part unique to leaf
+       int clusterindex; // -1 is not in pvs, >= 0 is pvs bit number
        int areaindex;
        int numleaffaces;
        struct q3msurface_s **firstleafface;
@@ -438,14 +438,12 @@ q3meffect_t;
 typedef struct q3msurface_s
 {
        // FIXME: collisionmarkframe should be kept in a separate array
-       // FIXME: visframe should be kept in a separate array
        // FIXME: shadowmark should be kept in a separate array
 
        struct q3mtexture_s *texture;
        struct q3meffect_s *effect;
        rtexture_t *lightmaptexture;
        int collisionmarkframe; // don't collide twice in one trace
-       int visframe; // visframe == r_framecount means it is visible this frame
        // bounding box for culling
        float mins[3];
        float maxs[3];
index fdc4ecb..cf47208 100644 (file)
--- a/portals.c
+++ b/portals.c
@@ -154,7 +154,7 @@ void Portal_PolygonRecursiveMarkLeafs(mnode_t *node, float *polypoints, int nump
        float *p;
 
 loc0:
-       if (node->contents < 0)
+       if (!node->plane)
        {
                ((mleaf_t *)node)->portalmarkid = portal_markid;
                return;
@@ -460,12 +460,7 @@ void Portal_RecursiveFlow (portalrecursioninfo_t *info, mleaf_t *leaf, int first
 
 void Portal_RecursiveFindLeafForFlow(portalrecursioninfo_t *info, mnode_t *node)
 {
-       if (node->contents)
-       {
-               if (node->contents != CONTENTS_SKY && node->contents != CONTENTS_SOLID)
-                       Portal_RecursiveFlow(info, (mleaf_t *)node, 0, info->numfrustumplanes);
-       }
-       else
+       if (node->plane)
        {
                float f = DotProduct(info->eye, node->plane->normal) - node->plane->dist;
                if (f > -0.1)
@@ -473,6 +468,12 @@ void Portal_RecursiveFindLeafForFlow(portalrecursioninfo_t *info, mnode_t *node)
                if (f < 0.1)
                        Portal_RecursiveFindLeafForFlow(info, node->children[1]);
        }
+       else
+       {
+               mleaf_t *leaf = (mleaf_t *)node;
+               if (leaf->portals)
+                       Portal_RecursiveFlow(info, leaf, 0, info->numfrustumplanes);
+       }
 }
 
 void Portal_Visibility(model_t *model, const vec3_t eye, qbyte *leafmark, qbyte *surfacemark, const mplane_t *frustumplanes, int numfrustumplanes, int exact, const float *boxmins, const float *boxmaxs, float *updateleafsmins, float *updateleafsmaxs)
index 1990bbd..8f906ef 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -184,7 +184,7 @@ static void R_RecursiveMarkLights(entity_render_t *ent, vec3_t lightorigin, dlig
        float dist;
 
        // for comparisons to minimum acceptable light
-       while(node->contents >= 0)
+       while(node->plane)
        {
                dist = PlaneDiff(lightorigin, node->plane);
                if (dist > light->rtlight.lightmap_cullradius)
@@ -202,15 +202,14 @@ static void R_RecursiveMarkLights(entity_render_t *ent, vec3_t lightorigin, dlig
        i = leaf->clusterindex;
        if (leaf->nummarksurfaces && (i >= pvsbits || CHECKPVSBIT(pvs, i)))
        {
-               int *surfacevisframes, d, impacts, impactt;
+               int d, impacts, impactt;
                float sdist, maxdist, dist2, impact[3];
                msurface_t *surf;
                // mark the polygons
                maxdist = light->rtlight.lightmap_cullradius2;
-               surfacevisframes = ent->model->brushq1.surfacevisframes;
                for (i = 0;i < leaf->nummarksurfaces;i++)
                {
-                       if (surfacevisframes[leaf->firstmarksurface[i]] != r_framecount)
+                       if (ent == r_refdef.worldentity && !r_worldsurfacevisible[leaf->firstmarksurface[i]])
                                continue;
                        surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[i];
                        dist = sdist = PlaneDiff(lightorigin, surf->plane);
index 46cc4e6..692f1eb 100644 (file)
--- a/render.h
+++ b/render.h
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define RENDER_H
 
 extern qbyte r_pvsbits[(MAX_MAP_LEAFS+7)>>3];
+extern qbyte r_worldsurfacevisible[MAX_MAP_LEAFS];
 
 extern matrix4x4_t r_identitymatrix;