allow a global override to enable radiosity mode on _surface

allow Q2-style rads and Q1-style rads to be added together; also mimic the behavior of _surface which loads multiple lights for a single surface
This commit is contained in:
Jonathan 2022-06-21 17:29:26 -04:00
parent 210d994445
commit e97ad64bdc
4 changed files with 58 additions and 54 deletions

View File

@ -130,13 +130,6 @@ const std::vector<sun_t> &GetSuns();
const std::vector<std::unique_ptr<light_t>> &GetSurfaceLightTemplates(); const std::vector<std::unique_ptr<light_t>> &GetSurfaceLightTemplates();
enum {
// Q1-style surface light copies
SURFLIGHT_Q1 = 0,
// Q2/Q3-style radiosity
SURFLIGHT_RAD = 1
};
bool FaceMatchesSurfaceLightTemplate(const mbsp_t *bsp, const mface_t *face, const light_t &surflight, int surf_type); bool FaceMatchesSurfaceLightTemplate(const mbsp_t *bsp, const mface_t *face, const light_t &surflight, int surf_type);
const entdict_t *FindEntDictWithKeyPair(const std::string &key, const std::string &value); const entdict_t *FindEntDictWithKeyPair(const std::string &key, const std::string &value);

View File

@ -268,6 +268,13 @@ enum class visapprox_t
// worldspawn keys / command-line settings // worldspawn keys / command-line settings
// //
enum {
// Q1-style surface light copies
SURFLIGHT_Q1 = 0,
// Q2/Q3-style radiosity
SURFLIGHT_RAD = 1
};
namespace settings namespace settings
{ {
extern setting_group worldspawn_group; extern setting_group worldspawn_group;
@ -333,6 +340,7 @@ public:
setting_scalar sun_deviance{this, "sunlight_penumbra", 0.0, 0.0, 180.0, &worldspawn_group}; setting_scalar sun_deviance{this, "sunlight_penumbra", 0.0, 0.0, 180.0, &worldspawn_group};
setting_vec3 sky_surface{ setting_vec3 sky_surface{
this, {"sky_surface", "sun_surface"}, 0, 0, 0, &worldspawn_group} /* arghrad surface lights on sky faces */; this, {"sky_surface", "sun_surface"}, 0, 0, 0, &worldspawn_group} /* arghrad surface lights on sky faces */;
setting_int32 surflight_radiosity{this, "surflight_radiosity", SURFLIGHT_Q1, &worldspawn_group, "whether to use Q1-style surface subdivision (0) or Q2-style surface radiosity"};
}; };
extern setting_group output_group; extern setting_group output_group;

View File

@ -1182,8 +1182,17 @@ static aabb3d BoundPoly(int numverts, qvec3d *verts)
bool FaceMatchesSurfaceLightTemplate(const mbsp_t *bsp, const mface_t *face, const light_t &surflight, int surf_type) bool FaceMatchesSurfaceLightTemplate(const mbsp_t *bsp, const mface_t *face, const light_t &surflight, int surf_type)
{ {
const char *texname = Face_TextureName(bsp, face); const char *texname = Face_TextureName(bsp, face);
int32_t radiosity_type;
if (surflight.epairs->has("_surface_radiosity")) {
radiosity_type = surflight.epairs->get_int("_surface_radiosity");
} else {
radiosity_type = options.surflight_radiosity.value();
}
return !Q_strcasecmp(texname, surflight.epairs->get("_surface")) && return !Q_strcasecmp(texname, surflight.epairs->get("_surface")) &&
!!surflight.epairs->get_int("_surface_radiosity") == surf_type; radiosity_type == surf_type;
} }
/* /*

View File

@ -46,53 +46,8 @@ std::vector<surfacelight_t> surfacelights;
std::map<int, std::vector<int>> surfacelightsByFacenum; std::map<int, std::vector<int>> surfacelightsByFacenum;
int total_surflight_points = 0; int total_surflight_points = 0;
static void MakeSurfaceLightsThread(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, size_t i) static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, const mface_t *face, std::optional<qvec3f> texture_color, bool is_directional, bool is_sky, int32_t style, int32_t light_value)
{ {
const mface_t *face = BSP_GetFace(bsp, i);
// Face casts light?
int32_t light_value = 0;
bool is_sky = false, is_directional = false;
int32_t style = 0;
std::optional<qvec3f> texture_color;
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
// first, check if it's a Q2 surface
const mtexinfo_t *info = Face_Texinfo(bsp, face);
if (info == nullptr)
return;
if (!(info->flags.native & Q2_SURF_LIGHT) || info->value == 0) {
if (info->flags.native & Q2_SURF_LIGHT) {
qvec3d wc = winding_t::from_face(bsp, face).center();
logging::print("WARNING: surface light '{}' at [{}] has 0 intensity.\n", Face_TextureName(bsp, face), wc);
}
return;
}
light_value = info->value;
is_sky = (info->flags.native & Q2_SURF_SKY);
}
// check matching templates
if (!light_value) {
for (const auto &surflight : GetSurfaceLightTemplates()) {
if (FaceMatchesSurfaceLightTemplate(bsp, face, *surflight, SURFLIGHT_RAD)) {
light_value = surflight->light.value();
is_sky = surflight->epairs->get_int("_surface_is_sky");
is_directional = !!surflight->epairs->get_int("_surface_spotlight");
style = surflight->epairs->get_int("style");
if (surflight->color.isChanged()) {
texture_color = surflight->color.value() / 255.f;
}
break;
}
}
}
// Create face points... // Create face points...
auto poly = GLM_FacePoints(bsp, face); auto poly = GLM_FacePoints(bsp, face);
const float facearea = qv::PolyArea(poly.begin(), poly.end()); const float facearea = qv::PolyArea(poly.begin(), poly.end());
@ -176,6 +131,45 @@ static void MakeSurfaceLightsThread(const mbsp_t *bsp, const settings::worldspaw
surfacelightsByFacenum[Face_GetNum(bsp, face)].push_back(index); surfacelightsByFacenum[Face_GetNum(bsp, face)].push_back(index);
} }
static void MakeSurfaceLightsThread(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, size_t i)
{
const mface_t *face = BSP_GetFace(bsp, i);
// Face casts light?
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
// first, check if it's a Q2 surface
const mtexinfo_t *info = Face_Texinfo(bsp, face);
if (info == nullptr)
return;
if (!(info->flags.native & Q2_SURF_LIGHT) || info->value == 0) {
if (info->flags.native & Q2_SURF_LIGHT) {
qvec3d wc = winding_t::from_face(bsp, face).center();
logging::print("WARNING: surface light '{}' at [{}] has 0 intensity.\n", Face_TextureName(bsp, face), wc);
}
return;
}
MakeSurfaceLight(bsp, cfg, face, std::nullopt, false, (info->flags.native & Q2_SURF_SKY), 0, info->value);
}
// check matching templates
for (const auto &surflight : GetSurfaceLightTemplates()) {
if (FaceMatchesSurfaceLightTemplate(bsp, face, *surflight, SURFLIGHT_RAD)) {
std::optional<qvec3f> texture_color;
if (surflight->color.isChanged()) {
texture_color = surflight->color.value() / 255.f;
}
MakeSurfaceLight(bsp, cfg, face, texture_color, !!surflight->epairs->get_int("_surface_spotlight"),
surflight->epairs->get_int("_surface_is_sky"), surflight->epairs->get_int("style"), surflight->light.value());
}
}
}
const std::vector<surfacelight_t> &SurfaceLights() const std::vector<surfacelight_t> &SurfaceLights()
{ {
return surfacelights; return surfacelights;