mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 09:19:18 +02:00
engine-powered compressor sound pitch adjustment, model node angles, global settings export and diagnostics, departure permit sound enhancement, radio channel selection ai logic enhancement, door permission ai logic fix
This commit is contained in:
@@ -432,6 +432,15 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
|
|||||||
return ( pModel != nullptr );
|
return ( pModel != nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TAnimModel::is_keyword( std::string const &Token ) const {
|
||||||
|
|
||||||
|
return ( Token == "endmodel" )
|
||||||
|
|| ( Token == "lights" )
|
||||||
|
|| ( Token == "lightcolors" )
|
||||||
|
|| ( Token == "angles" );
|
||||||
|
}
|
||||||
|
|
||||||
bool TAnimModel::Load(cParser *parser, bool ter)
|
bool TAnimModel::Load(cParser *parser, bool ter)
|
||||||
{ // rozpoznanie wpisu modelu i ustawienie świateł
|
{ // rozpoznanie wpisu modelu i ustawienie świateł
|
||||||
std::string name = parser->getToken<std::string>();
|
std::string name = parser->getToken<std::string>();
|
||||||
@@ -485,8 +494,7 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
|||||||
if( token == "lights" ) {
|
if( token == "lights" ) {
|
||||||
auto i{ 0 };
|
auto i{ 0 };
|
||||||
while( ( false == ( token = parser->getToken<std::string>() ).empty() )
|
while( ( false == ( token = parser->getToken<std::string>() ).empty() )
|
||||||
&& ( token != "lightcolors" )
|
&& ( false == is_keyword( token ) ) ) {
|
||||||
&& ( token != "endmodel" ) ) {
|
|
||||||
|
|
||||||
if( i < iNumLights ) {
|
if( i < iNumLights ) {
|
||||||
// stan światła jest liczbą z ułamkiem
|
// stan światła jest liczbą z ułamkiem
|
||||||
@@ -499,8 +507,7 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
|||||||
if( token == "lightcolors" ) {
|
if( token == "lightcolors" ) {
|
||||||
auto i{ 0 };
|
auto i{ 0 };
|
||||||
while( ( false == ( token = parser->getToken<std::string>() ).empty() )
|
while( ( false == ( token = parser->getToken<std::string>() ).empty() )
|
||||||
&& ( token != "lights" )
|
&& ( false == is_keyword( token ) ) ) {
|
||||||
&& ( token != "endmodel" ) ) {
|
|
||||||
|
|
||||||
if( ( i < iNumLights )
|
if( ( i < iNumLights )
|
||||||
&& ( token != "-1" ) ) { // -1 leaves the default color intact
|
&& ( token != "-1" ) ) { // -1 leaves the default color intact
|
||||||
@@ -513,6 +520,15 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( token == "angles" ) {
|
||||||
|
parser->getTokens( 3 );
|
||||||
|
*parser
|
||||||
|
>> vAngle[ 0 ]
|
||||||
|
>> vAngle[ 1 ]
|
||||||
|
>> vAngle[ 2 ];
|
||||||
|
}
|
||||||
|
|
||||||
} while( ( false == token.empty() )
|
} while( ( false == token.empty() )
|
||||||
&& ( token != "endmodel" ) );
|
&& ( token != "endmodel" ) );
|
||||||
|
|
||||||
|
|||||||
@@ -177,6 +177,8 @@ private:
|
|||||||
void deserialize_( std::istream &Input );
|
void deserialize_( std::istream &Input );
|
||||||
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
|
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
|
||||||
void export_as_text_( std::ostream &Output ) const;
|
void export_as_text_( std::ostream &Output ) const;
|
||||||
|
// checks whether provided token is a legacy (text) format keyword
|
||||||
|
bool is_keyword( std::string const &Token ) const;
|
||||||
|
|
||||||
// members
|
// members
|
||||||
TAnimContainer *pRoot { nullptr }; // pojemniki sterujące, tylko dla aniomowanych submodeli
|
TAnimContainer *pRoot { nullptr }; // pojemniki sterujące, tylko dla aniomowanych submodeli
|
||||||
|
|||||||
93
Driver.cpp
93
Driver.cpp
@@ -898,6 +898,21 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
}
|
}
|
||||||
else if (iDrivigFlags & moveStopPoint) // jeśli pomijanie W4, to nie sprawdza czasu odjazdu
|
else if (iDrivigFlags & moveStopPoint) // jeśli pomijanie W4, to nie sprawdza czasu odjazdu
|
||||||
{ // tylko gdy nazwa zatrzymania się zgadza
|
{ // tylko gdy nazwa zatrzymania się zgadza
|
||||||
|
if( ( OrderCurrentGet() & ( Obey_train | Bank ) ) != 0 ) {
|
||||||
|
// check whether the station specifies radio channel change
|
||||||
|
// NOTE: we don't do it in shunt mode, as shunting operations tend to use dedicated radio channel
|
||||||
|
// NOTE: there's a risk radio channel change was specified by a station which we skipped during timetable rewind
|
||||||
|
// we ignore this for the time being as it's not a high priority error
|
||||||
|
auto const radiochannel { TrainParams.radio_channel() };
|
||||||
|
if( radiochannel > 0 ) {
|
||||||
|
if( iGuardRadio != 0 ) {
|
||||||
|
iGuardRadio = radiochannel;
|
||||||
|
}
|
||||||
|
if( AIControllFlag ) {
|
||||||
|
iRadioChannel = radiochannel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
IsScheduledPassengerStopVisible = true; // block potential timetable rewind if the next stop shows up later in the scan
|
IsScheduledPassengerStopVisible = true; // block potential timetable rewind if the next stop shows up later in the scan
|
||||||
if (false == TrainParams.IsStop())
|
if (false == TrainParams.IsStop())
|
||||||
{ // jeśli nie ma tu postoju
|
{ // jeśli nie ma tu postoju
|
||||||
@@ -3217,8 +3232,8 @@ bool TController::IncSpeed()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool OK = true;
|
bool OK = true;
|
||||||
if( ( doors_open() )
|
if( ( VelDesired > 0.0 ) // to prevent door shuffle on stop
|
||||||
&& ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop
|
&& ( doors_open() || doors_permit_active() ) ) {
|
||||||
// zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
|
// zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
|
||||||
Doors( false );
|
Doors( false );
|
||||||
}
|
}
|
||||||
@@ -4091,14 +4106,14 @@ void TController::Doors( bool const Open, int const Side ) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// zamykanie
|
// zamykanie
|
||||||
if( ( false == pVehicle->MoverParameters->Doors.permit_needed )
|
if( ( false == doors_permit_active() )
|
||||||
&& ( false == doors_open() ) ) {
|
&& ( false == doors_open() ) ) {
|
||||||
// the doors are already closed and we don't have to revoke control permit, we can skip all hard work
|
// the doors are already closed and we don't have to revoke control permit, we can skip all hard work
|
||||||
iDrivigFlags &= ~moveDoorOpened;
|
iDrivigFlags &= ~moveDoorOpened;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( AIControllFlag ) {
|
if( ( AIControllFlag ) && ( doors_open() ) ) {
|
||||||
if( ( true == mvOccupied->Doors.has_warning )
|
if( ( true == mvOccupied->Doors.has_warning )
|
||||||
&& ( false == mvOccupied->DepartureSignal )
|
&& ( false == mvOccupied->DepartureSignal )
|
||||||
&& ( true == TestFlag( iDrivigFlags, moveDoorOpened ) ) ) {
|
&& ( true == TestFlag( iDrivigFlags, moveDoorOpened ) ) ) {
|
||||||
@@ -4107,20 +4122,22 @@ void TController::Doors( bool const Open, int const Side ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( true == doors_open() )
|
if( ( false == AIControllFlag ) || ( fActionTime > -0.5 ) ) {
|
||||||
&& ( ( fActionTime > -0.5 )
|
|
||||||
|| ( false == AIControllFlag ) ) ) {
|
|
||||||
// ai doesn't close the door until it's free to depart, but human driver has free reign to do stupid things
|
// ai doesn't close the door until it's free to depart, but human driver has free reign to do stupid things
|
||||||
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::conductor )
|
if( true == doors_open() ) {
|
||||||
|| ( ( true == AIControllFlag ) ) ) {
|
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::conductor )
|
||||||
// if the door are controlled by the driver, we let the user operate them unless this user is an ai
|
|| ( ( true == AIControllFlag ) ) ) {
|
||||||
// the train conductor, if present, handles door operation also for human-driven trains
|
// if the door are controlled by the driver, we let the user operate them unless this user is an ai
|
||||||
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::driver )
|
// the train conductor, if present, handles door operation also for human-driven trains
|
||||||
|| ( pVehicle->MoverParameters->Doors.close_control == control_t::mixed ) ) {
|
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::driver )
|
||||||
pVehicle->MoverParameters->OperateDoors( side::right, false );
|
|| ( pVehicle->MoverParameters->Doors.close_control == control_t::mixed ) ) {
|
||||||
pVehicle->MoverParameters->OperateDoors( side::left, false );
|
pVehicle->MoverParameters->OperateDoors( side::right, false );
|
||||||
|
pVehicle->MoverParameters->OperateDoors( side::left, false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( pVehicle->MoverParameters->Doors.permit_needed ) {
|
}
|
||||||
|
if( true == doors_permit_active() ) {
|
||||||
|
if( true == AIControllFlag ) {
|
||||||
pVehicle->MoverParameters->PermitDoors( side::right, false );
|
pVehicle->MoverParameters->PermitDoors( side::right, false );
|
||||||
pVehicle->MoverParameters->PermitDoors( side::left, false );
|
pVehicle->MoverParameters->PermitDoors( side::left, false );
|
||||||
}
|
}
|
||||||
@@ -4157,19 +4174,14 @@ TController::doors_open() const {
|
|||||||
return (
|
return (
|
||||||
IsAnyDoorOpen[ side::right ]
|
IsAnyDoorOpen[ side::right ]
|
||||||
|| IsAnyDoorOpen[ side::left ] );
|
|| IsAnyDoorOpen[ side::left ] );
|
||||||
/*
|
}
|
||||||
auto *vehicle = pVehicles[ 0 ]; // pojazd na czole składu
|
|
||||||
while( vehicle != nullptr ) {
|
bool
|
||||||
if( ( false == vehicle->MoverParameters->Doors.instances[side::right].is_closed )
|
TController::doors_permit_active() const {
|
||||||
|| ( false == vehicle->MoverParameters->Doors.instances[side::left].is_closed ) ) {
|
|
||||||
// any open door is enough
|
return (
|
||||||
return true;
|
IsAnyDoorPermitActive[ side::right ]
|
||||||
}
|
|| IsAnyDoorPermitActive[ side::left ] );
|
||||||
vehicle = vehicle->Next();
|
|
||||||
}
|
|
||||||
// if we're still here there's nothing open
|
|
||||||
return false;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TController::RecognizeCommand()
|
void TController::RecognizeCommand()
|
||||||
@@ -4275,7 +4287,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
{ ".ogg", ".flac", ".wav" } );
|
{ ".ogg", ".flac", ".wav" } );
|
||||||
if( false == lookup.first.empty() ) {
|
if( false == lookup.first.empty() ) {
|
||||||
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
|
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
|
||||||
tsGuardSignal = sound_source( sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE ).deserialize( lookup.first + lookup.second, sound_type::single );
|
tsGuardSignal = sound_source( sound_placement::internal, EU07_SOUND_HANDHELDRADIORANGE ).deserialize( lookup.first + lookup.second, sound_type::single );
|
||||||
iGuardRadio = iRadioChannel;
|
iGuardRadio = iRadioChannel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4733,6 +4745,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
double AbsAccS = 0;
|
double AbsAccS = 0;
|
||||||
IsAnyCouplerStretched = false;
|
IsAnyCouplerStretched = false;
|
||||||
IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::left ] = false;
|
IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::left ] = false;
|
||||||
|
IsAnyDoorPermitActive[ side::right ] = IsAnyDoorPermitActive[ side::left ] = false;
|
||||||
ConsistShade = 0.0;
|
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)
|
||||||
@@ -4777,12 +4790,11 @@ TController::UpdateSituation(double dt) {
|
|||||||
|| ( vehicle->Couplers[ end::rear ].stretch_duration > 0.0 );
|
|| ( vehicle->Couplers[ end::rear ].stretch_duration > 0.0 );
|
||||||
// check door state
|
// check door state
|
||||||
auto const switchsides { p->DirectionGet() != iDirection };
|
auto const switchsides { p->DirectionGet() != iDirection };
|
||||||
IsAnyDoorOpen[ side::right ] =
|
IsAnyDoorOpen[ side::right ] |= ( false == vehicle->Doors.instances[ ( switchsides ? side::left : side::right ) ].is_closed );
|
||||||
IsAnyDoorOpen[ side::right ]
|
IsAnyDoorOpen[ side::left ] |= ( false == vehicle->Doors.instances[ ( switchsides ? side::right : side::left ) ].is_closed );
|
||||||
|| ( false == vehicle->Doors.instances[ ( switchsides ? side::left : side::right ) ].is_closed );
|
IsAnyDoorPermitActive[ side::right ] |= ( vehicle->Doors.permit_needed && vehicle->Doors.instances[ ( switchsides ? side::left : side::right ) ].open_permit );
|
||||||
IsAnyDoorOpen[ side::left ] =
|
IsAnyDoorPermitActive[ side::left ] |= ( vehicle->Doors.permit_needed && vehicle->Doors.instances[ ( switchsides ? side::right : side::left ) ].open_permit );
|
||||||
IsAnyDoorOpen[ side::left ]
|
|
||||||
|| ( false == vehicle->Doors.instances[ ( switchsides ? side::right : side::left ) ].is_closed );
|
|
||||||
// measure lighting level
|
// measure lighting level
|
||||||
// TBD: apply weight (multiplier) to partially lit vehicles?
|
// TBD: apply weight (multiplier) to partially lit vehicles?
|
||||||
ConsistShade += ( p->fShade > 0.0 ? p->fShade : 1.0 );
|
ConsistShade += ( p->fShade > 0.0 ? p->fShade : 1.0 );
|
||||||
@@ -6012,14 +6024,13 @@ TController::UpdateSituation(double dt) {
|
|||||||
fActionTime = -5.0; // niech trochę potrzyma
|
fActionTime = -5.0; // niech trochę potrzyma
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if (iGuardRadio==iRadioChannel) //zgodność kanału
|
// radio message
|
||||||
// if (!FreeFlyModeFlag) //obserwator musi być w środku pojazdu
|
|
||||||
// (albo może mieć radio przenośne) - kierownik mógłby powtarzać przy braku reakcji
|
|
||||||
// TODO: proper system for sending/receiving radio messages
|
|
||||||
// place the sound in appropriate cab of the manned vehicle
|
|
||||||
tsGuardSignal.owner( pVehicle );
|
tsGuardSignal.owner( pVehicle );
|
||||||
|
/*
|
||||||
tsGuardSignal.offset( { 0.f, 2.f, pVehicle->MoverParameters->Dim.L * 0.4f * ( pVehicle->MoverParameters->CabOccupied < 0 ? -1 : 1 ) } );
|
tsGuardSignal.offset( { 0.f, 2.f, pVehicle->MoverParameters->Dim.L * 0.4f * ( pVehicle->MoverParameters->CabOccupied < 0 ? -1 : 1 ) } );
|
||||||
tsGuardSignal.play( sound_flags::exclusive );
|
tsGuardSignal.play( sound_flags::exclusive );
|
||||||
|
*/
|
||||||
|
simulation::radio_message( &tsGuardSignal, iGuardRadio );
|
||||||
// NOTE: we can't rely on is_playing() check as sound playback is based on distance from local camera
|
// NOTE: we can't rely on is_playing() check as sound playback is based on distance from local camera
|
||||||
fActionTime = -5.0; // niech trochę potrzyma
|
fActionTime = -5.0; // niech trochę potrzyma
|
||||||
}
|
}
|
||||||
|
|||||||
2
Driver.h
2
Driver.h
@@ -465,6 +465,7 @@ private:
|
|||||||
void Doors( bool const Open, int const Side = 0 );
|
void Doors( bool const Open, int const Side = 0 );
|
||||||
// returns true if any vehicle in the consist has an open door
|
// returns true if any vehicle in the consist has an open door
|
||||||
bool doors_open() const;
|
bool doors_open() const;
|
||||||
|
bool doors_permit_active() const;
|
||||||
void AutoRewident(); // ustawia hamulce w składzie
|
void AutoRewident(); // ustawia hamulce w składzie
|
||||||
void UpdatePantographs();
|
void UpdatePantographs();
|
||||||
// members
|
// members
|
||||||
@@ -482,6 +483,7 @@ private:
|
|||||||
double ConsistShade{ 1.0 }; // averaged amount of sunlight received by the consist
|
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
|
||||||
|
bool IsAnyDoorPermitActive[ 2 ]; // state of door permit in the consist
|
||||||
bool IsAnyLineBreakerOpen{ false }; // state of line breaker in all powered vehicles under control
|
bool IsAnyLineBreakerOpen{ false }; // state of line breaker in all powered vehicles under control
|
||||||
bool IsAnyConverterOverloadRelayOpen{ false }; // state of converter overload relays in all vehicles under control
|
bool IsAnyConverterOverloadRelayOpen{ false }; // state of converter overload relays in all vehicles under control
|
||||||
bool IsAnyMotorOverloadRelayOpen{ false }; // state of motor overload relays in all vehicles under control
|
bool IsAnyMotorOverloadRelayOpen{ false }; // state of motor overload relays in all vehicles under control
|
||||||
|
|||||||
17
DynObj.cpp
17
DynObj.cpp
@@ -4096,6 +4096,15 @@ void TDynamicObject::RenderSounds() {
|
|||||||
if( MoverParameters->CompressorSpeed > 0.0 ) {
|
if( MoverParameters->CompressorSpeed > 0.0 ) {
|
||||||
// McZapkie! - dzwiek compressor.wav tylko gdy dziala sprezarka
|
// McZapkie! - dzwiek compressor.wav tylko gdy dziala sprezarka
|
||||||
if( MoverParameters->CompressorFlag ) {
|
if( MoverParameters->CompressorFlag ) {
|
||||||
|
if( MoverParameters->CompressorPower == 3 ) {
|
||||||
|
// presume the compressor sound is recorded for idle revolutions
|
||||||
|
// increase the pitch according to increase of engine revolutions
|
||||||
|
auto const enginefactor { ( MoverParameters->EngineMaxRPM() / MoverParameters->EngineIdleRPM() ) * MoverParameters->EngineRPMRatio() };
|
||||||
|
sCompressor.pitch(
|
||||||
|
clamp( // try to keep the sound pitch in semi-reasonable range
|
||||||
|
enginefactor,
|
||||||
|
0.5, 2.5 ) );
|
||||||
|
}
|
||||||
sCompressor.play( sound_flags::exclusive | sound_flags::looping );
|
sCompressor.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -7269,7 +7278,7 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
engine.m_amplitudeoffset
|
engine.m_amplitudeoffset
|
||||||
+ engine.m_amplitudefactor * (
|
+ engine.m_amplitudefactor * (
|
||||||
0.25 * ( Vehicle.EnginePower / Vehicle.Power )
|
0.25 * ( Vehicle.EnginePower / Vehicle.Power )
|
||||||
+ 0.75 * ( Vehicle.enrot * 60 ) / ( Vehicle.DElist[ Vehicle.MainCtrlPosNo ].RPM ) );
|
+ 0.75 * Vehicle.EngineRPMRatio() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TEngineType::DieselEngine: {
|
case TEngineType::DieselEngine: {
|
||||||
@@ -7299,11 +7308,7 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
// calculate potential recent increase of engine revolutions
|
// calculate potential recent increase of engine revolutions
|
||||||
auto const revolutionsperminute { Vehicle.enrot * 60 };
|
auto const revolutionsperminute { Vehicle.enrot * 60 };
|
||||||
auto const revolutionsdifference { revolutionsperminute - engine_revs_last };
|
auto const revolutionsdifference { revolutionsperminute - engine_revs_last };
|
||||||
auto const idlerevolutionsthreshold { 1.01 * (
|
auto const idlerevolutionsthreshold { 1.01 * Vehicle.EngineIdleRPM() };
|
||||||
Vehicle.EngineType == TEngineType::DieselElectric ?
|
|
||||||
Vehicle.DElist[ 0 ].RPM :
|
|
||||||
Vehicle.dizel_nmin * 60 ) };
|
|
||||||
|
|
||||||
engine_revs_change = std::max( 0.0, engine_revs_change - 2.5 * Deltatime );
|
engine_revs_change = std::max( 0.0, engine_revs_change - 2.5 * Deltatime );
|
||||||
if( ( revolutionsperminute > idlerevolutionsthreshold )
|
if( ( revolutionsperminute > idlerevolutionsthreshold )
|
||||||
&& ( revolutionsdifference > 1.0 * Deltatime ) ) {
|
&& ( revolutionsdifference > 1.0 * Deltatime ) ) {
|
||||||
|
|||||||
247
Globals.cpp
247
Globals.cpp
@@ -656,10 +656,11 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser >> token;
|
Parser >> token;
|
||||||
auto const priority { token };
|
auto const priority { token };
|
||||||
PythonScreenUpdateRate = (
|
PythonScreenUpdateRate = (
|
||||||
|
priority == "normal" ? 200 :
|
||||||
priority == "lower" ? 500 :
|
priority == "lower" ? 500 :
|
||||||
priority == "lowest" ? 1000 :
|
priority == "lowest" ? 1000 :
|
||||||
priority == "off" ? 0 :
|
priority == "off" ? 0 :
|
||||||
200 );
|
stol_def( priority, 200 ) );
|
||||||
}
|
}
|
||||||
else if( token == "python.updatetime" )
|
else if( token == "python.updatetime" )
|
||||||
{
|
{
|
||||||
@@ -954,4 +955,246 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej
|
Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
global_settings::export_as_text( std::ostream &Output ) const {
|
||||||
|
|
||||||
|
export_as_text( Output, "sceneryfile", SceneryFile );
|
||||||
|
export_as_text( Output, "humanctrlvehicle", local_start_vehicle );
|
||||||
|
export_as_text( Output, "fieldofview", FieldOfView );
|
||||||
|
export_as_text( Output, "width", iWindowWidth );
|
||||||
|
export_as_text( Output, "height", iWindowHeight );
|
||||||
|
export_as_text( Output, "heightbase", fDistanceFactor );
|
||||||
|
export_as_text( Output, "targetfps", targetfps );
|
||||||
|
export_as_text( Output, "basedrawrange", BaseDrawRange );
|
||||||
|
export_as_text( Output, "fullscreen", bFullScreen );
|
||||||
|
export_as_text( Output, "fullscreenmonitor", fullscreen_monitor );
|
||||||
|
export_as_text( Output, "vsync", VSync );
|
||||||
|
// NOTE: values are changed dynamically during simulation. cache initial settings and export instead
|
||||||
|
if( FreeFlyModeFlag ) {
|
||||||
|
Output
|
||||||
|
<< "freefly yes "
|
||||||
|
<< FreeCameraInit[ 0 ].x << " "
|
||||||
|
<< FreeCameraInit[ 0 ].y << " "
|
||||||
|
<< FreeCameraInit[ 0 ].z << "\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
export_as_text( Output, "freefly", FreeFlyModeFlag );
|
||||||
|
}
|
||||||
|
export_as_text( Output, "wireframe", bWireFrame );
|
||||||
|
export_as_text( Output, "debugmode", DebugModeFlag );
|
||||||
|
export_as_text( Output, "soundenabled", bSoundEnabled );
|
||||||
|
export_as_text( Output, "sound.openal.renderer", AudioRenderer );
|
||||||
|
export_as_text( Output, "sound.volume", AudioVolume );
|
||||||
|
export_as_text( Output, "sound.volume.radio", RadioVolume );
|
||||||
|
export_as_text( Output, "physicslog", WriteLogFlag );
|
||||||
|
export_as_text( Output, "fullphysics", FullPhysics );
|
||||||
|
export_as_text( Output, "debuglog", iWriteLogEnabled );
|
||||||
|
export_as_text( Output, "multiplelogs", MultipleLogs );
|
||||||
|
export_as_text( Output, "logs.filter", DisabledLogTypes );
|
||||||
|
Output
|
||||||
|
<< "mousescale "
|
||||||
|
<< fMouseXScale << " "
|
||||||
|
<< fMouseYScale << "\n";
|
||||||
|
export_as_text( Output, "mousecontrol", InputMouse );
|
||||||
|
export_as_text( Output, "enabletraction", bEnableTraction );
|
||||||
|
export_as_text( Output, "loadtraction", bLoadTraction );
|
||||||
|
export_as_text( Output, "friction", fFriction );
|
||||||
|
export_as_text( Output, "livetraction", bLiveTraction );
|
||||||
|
export_as_text( Output, "skyenabled", asSky );
|
||||||
|
export_as_text( Output, "defaultext", szDefaultExt );
|
||||||
|
export_as_text( Output, "newaircouplers", bnewAirCouplers );
|
||||||
|
export_as_text( Output, "anisotropicfiltering", AnisotropicFiltering );
|
||||||
|
export_as_text( Output, "usevbo", bUseVBO );
|
||||||
|
export_as_text( Output, "feedbackmode", iFeedbackMode );
|
||||||
|
export_as_text( Output, "feedbackport", iFeedbackPort );
|
||||||
|
export_as_text( Output, "multiplayer", iMultiplayer );
|
||||||
|
export_as_text( Output, "maxtexturesize", iMaxTextureSize );
|
||||||
|
export_as_text( Output, "maxcabtexturesize", iMaxCabTextureSize );
|
||||||
|
export_as_text( Output, "movelight", fMoveLight );
|
||||||
|
export_as_text( Output, "dynamiclights", DynamicLightCount );
|
||||||
|
if( std::isnormal( ScenarioTimeOverride ) ) {
|
||||||
|
export_as_text( Output, "scenario.time.override", ScenarioTimeOverride );
|
||||||
|
}
|
||||||
|
export_as_text( Output, "scenario.time.offset", ScenarioTimeOffset );
|
||||||
|
export_as_text( Output, "scenario.time.current", ScenarioTimeCurrent );
|
||||||
|
export_as_text( Output, "scenario.weather.temperature", AirTemperature );
|
||||||
|
export_as_text( Output, "scalespeculars", ScaleSpecularValues );
|
||||||
|
export_as_text( Output, "gfxrenderer", GfxRenderer );
|
||||||
|
export_as_text( Output, "shadows", RenderShadows );
|
||||||
|
Output
|
||||||
|
<< "shadowtune "
|
||||||
|
<< shadowtune.map_size << " "
|
||||||
|
<< 0 << " "
|
||||||
|
<< shadowtune.range << " "
|
||||||
|
<< 0 << "\n";
|
||||||
|
export_as_text( Output, "gfx.shadows.cab.range", RenderCabShadowsRange );
|
||||||
|
export_as_text( Output, "gfx.smoke", Smoke );
|
||||||
|
export_as_text( Output, "gfx.smoke.fidelity", SmokeFidelity );
|
||||||
|
export_as_text( Output, "smoothtraction", bSmoothTraction );
|
||||||
|
export_as_text( Output, "splinefidelity", SplineFidelity );
|
||||||
|
export_as_text( Output, "rendercab", render_cab );
|
||||||
|
export_as_text( Output, "createswitchtrackbeds", CreateSwitchTrackbeds );
|
||||||
|
export_as_text( Output, "gfx.resource.sweep", ResourceSweep );
|
||||||
|
export_as_text( Output, "gfx.resource.move", ResourceMove );
|
||||||
|
export_as_text( Output, "gfx.reflections.framerate", 1.0 / ReflectionUpdateInterval );
|
||||||
|
export_as_text( Output, "timespeed", fTimeSpeed );
|
||||||
|
export_as_text( Output, "multisampling", iMultisampling );
|
||||||
|
export_as_text( Output, "latitude", fLatitudeDeg );
|
||||||
|
export_as_text( Output, "convertmodels", iConvertModels + ( iConvertModels > 0 ? 128 : 0 ) );
|
||||||
|
export_as_text( Output, "file.binary.terrain", file_binary_terrain );
|
||||||
|
export_as_text( Output, "inactivepause", bInactivePause );
|
||||||
|
export_as_text( Output, "slowmotion", iSlowMotionMask );
|
||||||
|
export_as_text( Output, "hideconsole", bHideConsole );
|
||||||
|
export_as_text( Output, "rollfix", bRollFix );
|
||||||
|
export_as_text( Output, "fpsaverage", fFpsAverage );
|
||||||
|
export_as_text( Output, "fpsdeviation", fFpsDeviation );
|
||||||
|
for( auto idx = 0; idx < 6; ++idx ) {
|
||||||
|
Output
|
||||||
|
<< "calibrate5din "
|
||||||
|
<< idx << " "
|
||||||
|
<< fCalibrateIn[ idx ][ 0 ] << " "
|
||||||
|
<< fCalibrateIn[ idx ][ 1 ] << " "
|
||||||
|
<< fCalibrateIn[ idx ][ 2 ] << " "
|
||||||
|
<< fCalibrateIn[ idx ][ 3 ] << " "
|
||||||
|
<< fCalibrateIn[ idx ][ 4 ] << " "
|
||||||
|
<< fCalibrateIn[ idx ][ 5 ] << "\n";
|
||||||
|
}
|
||||||
|
for( auto idx = 0; idx < 6; ++idx ) {
|
||||||
|
Output
|
||||||
|
<< "calibrate5dout "
|
||||||
|
<< idx << " "
|
||||||
|
<< fCalibrateOut[ idx ][ 0 ] << " "
|
||||||
|
<< fCalibrateOut[ idx ][ 1 ] << " "
|
||||||
|
<< fCalibrateOut[ idx ][ 2 ] << " "
|
||||||
|
<< fCalibrateOut[ idx ][ 3 ] << " "
|
||||||
|
<< fCalibrateOut[ idx ][ 4 ] << " "
|
||||||
|
<< fCalibrateOut[ idx ][ 5 ] << "\n";
|
||||||
|
}
|
||||||
|
Output
|
||||||
|
<< "calibrateoutmaxvalues "
|
||||||
|
<< fCalibrateOutMax[ 0 ] << " "
|
||||||
|
<< fCalibrateOutMax[ 1 ] << " "
|
||||||
|
<< fCalibrateOutMax[ 2 ] << " "
|
||||||
|
<< fCalibrateOutMax[ 3 ] << " "
|
||||||
|
<< fCalibrateOutMax[ 4 ] << " "
|
||||||
|
<< fCalibrateOutMax[ 5 ] << " "
|
||||||
|
<< fCalibrateOutMax[ 6 ] << "\n";
|
||||||
|
export_as_text( Output, "calibrateoutdebuginfo", iCalibrateOutDebugInfo );
|
||||||
|
for( auto idx = 0; idx < 7; ++idx ) {
|
||||||
|
Output
|
||||||
|
<< "pwm "
|
||||||
|
<< idx << " "
|
||||||
|
<< iPoKeysPWM[ idx ] << "\n";
|
||||||
|
}
|
||||||
|
export_as_text( Output, "brakestep", fBrakeStep );
|
||||||
|
export_as_text( Output, "joinduplicatedevents", bJoinEvents );
|
||||||
|
export_as_text( Output, "hiddenevents", iHiddenEvents );
|
||||||
|
export_as_text( Output, "pause", ( iPause & 1 ) != 0 );
|
||||||
|
export_as_text( Output, "lang", asLang );
|
||||||
|
export_as_text( Output, "python.updatetime", PythonScreenUpdateRate );
|
||||||
|
Output
|
||||||
|
<< "uitextcolor "
|
||||||
|
<< UITextColor.r * 255 << " "
|
||||||
|
<< UITextColor.g * 255 << " "
|
||||||
|
<< UITextColor.b * 255 << "\n";
|
||||||
|
export_as_text( Output, "ui.bg.opacity", UIBgOpacity );
|
||||||
|
export_as_text( Output, "input.gamepad", InputGamepad );
|
||||||
|
#ifdef WITH_UART
|
||||||
|
if( uart_conf.enable ) {
|
||||||
|
Output
|
||||||
|
<< "uart "
|
||||||
|
<< uart_conf.port << " "
|
||||||
|
<< uart_conf.baud << " "
|
||||||
|
<< uart_conf.updatetime << "\n";
|
||||||
|
}
|
||||||
|
Output
|
||||||
|
<< "uarttune "
|
||||||
|
<< uart_conf.mainbrakemin << " "
|
||||||
|
<< uart_conf.mainbrakemax << " "
|
||||||
|
<< uart_conf.localbrakemin << " "
|
||||||
|
<< uart_conf.localbrakemax << " "
|
||||||
|
<< uart_conf.tankmax << " "
|
||||||
|
<< uart_conf.tankuart << " "
|
||||||
|
<< uart_conf.pipemax << " "
|
||||||
|
<< uart_conf.pipeuart << " "
|
||||||
|
<< uart_conf.brakemax << " "
|
||||||
|
<< uart_conf.brakeuart << " "
|
||||||
|
<< uart_conf.hvmax << " "
|
||||||
|
<< uart_conf.hvuart << " "
|
||||||
|
<< uart_conf.currentmax << " "
|
||||||
|
<< uart_conf.currentuart << " "
|
||||||
|
<< uart_conf.lvmax << " "
|
||||||
|
<< uart_conf.lvuart << "\n";
|
||||||
|
export_as_text( Output, "uarttachoscale", uart_conf.tachoscale );
|
||||||
|
Output
|
||||||
|
<< "uartfeature "
|
||||||
|
<< uart_conf.mainenable << " "
|
||||||
|
<< uart_conf.scndenable << " "
|
||||||
|
<< uart_conf.trainenable << " "
|
||||||
|
<< uart_conf.localenable << "\n";
|
||||||
|
export_as_text( Output, "uartdebug", uart_conf.debug );
|
||||||
|
#endif
|
||||||
|
#ifdef USE_EXTCAM_CAMERA
|
||||||
|
export_as_text( Output, "extcam.cmd", extcam_cmd );
|
||||||
|
export_as_text( Output, "extcam.rec", extcam_rec );
|
||||||
|
Output
|
||||||
|
<< "extcam.res "
|
||||||
|
<< extcam_res.x << " "
|
||||||
|
<< extcam_res.y << "\n";
|
||||||
|
#endif
|
||||||
|
export_as_text( Output, "compresstex", compress_tex );
|
||||||
|
export_as_text( Output, "gfx.framebuffer.width", gfx_framebuffer_width );
|
||||||
|
export_as_text( Output, "gfx.framebuffer.height", gfx_framebuffer_height );
|
||||||
|
export_as_text( Output, "gfx.framebuffer.fidelity", gfx_framebuffer_fidelity );
|
||||||
|
export_as_text( Output, "gfx.shadowmap.enabled", gfx_shadowmap_enabled );
|
||||||
|
// TODO: export fpslimit
|
||||||
|
export_as_text( Output, "randomseed", Global.random_seed );
|
||||||
|
export_as_text( Output, "gfx.envmap.enabled", gfx_envmap_enabled );
|
||||||
|
export_as_text( Output, "gfx.postfx.motionblur.enabled", gfx_postfx_motionblur_enabled );
|
||||||
|
export_as_text( Output, "gfx.postfx.motionblur.shutter", gfx_postfx_motionblur_shutter );
|
||||||
|
// TODO: export gfx_postfx_motionblur_format
|
||||||
|
export_as_text( Output, "gfx.postfx.chromaticaberration.enabled", gfx_postfx_chromaticaberration_enabled );
|
||||||
|
// TODO: export gfx_format_color
|
||||||
|
// TODO: export gfx_format_depth
|
||||||
|
export_as_text( Output, "gfx.skiprendering", gfx_skiprendering );
|
||||||
|
export_as_text( Output, "gfx.skippipeline", gfx_skippipeline );
|
||||||
|
export_as_text( Output, "gfx.extraeffects", gfx_extraeffects );
|
||||||
|
export_as_text( Output, "python.enabled", python_enabled );
|
||||||
|
export_as_text( Output, "python.threadedupload", python_threadedupload );
|
||||||
|
export_as_text( Output, "python.uploadmain", python_uploadmain );
|
||||||
|
export_as_text( Output, "python.mipmaps", python_mipmaps );
|
||||||
|
for( auto const &server : network_servers ) {
|
||||||
|
Output
|
||||||
|
<< "network.server "
|
||||||
|
<< server.first << " " << server.second << "\n";
|
||||||
|
}
|
||||||
|
if( false == network_client->first.empty() ) {
|
||||||
|
Output
|
||||||
|
<< "network.client "
|
||||||
|
<< network_client->first << " " << network_client->second << "\n";
|
||||||
|
}
|
||||||
|
export_as_text( Output, "execonexit", exec_on_exit );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void
|
||||||
|
global_settings::export_as_text( std::ostream &Output, std::string const Key, std::string const &Value ) const {
|
||||||
|
|
||||||
|
if( Value.empty() ) { return; }
|
||||||
|
|
||||||
|
if( Value.find( ' ' ) != std::string::npos ) {
|
||||||
|
Output << Key << " \"" << Value << "\"\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Output << Key << " " << Value << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void
|
||||||
|
global_settings::export_as_text( std::ostream &Output, std::string const Key, bool const &Value ) const {
|
||||||
|
|
||||||
|
Output << Key << " " << ( Value ? "yes" : "no" ) << "\n";
|
||||||
|
}
|
||||||
|
|||||||
63
Globals.h
63
Globals.h
@@ -28,11 +28,11 @@ struct global_settings {
|
|||||||
bool shiftState{ false }; //m7todo: brzydko
|
bool shiftState{ false }; //m7todo: brzydko
|
||||||
bool ctrlState{ false };
|
bool ctrlState{ false };
|
||||||
bool altState{ false };
|
bool altState{ false };
|
||||||
std::mt19937 random_engine;
|
std::mt19937 random_engine;
|
||||||
std::mt19937 local_random_engine;
|
std::mt19937 local_random_engine;
|
||||||
bool ready_to_load { false };
|
bool ready_to_load{ false };
|
||||||
std::time_t starting_timestamp = 0; // starting time, in local timezone
|
std::time_t starting_timestamp = 0; // starting time, in local timezone
|
||||||
uint32_t random_seed = 0;
|
uint32_t random_seed = 0;
|
||||||
TCamera pCamera; // parametry kamery
|
TCamera pCamera; // parametry kamery
|
||||||
TCamera pDebugCamera;
|
TCamera pDebugCamera;
|
||||||
std::array<Math3D::vector3, 10> FreeCameraInit; // pozycje kamery
|
std::array<Math3D::vector3, 10> FreeCameraInit; // pozycje kamery
|
||||||
@@ -56,12 +56,12 @@ struct global_settings {
|
|||||||
std::string asCurrentTexturePath{ szTexturePath };
|
std::string asCurrentTexturePath{ szTexturePath };
|
||||||
std::string asCurrentDynamicPath;
|
std::string asCurrentDynamicPath;
|
||||||
int CurrentMaxTextureSize{ 4096 };
|
int CurrentMaxTextureSize{ 4096 };
|
||||||
bool GfxFramebufferSRGB { true };
|
bool GfxFramebufferSRGB{ true };
|
||||||
bool UpdateMaterials { true };
|
bool UpdateMaterials{ true };
|
||||||
// settings
|
// settings
|
||||||
// filesystem
|
// filesystem
|
||||||
bool bLoadTraction{ true };
|
bool bLoadTraction{ true };
|
||||||
bool CreateSwitchTrackbeds { true };
|
bool CreateSwitchTrackbeds{ true };
|
||||||
std::string szTexturesTGA{ ".tga" }; // lista tekstur od TGA
|
std::string szTexturesTGA{ ".tga" }; // lista tekstur od TGA
|
||||||
std::string szTexturesDDS{ ".dds" }; // lista tekstur od DDS
|
std::string szTexturesDDS{ ".dds" }; // lista tekstur od DDS
|
||||||
std::string szDefaultExt{ szTexturesDDS };
|
std::string szDefaultExt{ szTexturesDDS };
|
||||||
@@ -77,7 +77,7 @@ struct global_settings {
|
|||||||
bool RealisticControlMode{ false }; // controls ability to steer the vehicle from outside views
|
bool RealisticControlMode{ false }; // controls ability to steer the vehicle from outside views
|
||||||
bool bEnableTraction{ true };
|
bool bEnableTraction{ true };
|
||||||
float fFriction{ 1.f }; // mnożnik tarcia - KURS90
|
float fFriction{ 1.f }; // mnożnik tarcia - KURS90
|
||||||
float FrictionWeatherFactor { 1.f };
|
float FrictionWeatherFactor{ 1.f };
|
||||||
bool bLiveTraction{ true };
|
bool bLiveTraction{ true };
|
||||||
float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
||||||
glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f };
|
glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f };
|
||||||
@@ -91,9 +91,9 @@ struct global_settings {
|
|||||||
bool FakeLight{ false }; // toggle between fixed and dynamic daylight
|
bool FakeLight{ false }; // toggle between fixed and dynamic daylight
|
||||||
double fTimeSpeed{ 1.0 }; // przyspieszenie czasu, zmienna do testów
|
double fTimeSpeed{ 1.0 }; // przyspieszenie czasu, zmienna do testów
|
||||||
double fLatitudeDeg{ 52.0 }; // szerokość geograficzna
|
double fLatitudeDeg{ 52.0 }; // szerokość geograficzna
|
||||||
float ScenarioTimeOverride { std::numeric_limits<float>::quiet_NaN() }; // requested scenario start time
|
float ScenarioTimeOverride{ std::numeric_limits<float>::quiet_NaN() }; // requested scenario start time
|
||||||
float ScenarioTimeOffset { 0.f }; // time shift (in hours) applied to train timetables
|
float ScenarioTimeOffset{ 0.f }; // time shift (in hours) applied to train timetables
|
||||||
bool ScenarioTimeCurrent { false }; // automatic time shift to match scenario time with local clock
|
bool ScenarioTimeCurrent{ false }; // automatic time shift to match scenario time with local clock
|
||||||
bool bInactivePause{ true }; // automatyczna pauza, gdy okno nieaktywne
|
bool bInactivePause{ true }; // automatyczna pauza, gdy okno nieaktywne
|
||||||
int iSlowMotionMask{ -1 }; // maska wyłączanych właściwości
|
int iSlowMotionMask{ -1 }; // maska wyłączanych właściwości
|
||||||
bool bHideConsole{ false }; // hunter-271211: ukrywanie konsoli
|
bool bHideConsole{ false }; // hunter-271211: ukrywanie konsoli
|
||||||
@@ -101,16 +101,16 @@ struct global_settings {
|
|||||||
bool bJoinEvents{ false }; // czy grupować eventy o tych samych nazwach
|
bool bJoinEvents{ false }; // czy grupować eventy o tych samych nazwach
|
||||||
int iHiddenEvents{ 1 }; // czy łączyć eventy z torami poprzez nazwę toru
|
int iHiddenEvents{ 1 }; // czy łączyć eventy z torami poprzez nazwę toru
|
||||||
// ui
|
// ui
|
||||||
int PythonScreenUpdateRate { 200 }; // delay between python-based screen updates, in milliseconds
|
int PythonScreenUpdateRate{ 200 }; // delay between python-based screen updates, in milliseconds
|
||||||
int iTextMode{ 0 }; // tryb pracy wyświetlacza tekstowego
|
int iTextMode{ 0 }; // tryb pracy wyświetlacza tekstowego
|
||||||
glm::vec4 UITextColor { glm::vec4( 225.f / 255.f, 225.f / 255.f, 225.f / 255.f, 1.f ) }; // base color of UI text
|
glm::vec4 UITextColor{ glm::vec4( 225.f / 255.f, 225.f / 255.f, 225.f / 255.f, 1.f ) }; // base color of UI text
|
||||||
float UIBgOpacity { 0.65f }; // opacity of ui windows
|
float UIBgOpacity{ 0.65f }; // opacity of ui windows
|
||||||
std::string asLang{ "pl" }; // domyślny język - http://tools.ietf.org/html/bcp47
|
std::string asLang{ "pl" }; // domyślny język - http://tools.ietf.org/html/bcp47
|
||||||
// gfx
|
// gfx
|
||||||
int iWindowWidth{ 800 };
|
int iWindowWidth{ 800 };
|
||||||
int iWindowHeight{ 600 };
|
int iWindowHeight{ 600 };
|
||||||
float fDistanceFactor{ 1.f }; // baza do przeliczania odległości dla LoD
|
float fDistanceFactor{ 1.f }; // baza do przeliczania odległości dla LoD
|
||||||
float targetfps { 0.0f };
|
float targetfps{ 0.0f };
|
||||||
bool bFullScreen{ false };
|
bool bFullScreen{ false };
|
||||||
bool VSync{ false };
|
bool VSync{ false };
|
||||||
bool bWireFrame{ false };
|
bool bWireFrame{ false };
|
||||||
@@ -179,7 +179,7 @@ struct global_settings {
|
|||||||
// wartości maksymalne wyjść dla pulpitu
|
// wartości maksymalne wyjść dla pulpitu
|
||||||
double fCalibrateOutMax[ 7 ] = {
|
double fCalibrateOutMax[ 7 ] = {
|
||||||
0, 0, 0, 0, 0, 0, 0 };
|
0, 0, 0, 0, 0, 0, 0 };
|
||||||
int iCalibrateOutDebugInfo { -1 }; // numer wyjścia kalibrowanego dla którego wyświetlać informacje podczas kalibracji
|
int iCalibrateOutDebugInfo{ -1 }; // numer wyjścia kalibrowanego dla którego wyświetlać informacje podczas kalibracji
|
||||||
int iPoKeysPWM[ 7 ] = { 0, 1, 2, 3, 4, 5, 6 }; // numery wejść dla PWM
|
int iPoKeysPWM[ 7 ] = { 0, 1, 2, 3, 4, 5, 6 }; // numery wejść dla PWM
|
||||||
#ifdef WITH_UART
|
#ifdef WITH_UART
|
||||||
uart_input::conf_t uart_conf;
|
uart_input::conf_t uart_conf;
|
||||||
@@ -192,14 +192,14 @@ struct global_settings {
|
|||||||
// TODO: move these to relevant areas
|
// TODO: move these to relevant areas
|
||||||
bool render_cab = true;
|
bool render_cab = true;
|
||||||
|
|
||||||
std::chrono::duration<float> minframetime {0.0f};
|
std::chrono::duration<float> minframetime{ 0.0f };
|
||||||
|
|
||||||
std::string fullscreen_monitor;
|
std::string fullscreen_monitor;
|
||||||
|
|
||||||
bool python_enabled = true;
|
bool python_enabled = true;
|
||||||
bool python_mipmaps = true;
|
bool python_mipmaps = true;
|
||||||
bool python_threadedupload = true;
|
bool python_threadedupload = true;
|
||||||
bool python_uploadmain = true;
|
bool python_uploadmain = true;
|
||||||
|
|
||||||
bool gfx_skiprendering = false;
|
bool gfx_skiprendering = false;
|
||||||
int gfx_framebuffer_width = -1;
|
int gfx_framebuffer_width = -1;
|
||||||
@@ -227,8 +227,29 @@ struct global_settings {
|
|||||||
// methods
|
// methods
|
||||||
void LoadIniFile( std::string asFileName );
|
void LoadIniFile( std::string asFileName );
|
||||||
void ConfigParse( cParser &parser );
|
void ConfigParse( cParser &parser );
|
||||||
|
// sends basic content of the class in legacy (text) format to provided stream
|
||||||
|
void
|
||||||
|
export_as_text( std::ostream &Output ) const;
|
||||||
|
template <typename Type_>
|
||||||
|
void
|
||||||
|
export_as_text( std::ostream &Output, std::string const Key, Type_ const &Value ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Type_>
|
||||||
|
void
|
||||||
|
global_settings::export_as_text( std::ostream &Output, std::string const Key, Type_ const &Value ) const {
|
||||||
|
|
||||||
|
Output << Key << " " << Value << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void
|
||||||
|
global_settings::export_as_text( std::ostream &Output, std::string const Key, std::string const &Value ) const;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void
|
||||||
|
global_settings::export_as_text( std::ostream &Output, std::string const Key, bool const &Value ) const;
|
||||||
|
|
||||||
extern global_settings Global;
|
extern global_settings Global;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1647,6 +1647,9 @@ public:
|
|||||||
double PipeRatio(void);/*ile napelniac*/
|
double PipeRatio(void);/*ile napelniac*/
|
||||||
double RealPipeRatio(void);/*jak szybko*/
|
double RealPipeRatio(void);/*jak szybko*/
|
||||||
double BrakeVP(void) const;
|
double BrakeVP(void) const;
|
||||||
|
double EngineRPMRatio() const; // returns current engine revolutions as percentage of max engine revolutions, in range 0-1
|
||||||
|
double EngineIdleRPM() const;
|
||||||
|
double EngineMaxRPM() const;
|
||||||
|
|
||||||
/*! przesylanie komend sterujacych*/
|
/*! przesylanie komend sterujacych*/
|
||||||
bool SendCtrlToNext(std::string const CtrlCommand, double const ctrlvalue, double const dir, int const Couplertype = coupling::control );
|
bool SendCtrlToNext(std::string const CtrlCommand, double const ctrlvalue, double const dir, int const Couplertype = coupling::control );
|
||||||
|
|||||||
@@ -1000,6 +1000,34 @@ double TMoverParameters::PipeRatio(void)
|
|||||||
return pr;
|
return pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
TMoverParameters::EngineRPMRatio() const {
|
||||||
|
|
||||||
|
return clamp( (
|
||||||
|
EngineType == TEngineType::DieselElectric ? ( ( 60.0 * std::abs( enrot ) ) / DElist[ MainCtrlPosNo ].RPM ) :
|
||||||
|
EngineType == TEngineType::DieselEngine ? ( std::abs( enrot ) / nmax ) :
|
||||||
|
1.0 ), // shouldn't ever get here but, eh
|
||||||
|
0.0, 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
TMoverParameters::EngineIdleRPM() const {
|
||||||
|
|
||||||
|
return (
|
||||||
|
EngineType == TEngineType::DieselEngine ? dizel_nmin * 60 :
|
||||||
|
EngineType == TEngineType::DieselElectric ? DElist[ MainCtrlNoPowerPos() ].RPM :
|
||||||
|
std::numeric_limits<double>::max() ); // shouldn't ever get here but, eh
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
TMoverParameters::EngineMaxRPM() const {
|
||||||
|
|
||||||
|
return (
|
||||||
|
EngineType == TEngineType::DieselEngine ? dizel_nmax * 60 :
|
||||||
|
EngineType == TEngineType::DieselElectric ? DElist[ MainCtrlPosNo ].RPM :
|
||||||
|
std::numeric_limits<double>::max() ); // shouldn't ever get here but, eh
|
||||||
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// Q: 20160716
|
// Q: 20160716
|
||||||
// Wykrywanie kolizji
|
// Wykrywanie kolizji
|
||||||
@@ -1959,17 +1987,13 @@ void TMoverParameters::OilPumpCheck( double const Timestep ) {
|
|||||||
OilPump.start_type == start_t::manualwithautofallback ? ( OilPump.is_enabled || dizel_startup ) :
|
OilPump.start_type == start_t::manualwithautofallback ? ( OilPump.is_enabled || dizel_startup ) :
|
||||||
false ) ) ); // shouldn't ever get this far but, eh
|
false ) ) ); // shouldn't ever get this far but, eh
|
||||||
|
|
||||||
auto const maxrevolutions {
|
|
||||||
EngineType == TEngineType::DieselEngine ?
|
|
||||||
dizel_nmax :
|
|
||||||
DElist[ MainCtrlPosNo ].RPM / 60.0 };
|
|
||||||
auto const minpressure {
|
auto const minpressure {
|
||||||
OilPump.pressure_minimum > 0.f ?
|
OilPump.pressure_minimum > 0.f ?
|
||||||
OilPump.pressure_minimum :
|
OilPump.pressure_minimum :
|
||||||
0.15f }; // arbitrary fallback value
|
0.15f }; // arbitrary fallback value
|
||||||
|
|
||||||
OilPump.pressure_target = (
|
OilPump.pressure_target = (
|
||||||
enrot > 0.1 ? interpolate( minpressure, OilPump.pressure_maximum, static_cast<float>( clamp( enrot / maxrevolutions, 0.0, 1.0 ) ) ) * OilPump.resource_amount :
|
enrot > 0.1 ? interpolate( minpressure, OilPump.pressure_maximum, static_cast<float>( EngineRPMRatio() ) ) * OilPump.resource_amount :
|
||||||
true == OilPump.is_active ? std::min( minpressure + 0.1f, OilPump.pressure_maximum ) : // slight pressure margin to give time to switch off the pump and start the engine
|
true == OilPump.is_active ? std::min( minpressure + 0.1f, OilPump.pressure_maximum ) : // slight pressure margin to give time to switch off the pump and start the engine
|
||||||
0.f );
|
0.f );
|
||||||
|
|
||||||
@@ -4128,14 +4152,10 @@ void TMoverParameters::CompressorCheck(double dt) {
|
|||||||
switch( CompressorPower ) {
|
switch( CompressorPower ) {
|
||||||
case 3: {
|
case 3: {
|
||||||
// the compressor is coupled with the diesel engine, engine revolutions affect the output
|
// the compressor is coupled with the diesel engine, engine revolutions affect the output
|
||||||
auto const enginefactor { (
|
|
||||||
EngineType == TEngineType::DieselElectric ? ( ( 60.0 * std::abs( enrot ) ) / DElist[ MainCtrlPosNo ].RPM ) :
|
|
||||||
EngineType == TEngineType::DieselEngine ? ( std::abs( enrot ) / nmax ) :
|
|
||||||
1.0 ) }; // shouldn't ever get here but, eh
|
|
||||||
CompressedVolume +=
|
CompressedVolume +=
|
||||||
CompressorSpeedF
|
CompressorSpeedF
|
||||||
* ( 2.0 * MaxCompressorF - Compressor ) / MaxCompressorF
|
* ( 2.0 * MaxCompressorF - Compressor ) / MaxCompressorF
|
||||||
* enginefactor
|
* EngineRPMRatio()
|
||||||
* dt
|
* dt
|
||||||
* ( CompressorGovernorLock ? 0.0 : 1.0 ); // with the lock active air is vented out
|
* ( CompressorGovernorLock ? 0.0 : 1.0 ); // with the lock active air is vented out
|
||||||
break;
|
break;
|
||||||
@@ -5217,7 +5237,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
std::max(
|
std::max(
|
||||||
tmp,
|
tmp,
|
||||||
std::min(
|
std::min(
|
||||||
DElist[ MainCtrlPosNo ].RPM,
|
EngineMaxRPM(),
|
||||||
EngineHeatingRPM )
|
EngineHeatingRPM )
|
||||||
/ 60.0 );
|
/ 60.0 );
|
||||||
}
|
}
|
||||||
@@ -5576,7 +5596,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
if (EIMCtrlType > 0) //sterowanie cyfrowe
|
if (EIMCtrlType > 0) //sterowanie cyfrowe
|
||||||
{
|
{
|
||||||
auto eimic_positive = std::max(0.0, eimic_real);
|
auto eimic_positive = std::max(0.0, eimic_real);
|
||||||
auto const rpmratio {60.0 * enrot / DElist[MainCtrlPosNo].RPM};
|
auto const rpmratio { EngineRPMRatio() };
|
||||||
tempImax = DElist[MainCtrlPosNo].Imax * eimic_positive;
|
tempImax = DElist[MainCtrlPosNo].Imax * eimic_positive;
|
||||||
tempUmax = DElist[MainCtrlPosNo].Umax * std::min(eimic_positive, rpmratio);
|
tempUmax = DElist[MainCtrlPosNo].Umax * std::min(eimic_positive, rpmratio);
|
||||||
tempPmax = DElist[MainCtrlPosNo].GenPower * std::min(eimic_positive, rpmratio);
|
tempPmax = DElist[MainCtrlPosNo].GenPower * std::min(eimic_positive, rpmratio);
|
||||||
@@ -5611,8 +5631,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
EngineVoltage = ( SST[ MainCtrlPos ].Umax * AnPos ) + ( SST[ MainCtrlPos ].Umin * ( 1.0 - AnPos ) );
|
EngineVoltage = ( SST[ MainCtrlPos ].Umax * AnPos ) + ( SST[ MainCtrlPos ].Umin * ( 1.0 - AnPos ) );
|
||||||
// NOTE: very crude way to approximate power generated at current rpm instead of instant top output
|
// NOTE: very crude way to approximate power generated at current rpm instead of instant top output
|
||||||
// NOTE, TODO: doesn't take into account potentially increased revolutions if heating is on, fix it
|
// NOTE, TODO: doesn't take into account potentially increased revolutions if heating is on, fix it
|
||||||
auto const rpmratio { 60.0 * enrot / DElist[ MainCtrlPos ].RPM };
|
tmp = EngineRPMRatio() * ( SST[ MainCtrlPos ].Pmax * AnPos ) + ( SST[ MainCtrlPos ].Pmin * ( 1.0 - AnPos ) );
|
||||||
tmp = rpmratio * ( SST[ MainCtrlPos ].Pmax * AnPos ) + ( SST[ MainCtrlPos ].Pmin * ( 1.0 - AnPos ) );
|
|
||||||
Ft = tmp * 1000.0 / ( abs( tmpV ) + 1.6 );
|
Ft = tmp * 1000.0 / ( abs( tmpV ) + 1.6 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -6203,8 +6222,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
switch( EngineType ) {
|
switch( EngineType ) {
|
||||||
case TEngineType::DieselElectric: {
|
case TEngineType::DieselElectric: {
|
||||||
// rough approximation of extra effort to overcome friction etc
|
// rough approximation of extra effort to overcome friction etc
|
||||||
auto const rpmratio{ 60.0 * enrot / DElist[ MainCtrlPosNo ].RPM };
|
EnginePower += EngineRPMRatio() * 0.15 * DElist[ MainCtrlPosNo ].GenPower;
|
||||||
EnginePower += rpmratio * 0.15 * DElist[ MainCtrlPosNo ].GenPower;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -7780,11 +7798,7 @@ void TMoverParameters::dizel_Heat( double const dt ) {
|
|||||||
auto const engineoff { ( Mains ? 0 : 1 ) };
|
auto const engineoff { ( Mains ? 0 : 1 ) };
|
||||||
auto const rpm { enrot * 60 };
|
auto const rpm { enrot * 60 };
|
||||||
// TODO: calculate this once and cache for further use, instead of doing it repeatedly all over the place
|
// TODO: calculate this once and cache for further use, instead of doing it repeatedly all over the place
|
||||||
auto const maxrevolutions { (
|
auto const revolutionsfactor { EngineRPMRatio() };
|
||||||
EngineType == TEngineType::DieselEngine ? dizel_nmax * 60 :
|
|
||||||
EngineType == TEngineType::DieselElectric ? DElist[ MainCtrlPosNo ].RPM :
|
|
||||||
std::numeric_limits<double>::max() ) }; // shouldn't ever get here but, eh
|
|
||||||
auto const revolutionsfactor { clamp( rpm / maxrevolutions, 0.0, 1.0 ) };
|
|
||||||
auto const waterpump { WaterPump.is_active ? 1 : 0 };
|
auto const waterpump { WaterPump.is_active ? 1 : 0 };
|
||||||
|
|
||||||
auto const gw = engineon * interpolate( gwmin, gwmax, revolutionsfactor ) + waterpump * 1000 + engineoff * 200;
|
auto const gw = engineon * interpolate( gwmin, gwmax, revolutionsfactor ) + waterpump * 1000 + engineoff * 200;
|
||||||
|
|||||||
@@ -127,6 +127,15 @@ eu07_application::init( int Argc, char *Argv[] ) {
|
|||||||
WriteLog( "Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
WriteLog( "Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
||||||
"ShaXbee, Oli_EU, youBy, KURS90, Ra, hunter, szociu, Stele, Q, firleju and others\n" );
|
"ShaXbee, Oli_EU, youBy, KURS90, Ra, hunter, szociu, Stele, Q, firleju and others\n" );
|
||||||
|
|
||||||
|
{
|
||||||
|
WriteLog( "// settings" );
|
||||||
|
std::stringstream settingspipe;
|
||||||
|
Global.export_as_text( settingspipe );
|
||||||
|
WriteLog( settingspipe.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteLog( "// startup" );
|
||||||
|
|
||||||
if( ( result = init_glfw() ) != 0 ) {
|
if( ( result = init_glfw() ) != 0 ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -659,7 +659,6 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
|||||||
auto const &mover { *m_input.mover };
|
auto const &mover { *m_input.mover };
|
||||||
|
|
||||||
auto const isowned { /* ( vehicle.Mechanik == nullptr ) && */ ( vehicle.ctOwner != nullptr ) && ( vehicle.ctOwner->Vehicle() != m_input.vehicle ) };
|
auto const isowned { /* ( vehicle.Mechanik == nullptr ) && */ ( vehicle.ctOwner != nullptr ) && ( vehicle.ctOwner->Vehicle() != m_input.vehicle ) };
|
||||||
auto const isplayervehicle { ( m_input.train != nullptr ) && ( m_input.train->Dynamic() == m_input.vehicle ) };
|
|
||||||
auto const isdieselenginepowered { ( mover.EngineType == TEngineType::DieselElectric ) || ( mover.EngineType == TEngineType::DieselEngine ) };
|
auto const isdieselenginepowered { ( mover.EngineType == TEngineType::DieselElectric ) || ( mover.EngineType == TEngineType::DieselEngine ) };
|
||||||
auto const isdieselinshuntmode { mover.ShuntMode && mover.EngineType == TEngineType::DieselElectric };
|
auto const isdieselinshuntmode { mover.ShuntMode && mover.EngineType == TEngineType::DieselElectric };
|
||||||
|
|
||||||
@@ -699,7 +698,7 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
|||||||
( mover.CompressorGovernorLock ? '!' : '.' ),
|
( mover.CompressorGovernorLock ? '!' : '.' ),
|
||||||
( mover.StLinSwitchOff ? '-' : ( mover.ControlPressureSwitch ? '!' : ( mover.StLinFlag ? '+' : '.' ) ) ),
|
( mover.StLinSwitchOff ? '-' : ( mover.ControlPressureSwitch ? '!' : ( mover.StLinFlag ? '+' : '.' ) ) ),
|
||||||
( mover.Heating ? 'H' : ( mover.HeatingAllow ? 'h' : '.' ) ),
|
( mover.Heating ? 'H' : ( mover.HeatingAllow ? 'h' : '.' ) ),
|
||||||
std::string( isplayervehicle ? locale::strings[ locale::string::debug_vehicle_radio ] + ( mover.Radio ? std::to_string( m_input.train->RadioChannel() ) : "-" ) : "" ).c_str(),
|
std::string( m_input.mechanik ? locale::strings[ locale::string::debug_vehicle_radio ] + ( mover.Radio ? std::to_string( m_input.mechanik->iRadioChannel ) : "-" ) : "" ).c_str(),
|
||||||
std::string( isdieselenginepowered ? locale::strings[ locale::string::debug_vehicle_oilpressure ] + to_string( mover.OilPump.pressure, 2 ) : "" ).c_str(),
|
std::string( isdieselenginepowered ? locale::strings[ locale::string::debug_vehicle_oilpressure ] + to_string( mover.OilPump.pressure, 2 ) : "" ).c_str(),
|
||||||
// power transfers
|
// power transfers
|
||||||
// 3000v
|
// 3000v
|
||||||
|
|||||||
22
mtable.cpp
22
mtable.cpp
@@ -57,6 +57,13 @@ bool TTrainParameters::IsMaintenance() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TTrainParameters::radio_channel() const {
|
||||||
|
if( ( StationIndex < StationCount ) )
|
||||||
|
return TimeTable[ StationIndex ].radio_channel;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool TTrainParameters::UpdateMTable( scenario_time const &Time, std::string const &NewName ) {
|
bool TTrainParameters::UpdateMTable( scenario_time const &Time, std::string const &NewName ) {
|
||||||
|
|
||||||
return UpdateMTable( Time.data().wHour, Time.data().wMinute + Time.data().wSecond * 0.0167, NewName );
|
return UpdateMTable( Time.data().wHour, Time.data().wMinute + Time.data().wSecond * 0.0167, NewName );
|
||||||
@@ -406,9 +413,22 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
|||||||
|| ( s == "2" )
|
|| ( s == "2" )
|
||||||
|| fin.bad() ) ) {
|
|| fin.bad() ) ) {
|
||||||
record->StationWare += s;
|
record->StationWare += s;
|
||||||
record->is_maintenance = ( s.find( "pt" ) != std::string::npos );
|
|
||||||
fin >> s;
|
fin >> s;
|
||||||
}
|
}
|
||||||
|
// cache relevant station data
|
||||||
|
record->is_maintenance = ( s.find( "pt" ) != std::string::npos );
|
||||||
|
{
|
||||||
|
auto const stationware { Split( record->StationWare, ',' ) };
|
||||||
|
for( auto const &entry : stationware ) {
|
||||||
|
if( entry[ 0 ] == 'R' ) {
|
||||||
|
auto const entrysplit { split_index( entry ) };
|
||||||
|
if( ( entrysplit.first == "R" )
|
||||||
|
&& ( entrysplit.second <= 10 ) ) {
|
||||||
|
record->radio_channel = entrysplit.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
record->TrackNo = atoi(s.c_str());
|
record->TrackNo = atoi(s.c_str());
|
||||||
fin >> s;
|
fin >> s;
|
||||||
if (s != "|")
|
if (s != "|")
|
||||||
|
|||||||
3
mtable.h
3
mtable.h
@@ -37,6 +37,7 @@ struct TMTableLine
|
|||||||
float Dm{ -1.f }; // godz. i min. odjazdu
|
float Dm{ -1.f }; // godz. i min. odjazdu
|
||||||
float tm{ 0.f }; // czas jazdy do tej stacji w min. (z kolumny)
|
float tm{ 0.f }; // czas jazdy do tej stacji w min. (z kolumny)
|
||||||
bool is_maintenance{ false };
|
bool is_maintenance{ false };
|
||||||
|
int radio_channel{ -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TMTableLine TMTable[MaxTTableSize + 1];
|
typedef TMTableLine TMTable[MaxTTableSize + 1];
|
||||||
@@ -77,6 +78,8 @@ class TTrainParameters
|
|||||||
bool DirectionChange();
|
bool DirectionChange();
|
||||||
void StationIndexInc();
|
void StationIndexInc();
|
||||||
void serialize( dictionary_source *Output ) const;
|
void serialize( dictionary_source *Output ) const;
|
||||||
|
// returns: radio channel associated with current station, or -1
|
||||||
|
int radio_channel() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TMTableTime
|
class TMTableTime
|
||||||
|
|||||||
@@ -275,9 +275,10 @@ smoke_source::location() const {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case owner_type::node: {
|
case owner_type::node: {
|
||||||
// TODO: take into account node rotation
|
auto const rotationx { glm::angleAxis( glm::radians( m_owner.node->Angles().x ), glm::vec3{ 1.f, 0.f, 0.f } ) };
|
||||||
auto const rotation { glm::angleAxis( glm::radians( m_owner.node->Angles().y ), glm::vec3{ 0.f, 1.f, 0.f } ) };
|
auto const rotationy { glm::angleAxis( glm::radians( m_owner.node->Angles().y ), glm::vec3{ 0.f, 1.f, 0.f } ) };
|
||||||
location = rotation * glm::vec3{ m_offset };
|
auto const rotationz { glm::angleAxis( glm::radians( m_owner.node->Angles().z ), glm::vec3{ 0.f, 0.f, 1.f } ) };
|
||||||
|
location = rotationy * rotationx * rotationz * glm::vec3{ m_offset };
|
||||||
location += m_owner.node->location();
|
location += m_owner.node->location();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
1
sound.h
1
sound.h
@@ -17,6 +17,7 @@ float const EU07_SOUND_GLOBALRANGE { -1.f };
|
|||||||
float const EU07_SOUND_CABCONTROLSCUTOFFRANGE { 7.5f };
|
float const EU07_SOUND_CABCONTROLSCUTOFFRANGE { 7.5f };
|
||||||
float const EU07_SOUND_BRAKINGCUTOFFRANGE { 100.f };
|
float const EU07_SOUND_BRAKINGCUTOFFRANGE { 100.f };
|
||||||
float const EU07_SOUND_RUNNINGNOISECUTOFFRANGE { 200.f };
|
float const EU07_SOUND_RUNNINGNOISECUTOFFRANGE { 200.f };
|
||||||
|
float const EU07_SOUND_HANDHELDRADIORANGE { 750.f };
|
||||||
|
|
||||||
enum class sound_type {
|
enum class sound_type {
|
||||||
single,
|
single,
|
||||||
|
|||||||
Reference in New Issue
Block a user