mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-24 07:39:17 +02:00
compartment lighting vehicle subsystem, submodel diffuse impact on ambient lighting, minor gfx renderer bug fixes, minor ai logic tweaks
This commit is contained in:
103
Driver.cpp
103
Driver.cpp
@@ -1721,7 +1721,7 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
|
||||
}
|
||||
|
||||
// HACK: give the simulation a small window to potentially replace the AI with a human driver
|
||||
fActionTime = -2.0;
|
||||
fActionTime = -5.0;
|
||||
};
|
||||
|
||||
void TController::CloseLog()
|
||||
@@ -2229,6 +2229,11 @@ bool TController::CheckVehicles(TOrders user)
|
||||
|| ( pVehicle->NextC( coupling::control ) != nullptr ) ) {
|
||||
sync_consist_reversers();
|
||||
}
|
||||
// potentially sync compartment lighting state for the newly connected vehicles
|
||||
if( mvOccupied->CompartmentLights.start_type == start_t::manual ) {
|
||||
mvOccupied->CompartmentLightsSwitchOff( mvOccupied->CompartmentLights.is_disabled );
|
||||
mvOccupied->CompartmentLightsSwitch( mvOccupied->CompartmentLights.is_enabled );
|
||||
}
|
||||
}
|
||||
|
||||
if (AIControllFlag)
|
||||
@@ -2515,7 +2520,7 @@ void TController::SetDriverPsyche()
|
||||
bool TController::PrepareEngine()
|
||||
{ // odpalanie silnika
|
||||
// HACK: don't immediately activate inert vehicle in case the simulation is about to replace us with human driver
|
||||
if( /* ( mvOccupied->Vel < 1.0 ) && */ ( fActionTime < 0.0 ) ) { return false; }
|
||||
if( ( mvOccupied->Vel < 1.0 ) && ( fActionTime < 0.0 ) ) { return false; }
|
||||
|
||||
bool OK = false,
|
||||
voltfront = false,
|
||||
@@ -4525,6 +4530,7 @@ TController::UpdateSituation(double dt) {
|
||||
double dy; // składowa styczna grawitacji, w przedziale <0,1>
|
||||
double AbsAccS = 0;
|
||||
IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::left ] = false;
|
||||
ConsistShade = 0.0;
|
||||
TDynamicObject *p = pVehicles[0]; // pojazd na czole składu
|
||||
while (p)
|
||||
{ // sprawdzenie odhamowania wszystkich połączonych pojazdów
|
||||
@@ -4573,9 +4579,13 @@ TController::UpdateSituation(double dt) {
|
||||
IsAnyDoorOpen[ side::left ] =
|
||||
IsAnyDoorOpen[ side::left ]
|
||||
|| ( false == vehicle->Doors.instances[ ( switchsides ? side::right : side::left ) ].is_closed );
|
||||
|
||||
// measure lighting level
|
||||
// TBD: apply weight (multiplier) to partially lit vehicles?
|
||||
ConsistShade += ( p->fShade > 0.0 ? p->fShade : 1.0 );
|
||||
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
|
||||
}
|
||||
// calculate average amount of received sunlight
|
||||
ConsistShade /= iVehicles;
|
||||
|
||||
// test state of main switch in all powered vehicles under control
|
||||
IsLineBreakerClosed = ( mvOccupied->Power > 0.01 ? mvOccupied->Mains : true );
|
||||
@@ -4720,32 +4730,35 @@ TController::UpdateSituation(double dt) {
|
||||
}
|
||||
else {
|
||||
// jeśli nie trzeba opuszczać pantografów
|
||||
if( mvOccupied->AIHintPantstate == 0 ) {
|
||||
// jazda na tylnym
|
||||
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) {
|
||||
// jak jedzie w kierunku sprzęgu 0
|
||||
if( ( mvControlling->PantRearVolt == 0.0 )
|
||||
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't
|
||||
&& ( ( mvControlling->PantographVoltage == 0.0 )
|
||||
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
|
||||
mvControlling->OperatePantographValve( end::rear, operation_t::enable );
|
||||
if( fActionTime > 0.0 ) {
|
||||
if( mvOccupied->AIHintPantstate == 0 ) {
|
||||
// jazda na tylnym
|
||||
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) {
|
||||
// jak jedzie w kierunku sprzęgu 0
|
||||
if( ( mvControlling->PantRearVolt == 0.0 )
|
||||
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't
|
||||
&& ( ( mvControlling->PantographVoltage == 0.0 )
|
||||
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
|
||||
mvControlling->OperatePantographValve( end::rear, operation_t::enable );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// jak jedzie w kierunku sprzęgu 0
|
||||
if( ( mvControlling->PantFrontVolt == 0.0 )
|
||||
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't
|
||||
&& ( ( mvControlling->PantographVoltage == 0.0 )
|
||||
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
|
||||
mvControlling->OperatePantographValve( end::front, operation_t::enable );
|
||||
else {
|
||||
// jak jedzie w kierunku sprzęgu 0
|
||||
if( ( mvControlling->PantFrontVolt == 0.0 )
|
||||
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't
|
||||
&& ( ( mvControlling->PantographVoltage == 0.0 )
|
||||
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
|
||||
mvControlling->OperatePantographValve( end::front, operation_t::enable );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( mvOccupied->Vel > 5 ) {
|
||||
if( mvOccupied->AIHintPantstate != 0 ) {
|
||||
// use suggested pantograph setup
|
||||
auto const pantographsetup { mvOccupied->AIHintPantstate };
|
||||
if( fActionTime > 0.0 ) {
|
||||
if( mvOccupied->AIHintPantstate != 0 ) {
|
||||
// use suggested pantograph setup
|
||||
auto const pantographsetup{ mvOccupied->AIHintPantstate };
|
||||
mvControlling->OperatePantographValve(
|
||||
end::front,
|
||||
( pantographsetup & ( 1 << 0 ) ?
|
||||
@@ -4756,21 +4769,22 @@ TController::UpdateSituation(double dt) {
|
||||
( pantographsetup & ( 1 << 1 ) ?
|
||||
operation_t::enable :
|
||||
operation_t::disable ) );
|
||||
}
|
||||
else {
|
||||
// opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden
|
||||
if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) {
|
||||
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) // jak jedzie w kierunku sprzęgu 0
|
||||
{ // poczekać na podniesienie tylnego
|
||||
if( ( mvControlling->PantFrontVolt != 0.0 )
|
||||
&& ( mvControlling->PantRearVolt != 0.0 ) ) { // czy jest napięcie zasilające na tylnym?
|
||||
mvControlling->OperatePantographValve( end::front, operation_t::disable ); // opuszcza od sprzęgu 0
|
||||
}
|
||||
else {
|
||||
// opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden
|
||||
if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) {
|
||||
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) // jak jedzie w kierunku sprzęgu 0
|
||||
{ // poczekać na podniesienie tylnego
|
||||
if( ( mvControlling->PantFrontVolt != 0.0 )
|
||||
&& ( mvControlling->PantRearVolt != 0.0 ) ) { // czy jest napięcie zasilające na tylnym?
|
||||
mvControlling->OperatePantographValve( end::front, operation_t::disable ); // opuszcza od sprzęgu 0
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // poczekać na podniesienie przedniego
|
||||
if( ( mvControlling->PantRearVolt != 0.0 )
|
||||
&& ( mvControlling->PantFrontVolt != 0.0 ) ) { // czy jest napięcie zasilające na przednim?
|
||||
mvControlling->OperatePantographValve( end::rear, operation_t::disable ); // opuszcza od sprzęgu 1
|
||||
else { // poczekać na podniesienie przedniego
|
||||
if( ( mvControlling->PantRearVolt != 0.0 )
|
||||
&& ( mvControlling->PantFrontVolt != 0.0 ) ) { // czy jest napięcie zasilające na przednim?
|
||||
mvControlling->OperatePantographValve( end::rear, operation_t::disable ); // opuszcza od sprzęgu 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4860,6 +4874,21 @@ TController::UpdateSituation(double dt) {
|
||||
|
||||
if (AIControllFlag) {
|
||||
CheckTimeControllers();
|
||||
|
||||
// low priority operations
|
||||
// compartment lights
|
||||
if( mvOccupied->CompartmentLights.start_type == start_t::manual ) {
|
||||
auto const currentlightstate { mvOccupied->CompartmentLights.is_enabled };
|
||||
auto const lightlevel { Global.fLuminance * ConsistShade };
|
||||
auto const desiredlightstate { (
|
||||
currentlightstate ?
|
||||
lightlevel < 0.40 : // turn off if lighting level goes above 0.4
|
||||
lightlevel < 0.35 ) }; // turn on if lighting level goes below 0.35
|
||||
if( desiredlightstate != currentlightstate ) {
|
||||
mvOccupied->CompartmentLightsSwitch( desiredlightstate );
|
||||
mvOccupied->CompartmentLightsSwitchOff( !desiredlightstate );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LastReactionTime -= reactiontime;
|
||||
|
||||
1
Driver.h
1
Driver.h
@@ -466,6 +466,7 @@ private:
|
||||
bool IsLineBreakerClosed{ false }; // state of line breaker in all powered vehicles under control
|
||||
double fReady = 0.0; // poziom odhamowania wagonów
|
||||
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
||||
double ConsistShade{ 1.0 }; // averaged amount of sunlight received by the consist
|
||||
TDynamicObject *pVehicles[ 2 ]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
|
||||
bool IsAnyDoorOpen[ 2 ]; // state of door in the consist
|
||||
|
||||
|
||||
40
DynObj.cpp
40
DynObj.cpp
@@ -664,13 +664,7 @@ TDynamicObject::toggle_lights() {
|
||||
|
||||
if( true == SectionLightsActive ) {
|
||||
// switch all lights off...
|
||||
for( auto §ion : Sections ) {
|
||||
// ... but skip cab sections, their lighting ignores battery state
|
||||
auto const sectionname { section.compartment->pName };
|
||||
if( sectionname.find( "cab" ) == 0 ) { continue; }
|
||||
|
||||
section.light_level = 0.0f;
|
||||
}
|
||||
MoverParameters->BatterySwitch( false );
|
||||
SectionLightsActive = false;
|
||||
}
|
||||
else {
|
||||
@@ -690,6 +684,7 @@ TDynamicObject::toggle_lights() {
|
||||
section.light_level = ( Random() < 0.75 ? 0.75f : 0.15f );
|
||||
}
|
||||
}
|
||||
MoverParameters->BatterySwitch( true );
|
||||
SectionLightsActive = true;
|
||||
}
|
||||
}
|
||||
@@ -1092,15 +1087,20 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
}
|
||||
// interior light levels
|
||||
auto sectionlightcolor { glm::vec4( 1.f ) };
|
||||
bool cabsection{ true };
|
||||
for( auto const §ion : Sections ) {
|
||||
/*
|
||||
sectionlightcolor = glm::vec4( InteriorLight, section.light_level );
|
||||
*/
|
||||
if( cabsection ) {
|
||||
// check whether we're still processing cab sections
|
||||
auto const §ionname { section.compartment->pName };
|
||||
cabsection &= ( ( sectionname.size() >= 4 ) && ( sectionname.substr( 0, 3 ) == "cab" ) );
|
||||
}
|
||||
// TODO: add cablight devices
|
||||
auto const sectionlightlevel { section.light_level * ( cabsection ? 1.0f : MoverParameters->CompartmentLights.intensity ) };
|
||||
sectionlightcolor = glm::vec4(
|
||||
( ( ( section.light_level == 0.f ) || ( Global.fLuminance > section.compartment->fLight ) ) ?
|
||||
( ( ( sectionlightlevel == 0.f ) || ( Global.fLuminance > section.compartment->fLight ) ) ?
|
||||
glm::vec3( 240.f / 255.f ) : // TBD: save and restore initial submodel diffuse instead of enforcing one?
|
||||
InteriorLight ), // TODO: per-compartment (type) light color
|
||||
section.light_level );
|
||||
sectionlightlevel );
|
||||
section.compartment->SetLightLevel( sectionlightcolor, true );
|
||||
if( section.load != nullptr ) {
|
||||
section.load->SetLightLevel( sectionlightcolor, true );
|
||||
@@ -2069,7 +2069,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
// passenger car compartments
|
||||
std::vector<std::string> nameprefixes = { "corridor", "korytarz", "compartment", "przedzial" };
|
||||
for( auto const &nameprefix : nameprefixes ) {
|
||||
init_sections( mdLowPolyInt, nameprefix );
|
||||
init_sections( mdLowPolyInt, nameprefix, MoverParameters->CompartmentLights.start_type == start_t::manual );
|
||||
}
|
||||
}
|
||||
// destination sign
|
||||
@@ -2078,7 +2078,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
}
|
||||
// 'external_load' is an optional special section in the main model, pointing to submodel of external load
|
||||
if( mdModel ) {
|
||||
init_sections( mdModel, "external_load" );
|
||||
init_sections( mdModel, "external_load", false );
|
||||
}
|
||||
update_load_sections();
|
||||
update_load_visibility();
|
||||
@@ -2176,7 +2176,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
}
|
||||
|
||||
int
|
||||
TDynamicObject::init_sections( TModel3d const *Model, std::string const &Nameprefix ) {
|
||||
TDynamicObject::init_sections( TModel3d const *Model, std::string const &Nameprefix, bool const Overrideselfillum ) {
|
||||
|
||||
auto sectioncount = 0;
|
||||
auto sectionindex = 0;
|
||||
@@ -2192,6 +2192,10 @@ TDynamicObject::init_sections( TModel3d const *Model, std::string const &Namepre
|
||||
sectionsubmodel = Model->GetFromName( Nameprefix + "0" + sectionindexname );
|
||||
}
|
||||
if( sectionsubmodel != nullptr ) {
|
||||
// HACK: disable automatic self-illumination threshold, at least until 3d model update
|
||||
if( Overrideselfillum ) {
|
||||
sectionsubmodel->SetSelfIllum( 2.0f, true, true );
|
||||
}
|
||||
Sections.push_back( {
|
||||
sectionsubmodel,
|
||||
nullptr, // pointers to load sections are generated afterwards
|
||||
@@ -2609,6 +2613,10 @@ TDynamicObject::update_load_sections() {
|
||||
if( ( section.load != nullptr )
|
||||
&& ( section.load->count_children() > 0 ) ) {
|
||||
SectionLoadVisibility.push_back( { section.load, false } );
|
||||
// HACK: disable automatic self-illumination threshold, at least until 3d model update
|
||||
if( MoverParameters->CompartmentLights.start_type == start_t::manual ) {
|
||||
section.load->SetSelfIllum( 2.0f, true, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffle_load_sections();
|
||||
@@ -3690,7 +3698,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
// if the vehicle has a controller, we base the light state on state of the controller otherwise we check the vehicle itself
|
||||
if( ( ctOwner != nullptr ?
|
||||
ctOwner->Controlling()->Battery != SectionLightsActive :
|
||||
SectionLightsActive == true ) ) { // without controller lights are off. NOTE: this likely mess up the EMU
|
||||
MoverParameters->CompartmentLights.is_active == true ) ) { // without controller lights are off. NOTE: this likely mess up the EMU
|
||||
toggle_lights();
|
||||
}
|
||||
|
||||
|
||||
2
DynObj.h
2
DynObj.h
@@ -550,7 +550,7 @@ private:
|
||||
std::string Name, std::string BaseDir, std::string asReplacableSkin, std::string Type_Name,
|
||||
TTrack *Track, double fDist, std::string DriverType, double fVel, std::string TrainName,
|
||||
float Load, std::string LoadType, bool Reversed, std::string);
|
||||
int init_sections( TModel3d const *Model, std::string const &Nameprefix );
|
||||
int init_sections( TModel3d const *Model, std::string const &Nameprefix, bool const Overrideselfillum );
|
||||
bool init_destination( TModel3d *Model );
|
||||
void create_controller( std::string const Type, bool const Trainset );
|
||||
void AttachPrev(TDynamicObject *Object, int iType = 1);
|
||||
|
||||
8
Gauge.h
8
Gauge.h
@@ -22,10 +22,12 @@ enum class TGaugeAnimation {
|
||||
};
|
||||
|
||||
enum class TGaugeType : int {
|
||||
toggle = 1,
|
||||
push = 2,
|
||||
toggle = 1 << 0,
|
||||
push = 1 << 1,
|
||||
delayed = 1 << 2,
|
||||
pushtoggle = ( toggle | push ),
|
||||
push_delayed
|
||||
push_delayed = ( push | delayed ),
|
||||
pushtoggle_delayed = ( toggle | push | delayed )
|
||||
};
|
||||
|
||||
// animowany wskaźnik, mogący przyjmować wiele stanów pośrednich
|
||||
|
||||
@@ -756,6 +756,13 @@ private:
|
||||
bool is_active { false }; // device is working
|
||||
};
|
||||
|
||||
struct basic_light : public basic_device {
|
||||
// config
|
||||
float dimming { 1.0f }; // light strength multiplier
|
||||
// ld outputs
|
||||
float intensity { 0.0f }; // current light strength
|
||||
};
|
||||
|
||||
struct cooling_fan : public basic_device {
|
||||
// config
|
||||
float speed { 0.f }; // cooling fan rpm; either fraction of parent rpm, or absolute value if negative
|
||||
@@ -1315,6 +1322,11 @@ public:
|
||||
bool CompressorTankValve{ false }; // indicates excessive pressure is vented from compressor tank directly and instantly
|
||||
start_t CompressorStart{ start_t::manual }; // whether the compressor is started manually, or another way
|
||||
start_t PantographCompressorStart{ start_t::manual };
|
||||
basic_valve PantsValve;
|
||||
std::array<basic_pantograph, 2> Pantographs;
|
||||
bool PantAllDown { false };
|
||||
double PantFrontVolt = 0.0; //pantograf pod napieciem? 'Winger 160404
|
||||
double PantRearVolt = 0.0;
|
||||
// TODO converter parameters, for when we start cleaning up mover parameters
|
||||
start_t ConverterStart{ start_t::manual }; // whether converter is started manually, or by other means
|
||||
float ConverterStartDelay{ 0.0f }; // delay (in seconds) before the converter is started, once its activation conditions are met
|
||||
@@ -1506,11 +1518,6 @@ public:
|
||||
bool DoorRightOpened = false;
|
||||
double DoorRightOpenTimer{ -1.0 }; // right door closing timer for automatic door type
|
||||
#endif
|
||||
basic_valve PantsValve;
|
||||
std::array<basic_pantograph, 2> Pantographs;
|
||||
bool PantAllDown { false };
|
||||
double PantFrontVolt = 0.0; //pantograf pod napieciem? 'Winger 160404
|
||||
double PantRearVolt = 0.0;
|
||||
// TODO: move these switch types where they belong, cabin definition
|
||||
std::string PantSwitchType;
|
||||
std::string ConvSwitchType;
|
||||
@@ -1519,6 +1526,7 @@ public:
|
||||
bool Heating = false; //ogrzewanie 'Winger 020304
|
||||
bool HeatingAllow { false }; // heating switch // TODO: wrap heating in a basic device
|
||||
int DoubleTr = 1; //trakcja ukrotniona - przedni pojazd 'Winger 160304
|
||||
basic_light CompartmentLights;
|
||||
|
||||
bool PhysicActivation = true;
|
||||
|
||||
@@ -1674,6 +1682,8 @@ public:
|
||||
bool OilPumpSwitchOff( bool State, range_t const Notify = range_t::consist ); // oil pump state toggle
|
||||
bool MotorBlowersSwitch( bool State, end const Side, range_t const Notify = range_t::consist ); // traction motor fan state toggle
|
||||
bool MotorBlowersSwitchOff( bool State, end const Side, range_t const Notify = range_t::consist ); // traction motor fan state toggle
|
||||
bool CompartmentLightsSwitch( bool State, range_t const Notify = range_t::consist ); // compartment lights state toggle
|
||||
bool CompartmentLightsSwitchOff( bool State, range_t const Notify = range_t::consist ); // compartment lights state toggle
|
||||
bool MainSwitch( bool const State, range_t const Notify = range_t::consist );/*! wylacznik glowny*/
|
||||
void MainSwitch_( bool const State );
|
||||
bool ConverterSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl przetwornicy*/
|
||||
@@ -1691,6 +1701,7 @@ public:
|
||||
void OilPumpCheck( double const Timestep );
|
||||
void MotorBlowersCheck( double const Timestep );
|
||||
void PantographsCheck( double const Timestep );
|
||||
void LightsCheck( double const Timestep );
|
||||
bool FuseOn(void); //bezpiecznik nadamiary
|
||||
bool FuseFlagCheck(void) const; // sprawdzanie flagi nadmiarowego
|
||||
void FuseOff(void); // wylaczenie nadmiarowego
|
||||
|
||||
@@ -1439,6 +1439,8 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
|
||||
}
|
||||
// heating
|
||||
HeatingCheck( Deltatime );
|
||||
// lighting
|
||||
LightsCheck( Deltatime );
|
||||
|
||||
UpdateBrakePressure(Deltatime);
|
||||
UpdatePipePressure(Deltatime);
|
||||
@@ -1902,6 +1904,35 @@ void TMoverParameters::PantographsCheck( double const Timestep ) {
|
||||
}
|
||||
}
|
||||
|
||||
void TMoverParameters::LightsCheck( double const Timestep ) {
|
||||
|
||||
auto const lowvoltagepower { (
|
||||
( ConverterFlag )
|
||||
|| ( ( ( Couplers[ end::front ].CouplingFlag & coupling::permanent ) != 0 ) && ( Couplers[ end::front ].Connected->ConverterFlag ) )
|
||||
|| ( ( ( Couplers[ end::rear ].CouplingFlag & coupling::permanent ) != 0 ) && ( Couplers[ end::rear ].Connected->ConverterFlag ) ) ) };
|
||||
|
||||
auto &light { CompartmentLights };
|
||||
|
||||
light.is_active = (
|
||||
// TODO: bind properly power source when ld is in place
|
||||
( Battery || lowvoltagepower ) // power source
|
||||
&& ( false == light.is_disabled )
|
||||
&& ( ( true == light.is_active )
|
||||
|| ( light.start_type == start_t::manual ?
|
||||
light.is_enabled :
|
||||
true ) ) );
|
||||
|
||||
light.intensity =
|
||||
( light.is_active ?
|
||||
1.0f :
|
||||
0.0f )
|
||||
// TODO: bind properly power source when ld is in place
|
||||
* ( lowvoltagepower ? 1.0f :
|
||||
Battery ? 0.5f :
|
||||
0.0f )
|
||||
* light.dimming;
|
||||
}
|
||||
|
||||
double TMoverParameters::ShowCurrent(int AmpN) const
|
||||
{ // Odczyt poboru prądu na podanym amperomierzu
|
||||
switch (EngineType)
|
||||
@@ -3151,6 +3182,55 @@ bool TMoverParameters::MotorBlowersSwitchOff( bool State, end const Side, range_
|
||||
return ( fan.is_disabled != initialstate );
|
||||
}
|
||||
|
||||
bool TMoverParameters::CompartmentLightsSwitch( bool State, range_t const Notify ) {
|
||||
|
||||
if( CompartmentLights.start_type == start_t::automatic ) {
|
||||
// automatic lights ignore 'manual' state commands
|
||||
return false;
|
||||
}
|
||||
|
||||
bool const initialstate { CompartmentLights.is_enabled };
|
||||
|
||||
CompartmentLights.is_enabled = State;
|
||||
|
||||
if( Notify != range_t::local ) {
|
||||
SendCtrlToNext(
|
||||
"CompartmentLightsSwitch",
|
||||
( CompartmentLights.is_enabled ? 1 : 0 ),
|
||||
CabActive,
|
||||
( Notify == range_t::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
}
|
||||
|
||||
return ( CompartmentLights.is_enabled != initialstate );
|
||||
}
|
||||
|
||||
// water pump state toggle
|
||||
bool TMoverParameters::CompartmentLightsSwitchOff( bool State, range_t const Notify ) {
|
||||
|
||||
if( CompartmentLights.start_type == start_t::automatic ) {
|
||||
// automatic lights ignore 'manual' state commands
|
||||
return false;
|
||||
}
|
||||
|
||||
bool const initialstate { CompartmentLights.is_disabled };
|
||||
|
||||
CompartmentLights.is_disabled = State;
|
||||
|
||||
if( Notify != range_t::local ) {
|
||||
SendCtrlToNext(
|
||||
"CompartmentLightsSwitchOff",
|
||||
( CompartmentLights.is_disabled ? 1 : 0 ),
|
||||
CabActive,
|
||||
( Notify == range_t::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
}
|
||||
|
||||
return ( CompartmentLights.is_disabled != initialstate );
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Q: 20160713
|
||||
// włączenie / wyłączenie obwodu głownego
|
||||
@@ -9758,6 +9838,15 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
||||
lookup->second :
|
||||
start_t::manual;
|
||||
}
|
||||
// compartment lights
|
||||
{
|
||||
auto lookup = starts.find( extract_value( "CompartmentLightsStart", line ) );
|
||||
CompartmentLights.start_type =
|
||||
lookup != starts.end() ?
|
||||
lookup->second :
|
||||
start_t::automatic;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_Blending(std::string const &line) {
|
||||
@@ -11042,6 +11131,22 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
||||
}
|
||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||
}
|
||||
else if( Command == "CompartmentLightsSwitch" ) {
|
||||
|
||||
if( CompartmentLights.start_type != start_t::automatic ) {
|
||||
// automatic lights ignore 'manual' state commands
|
||||
CompartmentLights.is_enabled = ( CValue1 == 1 );
|
||||
}
|
||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||
}
|
||||
else if( Command == "CompartmentLightsSwitchOff" ) {
|
||||
|
||||
if( CompartmentLights.start_type != start_t::automatic ) {
|
||||
// automatic lights ignore 'manual' state commands
|
||||
CompartmentLights.is_disabled = ( CValue1 == 1 );
|
||||
}
|
||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||
}
|
||||
else if (Command == "MainSwitch")
|
||||
{
|
||||
MainSwitch_( CValue1 > 0.0 );
|
||||
|
||||
17
Model3d.cpp
17
Model3d.cpp
@@ -151,6 +151,23 @@ TSubModel::SetLightLevel( glm::vec4 const &Level, bool const Includechildren, bo
|
||||
}
|
||||
}
|
||||
|
||||
// sets activation threshold of self-illumination to specitied value
|
||||
void TSubModel::SetSelfIllum( float const Threshold, bool const Includechildren, bool const Includesiblings ) {
|
||||
|
||||
fLight = Threshold;
|
||||
if( true == Includesiblings ) {
|
||||
auto sibling { this };
|
||||
while( ( sibling = sibling->Next ) != nullptr ) {
|
||||
sibling->SetSelfIllum( Threshold, Includechildren, false ); // no need for all siblings to duplicate the work
|
||||
}
|
||||
}
|
||||
if( ( true == Includechildren )
|
||||
&& ( Child != nullptr ) ) {
|
||||
Child->SetSelfIllum( Threshold, Includechildren, true ); // node's children include child's siblings and children
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int TSubModel::SeekFaceNormal(std::vector<unsigned int> const &Masks, int const Startface, unsigned int const Mask, glm::vec3 const &Position, gfx::vertex_array const &Vertices)
|
||||
{ // szukanie punktu stycznego do (pt), zwraca numer wierzchołka, a nie trójkąta
|
||||
int facecount = iNumVerts / 3; // bo maska powierzchni jest jedna na trójkąt
|
||||
|
||||
@@ -214,6 +214,8 @@ public:
|
||||
void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
// sets light level (alpha component of illumination color) to specified value
|
||||
void SetLightLevel( glm::vec4 const &Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
// sets activation threshold of self-illumination to specitied value
|
||||
void SetSelfIllum( float const Threshold, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
inline float3 Translation1Get() {
|
||||
return fMatrix ? *(fMatrix->TranslationGet()) + v_TransVector : v_TransVector; }
|
||||
inline float3 Translation2Get() {
|
||||
|
||||
@@ -76,7 +76,7 @@ void render_task::run() {
|
||||
if (!Global.gfx_usegles)
|
||||
{
|
||||
int size = width * height * 3;
|
||||
format = GL_SRGB8;
|
||||
format = ( Global.GfxFramebufferSRGB ? GL_SRGB8 : GL_RGBA8 );
|
||||
components = GL_RGB;
|
||||
m_target->image = new unsigned char[size];
|
||||
memcpy(m_target->image, image, size);
|
||||
|
||||
172
Train.cpp
172
Train.cpp
@@ -335,6 +335,9 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
{ user_command::interiorlightdimtoggle, &TTrain::OnCommand_interiorlightdimtoggle },
|
||||
{ user_command::interiorlightdimenable, &TTrain::OnCommand_interiorlightdimenable },
|
||||
{ user_command::interiorlightdimdisable, &TTrain::OnCommand_interiorlightdimdisable },
|
||||
{ user_command::compartmentlightstoggle, &TTrain::OnCommand_compartmentlightstoggle },
|
||||
{ user_command::compartmentlightsenable, &TTrain::OnCommand_compartmentlightsenable },
|
||||
{ user_command::compartmentlightsdisable, &TTrain::OnCommand_compartmentlightsdisable },
|
||||
{ user_command::instrumentlighttoggle, &TTrain::OnCommand_instrumentlighttoggle },
|
||||
{ user_command::instrumentlightenable, &TTrain::OnCommand_instrumentlightenable },
|
||||
{ user_command::instrumentlightdisable, &TTrain::OnCommand_instrumentlightdisable },
|
||||
@@ -536,6 +539,7 @@ dictionary_source *TTrain::GetTrainState() {
|
||||
dict->insert( "pant_compressor", mvControlled->PantCompFlag );
|
||||
dict->insert( "lights_front", mvOccupied->iLights[ end::front ] );
|
||||
dict->insert( "lights_rear", mvOccupied->iLights[ end::rear ] );
|
||||
dict->insert( "lights_compartments", mvOccupied->CompartmentLights.is_active || mvOccupied->CompartmentLights.is_disabled );
|
||||
// reverser
|
||||
dict->insert( "direction", mvOccupied->DirActive );
|
||||
// throttle
|
||||
@@ -757,8 +761,8 @@ void TTrain::zero_charging_train_brake() {
|
||||
&& ( DynamicObject->Controller != AIdriver )
|
||||
&& ( Global.iFeedbackMode < 3 )
|
||||
&& ( ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 )
|
||||
|| (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57)
|
||||
|| (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P)) ) {
|
||||
|| ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57 )
|
||||
|| ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P ) ) ) {
|
||||
// Odskakiwanie hamulce EP
|
||||
set_train_brake( 0 );
|
||||
}
|
||||
@@ -2466,14 +2470,16 @@ void TTrain::OnCommand_linebreakeropen( TTrain *Train, command_data const &Comma
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
if( Train->m_controlmapper.contains( "main_off_bt:" ) ) {
|
||||
if( Train->ggMainOffButton.SubModel != nullptr ) {
|
||||
Train->ggMainOffButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
}
|
||||
else if( Train->m_controlmapper.contains( "main_sw:" ) ) {
|
||||
else if( Train->ggMainButton.SubModel != nullptr ) {
|
||||
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
else {
|
||||
// there's no switch capable of doing the job
|
||||
else if( Train->ggMainOnButton.SubModel != nullptr ) {
|
||||
// NOTE: legacy behaviour, for vehicles equipped only with impulse close switch
|
||||
// it doesn't make any real sense to animate this one, but some people can't get over how there's no visual reaction to their keypress
|
||||
Train->ggMainOnButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
return;
|
||||
}
|
||||
// play sound immediately when the switch is hit, not after release
|
||||
@@ -2514,10 +2520,14 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
|
||||
// two separate switches to close and break the circuit
|
||||
Train->ggMainOnButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
}
|
||||
else {
|
||||
else if( Train->ggMainButton.SubModel != nullptr ) {
|
||||
// single two-state switch
|
||||
Train->ggMainButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
}
|
||||
else {
|
||||
// no switch capable of doing the job
|
||||
return;
|
||||
}
|
||||
// the actual closing of the line breaker is handled in the train update routine
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
@@ -2526,7 +2536,7 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
|
||||
// setup with two separate switches
|
||||
Train->ggMainOnButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
else {
|
||||
else if( Train->ggMainButton.SubModel != nullptr ) {
|
||||
if( Train->ggMainButton.type() != TGaugeType::toggle ) {
|
||||
Train->ggMainButton.UpdateValue( 0.5, Train->dsbSwitch );
|
||||
}
|
||||
@@ -2536,8 +2546,9 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
|
||||
|
||||
if( Train->m_linebreakerstate == 2 ) {
|
||||
// we don't need to start the diesel twice, but the other types (with impulse switch setup) still need to be launched
|
||||
if( ( Train->mvControlled->EngineType != TEngineType::DieselEngine )
|
||||
&& ( Train->mvControlled->EngineType != TEngineType::DieselElectric ) ) {
|
||||
// NOTE: this behaviour should depend on MainOnButton presence and type_delayed
|
||||
// TODO: change it when/if vehicle definition files get their proper switch types
|
||||
if( Train->mvControlled->EngineType == TEngineType::ElectricSeriesMotor ) {
|
||||
// try to finalize state change of the line breaker, set the state based on the outcome
|
||||
Train->m_linebreakerstate = (
|
||||
Train->mvControlled->MainSwitch( true ) ?
|
||||
@@ -4356,6 +4367,79 @@ void TTrain::OnCommand_interiorlightdimdisable( TTrain *Train, command_data cons
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_compartmentlightstoggle( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_REPEAT ) { return; }
|
||||
|
||||
// keep the switch from flipping back and forth if key is held down
|
||||
if( ( false == Train->mvOccupied->CompartmentLights.is_active )
|
||||
&& ( false == Train->mvOccupied->CompartmentLights.is_enabled ) ) {
|
||||
// turn on
|
||||
OnCommand_compartmentlightsenable( Train, Command );
|
||||
}
|
||||
else {
|
||||
//turn off
|
||||
OnCommand_compartmentlightsdisable( Train, Command );
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_compartmentlightsenable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
Train->mvOccupied->CompartmentLightsSwitch( true );
|
||||
// visual feedback
|
||||
if( Train->m_controlmapper.contains( "compartmentlights_sw:" ) ) {
|
||||
Train->ggCompartmentLightsButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
}
|
||||
if( Train->m_controlmapper.contains( "compartmentlightson_sw:" ) ) {
|
||||
Train->ggCompartmentLightsOnButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
if( Train->m_controlmapper.contains( "compartmentlights_sw:" ) ) {
|
||||
if( Train->ggCompartmentLightsButton.type() == TGaugeType::push ) {
|
||||
// return the switch to neutral position
|
||||
Train->mvOccupied->CompartmentLightsSwitch( false );
|
||||
Train->mvOccupied->CompartmentLightsSwitchOff( false );
|
||||
Train->ggCompartmentLightsButton.UpdateValue( 0.5f );
|
||||
}
|
||||
}
|
||||
if( Train->m_controlmapper.contains( "compartmentlightson_sw:" ) ) {
|
||||
Train->mvOccupied->CompartmentLightsSwitch( false );
|
||||
Train->ggCompartmentLightsOnButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_compartmentlightsdisable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
if( Train->m_controlmapper.contains( "compartmentlights_sw:" ) ) {
|
||||
Train->ggCompartmentLightsButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
}
|
||||
if( Train->m_controlmapper.contains( "compartmentlightsoff_sw:" ) ) {
|
||||
Train->ggCompartmentLightsOffButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
}
|
||||
|
||||
Train->mvOccupied->CompartmentLightsSwitchOff( true );
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
if( Train->m_controlmapper.contains( "compartmentlights_sw:" ) ) {
|
||||
if( Train->ggCompartmentLightsButton.type() == TGaugeType::push ) {
|
||||
// return the switch to neutral position
|
||||
Train->mvOccupied->CompartmentLightsSwitch( false );
|
||||
Train->mvOccupied->CompartmentLightsSwitchOff( false );
|
||||
Train->ggCompartmentLightsButton.UpdateValue( 0.5f );
|
||||
}
|
||||
}
|
||||
if( Train->m_controlmapper.contains( "compartmentlightsoff_sw:" ) ) {
|
||||
Train->mvOccupied->CompartmentLightsSwitchOff( false );
|
||||
Train->ggCompartmentLightsOffButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -5709,8 +5793,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
}
|
||||
}
|
||||
|
||||
if( ( ggMainButton.GetDesiredValue() > 0.95 )
|
||||
|| ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) {
|
||||
if( ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) )
|
||||
|| ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) ) {
|
||||
// keep track of period the line breaker button is held down, to determine when/if circuit closes
|
||||
if( ( mvControlled->MainsInitTimeCountdown <= 0.0 )
|
||||
&& ( ( fHVoltage > 0.5 * mvControlled->EnginePowerSource.MaxVoltage )
|
||||
@@ -5733,15 +5817,15 @@ bool TTrain::Update( double const Deltatime )
|
||||
if( m_linebreakerstate == 0 ) {
|
||||
if( fMainRelayTimer > mvControlled->InitialCtrlDelay ) {
|
||||
// wlaczanie WSa z opoznieniem
|
||||
// mark the line breaker as ready to close; for electric vehicles with impulse switch the setup is completed on button release
|
||||
// mark the line breaker as ready to close; for electric series vehicles with impulse switch the setup is completed on button release
|
||||
m_linebreakerstate = 2;
|
||||
}
|
||||
}
|
||||
if( m_linebreakerstate == 2 ) {
|
||||
// for diesels and/or vehicles with toggle switch setup we complete the engine start here
|
||||
// TODO: make it a test for main_on_bt of type push_delayed instead
|
||||
if( ( ggMainOnButton.SubModel == nullptr )
|
||||
|| ( ( mvControlled->EngineType == TEngineType::DieselEngine )
|
||||
|| ( mvControlled->EngineType == TEngineType::DieselElectric ) ) ) {
|
||||
|| ( mvControlled->EngineType != TEngineType::ElectricSeriesMotor ) ) {
|
||||
// try to finalize state change of the line breaker, set the state based on the outcome
|
||||
m_linebreakerstate = (
|
||||
mvControlled->MainSwitch( true ) ?
|
||||
@@ -5749,6 +5833,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
0 );
|
||||
}
|
||||
}
|
||||
// helper variables
|
||||
m_doors = ( DynamicObject->Mechanik->IsAnyDoorOpen[ side::right ] || DynamicObject->Mechanik->IsAnyDoorOpen[ side::left ] );
|
||||
|
||||
// check for received user commands
|
||||
// NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one
|
||||
@@ -6204,8 +6290,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
( mvControlled->Mains )
|
||||
|| ( mvControlled->dizel_startup )
|
||||
|| ( fMainRelayTimer > 0.f )
|
||||
|| ( ggMainButton.GetDesiredValue() > 0.95 )
|
||||
|| ( ggMainOnButton.GetDesiredValue() > 0.95 ) );
|
||||
|| ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) )
|
||||
|| ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) );
|
||||
ggIgnitionKey.Update();
|
||||
}
|
||||
}
|
||||
@@ -6395,7 +6481,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
// NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu
|
||||
btLampkaDoorLeft.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::left : side::right ) ] );
|
||||
btLampkaDoorRight.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::right : side::left ) ] );
|
||||
btLampkaDoors.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ side::right ] || DynamicObject->Mechanik->IsAnyDoorOpen[ side::left ] );
|
||||
btLampkaBlokadaDrzwi.Turn( mvOccupied->Doors.is_locked );
|
||||
btLampkaDoorLockOff.Turn( false == mvOccupied->Doors.lock_enabled );
|
||||
btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal );
|
||||
@@ -6467,7 +6552,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
btLampkaHamulecReczny.Turn( false );
|
||||
btLampkaDoorLeft.Turn( false );
|
||||
btLampkaDoorRight.Turn( false );
|
||||
btLampkaDoors.Turn( false );
|
||||
btLampkaBlokadaDrzwi.Turn( false );
|
||||
btLampkaDoorLockOff.Turn( false );
|
||||
btLampkaDepartureSignal.Turn( false );
|
||||
@@ -6850,6 +6934,9 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggTimetableLightButton.Update();
|
||||
ggCabLightButton.Update();
|
||||
ggCabLightDimButton.Update();
|
||||
ggCompartmentLightsButton.Update();
|
||||
ggCompartmentLightsOnButton.Update();
|
||||
ggCompartmentLightsOffButton.Update();
|
||||
ggBatteryButton.Update();
|
||||
ggBatteryOnButton.Update();
|
||||
ggBatteryOffButton.Update();
|
||||
@@ -7942,13 +8029,14 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
||||
target_train->Dynamic()->ABuSetModelShake( {} );
|
||||
}
|
||||
|
||||
target_train->Dynamic()->bDisplayCab = true;
|
||||
target_train->Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
||||
|
||||
// potentially move player
|
||||
if (simulation::Train == this) {
|
||||
simulation::Train = target_train;
|
||||
}
|
||||
// our local driver may potentially be in external view mode, in which case we shouldn't activate cab visualization
|
||||
target_train->Dynamic()->bDisplayCab |= !FreeFlyModeFlag;
|
||||
}
|
||||
|
||||
// delete this TTrain
|
||||
pending_delete = true;
|
||||
@@ -7982,7 +8070,7 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
||||
Occupied()->LimPipePress = Occupied()->PipePress;
|
||||
Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
||||
Dynamic()->MechInside = true;
|
||||
Dynamic()->Controller = ( Dynamic()->Mechanik ? !Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
||||
Dynamic()->Controller = ( Dynamic()->Mechanik ? Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
||||
} else {
|
||||
Dynamic()->bDisplayCab = false;
|
||||
Dynamic()->ABuSetModelShake( {} );
|
||||
@@ -7994,9 +8082,13 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
||||
Occupied()->CabActive,
|
||||
Dynamic()->asBaseDir + Occupied()->TypeName + ".mmd" );
|
||||
|
||||
Dynamic()->bDisplayCab = true;
|
||||
Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
||||
|
||||
if( simulation::Train == this ) {
|
||||
// our local driver may potentially be in external view mode, in which case we shouldn't activate cab visualization
|
||||
Dynamic()->bDisplayCab |= !FreeFlyModeFlag;
|
||||
}
|
||||
|
||||
// add it back with updated dynamic name
|
||||
simulation::Trains.insert(this);
|
||||
}
|
||||
@@ -8157,6 +8249,9 @@ void TTrain::clear_cab_controls()
|
||||
// hunter-091012
|
||||
ggCabLightButton.Clear();
|
||||
ggCabLightDimButton.Clear();
|
||||
ggCompartmentLightsButton.Clear();
|
||||
ggCompartmentLightsOnButton.Clear();
|
||||
ggCompartmentLightsOffButton.Clear();
|
||||
ggBatteryButton.Clear();
|
||||
ggBatteryOnButton.Clear();
|
||||
ggBatteryOffButton.Clear();
|
||||
@@ -8262,7 +8357,6 @@ void TTrain::clear_cab_controls()
|
||||
btLampkaWentZaluzje.Clear();
|
||||
btLampkaDoorLeft.Clear();
|
||||
btLampkaDoorRight.Clear();
|
||||
btLampkaDoors.Clear();
|
||||
btLampkaDepartureSignal.Clear();
|
||||
btLampkaRezerwa.Clear();
|
||||
btLampkaBoczniki.Clear();
|
||||
@@ -8337,10 +8431,12 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
mvOccupied->Battery ? 1.f :
|
||||
0.f ) );
|
||||
// line breaker
|
||||
ggMainButton.PutValue(
|
||||
( ggMainButton.type() == TGaugeType::push ? 0.5f :
|
||||
m_linebreakerstate > 0 ? 1.f :
|
||||
0.f ) );
|
||||
if( ggMainButton.SubModel != nullptr ) { // instead of single main button there can be on/off pair
|
||||
ggMainButton.PutValue(
|
||||
( ggMainButton.type() == TGaugeType::push ? 0.5f :
|
||||
m_linebreakerstate > 0 ? 1.f :
|
||||
0.f ) );
|
||||
}
|
||||
// motor connectors
|
||||
ggStLinOffButton.PutValue(
|
||||
( mvControlled->StLinSwitchOff ?
|
||||
@@ -8487,7 +8583,12 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
if( true == Cabine[Cab].bLightDim ) {
|
||||
ggCabLightDimButton.PutValue( 1.f );
|
||||
}
|
||||
|
||||
// compartment lights
|
||||
ggCompartmentLightsButton.PutValue(
|
||||
( ggCompartmentLightsButton.type() == TGaugeType::push ? 0.5f :
|
||||
mvOccupied->CompartmentLights.is_enabled ? 1.f :
|
||||
0.f ) );
|
||||
// instrument lights
|
||||
ggInstrumentLightButton.PutValue( (
|
||||
InstrumentLightActive ?
|
||||
1.f :
|
||||
@@ -8687,7 +8788,6 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
{ "i-security_cabsignal:", btLampkaSHP },
|
||||
{ "i-door_left:", btLampkaDoorLeft },
|
||||
{ "i-door_right:", btLampkaDoorRight },
|
||||
{ "i-doors:", btLampkaDoors },
|
||||
{ "i-departure_signal:", btLampkaDepartureSignal },
|
||||
{ "i-reserve:", btLampkaRezerwa },
|
||||
{ "i-scnd:", btLampkaBoczniki },
|
||||
@@ -8752,6 +8852,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
}
|
||||
// TODO: move viable dedicated lights to the automatic light array
|
||||
std::unordered_map<std::string, bool const *> const autolights = {
|
||||
{ "i-doors:", &m_doors },
|
||||
{ "i-doorpermit_left:", &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::left : side::right ) ].open_permit },
|
||||
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit },
|
||||
{ "i-doorstep:", &mvOccupied->Doors.step_enabled },
|
||||
@@ -8844,8 +8945,6 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "fuse_bt:", ggFuseButton },
|
||||
{ "converterfuse_bt:", ggConverterFuseButton },
|
||||
{ "stlinoff_bt:", ggStLinOffButton },
|
||||
{ "doorleftpermit_sw:", ggDoorLeftPermitButton },
|
||||
{ "doorrightpermit_sw:", ggDoorRightPermitButton },
|
||||
{ "doorpermitpreset_sw:", ggDoorPermitPresetButton },
|
||||
{ "door_left_sw:", ggDoorLeftButton },
|
||||
{ "door_right_sw:", ggDoorRightButton },
|
||||
@@ -8854,7 +8953,6 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "doorleftoff_sw:", ggDoorLeftOffButton },
|
||||
{ "doorrightoff_sw:", ggDoorRightOffButton },
|
||||
{ "doorallon_sw:", ggDoorAllOnButton },
|
||||
{ "dooralloff_sw:", ggDoorAllOffButton },
|
||||
{ "departure_signal_bt:", ggDepartureSignalButton },
|
||||
{ "upperlight_sw:", ggUpperLightButton },
|
||||
{ "leftlight_sw:", ggLeftLightButton },
|
||||
@@ -8918,6 +9016,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "timetablelight_sw:", ggTimetableLightButton },
|
||||
{ "cablight_sw:", ggCabLightButton },
|
||||
{ "cablightdim_sw:", ggCabLightDimButton },
|
||||
{ "compartmentlights_sw:", ggCompartmentLightsButton },
|
||||
{ "compartmentlightson_sw:", ggCompartmentLightsOnButton },
|
||||
{ "compartmentlightsoff_sw:", ggCompartmentLightsOffButton },
|
||||
{ "battery_sw:", ggBatteryButton },
|
||||
{ "batteryon_sw:", ggBatteryOnButton },
|
||||
{ "batteryoff_sw:", ggBatteryOffButton },
|
||||
@@ -8957,7 +9058,10 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "speedbutton6:", { ggSpeedCtrlButtons[ 6 ], &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||
{ "speedbutton7:", { ggSpeedCtrlButtons[ 7 ], &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||
{ "speedbutton8:", { ggSpeedCtrlButtons[ 8 ], &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||
{ "speedbutton9:", { ggSpeedCtrlButtons[ 9 ], &mvOccupied->SpeedCtrlUnit.IsActive } }
|
||||
{ "speedbutton9:", { ggSpeedCtrlButtons[ 9 ], &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||
{ "doorleftpermit_sw:", { ggDoorLeftPermitButton, &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::left : side::right ) ].open_permit } },
|
||||
{ "doorrightpermit_sw:", { ggDoorRightPermitButton, &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit } },
|
||||
{ "dooralloff_sw:", { ggDoorAllOffButton, &m_doors } },
|
||||
};
|
||||
{
|
||||
auto const lookup { stategauges.find( Label ) };
|
||||
|
||||
10
Train.h
10
Train.h
@@ -361,6 +361,9 @@ class TTrain {
|
||||
static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightsenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightsdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlightdisable( TTrain *Train, command_data const &Command );
|
||||
@@ -539,10 +542,13 @@ public: // reszta może by?publiczna
|
||||
TGauge ggTimetableLightButton;
|
||||
TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny
|
||||
TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia
|
||||
// oswietlenia kabiny
|
||||
TGauge ggCompartmentLightsButton;
|
||||
TGauge ggCompartmentLightsOnButton;
|
||||
TGauge ggCompartmentLightsOffButton;
|
||||
TGauge ggBatteryButton; // Stele 161228 hebelek baterii
|
||||
TGauge ggBatteryOnButton;
|
||||
TGauge ggBatteryOffButton;
|
||||
// oswietlenia kabiny
|
||||
|
||||
// NBMX wrzesien 2003 - obsluga drzwi
|
||||
TGauge ggDoorLeftPermitButton;
|
||||
@@ -661,7 +667,6 @@ public: // reszta może by?publiczna
|
||||
TButton btLampkaPrzekrMaxSila;
|
||||
TButton btLampkaDoorLeft;
|
||||
TButton btLampkaDoorRight;
|
||||
TButton btLampkaDoors;
|
||||
TButton btLampkaDepartureSignal;
|
||||
TButton btLampkaBlokadaDrzwi;
|
||||
TButton btLampkaDoorLockOff;
|
||||
@@ -776,6 +781,7 @@ private:
|
||||
float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive
|
||||
double m_brakehandlecp{ 0.0 };
|
||||
int m_pantselection{ 0 };
|
||||
bool m_doors{ false }; // helper, true if any door is open
|
||||
|
||||
public:
|
||||
float fPress[20][3]; // cisnienia dla wszystkich czlonow
|
||||
|
||||
@@ -224,6 +224,9 @@ commanddescription_sequence Commands_descriptions = {
|
||||
{ "interiorlightdimtoggle", command_target::vehicle },
|
||||
{ "interiorlightdimenable", command_target::vehicle },
|
||||
{ "interiorlightdimdisable", command_target::vehicle },
|
||||
{ "compartmentlightstoggle", command_target::vehicle },
|
||||
{ "compartmentlightsenable", command_target::vehicle },
|
||||
{ "compartmentlightsdisable", command_target::vehicle },
|
||||
{ "instrumentlighttoggle", command_target::vehicle },
|
||||
{ "instrumentlightenable", command_target::vehicle },
|
||||
{ "instrumentlightdisable", command_target::vehicle },
|
||||
|
||||
@@ -215,6 +215,9 @@ enum class user_command {
|
||||
interiorlightdimtoggle,
|
||||
interiorlightdimenable,
|
||||
interiorlightdimdisable,
|
||||
compartmentlightstoggle,
|
||||
compartmentlightsenable,
|
||||
compartmentlightsdisable,
|
||||
instrumentlighttoggle,
|
||||
instrumentlightenable,
|
||||
instrumentlightdisable,
|
||||
|
||||
@@ -224,6 +224,9 @@ driverkeyboard_input::default_bindings() {
|
||||
{ user_command::interiorlightdimtoggle, GLFW_KEY_APOSTROPHE | keymodifier::control },
|
||||
// interiorlightdimenable,
|
||||
// interiorlightdimdisable,
|
||||
// compartmentlightstoggle,
|
||||
// compartmentlightsenable,
|
||||
// compartmentlightsdisable,
|
||||
{ user_command::instrumentlighttoggle, GLFW_KEY_SEMICOLON },
|
||||
// instrumentlightenable,
|
||||
// instrumentlightdisable,
|
||||
|
||||
@@ -106,6 +106,10 @@ std::unordered_map<user_command, std::pair<user_command, user_command>> commandf
|
||||
{ user_command::linebreakerclose, { user_command::linebreakertoggle, user_command::none } },
|
||||
{ user_command::pantographlowerfront, { user_command::pantographtogglefront, user_command::none } },
|
||||
{ user_command::pantographlowerrear, { user_command::pantographtogglerear, user_command::none } },
|
||||
{ user_command::compartmentlightsenable, { user_command::compartmentlightstoggle, user_command::none } },
|
||||
{ user_command::compartmentlightsdisable, { user_command::compartmentlightstoggle, user_command::none } },
|
||||
{ user_command::batteryenable, { user_command::batterytoggle, user_command::none } },
|
||||
{ user_command::batterydisable, { user_command::batterytoggle, user_command::none } },
|
||||
};
|
||||
|
||||
std::pair<user_command, user_command>
|
||||
|
||||
@@ -837,6 +837,15 @@ drivermouse_input::default_bindings() {
|
||||
{ "cablightdim_sw:", {
|
||||
user_command::interiorlightdimtoggle,
|
||||
user_command::none } },
|
||||
{ "compartmentlights_sw:", {
|
||||
user_command::compartmentlightstoggle,
|
||||
user_command::none } },
|
||||
{ "compartmentlightson_sw:", {
|
||||
user_command::compartmentlightsenable,
|
||||
user_command::none } },
|
||||
{ "compartmentlightsoff_sw:", {
|
||||
user_command::compartmentlightsdisable,
|
||||
user_command::none } },
|
||||
{ "battery_sw:", {
|
||||
user_command::batterytoggle,
|
||||
user_command::none } },
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glew/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
@@ -120,7 +120,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glew/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
@@ -142,7 +142,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glew/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<LargeAddressAware>true</LargeAddressAware>
|
||||
@@ -166,7 +166,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glew/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DXSKD_DIR)lib/$(PlatformShortName);$(SolutionDir)ref/glfw/lib/msvc-$(MSBuildToolsVersion)/$(PlatformShortName);$(SolutionDir)ref/openal/lib/$(PlatformShortName);$(SolutionDir)ref/python/lib/$(PlatformShortName);$(SolutionDir)ref/libserialport/lib/$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
|
||||
@@ -713,11 +713,10 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
setup_shadow_color( glm::min( colors::white, m_shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) );
|
||||
}
|
||||
Render_cab( vehicle, vehicle->InteriorLightLevel, false );
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
setup_shadow_color( m_shadowcolor );
|
||||
}
|
||||
}
|
||||
|
||||
setup_shadow_color( m_shadowcolor );
|
||||
|
||||
glDebug("render opaque region");
|
||||
|
||||
model_ubs.future = future;
|
||||
@@ -755,9 +754,9 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
|
||||
}
|
||||
glDebug( "render translucent cab" );
|
||||
Render_cab(vehicle, vehicle->InteriorLightLevel, true);
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
setup_shadow_color( m_shadowcolor );
|
||||
}
|
||||
|
||||
setup_shadow_color( m_shadowcolor );
|
||||
|
||||
if( Global.Overcast > 1.0f ) {
|
||||
// with the cab in place we can (finally) safely draw translucent part of the occupied vehicle
|
||||
Render_Alpha( vehicle );
|
||||
@@ -1023,7 +1022,19 @@ bool opengl33_renderer::Render_lowpoly( TDynamicObject *Dynamic, float const Squ
|
||||
}
|
||||
// HACK: reduce light level for vehicle interior if there's strong global lighting source
|
||||
if( false == Alpha ) {
|
||||
auto const luminance{ static_cast<float>( 0.5 * ( std::max( 0.3, Global.fLuminance - Global.Overcast ) ) ) };
|
||||
/*
|
||||
auto const luminance { static_cast<float>( std::min(
|
||||
( Dynamic->fShade > 0.0 ? Dynamic->fShade * Global.fLuminance : Global.fLuminance ),
|
||||
Global.fLuminance - 0.5 * ( std::max( 0.3, Global.fLuminance - Global.Overcast ) ) ) ) };
|
||||
*/
|
||||
auto const luminance{ static_cast<float>(
|
||||
0.5
|
||||
* ( std::max(
|
||||
0.3,
|
||||
( Global.fLuminance - Global.Overcast )
|
||||
* ( Dynamic->fShade > 0.0 ?
|
||||
Dynamic->fShade :
|
||||
1.0 ) ) ) ) };
|
||||
setup_sunlight_intensity(
|
||||
clamp( (
|
||||
Dynamic->fShade > 0.f ?
|
||||
@@ -1729,7 +1740,7 @@ std::shared_ptr<gl::program> opengl33_renderer::Fetch_Shader(const std::string &
|
||||
return m_shaders[name];
|
||||
}
|
||||
|
||||
void opengl33_renderer::Bind_Material(material_handle const Material, TSubModel *sm)
|
||||
void opengl33_renderer::Bind_Material( material_handle const Material, TSubModel const *sm, lighting_data const *lighting )
|
||||
{
|
||||
if (Material != null_handle)
|
||||
{
|
||||
@@ -1773,6 +1784,26 @@ void opengl33_renderer::Bind_Material(material_handle const Material, TSubModel
|
||||
}
|
||||
}
|
||||
}
|
||||
if( lighting )
|
||||
{
|
||||
switch( entry.defaultparam ) {
|
||||
case gl::shader::defaultparam_e::ambient: {
|
||||
src = lighting->ambient;
|
||||
break;
|
||||
}
|
||||
case gl::shader::defaultparam_e::diffuse: {
|
||||
src = lighting->diffuse;
|
||||
break;
|
||||
}
|
||||
case gl::shader::defaultparam_e::specular: {
|
||||
src = lighting->specular;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// material-based parameters
|
||||
switch( entry.defaultparam ) {
|
||||
case gl::shader::defaultparam_e::glossiness: {
|
||||
@@ -2280,7 +2311,7 @@ void opengl33_renderer::Render(scene::shape_node const &Shape, bool const Ignore
|
||||
{
|
||||
case rendermode::color:
|
||||
case rendermode::reflections:
|
||||
Bind_Material(data.material);
|
||||
Bind_Material(data.material, nullptr, &Shape.data().lighting );
|
||||
break;
|
||||
case rendermode::shadows:
|
||||
Bind_Material_Shadow(data.material);
|
||||
@@ -2546,9 +2577,10 @@ bool opengl33_renderer::Render_cab(TDynamicObject const *Dynamic, float const Li
|
||||
}
|
||||
|
||||
auto const old_ambient { light_ubs.ambient };
|
||||
auto const luminance { Global.fLuminance * ( Dynamic->fShade > 0.0f ? Dynamic->fShade : 1.0f ) };
|
||||
if( Lightlevel > 0.f ) {
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
light_ubs.ambient += ( Dynamic->InteriorLight * Lightlevel ) * static_cast<float>( clamp( 1.25 - Global.fLuminance, 0.0, 1.0 ) );
|
||||
light_ubs.ambient += ( Dynamic->InteriorLight * Lightlevel ) * static_cast<float>( clamp( 1.25 - luminance, 0.0, 1.0 ) );
|
||||
light_ubo->update( light_ubs );
|
||||
}
|
||||
|
||||
@@ -2564,17 +2596,8 @@ bool opengl33_renderer::Render_cab(TDynamicObject const *Dynamic, float const Li
|
||||
Render(Dynamic->mdKabina, Dynamic->Material(), 0.0);
|
||||
}
|
||||
// post-render restore
|
||||
if (Dynamic->fShade > 0.0f)
|
||||
{
|
||||
// change light level based on light level of the occupied track
|
||||
setup_sunlight_intensity();
|
||||
}
|
||||
|
||||
// restore ambient
|
||||
if( Lightlevel > 0.f ) {
|
||||
light_ubs.ambient = old_ambient;
|
||||
light_ubo->update( light_ubs );
|
||||
}
|
||||
light_ubs.ambient = old_ambient;
|
||||
setup_sunlight_intensity();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ class opengl33_renderer : public gfx_renderer {
|
||||
material_handle
|
||||
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override;
|
||||
void
|
||||
Bind_Material( material_handle const Material, TSubModel *sm = nullptr ) override;
|
||||
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override;
|
||||
opengl_material const &
|
||||
Material( material_handle const Material ) const override;
|
||||
// shader methods
|
||||
|
||||
@@ -797,7 +797,14 @@ bool opengl_renderer::Render_lowpoly( TDynamicObject *Dynamic, float const Squar
|
||||
}
|
||||
// HACK: reduce light level for vehicle interior if there's strong global lighting source
|
||||
if( false == Alpha ) {
|
||||
auto const luminance{ static_cast<float>( 0.5 * ( std::max( 0.3, Global.fLuminance - Global.Overcast ) ) ) };
|
||||
auto const luminance{ static_cast<float>(
|
||||
0.5
|
||||
* ( std::max(
|
||||
0.3,
|
||||
( Global.fLuminance - Global.Overcast )
|
||||
* ( Dynamic->fShade > 0.0 ?
|
||||
Dynamic->fShade :
|
||||
1.0 ) ) ) ) };
|
||||
m_sunlight.apply_intensity(
|
||||
clamp( (
|
||||
Dynamic->fShade > 0.f ?
|
||||
@@ -1677,7 +1684,7 @@ opengl_renderer::Fetch_Material( std::string const &Filename, bool const Loadnow
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Bind_Material( material_handle const Material, TSubModel *sm ) {
|
||||
opengl_renderer::Bind_Material( material_handle const Material, TSubModel const *sm, lighting_data const *lighting ) {
|
||||
|
||||
auto const &material = m_materials.material( Material );
|
||||
if( false == Global.BasicRenderer ) {
|
||||
@@ -2403,11 +2410,12 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, float const Lightlev
|
||||
}
|
||||
if( Lightlevel > 0.f ) {
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
auto const luminance { Global.fLuminance * ( Dynamic->fShade > 0.0f ? Dynamic->fShade : 1.0f ) };
|
||||
::glLightModelfv(
|
||||
GL_LIGHT_MODEL_AMBIENT,
|
||||
glm::value_ptr(
|
||||
glm::vec3( m_baseambient )
|
||||
+ ( Dynamic->InteriorLight * Lightlevel ) * static_cast<float>( clamp( 1.25 - Global.fLuminance, 0.0, 1.0 ) ) ) );
|
||||
+ ( Dynamic->InteriorLight * Lightlevel ) * static_cast<float>( clamp( 1.25 - luminance, 0.0, 1.0 ) ) ) );
|
||||
}
|
||||
// render
|
||||
if( true == Alpha ) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
material_handle
|
||||
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override;
|
||||
void
|
||||
Bind_Material( material_handle const Material, TSubModel *sm = nullptr ) override;
|
||||
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override;
|
||||
opengl_material const &
|
||||
Material( material_handle const Material ) const override;
|
||||
// shader methods
|
||||
|
||||
@@ -12,6 +12,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "geometrybank.h"
|
||||
#include "material.h"
|
||||
|
||||
class lighting_data;
|
||||
|
||||
class gfx_renderer {
|
||||
|
||||
public:
|
||||
@@ -38,7 +40,7 @@ public:
|
||||
virtual auto Vertices( gfx::geometry_handle const &Geometry ) const ->gfx::vertex_array const & = 0;
|
||||
// material methods
|
||||
virtual auto Fetch_Material( std::string const &Filename, bool const Loadnow = true ) -> material_handle = 0;
|
||||
virtual void Bind_Material( material_handle const Material, TSubModel *sm = nullptr ) = 0;
|
||||
virtual void Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) = 0;
|
||||
virtual auto Material( material_handle const Material ) const -> opengl_material const & = 0;
|
||||
// shader methods
|
||||
virtual auto Fetch_Shader( std::string const &name ) -> std::shared_ptr<gl::program> = 0;
|
||||
|
||||
@@ -108,12 +108,15 @@ vec2 calc_headlights(light_s light, vec3 fragnormal)
|
||||
|
||||
vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone)
|
||||
{
|
||||
fragcolor *= param[1].x;
|
||||
|
||||
vec3 emissioncolor = param[0].rgb * emission;
|
||||
vec3 envcolor = envmap_color(fragnormal);
|
||||
|
||||
if(lights_count == 0U)
|
||||
return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor;
|
||||
|
||||
// fragcolor *= lights[0].intensity;
|
||||
vec2 sunlight = calc_dir_light(lights[0], fragnormal);
|
||||
|
||||
float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity;
|
||||
|
||||
@@ -202,6 +202,9 @@ init() {
|
||||
"timetable light",
|
||||
"interior light",
|
||||
"interior light dimmer",
|
||||
"compartment lights",
|
||||
"compartment lights",
|
||||
"compartment lights",
|
||||
"battery",
|
||||
"battery",
|
||||
"battery",
|
||||
@@ -397,6 +400,9 @@ init() {
|
||||
"oswietlenie rozkladu jazdy",
|
||||
"oswietlenie kabiny",
|
||||
"przyciemnienie oswietlenia kabiny",
|
||||
"oswietlenie przedzialow",
|
||||
"oswietlenie przedzialow",
|
||||
"oswietlenie przedzialow",
|
||||
"bateria",
|
||||
"bateria",
|
||||
"bateria",
|
||||
@@ -545,6 +551,9 @@ init() {
|
||||
"timetablelight_sw:",
|
||||
"cablight_sw:",
|
||||
"cablightdim_sw:",
|
||||
"compartmentlights_sw:",
|
||||
"compartmentlightson_sw:",
|
||||
"compartmentlightsoff_sw:",
|
||||
"battery_sw:",
|
||||
"batteryon_sw:",
|
||||
"batteryoff_sw:",
|
||||
|
||||
@@ -191,6 +191,9 @@ enum string {
|
||||
cab_timetablelight_sw,
|
||||
cab_cablight_sw,
|
||||
cab_cablightdim_sw,
|
||||
cab_compartmentlights_sw,
|
||||
cab_compartmentlightson_sw,
|
||||
cab_compartmentlightsoff_sw,
|
||||
cab_battery_sw,
|
||||
cab_batteryon_sw,
|
||||
cab_batteryoff_sw,
|
||||
|
||||
Reference in New Issue
Block a user