diff --git a/include/light/entities.h b/include/light/entities.h index 99acfcc5..0302b0ea 100644 --- a/include/light/entities.h +++ b/include/light/entities.h @@ -120,6 +120,7 @@ const char *ValueForKey(const entity_t *ent, const char *key); void GetVectorForKey(const entity_t *ent, const char *key, vec3_t vec); void LoadEntities(const bsp2_t *bsp); +void SetupLights(const bsp2_t *bsp); void WriteEntitiesToString(bsp2_t *bsp); #endif /* __LIGHT_ENTITIES_H__ */ diff --git a/include/light/light.h b/include/light/light.h index 529d7a2c..2a1b139a 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -97,6 +97,7 @@ typedef struct sun_s { /* tracelist is a null terminated array of BSP models to use for LOS tests */ extern const dmodel_t *const *tracelist; +const modelinfo_t *ModelInfoForFace(const bsp2_t *bsp, int facenum); void LightFace(bsp2_dface_t *face, const modelinfo_t *modelinfo, const bsp2_t *bsp); void MakeTnodes(const bsp2_t *bsp); diff --git a/light/entities.c b/light/entities.c index d6075138..b29275ab 100644 --- a/light/entities.c +++ b/light/entities.c @@ -866,7 +866,11 @@ LoadEntities(const bsp2_t *bsp) } logprint("%d entities read, %d are lights.\n", num_entities, num_lights); +} +void +SetupLights(const bsp2_t *bsp) +{ // Creates more light entities, needs to be done before the rest MakeSurfaceLights(bsp); @@ -1051,7 +1055,7 @@ static void CreateSurfaceLight(const vec3_t origin, const vec3_t normal, const e num_lights++; } -static void CreateSurfaceLightOnFaceSubdivision(const bsp2_dface_t *face, const entity_t *surflight_template, const bsp2_t *bsp, int numverts, const vec_t *verts) +static void CreateSurfaceLightOnFaceSubdivision(const bsp2_dface_t *face, const modelinfo_t *face_modelinfo, const entity_t *surflight_template, const bsp2_t *bsp, int numverts, const vec_t *verts) { int i; vec3_t midpoint = {0, 0, 0}; @@ -1080,6 +1084,9 @@ static void CreateSurfaceLightOnFaceSubdivision(const bsp2_dface_t *face, const VectorMA(midpoint, offset, normal, midpoint); + /* Add the model offset */ + VectorAdd(midpoint, face_modelinfo->offset, midpoint); + CreateSurfaceLight(midpoint, normal, surflight_template); } @@ -1106,7 +1113,7 @@ static void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) SubdividePolygon - from GLQuake ================ */ -static void SubdividePolygon (const bsp2_dface_t *face, const bsp2_t *bsp, int numverts, vec_t *verts, float subdivide_size) +static void SubdividePolygon (const bsp2_dface_t *face, const modelinfo_t *face_modelinfo, const bsp2_t *bsp, int numverts, vec_t *verts, float subdivide_size) { int i, j, k; vec3_t mins, maxs; @@ -1170,8 +1177,8 @@ static void SubdividePolygon (const bsp2_dface_t *face, const bsp2_t *bsp, int n } } - SubdividePolygon (face, bsp, f, front[0], subdivide_size); - SubdividePolygon (face, bsp, b, back[0], subdivide_size); + SubdividePolygon (face, face_modelinfo, bsp, f, front[0], subdivide_size); + SubdividePolygon (face, face_modelinfo, bsp, b, back[0], subdivide_size); return; } @@ -1182,7 +1189,7 @@ static void SubdividePolygon (const bsp2_dface_t *face, const bsp2_t *bsp, int n for (i=0; ipoint, verts[i]); } - SubdividePolygon (face, bsp, face->numedges, verts[0], surflight_subdivide); + SubdividePolygon (face, face_modelinfo, bsp, face->numedges, verts[0], surflight_subdivide); } static void MakeSurfaceLights(const bsp2_t *bsp) @@ -1243,12 +1250,18 @@ static void MakeSurfaceLights(const bsp2_t *bsp) for (k = 0; k < leaf->nummarksurfaces; k++) { const texinfo_t *info; const miptex_t *miptex; + const modelinfo_t *face_modelinfo; int facenum = bsp->dmarksurfaces[leaf->firstmarksurface + k]; surf = &bsp->dfaces[facenum]; info = &bsp->texinfo[surf->texinfo]; ofs = bsp->dtexdata.header->dataofs[info->miptex]; miptex = (const miptex_t *)(bsp->dtexdata.base + ofs); + face_modelinfo = ModelInfoForFace(bsp, facenum); + + /* Skip face with no modelinfo */ + if (face_modelinfo == NULL) + continue; /* Ignore the underwater side of liquid surfaces */ if (miptex->name[0] == '*' && underwater) @@ -1260,9 +1273,9 @@ static void MakeSurfaceLights(const bsp2_t *bsp) /* Mark as handled */ face_visited[facenum] = true; - + /* Generate the lights */ - GL_SubdivideSurface(surf, bsp); + GL_SubdivideSurface(surf, face_modelinfo, bsp); } } free(face_visited); diff --git a/light/light.c b/light/light.c index 65e1161c..b52c9446 100644 --- a/light/light.c +++ b/light/light.c @@ -115,12 +115,30 @@ GetFileSpace(byte **lightdata, byte **colordata, byte **deluxdata, int size) Error("%s: overrun", __func__); } +const modelinfo_t *ModelInfoForFace(const bsp2_t *bsp, int facenum) +{ + int i; + dmodel_t *model; + + /* Find the correct model offset */ + for (i = 0, model = bsp->dmodels; i < bsp->nummodels; i++, model++) { + if (facenum < model->firstface) + continue; + if (facenum < model->firstface + model->numfaces) + break; + } + if (i == bsp->nummodels) { + return NULL; + } + return &modelinfo[i]; +} + static void * LightThread(void *arg) { - int facenum, i; - dmodel_t *model; + int facenum; const bsp2_t *bsp = arg; + const modelinfo_t *face_modelinfo; while (1) { facenum = GetThreadWork(); @@ -128,19 +146,14 @@ LightThread(void *arg) break; /* Find the correct model offset */ - for (i = 0, model = bsp->dmodels; i < bsp->nummodels; i++, model++) { - if (facenum < model->firstface) - continue; - if (facenum < model->firstface + model->numfaces) - break; - } - if (i == bsp->nummodels) { + face_modelinfo = ModelInfoForFace(bsp, facenum); + if (face_modelinfo == NULL) { // ericw -- silenced this warning becasue is causes spam when "skip" faces are used //logprint("warning: no model has face %d\n", facenum); continue; } - LightFace(bsp->dfaces + facenum, &modelinfo[i], bsp); + LightFace(bsp->dfaces + facenum, face_modelinfo, bsp); } return NULL; @@ -427,14 +440,15 @@ main(int argc, const char **argv) ConvertBSPFormat(BSP2VERSION, &bspdata); LoadEntities(bsp); - + modelinfo = malloc(bsp->nummodels * sizeof(*modelinfo)); + FindModelInfo(bsp); + SetupLights(bsp); + if (!onlyents) { if (dirty) SetupDirt(); MakeTnodes(bsp); - modelinfo = malloc(bsp->nummodels * sizeof(*modelinfo)); - FindModelInfo(bsp); LightWorld(bsp); free(modelinfo);