mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-29 04:37:30 +01:00
Light the occupied cab with the light points of its model
This commit is contained in:
@@ -173,14 +173,13 @@ scales can also be changed in the **Light clusters** debug window.
|
||||
light of the whole cab and weakened the shadows of the sun in it; now a share of that ambient light is kept for the light
|
||||
which bounces around the cab (`gfx.lights.cab.bounce`), and the sun shadows stay. With the probe of the cab (below) the
|
||||
light which bounces comes from the probe instead and nothing of the lamp is kept in the ambient light.
|
||||
- **Lights of the cab model.** Light points (`FreeSpotLight`) of the cab model whose names start with `cablight` (any case)
|
||||
are the lamps of the cab: they shine with its lamp switch (off, dimmed, half bright without 110 V), in place of the lamp
|
||||
under the top of the cab, which a cab model gets only when it has no `cablight` of its own. Those whose names start with
|
||||
`dashboardlight` are the lights of the desk: they shine with the dashboard light (`i-dashboardlight:` /
|
||||
`dashboardlight_sw:`). Their colour, power, cone and the optional `Radius:`/`SoftFalloff:`/`CastShadows:` are those of the
|
||||
light point (brightness `gfx.lights.freespot.intensity`, the self-illumination threshold doesn't matter), and they fade
|
||||
in the daylight as the cab lamp does. Visibility counts: a light point under a submodel that is hidden doesn't shine.
|
||||
Other light points of the cab only glare, as before.
|
||||
- **Lights of the cab model.** Every light point (`FreeSpotLight`) of the cab model lights the cab, in place of the lamp
|
||||
under the top of the cab, which a cab model gets only when it has no light points at all. They are switched by the
|
||||
visibility of the submodels they are children of: under the submodel of `i-cablight:` a light point shines with the
|
||||
lamp of the cab, under `i-dashboardlight:` with the dashboard light, and so on (one not under any switched submodel
|
||||
shines always). Their colour, power, cone and the optional `Radius:`/`SoftFalloff:`/`CastShadows:` are those of the light
|
||||
point (brightness `gfx.lights.freespot.intensity`, the self-illumination threshold doesn't matter), and they fade in the
|
||||
daylight as the cab lamp does. The dimming of the cab lamp applies only to the lamp under the top.
|
||||
|
||||
The lamps of models and compartments fade in from the light level at which scenery lamps switch on (`ls_Dark`) to full
|
||||
darkness; in daylight they are not gathered at all. The cab lamp and the lamps of scenery models nearest to the camera cast
|
||||
@@ -248,7 +247,7 @@ shadows of the sun, see `headlight shadows:` in Shift+F12); with the vehicle on
|
||||
| `gfx.lights.cab.bounce` | `0.3` | 0..1: share of the former ambient light of the cab lamp kept with the lamp on |
|
||||
| `gfx.lights.range` | `300` | distance from the camera the lamps of models and vehicles are gathered from, metres |
|
||||
| `gfx.lights.shadows` | `medium` | `no`/`low`/`medium`/`high` (or 0..3): shadows of the cab lamp and the scenery lamps, see above |
|
||||
| `gfx.lights.shadows.cab` | `4` | 0..8: how many lights of the cab (the brightest; the lamp, `cablight`/`dashboardlight` light points) cast the shadows of the cab, a cube map each; 0: none |
|
||||
| `gfx.lights.shadows.cab` | `4` | 0..8: how many lights of the cab (the brightest; the lamp or the light points of the cab model) cast the shadows of the cab, a cube map each; 0: none |
|
||||
| `gfx.lights.shadows.lamps` | `8` | 0..32: how many scenery lamps nearest to the camera cast shadows; 0: none |
|
||||
| `gfx.lights.shadows.lamps.size` | `512` | 128..2048: size of a face of the shadow map of a scenery lamp |
|
||||
| `gfx.lights.shadows.lamps.range` | `100` | distance from the camera within which scenery lamps cast shadows, metres |
|
||||
|
||||
@@ -13,10 +13,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <string_view>
|
||||
|
||||
#include "utilities/Globals.h"
|
||||
#include "rendering/common/skyocclusion.h"
|
||||
@@ -42,18 +40,6 @@ float const LIGHT_DUSK_LUMINANCE{0.325f};
|
||||
float const LIGHT_DAY_LUMINANCE{1.0f};
|
||||
// lights of the occupied cab, at most
|
||||
std::size_t const CAB_LIGHTS_MAX{16};
|
||||
// kinds of the light points of a cab model, by the start of their names (any case): the lamps of the cab and the lights of the desk
|
||||
std::uint8_t const CAB_LIGHT_LAMP{0x1};
|
||||
std::uint8_t const CAB_LIGHT_DASHBOARD{0x2};
|
||||
|
||||
std::uint8_t cab_light_kind(std::string const &Name)
|
||||
{
|
||||
auto const starts = [&Name](std::string_view const Prefix) {
|
||||
return (Name.size() >= Prefix.size()) &&
|
||||
std::equal(std::begin(Prefix), std::end(Prefix), std::begin(Name), [](char const Left, char const Right) { return Left == static_cast<char>(std::tolower(static_cast<unsigned char>(Right))); });
|
||||
};
|
||||
return starts("cablight") ? CAB_LIGHT_LAMP : starts("dashboardlight") ? CAB_LIGHT_DASHBOARD : 0;
|
||||
}
|
||||
|
||||
glm::vec3 to_linear(glm::vec3 const &Color)
|
||||
{
|
||||
@@ -209,7 +195,6 @@ void gfx::local_lights::reset()
|
||||
m_cablights.clear();
|
||||
m_cablampon = false;
|
||||
m_modellights.clear();
|
||||
m_cabkinds.clear();
|
||||
m_cells.clear();
|
||||
m_sections.clear();
|
||||
m_models.clear();
|
||||
@@ -341,25 +326,21 @@ void gfx::local_lights::gather_cab_lights(gfx::geometrybank_manager const &Geome
|
||||
{
|
||||
return;
|
||||
}
|
||||
// as bright as the ambient light the lamp used to add to the cab: lost in the daylight. the lamps of the cab at the level of
|
||||
// their switch (off, dimmed, with or without the 110 V), the lights of the desk with the dashboard light (i-dashboardlight:)
|
||||
// as bright as the ambient light the lamp used to add to the cab: lost in the daylight
|
||||
auto const luminance{Global.fLuminance * gfx::vehicle_light_level(vehicle)};
|
||||
auto const daylight{std::clamp(1.25f - static_cast<float>(luminance), 0.f, 1.f)};
|
||||
auto const cablevel{std::max(vehicle->InteriorLightLevel, 0.f) * daylight};
|
||||
auto const dashboardlevel{(train->btDashboardLight.GetValue() ? 1.f : 0.f) * daylight};
|
||||
auto const kinds{cab_light_kinds(vehicle->mdKabina)};
|
||||
auto const lightpoints{has_light_points(vehicle->mdKabina)};
|
||||
|
||||
if ((kinds != 0) && ((cablevel > 0.f) || (dashboardlevel > 0.f)))
|
||||
if (lightpoints && (daylight > 0.f))
|
||||
{
|
||||
// the light points of the cab model, in its space, the way Render_cab() sets it up
|
||||
// the light points of the cab model, in its space, the way Render_cab() sets it up. they are switched by the visibility of
|
||||
// the submodels they're in (the lamp of the cab under i-cablight:, the lights of the desk under i-dashboardlight:, ...)
|
||||
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>(vehicle);
|
||||
TSubModel::iVariantSeed = vehicle->variant_seed();
|
||||
TSubModel::fSquareDist = 0.f;
|
||||
auto const count{m_lights.size()};
|
||||
m_walkcab = true;
|
||||
m_walkcablevel = cablevel;
|
||||
m_walkdashboardlevel = dashboardlevel;
|
||||
walk(vehicle->mdKabina->Root, glm::mat4{1.f}, glm::dmat4{1.0}, Global.gfx_lights_freespot_intensity);
|
||||
walk(vehicle->mdKabina->Root, glm::mat4{1.f}, glm::dmat4{1.0}, Global.gfx_lights_freespot_intensity * daylight);
|
||||
m_walkcab = false;
|
||||
// within the cab: without shadows (gfx.lights.shadows) the light goes through its walls
|
||||
auto const reach{std::max(2.f * glm::length(bounds.extent), 2.5f)};
|
||||
@@ -378,8 +359,10 @@ void gfx::local_lights::gather_cab_lights(gfx::geometrybank_manager const &Geome
|
||||
m_lights.resize(count);
|
||||
}
|
||||
|
||||
// the lamp of a cab model without lamps of its own: under the ceiling, in the middle of the cab
|
||||
if (((kinds & CAB_LIGHT_LAMP) == 0) && (cablevel > 0.f))
|
||||
// the lamp of a cab model without light points of its own: under the ceiling, in the middle of the cab, at the level of its
|
||||
// switch (off, dimmed, with or without the 110 V)
|
||||
auto const cablevel{std::max(vehicle->InteriorLightLevel, 0.f) * daylight};
|
||||
if ((false == lightpoints) && (cablevel > 0.f))
|
||||
{
|
||||
auto const lamp{glm::vec3{bounds.center.x, std::max(bounds.center.y, bounds.center.y + bounds.extent.y - 0.25f), bounds.center.z}};
|
||||
cab_light cablight;
|
||||
@@ -441,10 +424,8 @@ void gfx::local_lights::add_light_point(TSubModel const &Submodel, glm::mat4 con
|
||||
{
|
||||
if (m_walkcab)
|
||||
{
|
||||
// the lights of the cab: with their switches, whatever the self-illumination threshold. other light points of the cab only glare
|
||||
auto const kind{cab_light_kind(Submodel.pName)};
|
||||
Brightness *= (kind == CAB_LIGHT_LAMP ? m_walkcablevel : kind == CAB_LIGHT_DASHBOARD ? m_walkdashboardlevel : 0.f);
|
||||
if ((Brightness <= 0.f) || (Submodel.f4Emision.a <= 0.f) || (Submodel.fVisible <= 0.f))
|
||||
// the lights of the cab: switched with the submodels they're in, whatever the self-illumination threshold
|
||||
if ((Submodel.f4Emision.a <= 0.f) || (Submodel.fVisible <= 0.f))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -520,35 +501,6 @@ bool gfx::local_lights::has_light_points(TModel3d *Model)
|
||||
return found;
|
||||
}
|
||||
|
||||
std::uint8_t gfx::local_lights::cab_light_kinds(TModel3d *Model)
|
||||
{
|
||||
auto lookup{m_cabkinds.find(Model)};
|
||||
if (lookup != m_cabkinds.end())
|
||||
{
|
||||
return lookup->second;
|
||||
}
|
||||
std::uint8_t kinds{0};
|
||||
std::vector<TSubModel const *> pending{Model->Root};
|
||||
while (false == pending.empty())
|
||||
{
|
||||
auto const *submodel{pending.back()};
|
||||
pending.pop_back();
|
||||
for (; submodel != nullptr; submodel = submodel->Next)
|
||||
{
|
||||
if (submodel->eType == TP_FREESPOTLIGHT)
|
||||
{
|
||||
kinds |= cab_light_kind(submodel->pName);
|
||||
}
|
||||
if (submodel->Child != nullptr)
|
||||
{
|
||||
pending.emplace_back(submodel->Child);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_cabkinds.emplace(Model, kinds);
|
||||
return kinds;
|
||||
}
|
||||
|
||||
gfx::local_lights::cell_data const &gfx::local_lights::cell_instances(scene::basic_cell &Cell, bool const Rebuild)
|
||||
{
|
||||
// light points are drawn in the translucent phase, so the instances which have them are on the translucent list of the cell
|
||||
@@ -636,7 +588,7 @@ void gfx::local_lights::draw_debug_ui()
|
||||
ImGui::TextUnformatted("local lights (need clustered lights)");
|
||||
ImGui::Checkbox("light points of scenery models", &Global.gfx_lights_scenery);
|
||||
ImGui::Checkbox("light points and compartments of vehicles", &Global.gfx_lights_vehicles);
|
||||
ImGui::Checkbox("cab lamp as a light (cablight... / dashboardlight... light points of the cab)", &Global.gfx_lights_cab);
|
||||
ImGui::Checkbox("cab lamp as a light (or the light points of the cab model)", &Global.gfx_lights_cab);
|
||||
ImGui::SliderFloat("light point brightness", &Global.gfx_lights_freespot_intensity, 0.f, 50.f);
|
||||
ImGui::SliderFloat("compartment brightness", &Global.gfx_lights_compartment_intensity, 0.f, 10.f);
|
||||
ImGui::SliderFloat("cab lamp brightness", &Global.gfx_lights_cab_intensity, 0.f, 10.f);
|
||||
|
||||
@@ -34,9 +34,9 @@ class TDynamicObject;
|
||||
// light along the -z axis of its submodel, with the cone of its glare. lamps of scenery models switched with Light_On / Light_Off
|
||||
// and the self-illumination of vehicle compartments (TDynamicObject::Sections) work through the same state
|
||||
// - the lit compartments of vehicles (low poly interior sections) without light points of their own: a point light in the middle
|
||||
// - the lights of the occupied cab, in place of the ambient light its lamp used to add: the light points of the cab model (mdKabina)
|
||||
// named cablight... (the lamps of the cab, switched and dimmed with them) and dashboardlight... (the lights of the desk, switched
|
||||
// with the dashboard light, i-dashboardlight:). a cab model without any cablight... gets a point light under its top instead
|
||||
// - the lights of the occupied cab, in place of the ambient light its lamp used to add: the light points of the cab model (mdKabina),
|
||||
// any of them, switched by the visibility of the submodels they're in (children of i-cablight:, i-dashboardlight: ...). a cab
|
||||
// model without light points gets a point light under its top instead, switched and dimmed with the lamp of the cab
|
||||
// gathered once per frame around the camera, written to the light buffers by the renderers (Update_Lights())
|
||||
namespace gfx
|
||||
{
|
||||
@@ -139,8 +139,6 @@ class local_lights
|
||||
void gather_vehicle(TDynamicObject *Vehicle, glm::dvec3 const &Camera, gfx::geometrybank_manager const &Geometry, float const Freespotbrightness, float const Compartmentbrightness);
|
||||
void gather_cab_lights(gfx::geometrybank_manager const &Geometry);
|
||||
bool has_light_points(TModel3d *Model);
|
||||
// the kinds of the light points of a cab model by their names, CAB_LIGHT_LAMP | CAB_LIGHT_DASHBOARD (locallights.cpp)
|
||||
std::uint8_t cab_light_kinds(TModel3d *Model);
|
||||
cell_data const &cell_instances(scene::basic_cell &Cell, bool const Rebuild);
|
||||
section_data const §ion(TModel3d *Model, TSubModel *Section, gfx::geometrybank_manager const &Geometry);
|
||||
section_data const &model_bounds(TModel3d *Model, gfx::geometrybank_manager const &Geometry);
|
||||
@@ -149,13 +147,9 @@ class local_lights
|
||||
std::vector<cab_light> m_cablights;
|
||||
bool m_cablampon{false};
|
||||
TDynamicObject const *m_cablampvehicle{nullptr};
|
||||
// walk() goes through the cab model: only its light points of the cab and of the desk, at these levels (0-1) of their switches,
|
||||
// whatever the self-illumination threshold
|
||||
// walk() goes through the cab model: its light points shine while they're visible, whatever the self-illumination threshold
|
||||
bool m_walkcab{false};
|
||||
float m_walkcablevel{0.f};
|
||||
float m_walkdashboardlevel{0.f};
|
||||
std::unordered_map<TModel3d const *, bool> m_modellights; // whether the model has light points
|
||||
std::unordered_map<TModel3d const *, std::uint8_t> m_cabkinds; // the kinds of light points of cab models
|
||||
std::unordered_map<scene::basic_cell const *, cell_data> m_cells;
|
||||
std::unordered_map<TSubModel const *, section_data> m_sections; // compartments, by their submodel
|
||||
std::unordered_map<TModel3d const *, section_data> m_models; // bounds of cab models
|
||||
|
||||
Reference in New Issue
Block a user