17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-06 08:08:36 +01:00

Add the optional LightOnly of FreeSpotLight

This commit is contained in:
2026-10-28 21:50:08 +01:00
parent 8c6a47f42c
commit 91c6324965
4 changed files with 14 additions and 3 deletions

View File

@@ -180,6 +180,9 @@ scales can also be changed in the **Light clusters** debug window.
shines always). Their colour, power, cone and the optional `Radius:`/`SoftFalloff:`/`CastShadows:` are those of the light 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 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. daylight as the cab lamp does. The dimming of the cab lamp applies only to the lamp under the top.
- **`LightOnly: true`** (an optional entry of any `FreeSpotLight`, after `HotspotAngle:` with the others; in e3d the flag 0x8
after the radius) makes the light point only a light: it lights its surroundings, but its glowing point and its glare,
seen from afar, aren't drawn. For lights hidden in fittings, the backlight of a desk and the like.
The lamps of models and compartments fade in from the light level at which scenery lamps switch on (`ls_Dark`) to full 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 darkness; in daylight they are not gathered at all. The cab lamp and the lamps of scenery models nearest to the camera cast

View File

@@ -227,6 +227,7 @@ inline void readMatrix(cParser &parser, float4x4 &matrix)
static constexpr std::uint32_t E3D_LIGHT_SHADESELF{0x1}; static constexpr std::uint32_t E3D_LIGHT_SHADESELF{0x1};
static constexpr std::uint32_t E3D_LIGHT_NOSHADOWS{0x2}; static constexpr std::uint32_t E3D_LIGHT_NOSHADOWS{0x2};
static constexpr std::uint32_t E3D_LIGHT_SOFTFALLOFF{0x4}; static constexpr std::uint32_t E3D_LIGHT_SOFTFALLOFF{0x4};
static constexpr std::uint32_t E3D_LIGHT_LIGHTONLY{0x8};
// a light point whose cone takes the whole sphere (FalloffAngle 360) is a point light: it shines and is seen all around // a light point whose cone takes the whole sphere (FalloffAngle 360) is a point light: it shines and is seen all around
static void point_light_cones(float &Falloff, float &Hotspot) static void point_light_cones(float &Falloff, float &Hotspot)
@@ -377,7 +378,7 @@ std::pair<int, int> TSubModel::Load(cParser &parser, bool dynamic)
>> discard >> fCosHotspotAngle; // kąt liczony dla średnicy, a nie promienia >> discard >> fCosHotspotAngle; // kąt liczony dla średnicy, a nie promienia
// opcjonalne parametry, każdy to nazwa i wartość, w dowolnej kolejności: natężenie światła w procentach (hotspotpower:), // opcjonalne parametry, każdy to nazwa i wartość, w dowolnej kolejności: natężenie światła w procentach (hotspotpower:),
// promień kuli świecącej (radius:), cienie od własnego modelu (shadeself:), rzucanie cieni (castshadows:), spadek natężenia // promień kuli świecącej (radius:), cienie od własnego modelu (shadeself:), rzucanie cieni (castshadows:), spadek natężenia
// jak przy soft falloff blendera (softfalloff:). trzeba pobrać do kolejki 2 tokeny; jeśli to nie żaden z nich, zostają w // jak przy soft falloff blendera (softfalloff:), samo oświetlenie bez punktu i poświaty (lightonly:). trzeba pobrać do kolejki 2 tokeny; jeśli to nie żaden z nich, zostają w
// kolejce dla odczytu zasięgu widoczności, który przywraca autoclear // kolejce dla odczytu zasięgu widoczności, który przywraca autoclear
while (true) while (true)
{ {
@@ -421,6 +422,10 @@ std::pair<int, int> TSubModel::Load(cParser &parser, bool dynamic)
{ {
parser >> discard >> bSoftFalloff; parser >> discard >> bSoftFalloff;
} }
else if (key == "lightonly:")
{
parser >> discard >> bLightOnly;
}
else else
{ {
parser.autoclear(false); parser.autoclear(false);
@@ -1976,7 +1981,7 @@ void TSubModel::serialize(std::ostream &s, std::vector<TSubModel *> &models, std
sn_utils::ls_float32(s, fHotspotPower); sn_utils::ls_float32(s, fHotspotPower);
// the optional parameters of light points. the zeros of the fill of older files are their defaults // the optional parameters of light points. the zeros of the fill of older files are their defaults
sn_utils::ls_float32(s, fLightRadius); sn_utils::ls_float32(s, fLightRadius);
sn_utils::ls_uint32(s, (bShadeSelf ? E3D_LIGHT_SHADESELF : 0u) | (bCastShadows ? 0u : E3D_LIGHT_NOSHADOWS) | (bSoftFalloff ? E3D_LIGHT_SOFTFALLOFF : 0u)); sn_utils::ls_uint32(s, (bShadeSelf ? E3D_LIGHT_SHADESELF : 0u) | (bCastShadows ? 0u : E3D_LIGHT_NOSHADOWS) | (bSoftFalloff ? E3D_LIGHT_SOFTFALLOFF : 0u) | (bLightOnly ? E3D_LIGHT_LIGHTONLY : 0u));
// fill empty space // fill empty space
size_t fill = end - s.tellp(); size_t fill = end - s.tellp();
@@ -2164,6 +2169,7 @@ void TSubModel::deserialize(std::istream &s)
bShadeSelf = (lightflags & E3D_LIGHT_SHADESELF) != 0; bShadeSelf = (lightflags & E3D_LIGHT_SHADESELF) != 0;
bCastShadows = (lightflags & E3D_LIGHT_NOSHADOWS) == 0; bCastShadows = (lightflags & E3D_LIGHT_NOSHADOWS) == 0;
bSoftFalloff = (lightflags & E3D_LIGHT_SOFTFALLOFF) != 0; bSoftFalloff = (lightflags & E3D_LIGHT_SOFTFALLOFF) != 0;
bLightOnly = (lightflags & E3D_LIGHT_LIGHTONLY) != 0;
// necessary rotations were already done during t3d->e3d conversion // necessary rotations were already done during t3d->e3d conversion
m_rotation_init_done = true; m_rotation_init_done = true;

View File

@@ -132,6 +132,7 @@ public:
bool bShadeSelf { false }; // cienie światła rzuca także model, do którego ono należy (shadeself:) bool bShadeSelf { false }; // cienie światła rzuca także model, do którego ono należy (shadeself:)
bool bCastShadows { true }; // światło rzuca cienie (castshadows:) bool bCastShadows { true }; // światło rzuca cienie (castshadows:)
bool bSoftFalloff { false }; // natężenie maleje jak 1 / (d^2 + r^2), jak przy soft falloff blendera, zamiast świecenia z powierzchni kuli (softfalloff:) bool bSoftFalloff { false }; // natężenie maleje jak 1 / (d^2 + r^2), jak przy soft falloff blendera, zamiast świecenia z powierzchni kuli (softfalloff:)
bool bLightOnly { false }; // tylko oświetlenie: bez świecącego punktu i poświaty, widocznych z daleka (lightonly:)
float fCosViewAngle { 0.0f }; // cos kata pod jakim sie teraz patrzy float fCosViewAngle { 0.0f }; // cos kata pod jakim sie teraz patrzy
bool m_rotation_init_done = false; bool m_rotation_init_done = false;

View File

@@ -3073,8 +3073,9 @@ void scene_walk::Render_Alpha(TSubModel *Submodel)
} }
} }
} }
else if (Submodel->eType == TP_FREESPOTLIGHT) else if ((Submodel->eType == TP_FREESPOTLIGHT) && (false == Submodel->bLightOnly))
{ {
// the point of the light and its glare; a light point marked lightonly: only lights its surroundings (gfx::local_lights)
// NOTE: we're forced here to redo view angle calculations etc, because this data isn't instanced but stored along with the single mesh // NOTE: we're forced here to redo view angle calculations etc, because this data isn't instanced but stored along with the single mesh
// TODO: separate instance data from reusable geometry // TODO: separate instance data from reusable geometry
auto const &modelview = OpenGLMatrices.data(GL_MODELVIEW); auto const &modelview = OpenGLMatrices.data(GL_MODELVIEW);