fix gate being incorrect

add surflight grouping
fix minlight on color'd _surface lights
This commit is contained in:
Jonathan 2022-12-05 20:35:44 -05:00
parent e73aa29dd1
commit 15b9a78fd1
11 changed files with 55 additions and 18 deletions

View File

@ -1725,13 +1725,15 @@ const bspversion_t bspver_qbism{Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II
bool surfflags_t::needs_write() const
{
return no_dirt || no_shadow || no_bounce || no_minlight || no_expand || no_phong || light_ignore || !surflight_rescale || phong_angle ||
phong_angle_concave || phong_group || minlight || !qv::emptyExact(minlight_color) || light_alpha || maxlight || lightcolorscale != 1.0;
phong_angle_concave || phong_group || minlight || !qv::emptyExact(minlight_color) || light_alpha || maxlight || lightcolorscale != 1.0 ||
surflight_group;
}
static auto as_tuple(const surfflags_t &flags)
{
return std::tie(flags.native, flags.is_nodraw, flags.is_hintskip, flags.is_hint, flags.no_dirt, flags.no_shadow, flags.no_bounce, flags.no_minlight, flags.no_expand,
flags.no_phong, flags.light_ignore, flags.surflight_rescale, flags.phong_angle, flags.phong_angle_concave, flags.phong_group, flags.minlight, flags.minlight_color, flags.light_alpha, flags.maxlight, flags.lightcolorscale);
flags.no_phong, flags.light_ignore, flags.surflight_rescale, flags.phong_angle, flags.phong_angle_concave, flags.phong_group, flags.minlight, flags.minlight_color, flags.light_alpha, flags.maxlight, flags.lightcolorscale,
flags.surflight_group);
}
bool surfflags_t::operator<(const surfflags_t &other) const

View File

@ -216,6 +216,9 @@ struct surfflags_t
// light color scale
vec_t lightcolorscale = 1.0;
// surface light group
int32_t surflight_group;
bool needs_write() const;
public:

View File

@ -534,11 +534,11 @@ template<size_t N, class T>
[[nodiscard]] inline bool gate(const qvec<T, N> &v, T epsilon)
{
for (size_t i = 0; i < N; i++) {
if (gate(v[i], epsilon)) {
return true;
if (!gate(v[i], epsilon)) {
return false;
}
}
return false;
return true;
}
template<size_t N, class T>

View File

@ -98,6 +98,7 @@ public:
settings::setting_string project_texture;
settings::setting_string suntexture;
settings::setting_bool nostaticlight;
settings::setting_int32 surflight_group;
light_t();
@ -130,7 +131,7 @@ std::vector<entdict_t> &GetRadLights();
const std::vector<std::unique_ptr<light_t>> &GetSurfaceLightTemplates();
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 modelinfo_t *face_modelinfo, const light_t &surflight, int surf_type);
const entdict_t *FindEntDictWithKeyPair(const std::string &key, const std::string &value);

View File

@ -51,6 +51,6 @@ struct surfacelight_t
void ResetSurflight();
std::vector<surfacelight_t> &GetSurfaceLights();
std::optional<std::tuple<int32_t, int32_t>> IsSurfaceLitFace(const mbsp_t *bsp, const mface_t *face);
std::optional<std::tuple<int32_t, int32_t, qvec3b>> IsSurfaceLitFace(const mbsp_t *bsp, const mface_t *face);
const std::vector<int> &SurfaceLightsForFaceNum(int facenum);
void MakeRadiositySurfaceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp);

View File

@ -104,7 +104,8 @@ light_t::light_t() :
projangle{this, "project_mangle", 20, 0, 0},
project_texture{this, "project_texture", ""},
suntexture{this, "suntexture", ""},
nostaticlight{this, "nostaticlight", false}
nostaticlight{this, "nostaticlight", false},
surflight_group{this, "surflight_group", 0}
{}
std::string light_t::classname() const
@ -1242,7 +1243,7 @@ static aabb3d BoundPoly(int numverts, qvec3d *verts)
return bounds;
}
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 modelinfo_t *face_modelinfo, const light_t &surflight, int surf_type)
{
const char *texname = Face_TextureName(bsp, face);
@ -1254,7 +1255,19 @@ bool FaceMatchesSurfaceLightTemplate(const mbsp_t *bsp, const mface_t *face, con
radiosity_type = light_options.surflight_radiosity.value();
}
return !Q_strcasecmp(texname, surflight.epairs->get("_surface")) && radiosity_type == surf_type;
if (radiosity_type != surf_type) {
return false;
}
const surfflags_t &extended_flags = extended_texinfo_flags[face->texinfo];
if (extended_flags.surflight_group) {
if (surflight.surflight_group.value() && surflight.surflight_group.value() != extended_flags.surflight_group) {
return false;
}
}
return !Q_strcasecmp(texname, surflight.epairs->get("_surface"));
}
/*
@ -1329,7 +1342,7 @@ static void SubdividePolygon(const mface_t *face, const modelinfo_t *face_modeli
}
for (const auto &surflight : surfacelight_templates) {
if (FaceMatchesSurfaceLightTemplate(bsp, face, *surflight, SURFLIGHT_Q1)) {
if (FaceMatchesSurfaceLightTemplate(bsp, face, face_modelinfo, *surflight, SURFLIGHT_Q1)) {
CreateSurfaceLightOnFaceSubdivision(face, face_modelinfo, surflight.get(), bsp, numverts, verts);
}
}
@ -1470,7 +1483,7 @@ static void MakeSurfaceLights(const mbsp_t *bsp)
/* Don't bother subdividing if it doesn't match any surface light templates */
if (!std::any_of(surfacelight_templates.begin(), surfacelight_templates.end(), [&](const auto &surflight) {
return FaceMatchesSurfaceLightTemplate(bsp, surf, *surflight, SURFLIGHT_Q1);
return FaceMatchesSurfaceLightTemplate(bsp, surf, face_modelinfo, *surflight, SURFLIGHT_Q1);
}))
continue;

View File

@ -1113,6 +1113,9 @@ static void LoadExtendedTexinfoFlags(const fs::path &sourcefilename, const mbsp_
if (val.contains("lightcolorscale")) {
flags.lightcolorscale = val.at("lightcolorscale").get<vec_t>();
}
if (val.contains("surflight_group")) {
flags.surflight_group = val.at("surflight_group").get<int32_t>();
}
}
}
@ -1607,6 +1610,9 @@ int light_main(int argc, const char **argv)
if (!light_options.bounce.isChanged()) {
light_options.bounce.setValue(true, settings::source::GAME_TARGET);
}
if (!light_options.surflight_radiosity.isChanged()) {
light_options.surflight_radiosity.setValue(SURFLIGHT_RAD, settings::source::GAME_TARGET);
}
}
// check vis approx type

View File

@ -3081,7 +3081,7 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::
if (auto value = IsSurfaceLitFace(bsp, face)) {
minlight = std::get<0>(value.value()) * 64.0f;
minlight_color = Face_LookupTextureColor(bsp, face);
minlight_color = std::get<2>(value.value());
LightFace_Min(bsp, face, minlight_color, minlight, &lightsurf, lightmaps, std::get<1>(value.value()));
}

View File

@ -147,20 +147,20 @@ static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys
surfacelightsByFacenum[Face_GetNum(bsp, face)].push_back(index);
}
std::optional<std::tuple<int32_t, int32_t>> IsSurfaceLitFace(const mbsp_t *bsp, const mface_t *face)
std::optional<std::tuple<int32_t, int32_t, qvec3b>> IsSurfaceLitFace(const mbsp_t *bsp, const mface_t *face)
{
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 && (info->flags.native & Q2_SURF_LIGHT) && info->value > 0) {
return std::make_tuple(info->value, 0);
return std::make_tuple(info->value, 0, Face_LookupTextureColor(bsp, face));
}
}
for (const auto &surflight : GetSurfaceLightTemplates()) {
if (FaceMatchesSurfaceLightTemplate(bsp, face, *surflight, SURFLIGHT_RAD)) {
return std::make_tuple(surflight->light.value(), surflight->style.value());
if (FaceMatchesSurfaceLightTemplate(bsp, face, ModelInfoForFace(bsp, face - bsp->dfaces.data()), *surflight, SURFLIGHT_RAD)) {
return std::make_tuple(surflight->light.value(), surflight->style.value(), surflight->color.isChanged() ? qvec3b(surflight->color.value() * 255) : Face_LookupTextureColor(bsp, face));
}
}
@ -193,7 +193,7 @@ static void MakeSurfaceLightsThread(const mbsp_t *bsp, const settings::worldspaw
// check matching templates
for (const auto &surflight : GetSurfaceLightTemplates()) {
if (FaceMatchesSurfaceLightTemplate(bsp, face, *surflight, SURFLIGHT_RAD)) {
if (FaceMatchesSurfaceLightTemplate(bsp, face, ModelInfoForFace(bsp, face - bsp->dfaces.data()), *surflight, SURFLIGHT_RAD)) {
std::optional<qvec3f> texture_color;
if (surflight->color.isChanged()) {

View File

@ -643,6 +643,15 @@ static surfflags_t SurfFlagsForEntity(const maptexinfo_t &texinfo, const mapenti
}
}
if (entity.epairs.has("_surflight_group"))
{
const int32_t surflight_group = entity.epairs.get_int("_surflight_group");
if (surflight_group) {
flags.surflight_group = surflight_group;
}
}
// handle "_mincolor"
{
qvec3d mincolor{};

View File

@ -398,6 +398,9 @@ static void WriteExtendedTexinfoFlags(void)
if (tx.flags.lightcolorscale != 1.0) {
t["lightcolorscale"] = tx.flags.lightcolorscale;
}
if (tx.flags.surflight_group) {
t["surflight_group"] = tx.flags.surflight_group;
}
texinfofile[std::to_string(*tx.outputnum)].swap(t);
}