From 3de3918e3e926a5a8bcbae825a50432477ce4b47 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 20 Nov 2002 12:54:15 +0000 Subject: [PATCH] CalcSurfaceExtents now uses surf->poly_verts instead of edges brush model bounding box calculations are now based on meshes instead of edges CalcSurfaceExtents has been merged into Mod_GenerateSurfacePolygon msurface_t firstedge and numedges have been removed (they were only used for generating the polygon during loading) shuffled around msurface_t fields in order of most common access at the top, to least common at the bottom, this is in an attempt to reduce wasted memory traffic git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2640 d7cf8633-e32d-0410-b094-e92efae38249 --- model_brush.c | 156 ++++++++++++++++++++------------------------------ model_brush.h | 67 +++++++++++----------- 2 files changed, 94 insertions(+), 129 deletions(-) diff --git a/model_brush.c b/model_brush.c index ea39f1cd..4959d8c3 100644 --- a/model_brush.c +++ b/model_brush.c @@ -1241,58 +1241,6 @@ static void Mod_LoadTexinfo (lump_t *l) } } -/* -================ -CalcSurfaceExtents - -Fills in s->texturemins[] and s->extents[] -================ -*/ -static void CalcSurfaceExtents (msurface_t *s) -{ - float mins[2], maxs[2], val; - int i,j, e; - mvertex_t *v; - mtexinfo_t *tex; - int bmins[2], bmaxs[2]; - - mins[0] = mins[1] = 999999999; - maxs[0] = maxs[1] = -999999999; - - tex = s->texinfo; - - for (i=0 ; inumedges ; i++) - { - e = loadmodel->surfedges[s->firstedge+i]; - if (e >= 0) - v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; - else - v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; - - for (j=0 ; j<2 ; j++) - { - val = v->position[0] * tex->vecs[j][0] + - v->position[1] * tex->vecs[j][1] + - v->position[2] * tex->vecs[j][2] + - tex->vecs[j][3]; - if (val < mins[j]) - mins[j] = val; - if (val > maxs[j]) - maxs[j] = val; - } - } - - for (i=0 ; i<2 ; i++) - { - bmins[i] = floor(mins[i]/16); - bmaxs[i] = ceil(maxs[i]/16); - - s->texturemins[i] = bmins[i] * 16; - s->extents[i] = (bmaxs[i] - bmins[i]) * 16; - } -} - - void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) { int i, j; @@ -1588,17 +1536,18 @@ void Mod_GenerateVertexMesh (msurface_t *surf) Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->verts, mesh->str, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals); } -void Mod_GenerateSurfacePolygon (msurface_t *surf) +void Mod_GenerateSurfacePolygon (msurface_t *surf, int firstedge, int numedges) { - int i, lindex; - float *vec, *vert, mins[3], maxs[3]; + int i, lindex, j; + float *vec, *vert, mins[3], maxs[3], val, *v; + mtexinfo_t *tex; // convert edges back to a normal polygon - surf->poly_numverts = surf->numedges; - vert = surf->poly_verts = Mem_Alloc(loadmodel->mempool, sizeof(float[3]) * surf->numedges); - for (i = 0;i < surf->numedges;i++) + surf->poly_numverts = numedges; + vert = surf->poly_verts = Mem_Alloc(loadmodel->mempool, sizeof(float[3]) * numedges); + for (i = 0;i < numedges;i++) { - lindex = loadmodel->surfedges[surf->firstedge + i]; + lindex = loadmodel->surfedges[firstedge + i]; if (lindex > 0) vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position; else @@ -1606,6 +1555,8 @@ void Mod_GenerateSurfacePolygon (msurface_t *surf) VectorCopy (vec, vert); vert += 3; } + + // calculate polygon bounding box and center vert = surf->poly_verts; VectorCopy(vert, mins); VectorCopy(vert, maxs); @@ -1621,6 +1572,27 @@ void Mod_GenerateSurfacePolygon (msurface_t *surf) surf->poly_center[0] = (mins[0] + maxs[0]) * 0.5f; surf->poly_center[1] = (mins[1] + maxs[1]) * 0.5f; surf->poly_center[2] = (mins[2] + maxs[2]) * 0.5f; + + // generate surface extents information + tex = surf->texinfo; + mins[0] = maxs[0] = DotProduct(surf->poly_verts, tex->vecs[0]) + tex->vecs[0][3]; + mins[1] = maxs[1] = DotProduct(surf->poly_verts, tex->vecs[1]) + tex->vecs[1][3]; + for (i = 1, v = surf->poly_verts + 3;i < surf->poly_numverts;i++, v += 3) + { + for (j = 0;j < 2;j++) + { + val = DotProduct(v, tex->vecs[j]) + tex->vecs[j][3]; + if (mins[j] > val) + mins[j] = val; + if (maxs[j] < val) + maxs[j] = val; + } + } + for (i = 0;i < 2;i++) + { + surf->texturemins[i] = (int) floor(mins[i] / 16) * 16; + surf->extents[i] = (int) ceil(maxs[i] / 16) * 16 - surf->texturemins[i]; + } } /* @@ -1632,7 +1604,7 @@ static void Mod_LoadFaces (lump_t *l) { dface_t *in; msurface_t *out; - int i, count, surfnum, planenum, ssize, tsize; + int i, count, surfnum, planenum, ssize, tsize, firstedge, numedges; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -1650,10 +1622,10 @@ static void Mod_LoadFaces (lump_t *l) { out->number = surfnum; // FIXME: validate edges, texinfo, etc? - out->firstedge = LittleLong(in->firstedge); - out->numedges = LittleShort(in->numedges); - if ((unsigned int) out->firstedge + (unsigned int) out->numedges > (unsigned int) loadmodel->numsurfedges) - Host_Error("Mod_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)\n", out->firstedge, out->numedges, loadmodel->numsurfedges); + firstedge = LittleLong(in->firstedge); + numedges = LittleShort(in->numedges); + if ((unsigned int) firstedge + (unsigned int) numedges > (unsigned int) loadmodel->numsurfedges) + Host_Error("Mod_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)\n", firstedge, numedges, loadmodel->numsurfedges); i = LittleShort (in->texinfo); if ((unsigned int) i >= (unsigned int) loadmodel->numtexinfo) @@ -1676,7 +1648,7 @@ static void Mod_LoadFaces (lump_t *l) // force lightmap upload on first time seeing the surface out->cached_dlight = true; - CalcSurfaceExtents (out); + Mod_GenerateSurfacePolygon(out, firstedge, numedges); ssize = (out->extents[0] >> 4) + 1; tsize = (out->extents[1] >> 4) + 1; @@ -1692,7 +1664,6 @@ static void Mod_LoadFaces (lump_t *l) else // LordHavoc: white lighting (bsp version 29) out->samples = loadmodel->lightdata + (i * 3); - Mod_GenerateSurfacePolygon(out); if (out->texinfo->texture->shader == &Cshader_wall_lightmap) { if ((out->extents[0] >> 4) + 1 > (256) || (out->extents[1] >> 4) + 1 > (256)) @@ -2839,12 +2810,15 @@ extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relative extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor); void Mod_LoadBrushModel (model_t *mod, void *buffer) { - int i, j; - dheader_t *header; - dmodel_t *bm; - mempool_t *mainmempool; - char *loadname; - model_t *originalloadmodel; + int i, j, k; + dheader_t *header; + dmodel_t *bm; + mempool_t *mainmempool; + char *loadname; + model_t *originalloadmodel; + float dist, modelyawradius, modelradius, *vec; + msurface_t *surf; + surfmesh_t *mesh; mod->type = mod_brush; @@ -2904,10 +2878,6 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) // for (i = 0;i < mod->numsubmodels;i++) { - int k, l; - float dist, modelyawradius, modelradius, *vec; - msurface_t *surf; - bm = &mod->submodels[i]; mod->hulls[0].firstclipnode = bm->headnode[0]; @@ -2944,25 +2914,23 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) if (surf->texinfo->texture->shader == &Cshader_sky) mod->DrawSky = R_Model_Brush_DrawSky; // calculate bounding shapes - for (k = 0;k < surf->numedges;k++) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - l = mod->surfedges[k + surf->firstedge]; - if (l > 0) - vec = mod->vertexes[mod->edges[l].v[0]].position; - else - vec = mod->vertexes[mod->edges[-l].v[1]].position; - if (mod->normalmins[0] > vec[0]) mod->normalmins[0] = vec[0]; - if (mod->normalmins[1] > vec[1]) mod->normalmins[1] = vec[1]; - if (mod->normalmins[2] > vec[2]) mod->normalmins[2] = vec[2]; - if (mod->normalmaxs[0] < vec[0]) mod->normalmaxs[0] = vec[0]; - if (mod->normalmaxs[1] < vec[1]) mod->normalmaxs[1] = vec[1]; - if (mod->normalmaxs[2] < vec[2]) mod->normalmaxs[2] = vec[2]; - dist = vec[0]*vec[0]+vec[1]*vec[1]; - if (modelyawradius < dist) - modelyawradius = dist; - dist += vec[2]*vec[2]; - if (modelradius < dist) - modelradius = dist; + for (k = 0, vec = mesh->verts;k < mesh->numverts;k++, vec += 4) + { + if (mod->normalmins[0] > vec[0]) mod->normalmins[0] = vec[0]; + if (mod->normalmins[1] > vec[1]) mod->normalmins[1] = vec[1]; + if (mod->normalmins[2] > vec[2]) mod->normalmins[2] = vec[2]; + if (mod->normalmaxs[0] < vec[0]) mod->normalmaxs[0] = vec[0]; + if (mod->normalmaxs[1] < vec[1]) mod->normalmaxs[1] = vec[1]; + if (mod->normalmaxs[2] < vec[2]) mod->normalmaxs[2] = vec[2]; + dist = vec[0]*vec[0]+vec[1]*vec[1]; + if (modelyawradius < dist) + modelyawradius = dist; + dist += vec[2]*vec[2]; + if (modelradius < dist) + modelradius = dist; + } } } modelyawradius = sqrt(modelyawradius); diff --git a/model_brush.h b/model_brush.h index 339c699e..7596a39f 100644 --- a/model_brush.h +++ b/model_brush.h @@ -173,28 +173,36 @@ surfmesh_t; typedef struct msurface_s { - // surface number, to avoid having to do a divide to find the number of a surface from it's address - int number; - // should be drawn if visframe == r_framecount (set by PrepareSurfaces) - int visframe; - // should be drawn if onscreen and not a backface (used for setting visframe) - //int pvsframe; - // chain of surfaces marked visible by pvs - //struct msurface_s *pvschain; + // bounding box for onscreen checks + vec3_t poly_mins; + vec3_t poly_maxs; // the node plane this is on, backwards if SURF_PLANEBACK flag set mplane_t *plane; // SURF_ flags int flags; + // texture mapping properties used by this surface + mtexinfo_t *texinfo; + + // the lightmap texture fragment to use on the rendering mesh + rtexture_t *lightmaptexture; + // mesh for rendering + surfmesh_t *mesh; + // if lightmap settings changed, this forces update + int cached_dlight; - // look up in model->surfedges[], negative numbers are backwards edges - int firstedge; - int numedges; + // should be drawn if visframe == r_framecount (set by PrepareSurfaces) + int visframe; + // should be drawn if onscreen and not a backface (used for setting visframe) + //int pvsframe; + // chain of surfaces marked visible by pvs + //struct msurface_s *pvschain; - short texturemins[2]; - short extents[2]; + // surface number, to avoid having to do a divide to find the number of a surface from it's address + int number; - mtexinfo_t *texinfo; + // center for sorting transparent meshes + vec3_t poly_center; // index into d_lightstylevalue array, 255 means not used (black) qbyte styles[MAXLIGHTMAPS]; @@ -202,39 +210,28 @@ typedef struct msurface_s qbyte *samples; // stain to apply on lightmap (soot/dirt/blood/whatever) qbyte *stainsamples; - - // these fields are generated during model loading - // the lightmap texture fragment to use on the surface - rtexture_t *lightmaptexture; // the stride when building lightmaps to comply with fragment update int lightmaptexturestride; - // mesh for rendering - surfmesh_t *mesh; + int texturemins[2]; + int extents[2]; + + // if this == r_framecount there are dynamic lights on the surface + int dlightframe; + // which dynamic lights are touching this surface + // (only access this if dlightframe is current) + int dlightbits[8]; + // avoid redundent addition of dlights + int lightframe; // these are just 3D points defining the outline of the polygon, // no texcoord info (that can be generated from these) int poly_numverts; float *poly_verts; - // bounding box for onscreen checks, and center for sorting - vec3_t poly_mins, poly_maxs, poly_center; // neighboring surfaces (one per poly_numverts) //struct msurface_s **neighborsurfaces; // currently used only for generating static shadow volumes int castshadow; - - // these are regenerated every frame - // lighting info - // if this == r_framecount there are dynamic lights on the surface - int dlightframe; - // which dynamic lights are touching this surface - // (only access this if dlightframe is current) - int dlightbits[8]; - // avoid redundent addition of dlights - int lightframe; - - // if lightmap settings changed, this forces update - int cached_dlight; } msurface_t; -- 2.39.2