From 697da87440cb50b17feea1c256b48c73434bcb89 Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 6 Mar 2005 14:58:54 +0000 Subject: [PATCH] got rid of node->contents, leaf->contents kept (only needed temporarily during loading to generate collision hull 0), now checks node->plane to know if it is a node (leaf has a NULL plane pointer) 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 | 4 + gl_rsurf.c | 56 +++++--------- model_brush.c | 196 +++++++++++++++++++++++-------------------------- model_brush.h | 39 +++------- model_shared.h | 12 ++- portals.c | 15 ++-- r_light.c | 7 +- render.h | 1 + 8 files changed, 138 insertions(+), 192 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index ccf6be3f..b73e5fbc 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -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; diff --git a/gl_rsurf.c b/gl_rsurf.c index 98b23f0a..6174b9bc 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -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 diff --git a/model_brush.c b/model_brush.c index edf6135e..df45a1d7 100644 --- a/model_brush.c +++ b/model_brush.c @@ -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; } diff --git a/model_brush.h b/model_brush.h index 139de2f1..32e5ab65 100644 --- a/model_brush.h +++ b/model_brush.h @@ -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; diff --git a/model_shared.h b/model_shared.h index 06e9a819..43dec612 100644 --- a/model_shared.h +++ b/model_shared.h @@ -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]; diff --git a/portals.c b/portals.c index fdc4ecb9..cf472082 100644 --- 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) diff --git a/r_light.c b/r_light.c index 1990bbd0..8f906ef7 100644 --- 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); diff --git a/render.h b/render.h index 46cc4e69..692f1ebf 100644 --- 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; -- 2.39.2