From 17eda31b40ed5d6c15834c39bc9f247b42902b42 Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Sat, 12 May 2001 15:31:17 +0000 Subject: [PATCH] build number 101 all leaf bounding boxes are recalculated based on portals (superior to qbsp's method) bounding box removed from node structure vismarkframe stuff removed from node and leaf structures minor tweaking to some network stuff (trying to track down a bug) R_BSPWorldmode and R_LeafWorldmode have been removed, related cvars have been removed R_NoVisWorldnode is only used when in a solid leaf now have been trying to track down very rare disappearing leaf bug in portal worldnode code (or portal building?), unsuccessfully redesign of entity dlight code, much cleaner and saner (all dlight effects can be combined at once now as well, no override occurs) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@201 d7cf8633-e32d-0410-b094-e92efae38249 --- buildnumber.c | 2 +- cl_main.c | 77 ++++++---- cl_parse.c | 1 - gl_rsurf.c | 390 +++++++++++++------------------------------------- model_brush.c | 78 +++++++--- model_brush.h | 16 +-- pr_cmds.c | 1 - render.h | 1 + sv_main.c | 2 +- world.c | 1 - 10 files changed, 217 insertions(+), 352 deletions(-) diff --git a/buildnumber.c b/buildnumber.c index 6bd87550..f574d342 100644 --- a/buildnumber.c +++ b/buildnumber.c @@ -1,4 +1,4 @@ -#define BUILDNUMBER 100 +#define BUILDNUMBER 101 int buildnumber = BUILDNUMBER; diff --git a/cl_main.c b/cl_main.c index 5f3d6cb0..56a5a779 100644 --- a/cl_main.c +++ b/cl_main.c @@ -388,13 +388,13 @@ float CL_LerpPoint (void) f = 0.1; } frac = (cl.time - cl.mtime[1]) / f; -//Con_Printf ("frac: %f\n",frac); +// Con_Printf ("frac: %f\n",frac); if (frac < 0) { if (frac < -0.01) { cl.time = cl.mtime[1]; -// Con_Printf ("low frac\n"); +// Con_Printf ("low frac\n"); } frac = 0; } @@ -403,7 +403,7 @@ float CL_LerpPoint (void) if (frac > 1.01) { cl.time = cl.mtime[0]; -// Con_Printf ("high frac\n"); +// Con_Printf ("high frac\n"); } frac = 1; } @@ -453,11 +453,8 @@ void CL_RelinkEntities (void) { entity_t *ent; int i, j; - float frac, f, d; - vec3_t delta; - float bobjrotate; -// float bobjoffset; - vec3_t oldorg; + float frac, f, d, bobjrotate/*, bobjoffset*/, dlightradius; + vec3_t oldorg, delta, dlightcolor; // determine partial update time frac = CL_LerpPoint (); @@ -559,6 +556,11 @@ void CL_RelinkEntities (void) ent->render.colormod[1] = (float) ((ent->state_current.colormod >> 2) & 7) * (1.0f / 7.0f); ent->render.colormod[2] = (float) (ent->state_current.colormod & 3) * (1.0f / 3.0f); + dlightradius = 0; + dlightcolor[0] = 0; + dlightcolor[1] = 0; + dlightcolor[2] = 0; + // LordHavoc: if the entity has no effects, don't check each if (ent->render.effects) { @@ -574,22 +576,33 @@ void CL_RelinkEntities (void) v[1] = v[1] * 18 + ent->render.origin[1]; v[2] = v[2] * 18 + ent->render.origin[2] + 16; - CL_AllocDlight (ent, v, 100, 1, 1, 1, 0, 0.1); + CL_AllocDlight (NULL, v, 100, 1, 1, 1, 0, 0.1); } - if (ent->render.effects & EF_BRIGHTLIGHT) - CL_AllocDlight (ent, ent->render.origin, 400, 1, 1, 1, 0, 0); if (ent->render.effects & EF_DIMLIGHT) - CL_AllocDlight (ent, ent->render.origin, 200, 1, 1, 1, 0, 0); + { + dlightcolor[0] += 200.0f; + dlightcolor[1] += 200.0f; + dlightcolor[2] += 200.0f; + } + if (ent->render.effects & EF_BRIGHTLIGHT) + { + dlightcolor[0] += 400.0f; + dlightcolor[1] += 400.0f; + dlightcolor[2] += 400.0f; + } // LordHavoc: added EF_RED and EF_BLUE if (ent->render.effects & EF_RED) // red - { - if (ent->render.effects & EF_BLUE) // magenta - CL_AllocDlight (ent, ent->render.origin, 200, 1.0f, 0.2f, 1.0f, 0, 0); - else // red - CL_AllocDlight (ent, ent->render.origin, 200, 1.0f, 0.1f, 0.1f, 0, 0); + { + dlightcolor[0] += 200.0f; + dlightcolor[1] += 20.0f; + dlightcolor[2] += 20.0f; + } + if (ent->render.effects & EF_BLUE) // blue + { + dlightcolor[0] += 20.0f; + dlightcolor[1] += 20.0f; + dlightcolor[2] += 200.0f; } - else if (ent->render.effects & EF_BLUE) // blue - CL_AllocDlight (ent, ent->render.origin, 200, 0.1f, 0.1f, 1.0f, 0, 0); else if (ent->render.effects & EF_FLAME) { if (ent->render.model) @@ -602,7 +615,10 @@ void CL_RelinkEntities (void) temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300); R_FlameCube(mins, maxs, temp); } - CL_AllocDlight (ent, ent->render.origin, lhrandom(200, 250), 1.0f, 0.7f, 0.3f, 0, 0); + d = lhrandom(200, 250); + dlightcolor[0] += d * 1.0f; + dlightcolor[1] += d * 0.7f; + dlightcolor[2] += d * 0.3f; } } @@ -628,7 +644,9 @@ void CL_RelinkEntities (void) else if (ent->render.model->flags & EF_ROCKET) { R_RocketTrail (oldorg, ent->render.origin, 0, ent); - CL_AllocDlight (ent, ent->render.origin, 200, 1.0f, 0.8f, 0.4f, 0, 0); + dlightcolor[0] += 200.0f; + dlightcolor[1] += 160.0f; + dlightcolor[2] += 80.0f; } else if (ent->render.model->flags & EF_GRENADE) { @@ -641,14 +659,25 @@ void CL_RelinkEntities (void) R_RocketTrail (oldorg, ent->render.origin, 6, ent); } } - if (ent->render.glowsize) // LordHavoc: customizable glow + // LordHavoc: customizable glow + if (ent->render.glowsize) { byte *tempcolor = (byte *)&d_8to24table[ent->render.glowcolor]; - CL_AllocDlight (ent, ent->render.origin, ent->render.glowsize, tempcolor[0]*(1.0/255.0), tempcolor[1]*(1.0/255.0), tempcolor[2]*(1.0/255.0), 0, 0); + dlightcolor[0] += ent->render.glowsize * tempcolor[0] * (1.0f / 255.0f); + dlightcolor[1] += ent->render.glowsize * tempcolor[1] * (1.0f / 255.0f); + dlightcolor[2] += ent->render.glowsize * tempcolor[2] * (1.0f / 255.0f); } - if (ent->render.flags & RENDER_GLOWTRAIL) // LordHavoc: customizable glow and trail + // LordHavoc: customizable trail + if (ent->render.flags & RENDER_GLOWTRAIL) R_RocketTrail2 (oldorg, ent->render.origin, ent->render.glowcolor, ent); + if (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) + { + dlightradius = VectorLength(dlightcolor); + d = 1.0f / dlightradius; + CL_AllocDlight (ent, ent->render.origin, dlightradius, dlightcolor[0] * d, dlightcolor[1] * d, dlightcolor[2] * d, 0, 0); + } + if (i == cl.viewentity && !chase_active.value) continue; diff --git a/cl_parse.c b/cl_parse.c index 371d7ccd..4e449e00 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -234,7 +234,6 @@ extern char skyname[]; extern void R_SetSkyBox (char *sky); extern void FOG_clear(); extern cvar_t r_farclip; -extern qboolean hlbsp; void CL_ParseEntityLump(char *entdata) { diff --git a/gl_rsurf.c b/gl_rsurf.c index 7a24a597..658c81b2 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -46,12 +46,8 @@ cvar_t gl_nosubimagefragments = {"gl_nosubimagefragments", "0"}; cvar_t gl_nosubimage = {"gl_nosubimage", "0"}; cvar_t r_ambient = {"r_ambient", "0"}; cvar_t gl_vertex = {"gl_vertex", "0"}; -cvar_t r_leafworldnode = {"r_leafworldnode", "0"}; -cvar_t r_portalworldnode = {"r_portalworldnode", "0"}; -//cvar_t r_oldclip = {"r_oldclip", "1"}; cvar_t r_dlightmap = {"r_dlightmap", "1"}; cvar_t r_drawportals = {"r_drawportals", "0"}; -cvar_t r_novis = {"r_novis","0"}; qboolean lightmaprgba, nosubimagefragments, nosubimage; int lightmapbytes; @@ -81,12 +77,8 @@ void GL_Surf_Init() Cvar_RegisterVariable(&gl_nosubimage); Cvar_RegisterVariable(&r_ambient); Cvar_RegisterVariable(&gl_vertex); - Cvar_RegisterVariable(&r_leafworldnode); - Cvar_RegisterVariable(&r_portalworldnode); -// Cvar_RegisterVariable(&r_oldclip); Cvar_RegisterVariable(&r_dlightmap); Cvar_RegisterVariable(&r_drawportals); - Cvar_RegisterVariable(&r_novis); R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap); } @@ -475,8 +467,6 @@ void UploadLightmaps() float wvert[1024*6]; // used by the following functions -extern qboolean hlbsp; - void RSurf_DrawSky(msurface_t *s, int transform) { glpoly_t *p; @@ -967,39 +957,22 @@ void R_DrawBrushModel (entity_t *e) ============================================================= */ -int r_vismarkframecount; // bumped when going to a new PVS +static byte *worldvis; +extern cvar_t r_novis; void R_MarkLeaves (void) { - byte *vis; - mnode_t *node; - int i; - - if (r_oldviewleaf == r_viewleaf) + static float noviscache; + if (r_oldviewleaf == r_viewleaf && noviscache == r_novis.value) return; - r_vismarkframecount++; r_oldviewleaf = r_viewleaf; + noviscache = r_novis.value; - vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); - - for (i = 0;i < cl.worldmodel->numleafs;i++) - { - if (vis[i>>3] & (1<<(i&7))) - { - node = (mnode_t *)&cl.worldmodel->leafs[i+1]; - do - { - if (node->vismarkframe == r_vismarkframecount) - break; - node->vismarkframe = r_vismarkframecount; - node = node->parent; - } while (node); - } - } + worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); } -void R_LeafWorldNode () +void R_SolidWorldNode () { int l; mleaf_t *leaf; @@ -1007,7 +980,7 @@ void R_LeafWorldNode () for (l = 0, leaf = cl.worldmodel->leafs;l < cl.worldmodel->numleafs;l++, leaf++) { - if ((leaf->vismarkframe == r_vismarkframecount) && (/*leaf->efrags || */leaf->nummarksurfaces)) + if (/*leaf->efrags || */leaf->nummarksurfaces) { if (R_CullBox(leaf->mins, leaf->maxs)) continue; @@ -1048,277 +1021,94 @@ void R_LeafWorldNode () } } -typedef struct nodestack_s -{ - unsigned short side, clip; - mnode_t *node; -} -nodestack_t; - -void R_NoVisWorldNode () +/* +// experimental and inferior to the other in recursion depth allowances +void R_PortalWorldNode () { - int side, c, clip; - nodestack_t *nstack, nodestack[8192]; - mnode_t *node; - mleaf_t *pleaf; - msurface_t *surf, *endsurf, **mark, **endmark; - nstack = nodestack; - - node = cl.worldmodel->nodes; - - if (!node) - return; + int i, j; + mportal_t *p; + msurface_t *surf, **mark, **endmark; + mleaf_t *leaf, *llistbuffer[8192], **l, **llist; - clip = true; - while(1) + leaf = r_viewleaf; + leaf->worldnodeframe = r_framecount; + l = llist = &llistbuffer[0]; + *llist++ = r_viewleaf; + while (l < llist) { - if (node->contents < 0) - { - if (node->contents != CONTENTS_SOLID && R_NotCulledBox(node->mins, node->maxs)) - { - // mark surfaces as being visible for processing by code later - pleaf = (mleaf_t *)node; - - c_leafs++; - - pleaf->visframe = r_framecount; - - if (pleaf->nummarksurfaces) - { - mark = pleaf->firstmarksurface; - endmark = mark + pleaf->nummarksurfaces; - do - (*mark++)->visframe = r_framecount; - while (mark < endmark); - } - - // deal with model fragments in this leaf -// if (pleaf->efrags) -// R_StoreEfrags (&pleaf->efrags); - } - -culled: - if (nstack <= nodestack) - break; - nstack--; - node = nstack->node; - side = nstack->side; - clip = nstack->clip; - goto loc0; - } - else if (clip) - { - // for easier reading, the values are: - // 1 = not culled at all (very uncommon in large nodes, uncommon in medium nodes, common in small nodes) - // 2 = completely culled (uncommon in large nodes, common in medium nodes, uncommon in small nodes) - // 3 = partially culled (common in large nodes, common in medium nodes, uncommon in small nodes) - if ((c = frustum[0].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[0])) == 3) goto cull1;else if (c == 2) goto culled;// else 1 - if ((c = frustum[1].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[1])) == 3) goto cull2;else if (c == 2) goto culled;// else 1 - if ((c = frustum[2].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[2])) == 3) goto cull3;else if (c == 2) goto culled;// else 1 - if ((c = frustum[3].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[3])) == 3) goto cull4;else if (c == 2) goto culled;// else 1 - // completely onscreen, no need to cull children - clip = false; - goto cull4; - // partially clipped node -cull1: if (frustum[1].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[1]) == 2) goto culled;// else 1 or 3 -cull2: if (frustum[2].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[2]) == 2) goto culled;// else 1 or 3 -cull3: if (frustum[3].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[3]) == 2) goto culled;// else 1 or 3 -cull4: ; - } - - c_nodes++; + leaf = *l++; - // node is just a decision point, so go down the apropriate sides + c_leafs++; - // find which side of the node we are on - side = PlaneDist(modelorg, node->plane) < node->plane->dist; + leaf->visframe = r_framecount; - // recurse down the children, front side first - nstack->node = node; - nstack->side = !side; // go down back side when we come back up - nstack->clip = clip; - nstack++; - node = node->children[side]; - continue; -loc0: + // deal with model fragments in this leaf + // if (leaf->efrags) + // R_StoreEfrags (&leaf->efrags); - // draw stuff - if (node->numsurfaces) + if (leaf->nummarksurfaces) { - surf = cl.worldmodel->surfaces + node->firstsurface; - endsurf = surf + node->numsurfaces; - - if (side) + mark = leaf->firstmarksurface; + endmark = mark + leaf->nummarksurfaces; + do { - for (;surf < endsurf;surf++) + surf = *mark++; + // make sure surfaces are only processed once + if (surf->worldnodeframe == r_framecount) + continue; + surf->worldnodeframe = r_framecount; + if (PlaneDist(modelorg, surf->plane) < surf->plane->dist) + { if (surf->flags & SURF_PLANEBACK) - surf->visframe = -1; - } - else - { - for (;surf < endsurf;surf++) - if (!(surf->flags & SURF_PLANEBACK)) - surf->visframe = -1; - } - } - - // recurse down the back side - node = node->children[side]; - continue; - } -} - -void R_BSPWorldNode () -{ - int side, c, clip/*, oldclip = r_oldclip.value*/; - nodestack_t *nstack, nodestack[8192]; - mnode_t *node; - mleaf_t *pleaf; - msurface_t *surf, *endsurf, **mark, **endmark; - nstack = nodestack; - - node = cl.worldmodel->nodes; - - if (!node) - return; - - clip = true; - while(1) - { - if (node->contents < 0) - { - if (node->contents != CONTENTS_SOLID && R_NotCulledBox(node->mins, node->maxs)) - { - // mark surfaces as being visible for processing by code later - pleaf = (mleaf_t *)node; - - c_leafs++; - - pleaf->visframe = r_framecount; - - if (pleaf->nummarksurfaces) + surf->visframe = r_framecount; + } + else { - mark = pleaf->firstmarksurface; - endmark = mark + pleaf->nummarksurfaces; - do - (*mark++)->visframe = r_framecount; - while (mark < endmark); + if (!(surf->flags & SURF_PLANEBACK)) + surf->visframe = r_framecount; } - - // deal with model fragments in this leaf -// if (pleaf->efrags) -// R_StoreEfrags (&pleaf->efrags); - } - -culled: - if (nstack <= nodestack) - break; - nstack--; - node = nstack->node; - side = nstack->side; - clip = nstack->clip; - goto loc0; - } - /* - else if (oldclip) - { - if (R_CullBox(node->mins, node->maxs)) - { - if (nstack <= nodestack) - break; - nstack--; - node = nstack->node; - side = nstack->side; - clip = nstack->clip; - goto loc0; } + while (mark < endmark); } - */ - else if (clip) - { - // for easier reading, the values are: - // 1 = not culled at all (very uncommon in large nodes, uncommon in medium nodes, common in small nodes) - // 2 = completely culled (uncommon in large nodes, common in medium nodes, uncommon in small nodes) - // 3 = partially culled (common in large nodes, common in medium nodes, uncommon in small nodes) - if ((c = frustum[0].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[0])) == 3) goto cull1;else if (c == 2) goto culled;// else 1 - if ((c = frustum[1].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[1])) == 3) goto cull2;else if (c == 2) goto culled;// else 1 - if ((c = frustum[2].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[2])) == 3) goto cull3;else if (c == 2) goto culled;// else 1 - if ((c = frustum[3].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[3])) == 3) goto cull4;else if (c == 2) goto culled;// else 1 - // completely onscreen, no need to cull children - clip = false; - goto cull4; - // partially clipped node -cull1: if (frustum[1].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[1]) == 2) goto culled;// else 1 or 3 -cull2: if (frustum[2].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[2]) == 2) goto culled;// else 1 or 3 -cull3: if (frustum[3].BoxOnPlaneSideFunc(node->mins, node->maxs, &frustum[3]) == 2) goto culled;// else 1 or 3 -cull4: ; - } - - c_nodes++; - - // node is just a decision point, so go down the apropriate sides - - // find which side of the node we are on - side = PlaneDist(modelorg, node->plane) < node->plane->dist; - - // recurse down the children, front side first - if (node->children[side]->vismarkframe == r_vismarkframecount) - { - nstack->node = node; - nstack->side = !side; // go down back side when we come back up - nstack->clip = clip; - nstack++; - node = node->children[side]; - continue; - } - side = !side; -loc0: - // draw stuff - if (node->numsurfaces) + // follow portals into other leafs + p = leaf->portals; + for (;p;p = p->next) { - surf = cl.worldmodel->surfaces + node->firstsurface; - endsurf = surf + node->numsurfaces; - - if (side) - { - for (;surf < endsurf;surf++) - if (surf->flags & SURF_PLANEBACK) - surf->visframe = -1; - } - else + leaf = p->past; + if (leaf->worldnodeframe != r_framecount) { - for (;surf < endsurf;surf++) - if (!(surf->flags & SURF_PLANEBACK)) - surf->visframe = -1; + leaf->worldnodeframe = r_framecount; + i = (leaf - cl.worldmodel->leafs) - 1; + if ((worldvis[i>>3] & (1<<(i&7))) && R_NotCulledBox(leaf->mins, leaf->maxs)) + *llist++ = leaf; } } + } - // recurse down the back side - if (node->children[side]->vismarkframe == r_vismarkframecount) - { - node = node->children[side]; - continue; - } - - if (nstack <= nodestack) - break; - nstack--; - node = nstack->node; - side = nstack->side; - clip = nstack->clip; - goto loc0; + i = 0; + j = 0; + p = r_viewleaf->portals; + for (;p;p = p->next) + { + j++; + if (p->past->worldnodeframe != r_framecount) + i++; } + if (i) + Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, j); } +*/ void R_PortalWorldNode () { - int portalstack; + int portalstack, i; mportal_t *p, *pstack[8192]; msurface_t *surf, **mark, **endmark; mleaf_t *leaf; leaf = r_viewleaf; + leaf->worldnodeframe = r_framecount; portalstack = 0; loc0: c_leafs++; @@ -1355,26 +1145,45 @@ loc0: } // follow portals into other leafs - for (p = leaf->portals;p;p = p->next) + p = leaf->portals; + for (;p;p = p->next) { - if (p->past->worldnodeframe != r_framecount) + leaf = p->past; + if (leaf->worldnodeframe != r_framecount) { - leaf = p->past; leaf->worldnodeframe = r_framecount; - if (leaf->contents != CONTENTS_SOLID && leaf->vismarkframe == r_vismarkframecount && R_NotCulledBox(leaf->mins, leaf->maxs)) + if (leaf->contents != CONTENTS_SOLID) { - pstack[portalstack++] = p; - goto loc0; -loc1:; + i = (leaf - cl.worldmodel->leafs) - 1; + if (worldvis[i>>3] & (1<<(i&7))) + { + if (R_NotCulledBox(leaf->mins, leaf->maxs)) + { + pstack[portalstack++] = p; + goto loc0; + +loc1: + p = pstack[--portalstack]; + } + } } } } if (portalstack) - { - p = pstack[--portalstack]; goto loc1; + + i = 0; + portalstack = 0; + p = r_viewleaf->portals; + for (;p;p = p->next) + { + portalstack++; + if (p->past->worldnodeframe != r_framecount) + i++; } + if (i) + Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, portalstack); } void R_DrawSurfaces (void) @@ -1469,17 +1278,12 @@ void R_DrawWorld (void) if (cl.worldmodel) { - if (r_novis.value || !r_viewleaf->compressed_vis) - R_NoVisWorldNode (); + if (r_viewleaf->contents == CONTENTS_SOLID) + R_SolidWorldNode (); else { R_MarkLeaves (); - if (r_portalworldnode.value) - R_PortalWorldNode (); - else if (r_leafworldnode.value) - R_LeafWorldNode (); - else - R_BSPWorldNode (); + R_PortalWorldNode (); } } diff --git a/model_brush.c b/model_brush.c index f1f87b8c..ccd95dc1 100644 --- a/model_brush.c +++ b/model_brush.c @@ -26,6 +26,7 @@ qboolean hlbsp; // LordHavoc: true if it is a HalfLife BSP file (version 30) cvar_t gl_subdivide_size = {"gl_subdivide_size", "128", true}; cvar_t halflifebsp = {"halflifebsp", "0"}; +cvar_t r_novis = {"r_novis", "0"}; /* =============== @@ -36,6 +37,7 @@ void Mod_BrushInit (void) { Cvar_RegisterVariable (&gl_subdivide_size); Cvar_RegisterVariable (&halflifebsp); + Cvar_RegisterVariable (&r_novis); memset (mod_novis, 0xff, sizeof(mod_novis)); } @@ -52,16 +54,11 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) // Sys_Error ("Mod_PointInLeaf: bad model"); node = model->nodes; - if (node->contents < 0) - return (mleaf_t *)node; - while (1) - { + do node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct (p,node->plane->normal)) < node->plane->dist]; - if (node->contents < 0) - return (mleaf_t *)node; - } - - return NULL; // never reached + while (node->contents == 0); + + return (mleaf_t *)node; } /* mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) @@ -102,9 +99,10 @@ byte *Mod_DecompressVis (byte *in, model_t *model) byte *out; int row; - row = (model->numleafs+7)>>3; + row = (model->numleafs+7)>>3; out = decompressed; + /* if (!in) { // no vis info, so make all visible while (row) @@ -114,6 +112,7 @@ byte *Mod_DecompressVis (byte *in, model_t *model) } return decompressed; } + */ do { @@ -137,7 +136,7 @@ byte *Mod_DecompressVis (byte *in, model_t *model) byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) { - if (leaf == model->leafs) + if (r_novis.value || leaf == model->leafs || leaf->compressed_vis == NULL) return mod_novis; return Mod_DecompressVis (leaf->compressed_vis, model); } @@ -250,6 +249,12 @@ void Mod_LoadTextures (lump_t *l) for (;j < 16;j++) tx->name[j] = 0; + if (!tx->name[0]) + { + Con_Printf("warning: unnamed texture in %s\n", loadname); + sprintf(tx->name, "unnamed%i", i); + } + tx->transparent = false; data = loadimagepixels(tx->name, false, 0, 0); if (data) @@ -885,11 +890,11 @@ void Mod_LoadNodes (lump_t *l) for ( i=0 ; imins[j] = LittleShort (in->mins[j]); - out->maxs[j] = LittleShort (in->maxs[j]); - } +// for (j=0 ; j<3 ; j++) +// { +// out->mins[j] = LittleShort (in->mins[j]); +// out->maxs[j] = LittleShort (in->maxs[j]); +// } p = LittleLong(in->planenum); out->plane = loadmodel->planes + p; @@ -1499,6 +1504,41 @@ void Mod_FinalizePortals() portal_t *p, *pnext; mportal_t *portal; mvertex_t *point; + mleaf_t *leaf, *endleaf; + winding_t *w; + + // recalculate bounding boxes for all leafs (because qbsp is very sloppy) + leaf = loadmodel->leafs; + endleaf = leaf + loadmodel->numleafs; + for (;leaf < endleaf;leaf++) + { + VectorSet( 2000000000, 2000000000, 2000000000, leaf->mins); + VectorSet(-2000000000, -2000000000, -2000000000, leaf->maxs); + } + p = portalchain; + while(p) + { + if (p->winding) + { + for (i = 0;i < 2;i++) + { + leaf = (mleaf_t *)p->nodes[i]; + w = p->winding; + for (j = 0;j < w->numpoints;j++) + { + if (leaf->mins[0] > w->points[j][0]) leaf->mins[0] = w->points[j][0]; + if (leaf->mins[1] > w->points[j][1]) leaf->mins[1] = w->points[j][1]; + if (leaf->mins[2] > w->points[j][2]) leaf->mins[2] = w->points[j][2]; + if (leaf->maxs[0] < w->points[j][0]) leaf->maxs[0] = w->points[j][0]; + if (leaf->maxs[1] < w->points[j][1]) leaf->maxs[1] = w->points[j][1]; + if (leaf->maxs[2] < w->points[j][2]) leaf->maxs[2] = w->points[j][2]; + } + } + } + p = p->chain; + } + + // tally up portal and point counts p = portalchain; numportals = 0; numpoints = 0; @@ -1620,7 +1660,7 @@ void RemovePortalFromNodes(portal_t *portal) { node = portal->nodes[i]; - portalpointer = &node->portals; + portalpointer = (void **) &node->portals; while (1) { t = *portalpointer; @@ -1645,9 +1685,9 @@ void RemovePortalFromNodes(portal_t *portal) } if (t->nodes[0] == node) - portalpointer = &t->next[0]; + portalpointer = (void **) &t->next[0]; else if (t->nodes[1] == node) - portalpointer = &t->next[1]; + portalpointer = (void **) &t->next[1]; else Host_Error ("RemovePortalFromNodes: portal not bounding leaf"); } diff --git a/model_brush.h b/model_brush.h index c88f1095..2355d2ec 100644 --- a/model_brush.h +++ b/model_brush.h @@ -140,11 +140,6 @@ typedef struct mnode_s { // common with leaf int contents; // 0, to differentiate from leafs - int vismarkframe; // node needs to be traversed if current (r_vismarkframecount) - - // for bounding box culling - vec3_t mins; - vec3_t maxs; struct mnode_s *parent; struct mportal_s *portals; @@ -162,12 +157,7 @@ typedef struct mnode_s typedef struct mleaf_s { // common with node - int contents; // wil be a negative contents number - int vismarkframe; // node needs to be traversed if current (r_vismarkframecount) - - // for bounding box culling - vec3_t mins; - vec3_t maxs; + int contents; // will be a negative contents number struct mnode_s *parent; struct mportal_s *portals; @@ -176,6 +166,10 @@ typedef struct mleaf_s int visframe; // visible if current (r_framecount) int worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame + // for bounding box culling + vec3_t mins; + vec3_t maxs; + // LordHavoc: leaf based dynamic lighting int dlightbits[8]; int dlightframe; diff --git a/pr_cmds.c b/pr_cmds.c index 4d312c73..90562b85 100644 --- a/pr_cmds.c +++ b/pr_cmds.c @@ -1298,7 +1298,6 @@ void PF_precache_sound (void) PR_RunError ("PF_precache_sound: overflow"); } -extern qboolean hlbsp; void PF_precache_model (void) { char *s; diff --git a/render.h b/render.h index 933a765d..2420f2ca 100644 --- a/render.h +++ b/render.h @@ -147,6 +147,7 @@ typedef struct extern refdef_t r_refdef; extern vec3_t r_origin, vpn, vright, vup; +extern qboolean hlbsp; void R_Init (void); void R_RenderView (void); // must set r_refdef first diff --git a/sv_main.c b/sv_main.c index 92276c2b..0ef1184b 100644 --- a/sv_main.c +++ b/sv_main.c @@ -578,7 +578,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg) if (ent != clent) { - if (glowsize == 0 && bits == 0) // no effects + if (glowsize == 0 && (bits & U_GLOWTRAIL) == 0) // no effects { if (ent->v.modelindex && pr_strings[ent->v.model]) // model { diff --git a/world.c b/world.c index 1c4b74bb..0409d61a 100644 --- a/world.c +++ b/world.c @@ -124,7 +124,6 @@ Offset is filled in to contain the adjustment that must be added to the testing object's origin to get a point to use with the returned hull. ================ */ -extern qboolean hlbsp; hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) { model_t *model; -- 2.39.2