16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 00:29:19 +02:00

load visualization submodel visibility selection tweak, passenger train acceleration ai logic enhancement, brake code enhancement, cab control label tweak

This commit is contained in:
tmj-fstate
2020-06-05 16:43:07 +02:00
parent 203cefac8d
commit ad1a14082c
8 changed files with 65 additions and 76 deletions

View File

@@ -153,6 +153,8 @@ const double EasyReactionTime = 0.5; //[s] przebłyski świadomości dla zwykłe
const double HardReactionTime = 0.2;
const double EasyAcceleration = 0.85; //[m/ss]
const double HardAcceleration = 9.81;
const double PassengetTrainAcceleration = 0.40;
const double HeavyPassengetTrainAcceleration = 0.20;
const double CargoTrainAcceleration = 0.25;
const double HeavyCargoTrainAcceleration = 0.10;
const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu
@@ -2065,6 +2067,7 @@ void TController::AutoRewident()
fBrake_a1[i+1] /= (12*fMass);
}
IsPassengerTrain = ( mvOccupied->CategoryFlag == 1 ) && ( mvOccupied->TrainType != dt_EZT ) && ( mvOccupied->TrainType != dt_DMU ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) == 0 );
IsCargoTrain = ( mvOccupied->CategoryFlag == 1 ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 );
IsHeavyCargoTrain = ( true == IsCargoTrain ) && ( fBrake_a0[ 1 ] > 0.4 ) && ( iVehicles - ControlledEnginesCount > 0 ) && ( fMass / iVehicles > 50000 );
@@ -6235,6 +6238,9 @@ TController::UpdateSituation(double dt) {
}
// HACK: limit acceleration for cargo trains, to reduce probability of breaking couplers on sudden jolts
// TBD: expand this behaviour to all trains with car(s) exceeding certain weight?
if( ( IsPassengerTrain ) && ( iVehicles - ControlledEnginesCount > 0 ) ) {
AccDesired = std::min( AccDesired, ( iVehicles - ControlledEnginesCount > 8 ? HeavyPassengetTrainAcceleration : PassengetTrainAcceleration ) );
}
if( ( IsCargoTrain ) && ( iVehicles - ControlledEnginesCount > 0 ) ) {
AccDesired = std::min( AccDesired, CargoTrainAcceleration );
}

View File

@@ -472,6 +472,7 @@ private:
int iVehicles = 0; // ilość pojazdów w składzie
int ControlledEnginesCount{ 0 }; // number of powered vehicles under driver's control
bool iEngineActive{ false }; // ABu: Czy silnik byl juz zalaczony
bool IsPassengerTrain{ false };
bool IsCargoTrain{ false };
bool IsHeavyCargoTrain{ false };
double fReady = 0.0; // poziom odhamowania wagonów

View File

@@ -686,7 +686,7 @@ TDynamicObject::toggle_lights() {
( sectionname.find( "compartment" ) == 0 )
|| ( sectionname.find( "przedzial" ) == 0 ) ) {
// compartments are lit with 75% probability
section.light_level = ( Random() < 0.75 ? 0.75f : 0.15f );
section.light_level = ( Random() < 0.75 ? 0.75f : 0.10f );
}
}
SectionLightsActive = true;
@@ -1119,21 +1119,22 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
}
}
// load chunks visibility
for( auto const &section : SectionLoadVisibility ) {
section.submodel->iVisible = section.visible;
if( false == section.visible ) {
// if the section root isn't visible we can skip meddling with its children
continue;
}
for( auto const &section : Sections ) {
// section isn't guaranteed to have load model, so check that first
if( section.load == nullptr ) { continue; }
section.load->iVisible = ( section.load_chunks_visible > 0 );
// if the section root isn't visible we can skip meddling with its children
if( false == section.load->iVisible ) { continue; }
// if the section root is visible set the state of section chunks
auto *sectionchunk { section.submodel->ChildGet() };
auto visiblechunkcount { section.visible_chunks };
auto *sectionchunk { section.load->ChildGet() };
auto visiblechunkcount { section.load_chunks_visible };
while( sectionchunk != nullptr ) {
sectionchunk->iVisible = ( visiblechunkcount > 0 );
--visiblechunkcount;
sectionchunk = sectionchunk->NextGet();
}
}
// driver cabs visibility
for( int cabidx = 0; cabidx < LowPolyIntCabs.size(); ++cabidx ) {
if( LowPolyIntCabs[ cabidx ] == nullptr ) { continue; }
@@ -2136,15 +2137,15 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
// TODO: definition of relevant compartments in the .mmd file
TSubModel *submodel { nullptr };
if( ( submodel = mdLowPolyInt->GetFromName( "cab0" ) ) != nullptr ) {
Sections.push_back( { submodel, nullptr, 0.0f } );
Sections.push_back( { submodel, nullptr, 0, 0.0f } );
LowPolyIntCabs[ 0 ] = submodel;
}
if( ( submodel = mdLowPolyInt->GetFromName( "cab1" ) ) != nullptr ) {
Sections.push_back( { submodel, nullptr, 0.0f } );
Sections.push_back( { submodel, nullptr, 0, 0.0f } );
LowPolyIntCabs[ 1 ] = submodel;
}
if( ( submodel = mdLowPolyInt->GetFromName( "cab2" ) ) != nullptr ) {
Sections.push_back( { submodel, nullptr, 0.0f } );
Sections.push_back( { submodel, nullptr, 0, 0.0f } );
LowPolyIntCabs[ 2 ] = submodel;
}
// passenger car compartments
@@ -2280,6 +2281,7 @@ TDynamicObject::init_sections( TModel3d const *Model, std::string const &Namepre
Sections.push_back( {
sectionsubmodel,
nullptr, // pointers to load sections are generated afterwards
0,
0.0f } );
++sectioncount;
}
@@ -2723,58 +2725,49 @@ void TDynamicObject::LoadUpdate() {
void
TDynamicObject::update_load_sections() {
SectionLoadVisibility.clear();
SectionLoadOrder.clear();
for( auto &section : Sections ) {
section.load = GetSubmodelFromName( mdLoad, section.compartment->pName );
if( ( section.load != nullptr )
&& ( section.load->count_children() > 0 ) ) {
SectionLoadVisibility.push_back( { section.load, false } );
if( section.load != nullptr ) {
// create entry for each load model chunk assigned to the section
// TBD, TODO: store also pointer to chunk submodel and control its visibility more directly, instead of per-section visibility flag?
auto loadchunkcount { section.load->count_children() };
while( loadchunkcount-- ) {
SectionLoadOrder.push_back( &section );
}
// 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, false );
}
}
}
shuffle_load_sections();
shuffle_load_order();
}
void
TDynamicObject::update_load_visibility() {
/*
if( Random() < 0.25 ) {
shuffle_load_sections();
// start with clean load chunk visibility slate
for( auto &section : Sections ) {
section.load_chunks_visible = 0;
}
*/
auto loadpercentage { (
// each entry in load order sequence matches a single chunk of the section it points to
// the length of load order sequence matches total number of load chunks
auto const loadpercentage { (
MoverParameters->MaxLoad == 0.f ?
0.0 :
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
auto const sectionloadpercentage { (
SectionLoadVisibility.empty() ?
0.0 :
100.0 / SectionLoadVisibility.size() ) };
// set as many sections as we can, given overall load percentage and how much of full percentage is covered by each chunk
std::for_each(
std::begin( SectionLoadVisibility ), std::end( SectionLoadVisibility ),
[&]( section_visibility &section ) {
section.visible = ( loadpercentage > 0.0 );
section.visible_chunks = 0;
auto const sectionchunkcount { section.submodel->count_children() };
auto const sectionchunkloadpercentage{ (
sectionchunkcount == 0 ?
0.0 :
sectionloadpercentage / sectionchunkcount ) };
auto *sectionchunk { section.submodel->ChildGet() };
while( sectionchunk != nullptr ) {
if( loadpercentage > 0.0 ) {
++section.visible_chunks;
loadpercentage -= sectionchunkloadpercentage;
}
sectionchunk = sectionchunk->NextGet();
} } );
MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
auto visiblechunkcount { (
SectionLoadOrder.empty() ?
0 :
static_cast<int>( std::ceil( loadpercentage * SectionLoadOrder.size() ) ) ) };
for( auto *section : SectionLoadOrder ) {
if( visiblechunkcount == 0 ) { break; }
section->load_chunks_visible++;
--visiblechunkcount;
}
}
void
@@ -2791,16 +2784,16 @@ TDynamicObject::update_load_offset() {
}
void
TDynamicObject::shuffle_load_sections() {
TDynamicObject::shuffle_load_order() {
std::shuffle( std::begin( SectionLoadVisibility ), std::end( SectionLoadVisibility ), Global.random_engine );
std::shuffle( std::begin( SectionLoadOrder ), std::end( SectionLoadOrder ), Global.random_engine );
// shift chunks assigned to corridors to the end of the list, so they show up last
std::stable_partition(
std::begin( SectionLoadVisibility ), std::end( SectionLoadVisibility ),
[]( section_visibility const &section ) {
std::begin( SectionLoadOrder ), std::end( SectionLoadOrder ),
[]( vehicle_section const *section ) {
return (
( section.submodel->pName.find( "compartment" ) == 0 )
|| ( section.submodel->pName.find( "przedzial" ) == 0 ) ); } );
( section->compartment->pName.find( "compartment" ) == 0 )
|| ( section->compartment->pName.find( "przedzial" ) == 0 ) ); } );
// NOTE: potentially we're left with a mix of corridor and external section loads
// but that's not necessarily a wrong outcome, so we leave it this way for the time being
}

View File

@@ -230,16 +230,12 @@ public:
struct vehicle_section {
TSubModel *compartment;
TSubModel *load;
int load_chunks_visible;
float light_level;
};
std::vector<vehicle_section> Sections; // table of recognized vehicle sections
bool SectionLightsActive { false }; // flag indicating whether section lights were set.
struct section_visibility {
TSubModel *submodel;
bool visible;
int visible_chunks;
};
std::vector<section_visibility> SectionLoadVisibility; // visibility of specific sections of the load 3d model
std::vector<vehicle_section *> SectionLoadOrder; // helper, activation/deactivation load chunk sequence
private:
// zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
@@ -574,7 +570,7 @@ private:
void update_load_sections();
void update_load_visibility();
void update_load_offset();
void shuffle_load_sections();
void shuffle_load_order();
void update_destinations();
bool Update(double dt, double dt1);
bool FastUpdate(double dt);

View File

@@ -10994,7 +10994,6 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
WriteLog( "XBT EStED" );
Hamulec = std::make_shared<TEStED>( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA );
Hamulec->SetRM( RapidMult );
Hamulec->SetRV( RapidVel );
if( MBPM < 2 ) {
//jesli przystawka wazaca
Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 );
@@ -11017,7 +11016,6 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
Hamulec = std::make_shared<TEStEP1>(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA);
Hamulec->SetLP( Mass, MBPM, MaxBrakePress[1] );
Hamulec->SetRM( RapidMult );
Hamulec->SetRV( RapidVel );
break;
}
case TBrakeValve::CV1:
@@ -11037,6 +11035,7 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
}
Hamulec->SetASBP( MaxBrakePress[ 4 ] );
Hamulec->SetRV( RapidVel );
switch( BrakeHandle ) {
case TBrakeHandle::FV4a:

View File

@@ -1685,11 +1685,6 @@ void TEStED::SetLP( double const TM, double const LM, double const TBP )
TareBP = TBP;
}
void TEStED::SetRV(double const RVR)
{
RV = RVR;
}
//---DAKO CV1---
void TCV1::CheckState( double const BCP, double &dV1 )
@@ -2137,13 +2132,13 @@ double TKE::GetPF( double const PP, double const dt, double const Vel )
if (!((typeid(*FM) == typeid(TDisk1)) ||
(typeid(*FM) == typeid(TDisk2)))) // jesli zeliwo to schodz
RapidStatus = ((BrakeDelayFlag & bdelay_R) == bdelay_R) &&
(((Vel > 50) && (RapidStatus)) || (Vel > 70));
((RV < 0) || ((Vel > RV) && (RapidStatus)) || (Vel > (RV + 20)));
else // jesli tarczowki, to zostan
RapidStatus = ((BrakeDelayFlag & bdelay_R) == bdelay_R);
// temp:=1.9-0.9*int(RapidStatus);
if ((RM * RM > 0.1)) // jesli jest rapid
if ((RM * RM > 0.001)) // jesli jest rapid
if ((RM > 0)) // jesli dodatni (naddatek);
temp = 1 - RM * int(RapidStatus);
else

View File

@@ -192,8 +192,9 @@ class TBrake {
double SizeBC = 0.0; //rozmiar^2 CH (w stosunku do 14")
bool DCV = false; //podwojny zawor zwrotny
double ASBP = 0.0; //cisnienie hamulca pp
int UniversalFlag = 0; //flaga wcisnietych przyciskow uniwersalnych
double RV = 0.0; // rapid activation vehicle velocity threshold
int UniversalFlag = 0; //flaga wcisnietych przyciskow uniwersalnych
int BrakeStatus{ b_off }; //flaga stanu
int SoundFlag = 0;
@@ -216,7 +217,7 @@ class TBrake {
bool Releaser() const;
virtual void SetEPS( double const nEPS ); //hamulec EP
virtual void SetRM( double const RMR ) {}; //ustalenie przelozenia rapida
virtual void SetRV( double const RVR) {}; //ustalenie przelozenia rapida
virtual void SetRV( double const RVR ) { RV = RVR; }; //ustalenie przelozenia rapida
virtual void SetLP(double const TM, double const LM, double const TBP) {}; //parametry przystawki wazacej
virtual void SetLBP(double const P) {}; //cisnienie z hamulca pomocniczego
virtual void PLC(double const mass) {}; //wspolczynnik cisnienia przystawki wazacej
@@ -347,7 +348,6 @@ class TLSt : public TESt4R {
protected:
double LBP = 0.0; //cisnienie hamulca pomocniczego
double RM = 0.0; //przelozenie rapida
double RV = 0.0;
double EDFlag = 0.0; //luzowanie hamulca z powodu zalaczonego ED
public:
@@ -383,7 +383,6 @@ class TEStED : public TLSt { //zawor z EP09 - Est4 z oddzielnym przekladnikiem,
double GetEDBCP()/*override*/; //cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED
void PLC(double const mass); //wspolczynnik cisnienia przystawki wazacej
void SetLP( double const TM, double const LM, double const TBP ); //parametry przystawki wazacej
void SetRV(double const RVR); //ustalenie predkosci przelaczenia rapida
inline TEStED(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) :
TLSt( i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)

View File

@@ -166,10 +166,10 @@ init() {
"right marker light",
"light pattern",
"rear upper headlight",
"rear left headlight",
"rear right headlight",
"rear left marker light",
"rear left headlight",
"rear right marker light",
"rear left marker light",
"compressor",
"local compressor",
"converter",
@@ -368,10 +368,10 @@ init() {
"sygnal prawy",
"programator swiatel",
"tylny reflektor gorny",
"tylny reflektor lewy",
"tylny reflektor prawy",
"tylny sygnal lewy",
"tylny reflektor lewy",
"tylny sygnal prawy",
"tylny sygnal lewy",
"sprezarka",
"sprezarka lokalna",
"przetwornica",