16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-24 09:49:18 +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:
tmj-fstate
2020-03-01 03:09:55 +01:00
parent e4502217e5
commit 642b8fb623
26 changed files with 485 additions and 130 deletions

View File

@@ -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 // 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() void TController::CloseLog()
@@ -2229,6 +2229,11 @@ bool TController::CheckVehicles(TOrders user)
|| ( pVehicle->NextC( coupling::control ) != nullptr ) ) { || ( pVehicle->NextC( coupling::control ) != nullptr ) ) {
sync_consist_reversers(); 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) if (AIControllFlag)
@@ -2515,7 +2520,7 @@ void TController::SetDriverPsyche()
bool TController::PrepareEngine() bool TController::PrepareEngine()
{ // odpalanie silnika { // odpalanie silnika
// HACK: don't immediately activate inert vehicle in case the simulation is about to replace us with human driver // 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, bool OK = false,
voltfront = false, voltfront = false,
@@ -4525,6 +4530,7 @@ TController::UpdateSituation(double dt) {
double dy; // składowa styczna grawitacji, w przedziale <0,1> double dy; // składowa styczna grawitacji, w przedziale <0,1>
double AbsAccS = 0; double AbsAccS = 0;
IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::left ] = false; IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::left ] = false;
ConsistShade = 0.0;
TDynamicObject *p = pVehicles[0]; // pojazd na czole składu TDynamicObject *p = pVehicles[0]; // pojazd na czole składu
while (p) while (p)
{ // sprawdzenie odhamowania wszystkich połączonych pojazdów { // sprawdzenie odhamowania wszystkich połączonych pojazdów
@@ -4573,9 +4579,13 @@ TController::UpdateSituation(double dt) {
IsAnyDoorOpen[ side::left ] = IsAnyDoorOpen[ side::left ] =
IsAnyDoorOpen[ side::left ] IsAnyDoorOpen[ side::left ]
|| ( false == vehicle->Doors.instances[ ( switchsides ? side::right : side::left ) ].is_closed ); || ( 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) 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 // test state of main switch in all powered vehicles under control
IsLineBreakerClosed = ( mvOccupied->Power > 0.01 ? mvOccupied->Mains : true ); IsLineBreakerClosed = ( mvOccupied->Power > 0.01 ? mvOccupied->Mains : true );
@@ -4720,32 +4730,35 @@ TController::UpdateSituation(double dt) {
} }
else { else {
// jeśli nie trzeba opuszczać pantografów // jeśli nie trzeba opuszczać pantografów
if( mvOccupied->AIHintPantstate == 0 ) { if( fActionTime > 0.0 ) {
// jazda na tylnym if( mvOccupied->AIHintPantstate == 0 ) {
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) { // jazda na tylnym
// jak jedzie w kierunku sprzęgu 0 if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) {
if( ( mvControlling->PantRearVolt == 0.0 ) // jak jedzie w kierunku sprzęgu 0
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't if( ( mvControlling->PantRearVolt == 0.0 )
&& ( ( mvControlling->PantographVoltage == 0.0 ) // filter out cases with single _other_ working pantograph so we don't try to raise something we can't
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) { && ( ( mvControlling->PantographVoltage == 0.0 )
mvControlling->OperatePantographValve( end::rear, operation_t::enable ); || ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
mvControlling->OperatePantographValve( end::rear, operation_t::enable );
}
} }
} else {
else { // jak jedzie w kierunku sprzęgu 0
// jak jedzie w kierunku sprzęgu 0 if( ( mvControlling->PantFrontVolt == 0.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
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't && ( ( mvControlling->PantographVoltage == 0.0 )
&& ( ( mvControlling->PantographVoltage == 0.0 ) || ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) { mvControlling->OperatePantographValve( end::front, operation_t::enable );
mvControlling->OperatePantographValve( end::front, operation_t::enable ); }
} }
} }
} }
} }
if( mvOccupied->Vel > 5 ) { if( mvOccupied->Vel > 5 ) {
if( mvOccupied->AIHintPantstate != 0 ) { if( fActionTime > 0.0 ) {
// use suggested pantograph setup if( mvOccupied->AIHintPantstate != 0 ) {
auto const pantographsetup { mvOccupied->AIHintPantstate }; // use suggested pantograph setup
auto const pantographsetup{ mvOccupied->AIHintPantstate };
mvControlling->OperatePantographValve( mvControlling->OperatePantographValve(
end::front, end::front,
( pantographsetup & ( 1 << 0 ) ? ( pantographsetup & ( 1 << 0 ) ?
@@ -4756,21 +4769,22 @@ TController::UpdateSituation(double dt) {
( pantographsetup & ( 1 << 1 ) ? ( pantographsetup & ( 1 << 1 ) ?
operation_t::enable : operation_t::enable :
operation_t::disable ) ); operation_t::disable ) );
} }
else { else {
// opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden // opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden
if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) { if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) {
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) // jak jedzie w kierunku sprzęgu 0 if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) // jak jedzie w kierunku sprzęgu 0
{ // poczekać na podniesienie tylnego { // poczekać na podniesienie tylnego
if( ( mvControlling->PantFrontVolt != 0.0 ) if( ( mvControlling->PantFrontVolt != 0.0 )
&& ( mvControlling->PantRearVolt != 0.0 ) ) { // czy jest napięcie zasilające na tylnym? && ( mvControlling->PantRearVolt != 0.0 ) ) { // czy jest napięcie zasilające na tylnym?
mvControlling->OperatePantographValve( end::front, operation_t::disable ); // opuszcza od sprzęgu 0 mvControlling->OperatePantographValve( end::front, operation_t::disable ); // opuszcza od sprzęgu 0
}
} }
} else { // poczekać na podniesienie przedniego
else { // poczekać na podniesienie przedniego if( ( mvControlling->PantRearVolt != 0.0 )
if( ( mvControlling->PantRearVolt != 0.0 ) && ( mvControlling->PantFrontVolt != 0.0 ) ) { // czy jest napięcie zasilające na przednim?
&& ( mvControlling->PantFrontVolt != 0.0 ) ) { // czy jest napięcie zasilające na przednim? mvControlling->OperatePantographValve( end::rear, operation_t::disable ); // opuszcza od sprzęgu 1
mvControlling->OperatePantographValve( end::rear, operation_t::disable ); // opuszcza od sprzęgu 1 }
} }
} }
} }
@@ -4860,6 +4874,21 @@ TController::UpdateSituation(double dt) {
if (AIControllFlag) { if (AIControllFlag) {
CheckTimeControllers(); 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; LastReactionTime -= reactiontime;

View File

@@ -466,6 +466,7 @@ private:
bool IsLineBreakerClosed{ false }; // state of line breaker in all powered vehicles under control bool IsLineBreakerClosed{ false }; // state of line breaker in all powered vehicles under control
double fReady = 0.0; // poziom odhamowania wagonów double fReady = 0.0; // poziom odhamowania wagonów
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow 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) TDynamicObject *pVehicles[ 2 ]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
bool IsAnyDoorOpen[ 2 ]; // state of door in the consist bool IsAnyDoorOpen[ 2 ]; // state of door in the consist

View File

@@ -664,13 +664,7 @@ TDynamicObject::toggle_lights() {
if( true == SectionLightsActive ) { if( true == SectionLightsActive ) {
// switch all lights off... // switch all lights off...
for( auto &section : Sections ) { MoverParameters->BatterySwitch( false );
// ... 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;
}
SectionLightsActive = false; SectionLightsActive = false;
} }
else { else {
@@ -690,6 +684,7 @@ TDynamicObject::toggle_lights() {
section.light_level = ( Random() < 0.75 ? 0.75f : 0.15f ); section.light_level = ( Random() < 0.75 ? 0.75f : 0.15f );
} }
} }
MoverParameters->BatterySwitch( true );
SectionLightsActive = true; SectionLightsActive = true;
} }
} }
@@ -1092,15 +1087,20 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
} }
// interior light levels // interior light levels
auto sectionlightcolor { glm::vec4( 1.f ) }; auto sectionlightcolor { glm::vec4( 1.f ) };
bool cabsection{ true };
for( auto const &section : Sections ) { for( auto const &section : Sections ) {
/* if( cabsection ) {
sectionlightcolor = glm::vec4( InteriorLight, section.light_level ); // check whether we're still processing cab sections
*/ auto const &sectionname { 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( 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? glm::vec3( 240.f / 255.f ) : // TBD: save and restore initial submodel diffuse instead of enforcing one?
InteriorLight ), // TODO: per-compartment (type) light color InteriorLight ), // TODO: per-compartment (type) light color
section.light_level ); sectionlightlevel );
section.compartment->SetLightLevel( sectionlightcolor, true ); section.compartment->SetLightLevel( sectionlightcolor, true );
if( section.load != nullptr ) { if( section.load != nullptr ) {
section.load->SetLightLevel( sectionlightcolor, true ); section.load->SetLightLevel( sectionlightcolor, true );
@@ -2069,7 +2069,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
// passenger car compartments // passenger car compartments
std::vector<std::string> nameprefixes = { "corridor", "korytarz", "compartment", "przedzial" }; std::vector<std::string> nameprefixes = { "corridor", "korytarz", "compartment", "przedzial" };
for( auto const &nameprefix : nameprefixes ) { for( auto const &nameprefix : nameprefixes ) {
init_sections( mdLowPolyInt, nameprefix ); init_sections( mdLowPolyInt, nameprefix, MoverParameters->CompartmentLights.start_type == start_t::manual );
} }
} }
// destination sign // 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 // 'external_load' is an optional special section in the main model, pointing to submodel of external load
if( mdModel ) { if( mdModel ) {
init_sections( mdModel, "external_load" ); init_sections( mdModel, "external_load", false );
} }
update_load_sections(); update_load_sections();
update_load_visibility(); update_load_visibility();
@@ -2176,7 +2176,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
} }
int 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 sectioncount = 0;
auto sectionindex = 0; auto sectionindex = 0;
@@ -2192,6 +2192,10 @@ TDynamicObject::init_sections( TModel3d const *Model, std::string const &Namepre
sectionsubmodel = Model->GetFromName( Nameprefix + "0" + sectionindexname ); sectionsubmodel = Model->GetFromName( Nameprefix + "0" + sectionindexname );
} }
if( sectionsubmodel != nullptr ) { 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( { Sections.push_back( {
sectionsubmodel, sectionsubmodel,
nullptr, // pointers to load sections are generated afterwards nullptr, // pointers to load sections are generated afterwards
@@ -2609,6 +2613,10 @@ TDynamicObject::update_load_sections() {
if( ( section.load != nullptr ) if( ( section.load != nullptr )
&& ( section.load->count_children() > 0 ) ) { && ( section.load->count_children() > 0 ) ) {
SectionLoadVisibility.push_back( { section.load, false } ); 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(); 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 the vehicle has a controller, we base the light state on state of the controller otherwise we check the vehicle itself
if( ( ctOwner != nullptr ? if( ( ctOwner != nullptr ?
ctOwner->Controlling()->Battery != SectionLightsActive : 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(); toggle_lights();
} }

View File

@@ -550,7 +550,7 @@ private:
std::string Name, std::string BaseDir, std::string asReplacableSkin, std::string Type_Name, 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, TTrack *Track, double fDist, std::string DriverType, double fVel, std::string TrainName,
float Load, std::string LoadType, bool Reversed, std::string); 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 ); bool init_destination( TModel3d *Model );
void create_controller( std::string const Type, bool const Trainset ); void create_controller( std::string const Type, bool const Trainset );
void AttachPrev(TDynamicObject *Object, int iType = 1); void AttachPrev(TDynamicObject *Object, int iType = 1);

View File

@@ -22,10 +22,12 @@ enum class TGaugeAnimation {
}; };
enum class TGaugeType : int { enum class TGaugeType : int {
toggle = 1, toggle = 1 << 0,
push = 2, push = 1 << 1,
delayed = 1 << 2,
pushtoggle = ( toggle | push ), 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 // animowany wskaźnik, mogący przyjmować wiele stanów pośrednich

View File

@@ -756,6 +756,13 @@ private:
bool is_active { false }; // device is working 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 { struct cooling_fan : public basic_device {
// config // config
float speed { 0.f }; // cooling fan rpm; either fraction of parent rpm, or absolute value if negative 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 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 CompressorStart{ start_t::manual }; // whether the compressor is started manually, or another way
start_t PantographCompressorStart{ start_t::manual }; 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 // 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 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 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; bool DoorRightOpened = false;
double DoorRightOpenTimer{ -1.0 }; // right door closing timer for automatic door type double DoorRightOpenTimer{ -1.0 }; // right door closing timer for automatic door type
#endif #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 // TODO: move these switch types where they belong, cabin definition
std::string PantSwitchType; std::string PantSwitchType;
std::string ConvSwitchType; std::string ConvSwitchType;
@@ -1519,6 +1526,7 @@ public:
bool Heating = false; //ogrzewanie 'Winger 020304 bool Heating = false; //ogrzewanie 'Winger 020304
bool HeatingAllow { false }; // heating switch // TODO: wrap heating in a basic device bool HeatingAllow { false }; // heating switch // TODO: wrap heating in a basic device
int DoubleTr = 1; //trakcja ukrotniona - przedni pojazd 'Winger 160304 int DoubleTr = 1; //trakcja ukrotniona - przedni pojazd 'Winger 160304
basic_light CompartmentLights;
bool PhysicActivation = true; bool PhysicActivation = true;
@@ -1674,6 +1682,8 @@ public:
bool OilPumpSwitchOff( bool State, range_t const Notify = range_t::consist ); // oil pump state toggle 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 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 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*/ bool MainSwitch( bool const State, range_t const Notify = range_t::consist );/*! wylacznik glowny*/
void MainSwitch_( bool const State ); void MainSwitch_( bool const State );
bool ConverterSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl przetwornicy*/ 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 OilPumpCheck( double const Timestep );
void MotorBlowersCheck( double const Timestep ); void MotorBlowersCheck( double const Timestep );
void PantographsCheck( double const Timestep ); void PantographsCheck( double const Timestep );
void LightsCheck( double const Timestep );
bool FuseOn(void); //bezpiecznik nadamiary bool FuseOn(void); //bezpiecznik nadamiary
bool FuseFlagCheck(void) const; // sprawdzanie flagi nadmiarowego bool FuseFlagCheck(void) const; // sprawdzanie flagi nadmiarowego
void FuseOff(void); // wylaczenie nadmiarowego void FuseOff(void); // wylaczenie nadmiarowego

View File

@@ -1439,6 +1439,8 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
} }
// heating // heating
HeatingCheck( Deltatime ); HeatingCheck( Deltatime );
// lighting
LightsCheck( Deltatime );
UpdateBrakePressure(Deltatime); UpdateBrakePressure(Deltatime);
UpdatePipePressure(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 double TMoverParameters::ShowCurrent(int AmpN) const
{ // Odczyt poboru prądu na podanym amperomierzu { // Odczyt poboru prądu na podanym amperomierzu
switch (EngineType) switch (EngineType)
@@ -3151,6 +3182,55 @@ bool TMoverParameters::MotorBlowersSwitchOff( bool State, end const Side, range_
return ( fan.is_disabled != initialstate ); 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 // Q: 20160713
// włączenie / wyłączenie obwodu głownego // włączenie / wyłączenie obwodu głownego
@@ -9758,6 +9838,15 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
lookup->second : lookup->second :
start_t::manual; 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) { 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 ); 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") else if (Command == "MainSwitch")
{ {
MainSwitch_( CValue1 > 0.0 ); MainSwitch_( CValue1 > 0.0 );

View File

@@ -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) 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 { // 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 int facecount = iNumVerts / 3; // bo maska powierzchni jest jedna na trójkąt

View File

@@ -214,6 +214,8 @@ public:
void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false ); void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
// sets light level (alpha component of illumination color) to specified value // 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 ); 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() { inline float3 Translation1Get() {
return fMatrix ? *(fMatrix->TranslationGet()) + v_TransVector : v_TransVector; } return fMatrix ? *(fMatrix->TranslationGet()) + v_TransVector : v_TransVector; }
inline float3 Translation2Get() { inline float3 Translation2Get() {

View File

@@ -76,7 +76,7 @@ void render_task::run() {
if (!Global.gfx_usegles) if (!Global.gfx_usegles)
{ {
int size = width * height * 3; int size = width * height * 3;
format = GL_SRGB8; format = ( Global.GfxFramebufferSRGB ? GL_SRGB8 : GL_RGBA8 );
components = GL_RGB; components = GL_RGB;
m_target->image = new unsigned char[size]; m_target->image = new unsigned char[size];
memcpy(m_target->image, image, size); memcpy(m_target->image, image, size);

172
Train.cpp
View File

@@ -335,6 +335,9 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::interiorlightdimtoggle, &TTrain::OnCommand_interiorlightdimtoggle }, { user_command::interiorlightdimtoggle, &TTrain::OnCommand_interiorlightdimtoggle },
{ user_command::interiorlightdimenable, &TTrain::OnCommand_interiorlightdimenable }, { user_command::interiorlightdimenable, &TTrain::OnCommand_interiorlightdimenable },
{ user_command::interiorlightdimdisable, &TTrain::OnCommand_interiorlightdimdisable }, { 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::instrumentlighttoggle, &TTrain::OnCommand_instrumentlighttoggle },
{ user_command::instrumentlightenable, &TTrain::OnCommand_instrumentlightenable }, { user_command::instrumentlightenable, &TTrain::OnCommand_instrumentlightenable },
{ user_command::instrumentlightdisable, &TTrain::OnCommand_instrumentlightdisable }, { user_command::instrumentlightdisable, &TTrain::OnCommand_instrumentlightdisable },
@@ -536,6 +539,7 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "pant_compressor", mvControlled->PantCompFlag ); dict->insert( "pant_compressor", mvControlled->PantCompFlag );
dict->insert( "lights_front", mvOccupied->iLights[ end::front ] ); dict->insert( "lights_front", mvOccupied->iLights[ end::front ] );
dict->insert( "lights_rear", mvOccupied->iLights[ end::rear ] ); dict->insert( "lights_rear", mvOccupied->iLights[ end::rear ] );
dict->insert( "lights_compartments", mvOccupied->CompartmentLights.is_active || mvOccupied->CompartmentLights.is_disabled );
// reverser // reverser
dict->insert( "direction", mvOccupied->DirActive ); dict->insert( "direction", mvOccupied->DirActive );
// throttle // throttle
@@ -757,8 +761,8 @@ void TTrain::zero_charging_train_brake() {
&& ( DynamicObject->Controller != AIdriver ) && ( DynamicObject->Controller != AIdriver )
&& ( Global.iFeedbackMode < 3 ) && ( Global.iFeedbackMode < 3 )
&& ( ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 ) && ( ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 )
|| (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57) || ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57 )
|| (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P)) ) { || ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P ) ) ) {
// Odskakiwanie hamulce EP // Odskakiwanie hamulce EP
set_train_brake( 0 ); set_train_brake( 0 );
} }
@@ -2466,14 +2470,16 @@ void TTrain::OnCommand_linebreakeropen( TTrain *Train, command_data const &Comma
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// visual feedback // visual feedback
if( Train->m_controlmapper.contains( "main_off_bt:" ) ) { if( Train->ggMainOffButton.SubModel != nullptr ) {
Train->ggMainOffButton.UpdateValue( 1.0, Train->dsbSwitch ); 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 ); Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
} }
else { else if( Train->ggMainOnButton.SubModel != nullptr ) {
// there's no switch capable of doing the job // 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; return;
} }
// play sound immediately when the switch is hit, not after release // 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 // two separate switches to close and break the circuit
Train->ggMainOnButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggMainOnButton.UpdateValue( 1.0, Train->dsbSwitch );
} }
else { else if( Train->ggMainButton.SubModel != nullptr ) {
// single two-state switch // single two-state switch
Train->ggMainButton.UpdateValue( 1.0, Train->dsbSwitch ); 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 // the actual closing of the line breaker is handled in the train update routine
} }
else if( Command.action == GLFW_RELEASE ) { 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 // setup with two separate switches
Train->ggMainOnButton.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggMainOnButton.UpdateValue( 0.0, Train->dsbSwitch );
} }
else { else if( Train->ggMainButton.SubModel != nullptr ) {
if( Train->ggMainButton.type() != TGaugeType::toggle ) { if( Train->ggMainButton.type() != TGaugeType::toggle ) {
Train->ggMainButton.UpdateValue( 0.5, Train->dsbSwitch ); 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 ) { 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 // 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 ) // NOTE: this behaviour should depend on MainOnButton presence and type_delayed
&& ( Train->mvControlled->EngineType != TEngineType::DieselElectric ) ) { // 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 // try to finalize state change of the line breaker, set the state based on the outcome
Train->m_linebreakerstate = ( Train->m_linebreakerstate = (
Train->mvControlled->MainSwitch( true ) ? 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 ) { void TTrain::OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
@@ -5709,8 +5793,8 @@ bool TTrain::Update( double const Deltatime )
} }
} }
if( ( ggMainButton.GetDesiredValue() > 0.95 ) if( ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) )
|| ( ggMainOnButton.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 // keep track of period the line breaker button is held down, to determine when/if circuit closes
if( ( mvControlled->MainsInitTimeCountdown <= 0.0 ) if( ( mvControlled->MainsInitTimeCountdown <= 0.0 )
&& ( ( fHVoltage > 0.5 * mvControlled->EnginePowerSource.MaxVoltage ) && ( ( fHVoltage > 0.5 * mvControlled->EnginePowerSource.MaxVoltage )
@@ -5733,15 +5817,15 @@ bool TTrain::Update( double const Deltatime )
if( m_linebreakerstate == 0 ) { if( m_linebreakerstate == 0 ) {
if( fMainRelayTimer > mvControlled->InitialCtrlDelay ) { if( fMainRelayTimer > mvControlled->InitialCtrlDelay ) {
// wlaczanie WSa z opoznieniem // 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; m_linebreakerstate = 2;
} }
} }
if( m_linebreakerstate == 2 ) { if( m_linebreakerstate == 2 ) {
// for diesels and/or vehicles with toggle switch setup we complete the engine start here // 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 ) if( ( ggMainOnButton.SubModel == nullptr )
|| ( ( mvControlled->EngineType == TEngineType::DieselEngine ) || ( mvControlled->EngineType != TEngineType::ElectricSeriesMotor ) ) {
|| ( mvControlled->EngineType == TEngineType::DieselElectric ) ) ) {
// try to finalize state change of the line breaker, set the state based on the outcome // try to finalize state change of the line breaker, set the state based on the outcome
m_linebreakerstate = ( m_linebreakerstate = (
mvControlled->MainSwitch( true ) ? mvControlled->MainSwitch( true ) ?
@@ -5749,6 +5833,8 @@ bool TTrain::Update( double const Deltatime )
0 ); 0 );
} }
} }
// helper variables
m_doors = ( DynamicObject->Mechanik->IsAnyDoorOpen[ side::right ] || DynamicObject->Mechanik->IsAnyDoorOpen[ side::left ] );
// check for received user commands // check for received user commands
// NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one // 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->Mains )
|| ( mvControlled->dizel_startup ) || ( mvControlled->dizel_startup )
|| ( fMainRelayTimer > 0.f ) || ( fMainRelayTimer > 0.f )
|| ( ggMainButton.GetDesiredValue() > 0.95 ) || ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) )
|| ( ggMainOnButton.GetDesiredValue() > 0.95 ) ); || ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) );
ggIgnitionKey.Update(); ggIgnitionKey.Update();
} }
} }
@@ -6395,7 +6481,6 @@ bool TTrain::Update( double const Deltatime )
// NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu // NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu
btLampkaDoorLeft.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::left : side::right ) ] ); 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 ) ] ); 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 ); btLampkaBlokadaDrzwi.Turn( mvOccupied->Doors.is_locked );
btLampkaDoorLockOff.Turn( false == mvOccupied->Doors.lock_enabled ); btLampkaDoorLockOff.Turn( false == mvOccupied->Doors.lock_enabled );
btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal ); btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal );
@@ -6467,7 +6552,6 @@ bool TTrain::Update( double const Deltatime )
btLampkaHamulecReczny.Turn( false ); btLampkaHamulecReczny.Turn( false );
btLampkaDoorLeft.Turn( false ); btLampkaDoorLeft.Turn( false );
btLampkaDoorRight.Turn( false ); btLampkaDoorRight.Turn( false );
btLampkaDoors.Turn( false );
btLampkaBlokadaDrzwi.Turn( false ); btLampkaBlokadaDrzwi.Turn( false );
btLampkaDoorLockOff.Turn( false ); btLampkaDoorLockOff.Turn( false );
btLampkaDepartureSignal.Turn( false ); btLampkaDepartureSignal.Turn( false );
@@ -6850,6 +6934,9 @@ bool TTrain::Update( double const Deltatime )
ggTimetableLightButton.Update(); ggTimetableLightButton.Update();
ggCabLightButton.Update(); ggCabLightButton.Update();
ggCabLightDimButton.Update(); ggCabLightDimButton.Update();
ggCompartmentLightsButton.Update();
ggCompartmentLightsOnButton.Update();
ggCompartmentLightsOffButton.Update();
ggBatteryButton.Update(); ggBatteryButton.Update();
ggBatteryOnButton.Update(); ggBatteryOnButton.Update();
ggBatteryOffButton.Update(); ggBatteryOffButton.Update();
@@ -7942,13 +8029,14 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
target_train->Dynamic()->ABuSetModelShake( {} ); target_train->Dynamic()->ABuSetModelShake( {} );
} }
target_train->Dynamic()->bDisplayCab = true;
target_train->Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem? target_train->Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
// potentially move player // potentially move player
if (simulation::Train == this) { if (simulation::Train == this) {
simulation::Train = target_train; 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 // delete this TTrain
pending_delete = true; pending_delete = true;
@@ -7982,7 +8070,7 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
Occupied()->LimPipePress = Occupied()->PipePress; Occupied()->LimPipePress = Occupied()->PipePress;
Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny) Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
Dynamic()->MechInside = true; Dynamic()->MechInside = true;
Dynamic()->Controller = ( Dynamic()->Mechanik ? !Dynamic()->Mechanik->AIControllFlag : Humandriver ); Dynamic()->Controller = ( Dynamic()->Mechanik ? Dynamic()->Mechanik->AIControllFlag : Humandriver );
} else { } else {
Dynamic()->bDisplayCab = false; Dynamic()->bDisplayCab = false;
Dynamic()->ABuSetModelShake( {} ); Dynamic()->ABuSetModelShake( {} );
@@ -7994,9 +8082,13 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
Occupied()->CabActive, Occupied()->CabActive,
Dynamic()->asBaseDir + Occupied()->TypeName + ".mmd" ); Dynamic()->asBaseDir + Occupied()->TypeName + ".mmd" );
Dynamic()->bDisplayCab = true;
Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem? 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 // add it back with updated dynamic name
simulation::Trains.insert(this); simulation::Trains.insert(this);
} }
@@ -8157,6 +8249,9 @@ void TTrain::clear_cab_controls()
// hunter-091012 // hunter-091012
ggCabLightButton.Clear(); ggCabLightButton.Clear();
ggCabLightDimButton.Clear(); ggCabLightDimButton.Clear();
ggCompartmentLightsButton.Clear();
ggCompartmentLightsOnButton.Clear();
ggCompartmentLightsOffButton.Clear();
ggBatteryButton.Clear(); ggBatteryButton.Clear();
ggBatteryOnButton.Clear(); ggBatteryOnButton.Clear();
ggBatteryOffButton.Clear(); ggBatteryOffButton.Clear();
@@ -8262,7 +8357,6 @@ void TTrain::clear_cab_controls()
btLampkaWentZaluzje.Clear(); btLampkaWentZaluzje.Clear();
btLampkaDoorLeft.Clear(); btLampkaDoorLeft.Clear();
btLampkaDoorRight.Clear(); btLampkaDoorRight.Clear();
btLampkaDoors.Clear();
btLampkaDepartureSignal.Clear(); btLampkaDepartureSignal.Clear();
btLampkaRezerwa.Clear(); btLampkaRezerwa.Clear();
btLampkaBoczniki.Clear(); btLampkaBoczniki.Clear();
@@ -8337,10 +8431,12 @@ void TTrain::set_cab_controls( int const Cab ) {
mvOccupied->Battery ? 1.f : mvOccupied->Battery ? 1.f :
0.f ) ); 0.f ) );
// line breaker // line breaker
ggMainButton.PutValue( if( ggMainButton.SubModel != nullptr ) { // instead of single main button there can be on/off pair
( ggMainButton.type() == TGaugeType::push ? 0.5f : ggMainButton.PutValue(
m_linebreakerstate > 0 ? 1.f : ( ggMainButton.type() == TGaugeType::push ? 0.5f :
0.f ) ); m_linebreakerstate > 0 ? 1.f :
0.f ) );
}
// motor connectors // motor connectors
ggStLinOffButton.PutValue( ggStLinOffButton.PutValue(
( mvControlled->StLinSwitchOff ? ( mvControlled->StLinSwitchOff ?
@@ -8487,7 +8583,12 @@ void TTrain::set_cab_controls( int const Cab ) {
if( true == Cabine[Cab].bLightDim ) { if( true == Cabine[Cab].bLightDim ) {
ggCabLightDimButton.PutValue( 1.f ); 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( ( ggInstrumentLightButton.PutValue( (
InstrumentLightActive ? InstrumentLightActive ?
1.f : 1.f :
@@ -8687,7 +8788,6 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
{ "i-security_cabsignal:", btLampkaSHP }, { "i-security_cabsignal:", btLampkaSHP },
{ "i-door_left:", btLampkaDoorLeft }, { "i-door_left:", btLampkaDoorLeft },
{ "i-door_right:", btLampkaDoorRight }, { "i-door_right:", btLampkaDoorRight },
{ "i-doors:", btLampkaDoors },
{ "i-departure_signal:", btLampkaDepartureSignal }, { "i-departure_signal:", btLampkaDepartureSignal },
{ "i-reserve:", btLampkaRezerwa }, { "i-reserve:", btLampkaRezerwa },
{ "i-scnd:", btLampkaBoczniki }, { "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 // TODO: move viable dedicated lights to the automatic light array
std::unordered_map<std::string, bool const *> const autolights = { 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_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-doorpermit_right:", &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit },
{ "i-doorstep:", &mvOccupied->Doors.step_enabled }, { "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 }, { "fuse_bt:", ggFuseButton },
{ "converterfuse_bt:", ggConverterFuseButton }, { "converterfuse_bt:", ggConverterFuseButton },
{ "stlinoff_bt:", ggStLinOffButton }, { "stlinoff_bt:", ggStLinOffButton },
{ "doorleftpermit_sw:", ggDoorLeftPermitButton },
{ "doorrightpermit_sw:", ggDoorRightPermitButton },
{ "doorpermitpreset_sw:", ggDoorPermitPresetButton }, { "doorpermitpreset_sw:", ggDoorPermitPresetButton },
{ "door_left_sw:", ggDoorLeftButton }, { "door_left_sw:", ggDoorLeftButton },
{ "door_right_sw:", ggDoorRightButton }, { "door_right_sw:", ggDoorRightButton },
@@ -8854,7 +8953,6 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "doorleftoff_sw:", ggDoorLeftOffButton }, { "doorleftoff_sw:", ggDoorLeftOffButton },
{ "doorrightoff_sw:", ggDoorRightOffButton }, { "doorrightoff_sw:", ggDoorRightOffButton },
{ "doorallon_sw:", ggDoorAllOnButton }, { "doorallon_sw:", ggDoorAllOnButton },
{ "dooralloff_sw:", ggDoorAllOffButton },
{ "departure_signal_bt:", ggDepartureSignalButton }, { "departure_signal_bt:", ggDepartureSignalButton },
{ "upperlight_sw:", ggUpperLightButton }, { "upperlight_sw:", ggUpperLightButton },
{ "leftlight_sw:", ggLeftLightButton }, { "leftlight_sw:", ggLeftLightButton },
@@ -8918,6 +9016,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "timetablelight_sw:", ggTimetableLightButton }, { "timetablelight_sw:", ggTimetableLightButton },
{ "cablight_sw:", ggCabLightButton }, { "cablight_sw:", ggCabLightButton },
{ "cablightdim_sw:", ggCabLightDimButton }, { "cablightdim_sw:", ggCabLightDimButton },
{ "compartmentlights_sw:", ggCompartmentLightsButton },
{ "compartmentlightson_sw:", ggCompartmentLightsOnButton },
{ "compartmentlightsoff_sw:", ggCompartmentLightsOffButton },
{ "battery_sw:", ggBatteryButton }, { "battery_sw:", ggBatteryButton },
{ "batteryon_sw:", ggBatteryOnButton }, { "batteryon_sw:", ggBatteryOnButton },
{ "batteryoff_sw:", ggBatteryOffButton }, { "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 } }, { "speedbutton6:", { ggSpeedCtrlButtons[ 6 ], &mvOccupied->SpeedCtrlUnit.IsActive } },
{ "speedbutton7:", { ggSpeedCtrlButtons[ 7 ], &mvOccupied->SpeedCtrlUnit.IsActive } }, { "speedbutton7:", { ggSpeedCtrlButtons[ 7 ], &mvOccupied->SpeedCtrlUnit.IsActive } },
{ "speedbutton8:", { ggSpeedCtrlButtons[ 8 ], &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 ) }; auto const lookup { stategauges.find( Label ) };

10
Train.h
View File

@@ -361,6 +361,9 @@ class TTrain {
static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlightdimenable( 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_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_instrumentlighttoggle( TTrain *Train, command_data const &Command );
static void OnCommand_instrumentlightenable( 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 ); static void OnCommand_instrumentlightdisable( TTrain *Train, command_data const &Command );
@@ -539,10 +542,13 @@ public: // reszta może by?publiczna
TGauge ggTimetableLightButton; TGauge ggTimetableLightButton;
TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny
TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia
// oswietlenia kabiny
TGauge ggCompartmentLightsButton;
TGauge ggCompartmentLightsOnButton;
TGauge ggCompartmentLightsOffButton;
TGauge ggBatteryButton; // Stele 161228 hebelek baterii TGauge ggBatteryButton; // Stele 161228 hebelek baterii
TGauge ggBatteryOnButton; TGauge ggBatteryOnButton;
TGauge ggBatteryOffButton; TGauge ggBatteryOffButton;
// oswietlenia kabiny
// NBMX wrzesien 2003 - obsluga drzwi // NBMX wrzesien 2003 - obsluga drzwi
TGauge ggDoorLeftPermitButton; TGauge ggDoorLeftPermitButton;
@@ -661,7 +667,6 @@ public: // reszta może by?publiczna
TButton btLampkaPrzekrMaxSila; TButton btLampkaPrzekrMaxSila;
TButton btLampkaDoorLeft; TButton btLampkaDoorLeft;
TButton btLampkaDoorRight; TButton btLampkaDoorRight;
TButton btLampkaDoors;
TButton btLampkaDepartureSignal; TButton btLampkaDepartureSignal;
TButton btLampkaBlokadaDrzwi; TButton btLampkaBlokadaDrzwi;
TButton btLampkaDoorLockOff; TButton btLampkaDoorLockOff;
@@ -776,6 +781,7 @@ private:
float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive
double m_brakehandlecp{ 0.0 }; double m_brakehandlecp{ 0.0 };
int m_pantselection{ 0 }; int m_pantselection{ 0 };
bool m_doors{ false }; // helper, true if any door is open
public: public:
float fPress[20][3]; // cisnienia dla wszystkich czlonow float fPress[20][3]; // cisnienia dla wszystkich czlonow

View File

@@ -224,6 +224,9 @@ commanddescription_sequence Commands_descriptions = {
{ "interiorlightdimtoggle", command_target::vehicle }, { "interiorlightdimtoggle", command_target::vehicle },
{ "interiorlightdimenable", command_target::vehicle }, { "interiorlightdimenable", command_target::vehicle },
{ "interiorlightdimdisable", command_target::vehicle }, { "interiorlightdimdisable", command_target::vehicle },
{ "compartmentlightstoggle", command_target::vehicle },
{ "compartmentlightsenable", command_target::vehicle },
{ "compartmentlightsdisable", command_target::vehicle },
{ "instrumentlighttoggle", command_target::vehicle }, { "instrumentlighttoggle", command_target::vehicle },
{ "instrumentlightenable", command_target::vehicle }, { "instrumentlightenable", command_target::vehicle },
{ "instrumentlightdisable", command_target::vehicle }, { "instrumentlightdisable", command_target::vehicle },

View File

@@ -215,6 +215,9 @@ enum class user_command {
interiorlightdimtoggle, interiorlightdimtoggle,
interiorlightdimenable, interiorlightdimenable,
interiorlightdimdisable, interiorlightdimdisable,
compartmentlightstoggle,
compartmentlightsenable,
compartmentlightsdisable,
instrumentlighttoggle, instrumentlighttoggle,
instrumentlightenable, instrumentlightenable,
instrumentlightdisable, instrumentlightdisable,

View File

@@ -224,6 +224,9 @@ driverkeyboard_input::default_bindings() {
{ user_command::interiorlightdimtoggle, GLFW_KEY_APOSTROPHE | keymodifier::control }, { user_command::interiorlightdimtoggle, GLFW_KEY_APOSTROPHE | keymodifier::control },
// interiorlightdimenable, // interiorlightdimenable,
// interiorlightdimdisable, // interiorlightdimdisable,
// compartmentlightstoggle,
// compartmentlightsenable,
// compartmentlightsdisable,
{ user_command::instrumentlighttoggle, GLFW_KEY_SEMICOLON }, { user_command::instrumentlighttoggle, GLFW_KEY_SEMICOLON },
// instrumentlightenable, // instrumentlightenable,
// instrumentlightdisable, // instrumentlightdisable,

View File

@@ -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::linebreakerclose, { user_command::linebreakertoggle, user_command::none } },
{ user_command::pantographlowerfront, { user_command::pantographtogglefront, user_command::none } }, { user_command::pantographlowerfront, { user_command::pantographtogglefront, user_command::none } },
{ user_command::pantographlowerrear, { user_command::pantographtogglerear, 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> std::pair<user_command, user_command>

View File

@@ -837,6 +837,15 @@ drivermouse_input::default_bindings() {
{ "cablightdim_sw:", { { "cablightdim_sw:", {
user_command::interiorlightdimtoggle, user_command::interiorlightdimtoggle,
user_command::none } }, 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:", { { "battery_sw:", {
user_command::batterytoggle, user_command::batterytoggle,
user_command::none } }, user_command::none } },

View File

@@ -97,7 +97,7 @@
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <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> <SubSystem>Windows</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries> </IgnoreSpecificDefaultLibraries>
@@ -120,7 +120,7 @@
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <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> <SubSystem>Windows</SubSystem>
<IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries> </IgnoreSpecificDefaultLibraries>
@@ -142,7 +142,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <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> <SubSystem>Windows</SubSystem>
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
<LargeAddressAware>true</LargeAddressAware> <LargeAddressAware>true</LargeAddressAware>
@@ -166,7 +166,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <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> <SubSystem>Windows</SubSystem>
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>

View File

@@ -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 ) ) ); setup_shadow_color( glm::min( colors::white, m_shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) );
} }
Render_cab( vehicle, vehicle->InteriorLightLevel, false ); 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"); glDebug("render opaque region");
model_ubs.future = future; model_ubs.future = future;
@@ -755,9 +754,9 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
} }
glDebug( "render translucent cab" ); glDebug( "render translucent cab" );
Render_cab(vehicle, vehicle->InteriorLightLevel, true); 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 ) { if( Global.Overcast > 1.0f ) {
// with the cab in place we can (finally) safely draw translucent part of the occupied vehicle // with the cab in place we can (finally) safely draw translucent part of the occupied vehicle
Render_Alpha( 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 // HACK: reduce light level for vehicle interior if there's strong global lighting source
if( false == Alpha ) { 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( setup_sunlight_intensity(
clamp( ( clamp( (
Dynamic->fShade > 0.f ? Dynamic->fShade > 0.f ?
@@ -1729,7 +1740,7 @@ std::shared_ptr<gl::program> opengl33_renderer::Fetch_Shader(const std::string &
return m_shaders[name]; 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) 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 // material-based parameters
switch( entry.defaultparam ) { switch( entry.defaultparam ) {
case gl::shader::defaultparam_e::glossiness: { 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::color:
case rendermode::reflections: case rendermode::reflections:
Bind_Material(data.material); Bind_Material(data.material, nullptr, &Shape.data().lighting );
break; break;
case rendermode::shadows: case rendermode::shadows:
Bind_Material_Shadow(data.material); 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 old_ambient { light_ubs.ambient };
auto const luminance { Global.fLuminance * ( Dynamic->fShade > 0.0f ? Dynamic->fShade : 1.0f ) };
if( Lightlevel > 0.f ) { if( Lightlevel > 0.f ) {
// crude way to light the cabin, until we have something more complete in place // 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 ); 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); Render(Dynamic->mdKabina, Dynamic->Material(), 0.0);
} }
// post-render restore // post-render restore
if (Dynamic->fShade > 0.0f) light_ubs.ambient = old_ambient;
{ setup_sunlight_intensity();
// 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 );
}
break; break;
} }

View File

@@ -73,7 +73,7 @@ class opengl33_renderer : public gfx_renderer {
material_handle material_handle
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override; Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override;
void 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 & opengl_material const &
Material( material_handle const Material ) const override; Material( material_handle const Material ) const override;
// shader methods // shader methods

View File

@@ -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 // HACK: reduce light level for vehicle interior if there's strong global lighting source
if( false == Alpha ) { 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( m_sunlight.apply_intensity(
clamp( ( clamp( (
Dynamic->fShade > 0.f ? Dynamic->fShade > 0.f ?
@@ -1677,7 +1684,7 @@ opengl_renderer::Fetch_Material( std::string const &Filename, bool const Loadnow
} }
void 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 ); auto const &material = m_materials.material( Material );
if( false == Global.BasicRenderer ) { if( false == Global.BasicRenderer ) {
@@ -2403,11 +2410,12 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, float const Lightlev
} }
if( Lightlevel > 0.f ) { if( Lightlevel > 0.f ) {
// crude way to light the cabin, until we have something more complete in place // 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( ::glLightModelfv(
GL_LIGHT_MODEL_AMBIENT, GL_LIGHT_MODEL_AMBIENT,
glm::value_ptr( glm::value_ptr(
glm::vec3( m_baseambient ) 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 // render
if( true == Alpha ) { if( true == Alpha ) {

View File

@@ -67,7 +67,7 @@ public:
material_handle material_handle
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override; Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override;
void 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 & opengl_material const &
Material( material_handle const Material ) const override; Material( material_handle const Material ) const override;
// shader methods // shader methods

View File

@@ -12,6 +12,8 @@ http://mozilla.org/MPL/2.0/.
#include "geometrybank.h" #include "geometrybank.h"
#include "material.h" #include "material.h"
class lighting_data;
class gfx_renderer { class gfx_renderer {
public: public:
@@ -38,7 +40,7 @@ public:
virtual auto Vertices( gfx::geometry_handle const &Geometry ) const ->gfx::vertex_array const & = 0; virtual auto Vertices( gfx::geometry_handle const &Geometry ) const ->gfx::vertex_array const & = 0;
// material methods // material methods
virtual auto Fetch_Material( std::string const &Filename, bool const Loadnow = true ) -> material_handle = 0; 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; virtual auto Material( material_handle const Material ) const -> opengl_material const & = 0;
// shader methods // shader methods
virtual auto Fetch_Shader( std::string const &name ) -> std::shared_ptr<gl::program> = 0; virtual auto Fetch_Shader( std::string const &name ) -> std::shared_ptr<gl::program> = 0;

View File

@@ -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) 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 emissioncolor = param[0].rgb * emission;
vec3 envcolor = envmap_color(fragnormal); vec3 envcolor = envmap_color(fragnormal);
if(lights_count == 0U) if(lights_count == 0U)
return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor; return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor;
// fragcolor *= lights[0].intensity;
vec2 sunlight = calc_dir_light(lights[0], fragnormal); vec2 sunlight = calc_dir_light(lights[0], fragnormal);
float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity; float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity;

View File

@@ -202,6 +202,9 @@ init() {
"timetable light", "timetable light",
"interior light", "interior light",
"interior light dimmer", "interior light dimmer",
"compartment lights",
"compartment lights",
"compartment lights",
"battery", "battery",
"battery", "battery",
"battery", "battery",
@@ -397,6 +400,9 @@ init() {
"oswietlenie rozkladu jazdy", "oswietlenie rozkladu jazdy",
"oswietlenie kabiny", "oswietlenie kabiny",
"przyciemnienie oswietlenia kabiny", "przyciemnienie oswietlenia kabiny",
"oswietlenie przedzialow",
"oswietlenie przedzialow",
"oswietlenie przedzialow",
"bateria", "bateria",
"bateria", "bateria",
"bateria", "bateria",
@@ -545,6 +551,9 @@ init() {
"timetablelight_sw:", "timetablelight_sw:",
"cablight_sw:", "cablight_sw:",
"cablightdim_sw:", "cablightdim_sw:",
"compartmentlights_sw:",
"compartmentlightson_sw:",
"compartmentlightsoff_sw:",
"battery_sw:", "battery_sw:",
"batteryon_sw:", "batteryon_sw:",
"batteryoff_sw:", "batteryoff_sw:",

View File

@@ -191,6 +191,9 @@ enum string {
cab_timetablelight_sw, cab_timetablelight_sw,
cab_cablight_sw, cab_cablight_sw,
cab_cablightdim_sw, cab_cablightdim_sw,
cab_compartmentlights_sw,
cab_compartmentlightson_sw,
cab_compartmentlightsoff_sw,
cab_battery_sw, cab_battery_sw,
cab_batteryon_sw, cab_batteryon_sw,
cab_batteryoff_sw, cab_batteryoff_sw,