simplify `needs_write` for surfflags

add `_surflight_color` key; allows overriding surface light color on an entity basis
load the .wal from wal_json and use the values as a base, if they exist
allow `_surflight_minlight_scale` to be specified on entities
This commit is contained in:
Jonathan 2023-04-24 02:16:39 -04:00
parent c2a787f6a3
commit dddc48e98b
13 changed files with 70 additions and 34 deletions

View File

@ -1782,21 +1782,19 @@ const bspversion_t bspver_qbism{Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II
},
&gamedef_q2};
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 || surflight_group ||
world_units_per_luxel || object_channel_mask || surflight_minlight_scale;
return as_tuple(*this) != as_tuple(surfflags_t());
}
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.surflight_rescale, flags.surflight_color, flags.surflight_minlight_scale, 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,
flags.world_units_per_luxel, flags.object_channel_mask, flags.surflight_minlight_scale);
flags.world_units_per_luxel, flags.object_channel_mask);
}
bool surfflags_t::operator<(const surfflags_t &other) const

View File

@ -516,6 +516,14 @@ std::optional<texture_meta> load_wal_json_meta(
texture_meta meta{};
{
fs::path wal = fs::path(name).replace_extension(".wal");
if (auto wal_file = fs::load(wal))
if (auto wal_meta = load_wal_meta(wal.string(), wal_file, game))
meta = *wal_meta;
}
if (json.contains("width") && json["width"].is_number_integer()) {
meta.width = json["width"].get<int32_t>();
}

View File

@ -192,6 +192,12 @@ struct surfflags_t
// normal if false, use a more natural angle falloff of 0% at 90 degrees
bool surflight_rescale = true;
// override the textures' surflight color
std::optional<qvec3b> surflight_color;
// surface light rescaling
std::optional<vec_t> surflight_minlight_scale;
// if non zero, enables phong shading and gives the angle threshold to use
vec_t phong_angle;
@ -224,8 +230,6 @@ struct surfflags_t
std::optional<int32_t> object_channel_mask;
std::optional<float> surflight_minlight_scale;
bool needs_write() const;
public:

View File

@ -102,7 +102,11 @@ constexpr struct
ext id;
decltype(load_wal) *loader;
} extension_list[] = {
{".tga", ext::TGA, load_tga}, {".wal", ext::WAL, load_wal}, {".mip", ext::MIP, load_mip}, {"", ext::MIP, load_mip}};
{".tga", ext::TGA, load_tga},
{".wal", ext::WAL, load_wal},
{".mip", ext::MIP, load_mip},
{"", ext::MIP, load_mip}
};
// Attempt to load a texture from the specified name.
std::tuple<std::optional<texture>, fs::resolve_result, fs::data> load_texture(
@ -127,7 +131,9 @@ constexpr struct
meta_ext id;
decltype(load_wal_meta) *loader;
} meta_extension_list[] = {
{".wal", meta_ext::WAL, load_wal_meta}, {".wal_json", meta_ext::WAL_JSON, load_wal_json_meta}};
{".wal_json", meta_ext::WAL_JSON, load_wal_json_meta},
{".wal", meta_ext::WAL, load_wal_meta}
};
// Attempt to load a texture meta from the specified name.
std::tuple<std::optional<texture_meta>, fs::resolve_result, fs::data> load_texture_meta(

View File

@ -100,7 +100,7 @@ public:
settings::setting_string suntexture;
settings::setting_bool nostaticlight;
settings::setting_int32 surflight_group;
settings::setting_scalar surface_minlight_scale;
settings::setting_scalar surflight_minlight_scale;
settings::setting_int32 light_channel_mask;
settings::setting_int32 shadow_channel_mask;
settings::setting_bool nonudge;

View File

@ -102,7 +102,7 @@ struct lightsurf_t
const mface_t *face;
/* these take precedence the values in modelinfo */
vec_t minlight, maxlight, lightcolorscale = 1.0;
vec_t surflight_minlight_scale;
vec_t surflight_minlight_scale = 1.0;
qvec3d minlight_color;
bool nodirt, minlightMottle;
int32_t object_channel_mask;
@ -269,8 +269,8 @@ public:
setting_scalar global_anglescale;
setting_scalar lightmapgamma;
setting_bool addminlight;
setting_scalar minlightMottle;
setting_scalar minlight;
setting_scalar minlightMottle;
setting_scalar maxlight;
setting_color minlight_color;
setting_bool spotlightautofalloff;

View File

@ -47,6 +47,7 @@ struct surfacelight_t
// rescale faces to account for perpendicular lights
bool rescale;
std::optional<vec_t> minlight_scale;
};
class light_t;

View File

@ -112,7 +112,7 @@ light_t::light_t()
suntexture{this, "suntexture", ""},
nostaticlight{this, "nostaticlight", false},
surflight_group{this, "surflight_group", 0},
surface_minlight_scale{this, "surface_minlight_scale", 64.f},
surflight_minlight_scale{this, "surflight_minlight_scale", 64.f},
light_channel_mask{this, "light_channel_mask", CHANNEL_MASK_DEFAULT},
shadow_channel_mask{this, "shadow_channel_mask", CHANNEL_MASK_DEFAULT},
nonudge{this, "nonudge", false}
@ -338,10 +338,10 @@ static void CheckEntityFields(const mbsp_t *bsp, const settings::worldspawn_keys
entity->shadow_channel_mask.setValue(entity->light_channel_mask.value(), settings::source::DEFAULT);
}
if (!entity->surface_minlight_scale.isChanged()) {
if (!entity->surflight_minlight_scale.isChanged()) {
if (bsp->loadversion->game->id != GAME_QUAKE_II) {
// TODO: also use 1.0 for Q2?
entity->surface_minlight_scale.setValue(1.0f, settings::source::DEFAULT);
entity->surflight_minlight_scale.setValue(1.0f, settings::source::DEFAULT);
}
}
}

View File

@ -164,8 +164,8 @@ worldspawn_keys::worldspawn_keys()
lightmapgamma{this, "gamma", 1.0, 0.0, 100.0, &worldspawn_group},
addminlight{this, "addmin", false, &worldspawn_group},
minlight{this, {"light", "minlight"}, 0, &worldspawn_group},
maxlight{this, "maxlight", 0, &worldspawn_group},
minlightMottle{this, "minlightMottle", false},
maxlight{this, "maxlight", 0, &worldspawn_group},
minlight_color{this, {"minlight_color", "mincolor"}, 255.0, 255.0, 255.0, &worldspawn_group},
spotlightautofalloff{this, "spotlightautofalloff", false, &worldspawn_group},
compilerstyle_start{this, "compilerstyle_start", 32, &worldspawn_group},
@ -1119,6 +1119,12 @@ static void LoadExtendedTexinfoFlags(const fs::path &sourcefilename, const mbsp_
if (val.contains("surflight_rescale")) {
flags.surflight_rescale = val.at("surflight_rescale").get<bool>();
}
if (val.contains("surflight_color")) {
flags.surflight_color = val.at("surflight_color").get<qvec3b>();
}
if (val.contains("surflight_minlight_scale")) {
flags.surflight_minlight_scale = val.at("surflight_minlight_scale").get<vec_t>();
}
if (val.contains("phong_angle")) {
flags.phong_angle = val.at("phong_angle").get<vec_t>();
}

View File

@ -3239,7 +3239,7 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::
if (auto value = IsSurfaceLitFace(bsp, face)) {
auto *entity = std::get<3>(value.value());
float surface_minlight_scale = entity ? entity->surface_minlight_scale.value() : 64.f;
float surface_minlight_scale = entity ? entity->surflight_minlight_scale.value() : 64.f;
surface_minlight_scale *= lightsurf.surflight_minlight_scale;
minlight = std::get<0>(value.value()) * surface_minlight_scale;
minlight_color = std::get<2>(value.value());

View File

@ -83,15 +83,19 @@ static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys
// Calculate emit color and intensity...
// Handle arghrad sky light settings http://www.bspquakeeditor.com/arghrad/sunlight.html#sky
if (!texture_color.has_value()) {
if (cfg.sky_surface.isChanged() && is_sky) {
// FIXME: this only handles the "_sky_surface" "red green blue" format.
// There are other more complex variants we could handle documented in the link above.
// FIXME: we require value to be nonzero, see the check above - not sure if this matches arghrad
texture_color = cfg.sky_surface.value() * 255.0;
} else {
texture_color = qvec3f(Face_LookupTextureColor(bsp, face));
if (extended_flags.surflight_color.has_value()) {
texture_color = extended_flags.surflight_color.value();
} else {
// Handle arghrad sky light settings http://www.bspquakeeditor.com/arghrad/sunlight.html#sky
if (!texture_color.has_value()) {
if (cfg.sky_surface.isChanged() && is_sky) {
// FIXME: this only handles the "_sky_surface" "red green blue" format.
// There are other more complex variants we could handle documented in the link above.
// FIXME: we require value to be nonzero, see the check above - not sure if this matches arghrad
texture_color = cfg.sky_surface.value() * 255.0;
} else {
texture_color = qvec3f(Face_LookupTextureColor(bsp, face));
}
}
}
@ -118,6 +122,7 @@ static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys
l.points = std::move(points);
l.style = style;
l.rescale = extended_flags.surflight_rescale;
l.minlight_scale = extended_flags.surflight_minlight_scale;
// Init bbox...
if (light_options.visapprox.value() == visapprox_t::RAYS) {

View File

@ -619,6 +619,15 @@ static surfflags_t SurfFlagsForEntity(
flags.light_ignore = true;
if (entity.epairs.has("_surflight_rescale") && entity.epairs.get_int("_surflight_rescale") == 0)
flags.surflight_rescale = false;
{
qvec3d color;
// FIXME: get_color, to match settings
if (entity.epairs.has("_surflight_color") && entity.epairs.get_vector("_surflight_color", color) == 3) {
flags.surflight_color = qvec3b{ (uint8_t) (color[0] * 255), (uint8_t) (color[1] * 255), (uint8_t) (color[2] * 255) };
}
}
if (entity.epairs.has("_surflight_minlight_scale"))
flags.surflight_minlight_scale = entity.epairs.get_float("_surflight_minlight_scale");
// "_minlight_exclude", "_minlight_exclude2", "_minlight_exclude3"...
for (int i = 0; i <= 9; i++) {
@ -715,10 +724,6 @@ static surfflags_t SurfFlagsForEntity(
flags.object_channel_mask = entity.epairs.get_int("_object_channel_mask");
}
if (entity.epairs.has("_surflight_minlight_scale")) {
flags.surflight_minlight_scale = entity.epairs.get_float("_surflight_minlight_scale");
}
// handle "_mincolor"
{
qvec3d mincolor{};

View File

@ -384,6 +384,12 @@ static void WriteExtendedTexinfoFlags(void)
if (tx.flags.surflight_rescale == false) {
t["surflight_rescale"] = tx.flags.surflight_rescale;
}
if (tx.flags.surflight_color.has_value()) {
t["surflight_color"] = tx.flags.surflight_color.value();
}
if (tx.flags.surflight_minlight_scale.has_value()) {
t["surflight_minlight_scale"] = tx.flags.surflight_minlight_scale.value();
}
if (tx.flags.phong_angle) {
t["phong_angle"] = tx.flags.phong_angle;
}
@ -417,9 +423,6 @@ static void WriteExtendedTexinfoFlags(void)
if (tx.flags.object_channel_mask) {
t["object_channel_mask"] = *tx.flags.object_channel_mask;
}
if (tx.flags.surflight_minlight_scale) {
t["surflight_minlight_scale"] = *tx.flags.surflight_minlight_scale;
}
texinfofile[std::to_string(*tx.outputnum)].swap(t);
}