light: handle surface lights on rotators
This commit is contained in:
parent
5face9dd51
commit
81cefad71a
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; i<num_surfacelight_templates; i++) {
|
||||
if (!strcasecmp(texname, ValueForKey(surfacelight_templates[i], "_surface"))) {
|
||||
CreateSurfaceLightOnFaceSubdivision(face, surfacelight_templates[i], bsp, numverts, verts);
|
||||
CreateSurfaceLightOnFaceSubdivision(face, face_modelinfo, surfacelight_templates[i], bsp, numverts, verts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1192,7 +1199,7 @@ static void SubdividePolygon (const bsp2_dface_t *face, const bsp2_t *bsp, int n
|
|||
GL_SubdivideSurface - from GLQuake
|
||||
================
|
||||
*/
|
||||
static void GL_SubdivideSurface (const bsp2_dface_t *face, const bsp2_t *bsp)
|
||||
static void GL_SubdivideSurface (const bsp2_dface_t *face, const modelinfo_t *face_modelinfo, const bsp2_t *bsp)
|
||||
{
|
||||
int i;
|
||||
vec3_t verts[64];
|
||||
|
|
@ -1208,7 +1215,7 @@ static void GL_SubdivideSurface (const bsp2_dface_t *face, const bsp2_t *bsp)
|
|||
VectorCopy(v->point, 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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue