mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 21:29:18 +02:00
ai direction change logic enhamcement, minor bug fixes
This commit is contained in:
152
Driver.cpp
152
Driver.cpp
@@ -973,12 +973,6 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
iDrivigFlags &= ~moveStopCloser;
|
iDrivigFlags &= ~moveStopCloser;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( iDrivigFlags & moveDoorOpened ) == 0 ) {
|
|
||||||
// drzwi otwierać jednorazowo
|
|
||||||
iDrivigFlags |= moveDoorOpened; // nie wykonywać drugi raz
|
|
||||||
Doors( true, static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TrainParams.UpdateMTable( simulation::Time, asNextStop) ) {
|
if (TrainParams.UpdateMTable( simulation::Time, asNextStop) ) {
|
||||||
// to się wykona tylko raz po zatrzymaniu na W4
|
// to się wykona tylko raz po zatrzymaniu na W4
|
||||||
if( TrainParams.StationIndex < TrainParams.StationCount ) {
|
if( TrainParams.StationIndex < TrainParams.StationCount ) {
|
||||||
@@ -998,6 +992,15 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
m_lastexchangestop = asNextStop;
|
m_lastexchangestop = asNextStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( false == TrainParams.IsMaintenance() )
|
||||||
|
// && ( ( iDrivigFlags & moveDoorOpened ) == 0 ) )
|
||||||
|
{
|
||||||
|
// drzwi otwierać jednorazowo
|
||||||
|
iDrivigFlags |= moveDoorOpened; // nie wykonywać drugi raz
|
||||||
|
Doors( true, static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (TrainParams.DirectionChange()) {
|
if (TrainParams.DirectionChange()) {
|
||||||
// jeśli "@" w rozkładzie, to wykonanie dalszych komend
|
// jeśli "@" w rozkładzie, to wykonanie dalszych komend
|
||||||
// wykonanie kolejnej komendy, nie dotyczy ostatniej stacji
|
// wykonanie kolejnej komendy, nie dotyczy ostatniej stacji
|
||||||
@@ -1193,13 +1196,22 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
VelSignalLast = v; //!!! to też koniec ograniczenia
|
VelSignalLast = v; //!!! to też koniec ograniczenia
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // w trybie manewrowym: skanować od niego wstecz, stanąć po wyjechaniu za
|
{ // w trybie manewrowym: skanować od niego wstecz, stanąć po wyjechaniu za sygnalizator i zmienić kierunek
|
||||||
// sygnalizator i zmienić kierunek
|
v = 0.0; // zmiana kierunku może być podanym sygnałem, ale wypadało by zmienić światło wcześniej
|
||||||
v = 0.0; // zmiana kierunku może być podanym sygnałem, ale wypadało by
|
if( !( iDrivigFlags & moveSwitchFound ) ) { // jeśli nie ma rozjazdu
|
||||||
// zmienić światło wcześniej
|
// check for presence of a signal facing the opposite direction
|
||||||
if (!(iDrivigFlags & moveSwitchFound)) // jeśli nie ma rozjazdu
|
// if there's one, we'll want to pass it before changing direction
|
||||||
iDrivigFlags |= moveTrackEnd; // to dalsza jazda trwale ograniczona (W5,
|
basic_event *foundevent = nullptr;
|
||||||
// koniec toru)
|
if( sSpeedTable[ i ].fDist - fMaxProximityDist > 0 ) {
|
||||||
|
auto scandistance{ sSpeedTable[ i ].fDist + fLength - fMaxProximityDist };
|
||||||
|
auto *scanvehicle{ pVehicles[ end::rear ] };
|
||||||
|
auto scandirection{ scanvehicle->DirectionGet() * scanvehicle->RaDirectionGet() };
|
||||||
|
auto *foundtrack = BackwardTraceRoute( scandistance, scandirection, scanvehicle, foundevent, -1, end::front, false );
|
||||||
|
}
|
||||||
|
if( foundevent == nullptr ) {
|
||||||
|
iDrivigFlags |= moveTrackEnd; // to dalsza jazda trwale ograniczona (W5, koniec toru)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sSpeedTable[i].iFlags & spStopOnSBL) {
|
else if (sSpeedTable[i].iFlags & spStopOnSBL) {
|
||||||
@@ -3183,7 +3195,7 @@ bool TController::IncSpeed()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool OK = true;
|
bool OK = true;
|
||||||
if( ( iDrivigFlags & moveDoorOpened )
|
if( ( doors_open() )
|
||||||
&& ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop
|
&& ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop
|
||||||
// zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
|
// zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
|
||||||
Doors( false );
|
Doors( false );
|
||||||
@@ -4073,7 +4085,7 @@ void TController::Doors( bool const Open, int const Side ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( true == TestFlag( iDrivigFlags, moveDoorOpened ) )
|
if( ( true == doors_open() )
|
||||||
&& ( ( fActionTime > -0.5 )
|
&& ( ( fActionTime > -0.5 )
|
||||||
|| ( false == AIControllFlag ) ) ) {
|
|| ( 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
|
||||||
@@ -4095,7 +4107,9 @@ void TController::Doors( bool const Open, int const Side ) {
|
|||||||
auto *vehicle = pVehicles[ 0 ]; // pojazd na czole składu
|
auto *vehicle = pVehicles[ 0 ]; // pojazd na czole składu
|
||||||
while( vehicle != nullptr ) {
|
while( vehicle != nullptr ) {
|
||||||
// zamykanie drzwi w pojazdach - flaga zezwolenia była by lepsza
|
// zamykanie drzwi w pojazdach - flaga zezwolenia była by lepsza
|
||||||
if( vehicle->MoverParameters->Doors.auto_velocity < 0.f ) {
|
if( ( vehicle->MoverParameters->Doors.auto_velocity < 0.f )
|
||||||
|
&& ( ( vehicle->LoadExchangeTime() == 0.f )
|
||||||
|
|| ( vehicle->MoverParameters->Vel > 0.1 ) ) ) {
|
||||||
vehicle->MoverParameters->OperateDoors( side::right, false, range_t::local ); // w lokomotywie można by nie zamykać...
|
vehicle->MoverParameters->OperateDoors( side::right, false, range_t::local ); // w lokomotywie można by nie zamykać...
|
||||||
vehicle->MoverParameters->OperateDoors( side::left, false, range_t::local );
|
vehicle->MoverParameters->OperateDoors( side::left, false, range_t::local );
|
||||||
}
|
}
|
||||||
@@ -4172,7 +4186,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
|
|
||||||
if (NewCommand == "Emergency_brake") // wymuszenie zatrzymania, niezależnie kto prowadzi
|
if (NewCommand == "Emergency_brake") // wymuszenie zatrzymania, niezależnie kto prowadzi
|
||||||
{ // Ra: no nadal nie jest zbyt pięknie
|
{ // Ra: no nadal nie jest zbyt pięknie
|
||||||
SetVelocity(0, 0, reason);
|
// SetVelocity(0, 0, reason);
|
||||||
mvOccupied->PutCommand("Emergency_brake", 1.0, 1.0, mvOccupied->Loc);
|
mvOccupied->PutCommand("Emergency_brake", 1.0, 1.0, mvOccupied->Loc);
|
||||||
return true; // załatwione
|
return true; // załatwione
|
||||||
}
|
}
|
||||||
@@ -4820,8 +4834,9 @@ TController::UpdateSituation(double dt) {
|
|||||||
// for human-controlled vehicles with no door control and dynamic brake auto-activating with door open
|
// for human-controlled vehicles with no door control and dynamic brake auto-activating with door open
|
||||||
// TODO: check if this situation still happens and the hack is still needed
|
// TODO: check if this situation still happens and the hack is still needed
|
||||||
if( ( false == AIControllFlag )
|
if( ( false == AIControllFlag )
|
||||||
&& ( iDrivigFlags & moveDoorOpened )
|
// && ( iDrivigFlags & moveDoorOpened )
|
||||||
&& ( mvOccupied->Doors.close_control != control_t::driver ) ) {
|
// && ( mvOccupied->Doors.close_control != control_t::driver )
|
||||||
|
&& ( doors_open() ) ) {
|
||||||
// for diesel engines react when engine is put past idle revolutions
|
// for diesel engines react when engine is put past idle revolutions
|
||||||
// for others straightforward master controller check
|
// for others straightforward master controller check
|
||||||
if( ( mvControlling->EngineType == TEngineType::DieselEngine ?
|
if( ( mvControlling->EngineType == TEngineType::DieselEngine ?
|
||||||
@@ -4866,7 +4881,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
|
|
||||||
if( mvOccupied->Vel > 1.0 ) {
|
if( mvOccupied->Vel > 1.0 ) {
|
||||||
// jeżeli jedzie
|
// jeżeli jedzie
|
||||||
if( iDrivigFlags & moveDoorOpened ) {
|
if( doors_open() ) {
|
||||||
// jeśli drzwi otwarte
|
// jeśli drzwi otwarte
|
||||||
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
|
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
|
||||||
Doors( false );
|
Doors( false );
|
||||||
@@ -5166,7 +5181,8 @@ TController::UpdateSituation(double dt) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
Obstacle = neighbour_data();
|
Obstacle = neighbour_data();
|
||||||
auto const lookup { frontvehicle->find_vehicle( routescandirection, routescanrange ) };
|
auto const obstaclescanrange { std::max( ( mvOccupied->CategoryFlag == 2 ? 250.0 : 1000.0 ), routescanrange ) };
|
||||||
|
auto const lookup { frontvehicle->find_vehicle( routescandirection, obstaclescanrange ) };
|
||||||
|
|
||||||
if( std::get<bool>( lookup ) == true ) {
|
if( std::get<bool>( lookup ) == true ) {
|
||||||
|
|
||||||
@@ -5560,6 +5576,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
VelNext = VelDesired; // maksymalna prędkość wynikająca z innych czynników niż trajektoria ruchu
|
VelNext = VelDesired; // maksymalna prędkość wynikająca z innych czynników niż trajektoria ruchu
|
||||||
ActualProximityDist = routescanrange; // funkcja Update() może pozostawić wartości bez zmian
|
ActualProximityDist = routescanrange; // funkcja Update() może pozostawić wartości bez zmian
|
||||||
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci
|
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci
|
||||||
|
|
||||||
TCommandType comm = TableUpdate(VelDesired, ActualProximityDist, VelNext, AccDesired);
|
TCommandType comm = TableUpdate(VelDesired, ActualProximityDist, VelNext, AccDesired);
|
||||||
|
|
||||||
switch (comm) {
|
switch (comm) {
|
||||||
@@ -6218,10 +6235,10 @@ TController::UpdateSituation(double dt) {
|
|||||||
}
|
}
|
||||||
// HACK: limit acceleration for cargo trains, to reduce probability of breaking couplers on sudden jolts
|
// 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?
|
// TBD: expand this behaviour to all trains with car(s) exceeding certain weight?
|
||||||
if( IsCargoTrain ) {
|
if( ( IsCargoTrain ) && ( iVehicles - ControlledEnginesCount > 0 ) ) {
|
||||||
AccDesired = std::min( AccDesired, CargoTrainAcceleration );
|
AccDesired = std::min( AccDesired, CargoTrainAcceleration );
|
||||||
}
|
}
|
||||||
if( IsHeavyCargoTrain ) {
|
if( ( IsHeavyCargoTrain ) && ( iVehicles - ControlledEnginesCount > 0 ) ) {
|
||||||
AccDesired = std::min( AccDesired, HeavyCargoTrainAcceleration );
|
AccDesired = std::min( AccDesired, HeavyCargoTrainAcceleration );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6919,7 +6936,7 @@ std::string TController::StopReasonText() const
|
|||||||
//- rozpoznają tylko zerową prędkość (jako koniec toru i brak podstaw do dalszego skanowania)
|
//- rozpoznają tylko zerową prędkość (jako koniec toru i brak podstaw do dalszego skanowania)
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool TController::BackwardTrackBusy(TTrack *Track)
|
bool TController::IsOccupiedByAnotherConsist(TTrack *Track)
|
||||||
{ // najpierw sprawdzamy, czy na danym torze są pojazdy z innego składu
|
{ // najpierw sprawdzamy, czy na danym torze są pojazdy z innego składu
|
||||||
if( false == Track->Dynamics.empty() ) {
|
if( false == Track->Dynamics.empty() ) {
|
||||||
for( auto dynamic : Track->Dynamics ) {
|
for( auto dynamic : Track->Dynamics ) {
|
||||||
@@ -6932,13 +6949,13 @@ bool TController::BackwardTrackBusy(TTrack *Track)
|
|||||||
return false; // wolny
|
return false; // wolny
|
||||||
};
|
};
|
||||||
|
|
||||||
basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Track)
|
basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Track, TDynamicObject *Vehicle, int const Eventdirection, end const End)
|
||||||
{ // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu
|
{ // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu
|
||||||
// NOTE: this method returns only one event which meets the conditions, due to limitations in the caller
|
// NOTE: this method returns only one event which meets the conditions, due to limitations in the caller
|
||||||
// TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal
|
// TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal
|
||||||
auto const dir{ pVehicles[ 0 ]->VectorFront() * pVehicles[ 0 ]->DirectionGet() };
|
auto const dir{ Vehicle->VectorFront() * Vehicle->DirectionGet() };
|
||||||
auto const pos{ pVehicles[ 0 ]->HeadPosition() };
|
auto const pos{ End == end::front ? Vehicle->RearPosition() : Vehicle->HeadPosition() };
|
||||||
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
|
auto const &eventsequence { ( fDirection * Eventdirection > 0 ? Track->m_events2 : Track->m_events1 ) };
|
||||||
for( auto const &event : eventsequence ) {
|
for( auto const &event : eventsequence ) {
|
||||||
if( ( event.second != nullptr )
|
if( ( event.second != nullptr )
|
||||||
&& ( event.second->m_passive )
|
&& ( event.second->m_passive )
|
||||||
@@ -6946,7 +6963,8 @@ basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Tr
|
|||||||
// since we're checking for events behind us discard the sources in front of the scanning vehicle
|
// since we're checking for events behind us discard the sources in front of the scanning vehicle
|
||||||
auto const sl{ event.second->input_location() }; // położenie komórki pamięci
|
auto const sl{ event.second->input_location() }; // położenie komórki pamięci
|
||||||
auto const sem{ sl - pos }; // wektor do komórki pamięci od końca składu
|
auto const sem{ sl - pos }; // wektor do komórki pamięci od końca składu
|
||||||
if( dir.x * sem.x + dir.z * sem.z < 0 ) {
|
auto const isahead { dir.x * sem.x + dir.z * sem.z > 0 };
|
||||||
|
if( ( End == end::front ? isahead : !isahead ) ) {
|
||||||
// iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
|
// iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
|
||||||
return event.second;
|
return event.second;
|
||||||
}
|
}
|
||||||
@@ -6955,30 +6973,29 @@ basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Tr
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event)
|
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TDynamicObject *Vehicle, basic_event *&Event, int const Eventdirection, end const End, bool const Untiloccupied )
|
||||||
{ // szukanie sygnalizatora w kierunku przeciwnym jazdy (eventu odczytu komórki pamięci)
|
{ // szukanie sygnalizatora w kierunku przeciwnym jazdy (eventu odczytu komórki pamięci)
|
||||||
TTrack *pTrackChVel = Track; // tor ze zmianą prędkości
|
auto *Track = Vehicle->GetTrack();
|
||||||
TTrack *pTrackFrom; // odcinek poprzedni, do znajdywania końca dróg
|
double fCurrentDistance = Vehicle->RaTranslationGet(); // aktualna pozycja na torze
|
||||||
double fDistChVel = -1; // odległość do toru ze zmianą prędkości
|
|
||||||
double fCurrentDistance = pVehicle->RaTranslationGet(); // aktualna pozycja na torze
|
|
||||||
double s = 0;
|
|
||||||
if (fDirection > 0) // jeśli w kierunku Point2 toru
|
if (fDirection > 0) // jeśli w kierunku Point2 toru
|
||||||
fCurrentDistance = Track->Length() - fCurrentDistance;
|
fCurrentDistance = Track->Length() - fCurrentDistance;
|
||||||
if (BackwardTrackBusy(Track))
|
double s = 0;
|
||||||
{ // jak tor zajęty innym składem, to nie ma po co skanować
|
|
||||||
fDistance = 0; // to na tym torze stoimy
|
if( Track->VelocityGet() == 0.0 ) { // jak prędkosć 0 albo uszkadza, to nie ma po co skanować
|
||||||
return NULL; // stop, skanowanie nie dało sensownych rezultatów
|
fDistance = s; // to na tym torze stoimy
|
||||||
|
return nullptr; // stop, skanowanie nie dało sensownych rezultatów
|
||||||
}
|
}
|
||||||
if ((Event = CheckTrackEventBackward(fDirection, Track)) != NULL)
|
if (Untiloccupied && IsOccupiedByAnotherConsist(Track))
|
||||||
|
{ // jak tor zajęty innym składem, to nie ma po co skanować
|
||||||
|
fDistance = s; // to na tym torze stoimy
|
||||||
|
return nullptr; // stop, skanowanie nie dało sensownych rezultatów
|
||||||
|
}
|
||||||
|
if ((Event = CheckTrackEventBackward(fDirection, Track, Vehicle, Eventdirection, End)) != nullptr)
|
||||||
{ // jeśli jest semafor na tym torze
|
{ // jeśli jest semafor na tym torze
|
||||||
fDistance = 0; // to na tym torze stoimy
|
fDistance = s; // to na tym torze stoimy
|
||||||
return Track;
|
return Track;
|
||||||
}
|
}
|
||||||
if ((Track->VelocityGet() == 0.0) || (Track->iDamageFlag & 128))
|
TTrack *pTrackFrom; // odcinek poprzedni, do znajdywania końca dróg
|
||||||
{ // jak prędkosć 0 albo uszkadza, to nie ma po co skanować
|
|
||||||
fDistance = 0; // to na tym torze stoimy
|
|
||||||
return NULL; // stop, skanowanie nie dało sensownych rezultatów
|
|
||||||
}
|
|
||||||
while (s < fDistance)
|
while (s < fDistance)
|
||||||
{
|
{
|
||||||
// Track->ScannedFlag=true; //do pokazywania przeskanowanych torów
|
// Track->ScannedFlag=true; //do pokazywania przeskanowanych torów
|
||||||
@@ -6997,32 +7014,35 @@ TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection,
|
|||||||
Track = Track->CurrentPrev(); // może być NULL
|
Track = Track->CurrentPrev(); // może być NULL
|
||||||
}
|
}
|
||||||
if (Track == pTrackFrom)
|
if (Track == pTrackFrom)
|
||||||
Track = NULL; // koniec, tak jak dla torów
|
Track = nullptr; // koniec, tak jak dla torów
|
||||||
if( ( Track ?
|
|
||||||
( ( Track->VelocityGet() == 0.0 )
|
// gdy dalej toru nie ma albo zerowa prędkość, albo uszkadza pojazd
|
||||||
|| ( Track->iDamageFlag & 128 )
|
// zwraca NULL, że skanowanie nie dało sensownych rezultatów
|
||||||
|| ( true == BackwardTrackBusy( Track ) ) ) :
|
if( Track == nullptr ) {
|
||||||
true ) )
|
|
||||||
{ // gdy dalej toru nie ma albo zerowa prędkość, albo uszkadza pojazd
|
|
||||||
fDistance = s;
|
fDistance = s;
|
||||||
return NULL; // zwraca NULL, że skanowanie nie dało sensownych rezultatów
|
return nullptr;
|
||||||
|
}
|
||||||
|
if( Track->VelocityGet() == 0.0 )
|
||||||
|
{
|
||||||
|
fDistance = s;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if( Untiloccupied && IsOccupiedByAnotherConsist( Track ) ) {
|
||||||
|
fDistance = s;
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
fCurrentDistance = Track->Length();
|
fCurrentDistance = Track->Length();
|
||||||
if ((Event = CheckTrackEventBackward(fDirection, Track)) != NULL)
|
if ((Event = CheckTrackEventBackward(fDirection, Track, Vehicle, Eventdirection, End)) != nullptr)
|
||||||
{ // znaleziony tor z eventem
|
{ // znaleziony tor z eventem
|
||||||
fDistance = s;
|
fDistance = s;
|
||||||
return Track;
|
return Track;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event = NULL; // jak dojdzie tu, to nie ma semafora
|
Event = nullptr; // jak dojdzie tu, to nie ma semafora
|
||||||
if (fDistChVel < 0)
|
// zwraca ostatni sprawdzony tor
|
||||||
{ // zwraca ostatni sprawdzony tor
|
|
||||||
fDistance = s;
|
fDistance = s;
|
||||||
return Track;
|
return Track;
|
||||||
}
|
}
|
||||||
fDistance = fDistChVel; // odległość do zmiany prędkości
|
|
||||||
return pTrackChVel; // i tor na którym się zmienia
|
|
||||||
}
|
|
||||||
|
|
||||||
// sprawdzanie zdarzeń semaforów i ograniczeń szlakowych
|
// sprawdzanie zdarzeń semaforów i ograniczeń szlakowych
|
||||||
void TController::SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos )
|
void TController::SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos )
|
||||||
@@ -7071,8 +7091,8 @@ TCommandType TController::BackwardScan()
|
|||||||
double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane
|
double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane
|
||||||
basic_event *e = NULL; // event potencjalnie od semafora
|
basic_event *e = NULL; // event potencjalnie od semafora
|
||||||
// opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru wg drugiej osi w kierunku ruchu
|
// opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru wg drugiej osi w kierunku ruchu
|
||||||
TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->GetTrack(), e);
|
TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[end::front], e);
|
||||||
auto const dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania
|
auto const dir = startdir * pVehicles[end::front]->VectorFront(); // wektor w kierunku jazdy/szukania
|
||||||
if( !scantrack ) {
|
if( !scantrack ) {
|
||||||
// jeśli wstecz wykryto koniec toru to raczej nic się nie da w takiej sytuacji zrobić
|
// jeśli wstecz wykryto koniec toru to raczej nic się nie da w takiej sytuacji zrobić
|
||||||
return TCommandType::cm_Unknown;
|
return TCommandType::cm_Unknown;
|
||||||
@@ -7095,7 +7115,7 @@ TCommandType TController::BackwardScan()
|
|||||||
if( typeid( *e ) == typeid( getvalues_event ) )
|
if( typeid( *e ) == typeid( getvalues_event ) )
|
||||||
{ // przesłać info o zbliżającym się semaforze
|
{ // przesłać info o zbliżającym się semaforze
|
||||||
#if LOGBACKSCAN
|
#if LOGBACKSCAN
|
||||||
edir += "(" + ( e->asNodeName ) + ")";
|
edir += "(" + ( e->name() ) + ")";
|
||||||
#endif
|
#endif
|
||||||
auto sl = e->input_location(); // położenie komórki pamięci
|
auto sl = e->input_location(); // położenie komórki pamięci
|
||||||
auto sem = sl - pos; // wektor do komórki pamięci od końca składu
|
auto sem = sl - pos; // wektor do komórki pamięci od końca składu
|
||||||
@@ -7147,7 +7167,7 @@ TCommandType TController::BackwardScan()
|
|||||||
WriteLog(
|
WriteLog(
|
||||||
edir + " - [SetVelocity] ["
|
edir + " - [SetVelocity] ["
|
||||||
+ to_string( vmechmax, 2 ) + "] ["
|
+ to_string( vmechmax, 2 ) + "] ["
|
||||||
+ to_string( e->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" );
|
+ to_string( e->input_value( 2 ), 2 ) + "]" );
|
||||||
#endif
|
#endif
|
||||||
return (
|
return (
|
||||||
vmechmax > 0 ?
|
vmechmax > 0 ?
|
||||||
@@ -7191,7 +7211,7 @@ TCommandType TController::BackwardScan()
|
|||||||
WriteLog(
|
WriteLog(
|
||||||
edir + " - [ShuntVelocity] ["
|
edir + " - [ShuntVelocity] ["
|
||||||
+ to_string( vmechmax, 2 ) + "] ["
|
+ to_string( vmechmax, 2 ) + "] ["
|
||||||
+ to_string( e->value( 2 ), 2 ) + "]" );
|
+ to_string( e->input_value( 2 ), 2 ) + "]" );
|
||||||
#endif
|
#endif
|
||||||
return (
|
return (
|
||||||
vmechmax > 0 ?
|
vmechmax > 0 ?
|
||||||
|
|||||||
6
Driver.h
6
Driver.h
@@ -408,9 +408,9 @@ private:
|
|||||||
void TableClear();
|
void TableClear();
|
||||||
int TableDirection() { return iTableDirection; }
|
int TableDirection() { return iTableDirection; }
|
||||||
// Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
|
// Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
|
||||||
bool BackwardTrackBusy( TTrack *Track );
|
bool IsOccupiedByAnotherConsist( TTrack *Track );
|
||||||
basic_event *CheckTrackEventBackward( double fDirection, TTrack *Track );
|
basic_event *CheckTrackEventBackward( double fDirection, TTrack *Track, TDynamicObject *Vehicle, int const Eventdirection = 1, end const End = end::rear );
|
||||||
TTrack *BackwardTraceRoute( double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event );
|
TTrack *BackwardTraceRoute( double &fDistance, double &fDirection, TDynamicObject *Vehicle, basic_event *&Event, int const Eventdirection = 1, end const End = end::rear, bool const Untiloccupied = true );
|
||||||
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
|
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
|
||||||
TCommandType BackwardScan();
|
TCommandType BackwardScan();
|
||||||
std::string TableText( std::size_t const Index ) const;
|
std::string TableText( std::size_t const Index ) const;
|
||||||
|
|||||||
4
DynObj.h
4
DynObj.h
@@ -589,10 +589,10 @@ private:
|
|||||||
inline Math3D::vector3 GetWorldPosition( Math3D::vector3 const &Location ) const {
|
inline Math3D::vector3 GetWorldPosition( Math3D::vector3 const &Location ) const {
|
||||||
return vPosition + mMatrix * Location; }
|
return vPosition + mMatrix * Location; }
|
||||||
// pobranie współrzędnych czoła
|
// pobranie współrzędnych czoła
|
||||||
inline Math3D::vector3 HeadPosition() {
|
inline Math3D::vector3 HeadPosition() const {
|
||||||
return vCoulpler[iDirection ^ 1]; };
|
return vCoulpler[iDirection ^ 1]; };
|
||||||
// pobranie współrzędnych tyłu
|
// pobranie współrzędnych tyłu
|
||||||
inline Math3D::vector3 RearPosition() {
|
inline Math3D::vector3 RearPosition() const {
|
||||||
return vCoulpler[iDirection]; };
|
return vCoulpler[iDirection]; };
|
||||||
inline Math3D::vector3 CouplerPosition( end const End ) const {
|
inline Math3D::vector3 CouplerPosition( end const End ) const {
|
||||||
return vCoulpler[ End ]; }
|
return vCoulpler[ End ]; }
|
||||||
|
|||||||
@@ -1545,7 +1545,7 @@ public:
|
|||||||
double eimv[21];
|
double eimv[21];
|
||||||
static std::vector<std::string> const eimv_labels;
|
static std::vector<std::string> const eimv_labels;
|
||||||
double SpeedCtrlTimer = 0; /*zegar dzialania tempomatu z wybieralna predkoscia*/
|
double SpeedCtrlTimer = 0; /*zegar dzialania tempomatu z wybieralna predkoscia*/
|
||||||
double eimicSpeedCtrl = 0; /*pozycja sugerowana przez tempomat*/
|
double eimicSpeedCtrl = 1; /*pozycja sugerowana przez tempomat*/
|
||||||
double eimicSpeedCtrlIntegral = 0; /*calkowany blad ustawienia predkosci*/
|
double eimicSpeedCtrlIntegral = 0; /*calkowany blad ustawienia predkosci*/
|
||||||
double NewSpeed = 0; /*nowa predkosc do zadania*/
|
double NewSpeed = 0; /*nowa predkosc do zadania*/
|
||||||
double MED_EPVC_CurrentTime = 0; /*aktualny czas licznika czasu korekcji siły EP*/
|
double MED_EPVC_CurrentTime = 0; /*aktualny czas licznika czasu korekcji siły EP*/
|
||||||
|
|||||||
@@ -1310,7 +1310,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
|||||||
compute_movement_( dt );
|
compute_movement_( dt );
|
||||||
|
|
||||||
// security system
|
// security system
|
||||||
if (!DebugModeFlag)
|
|
||||||
SecuritySystemCheck(dt1);
|
SecuritySystemCheck(dt1);
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
@@ -2907,6 +2906,11 @@ void TMoverParameters::SecuritySystemCheck(double dt)
|
|||||||
RadiostopSwitch(false);
|
RadiostopSwitch(false);
|
||||||
// SecuritySystem.Status = 0; //deaktywacja czuwaka
|
// SecuritySystem.Status = 0; //deaktywacja czuwaka
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// automatic reset in debug mode
|
||||||
|
if( DebugModeFlag ) {
|
||||||
|
SSReset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
@@ -7132,6 +7136,7 @@ void TMoverParameters::CheckSpeedCtrl(double dt)
|
|||||||
eimicSpeedCtrl = 1;
|
eimicSpeedCtrl = 1;
|
||||||
eimicSpeedCtrlIntegral = 0;
|
eimicSpeedCtrlIntegral = 0;
|
||||||
SpeedCtrlUnit.Parking = false;
|
SpeedCtrlUnit.Parking = false;
|
||||||
|
SendCtrlToNext( "SpeedCtrlUnit.Parking", SpeedCtrlUnit.Parking, CabActive );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -787,7 +787,7 @@ opengl_texture::unbind(size_t unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
opengl_texture::create() {
|
opengl_texture::create( bool const Static ) {
|
||||||
|
|
||||||
if( data_state != resource_state::good && !is_rendertarget ) {
|
if( data_state != resource_state::good && !is_rendertarget ) {
|
||||||
// don't bother until we have useful texture data
|
// don't bother until we have useful texture data
|
||||||
@@ -934,6 +934,8 @@ opengl_texture::create() {
|
|||||||
make_request();
|
make_request();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_static = Static;
|
||||||
|
|
||||||
is_ready = true;
|
is_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,6 +947,7 @@ void
|
|||||||
opengl_texture::release() {
|
opengl_texture::release() {
|
||||||
|
|
||||||
if( id == -1 ) { return; }
|
if( id == -1 ) { return; }
|
||||||
|
if( is_static ) { return; }
|
||||||
|
|
||||||
if( true == Global.ResourceMove ) {
|
if( true == Global.ResourceMove ) {
|
||||||
// if resource move is enabled we don't keep a cpu side copy after upload
|
// if resource move is enabled we don't keep a cpu side copy after upload
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ struct opengl_texture {
|
|||||||
static void
|
static void
|
||||||
unbind( size_t unit );
|
unbind( size_t unit );
|
||||||
bool
|
bool
|
||||||
create();
|
create( bool const Static = false );
|
||||||
// releases resources allocated on the opengl end, storing local copy if requested
|
// releases resources allocated on the opengl end, storing local copy if requested
|
||||||
void
|
void
|
||||||
release();
|
release();
|
||||||
@@ -78,6 +78,7 @@ private:
|
|||||||
void gles_match_internalformat( GLuint format );
|
void gles_match_internalformat( GLuint format );
|
||||||
|
|
||||||
// members
|
// members
|
||||||
|
bool is_static = false; // is excluded from garbage collection
|
||||||
bool is_rendertarget = false; // is used as postfx rendertarget, without loaded data
|
bool is_rendertarget = false; // is used as postfx rendertarget, without loaded data
|
||||||
int samples = 1;
|
int samples = 1;
|
||||||
int layers = 1;
|
int layers = 1;
|
||||||
|
|||||||
22
Train.cpp
22
Train.cpp
@@ -2437,8 +2437,8 @@ void TTrain::OnCommand_pantographcompressorvalveenable( TTrain *Train, command_d
|
|||||||
|
|
||||||
auto const valveispresent {
|
auto const valveispresent {
|
||||||
( Train->ggPantCompressorValve.SubModel != nullptr )
|
( Train->ggPantCompressorValve.SubModel != nullptr )
|
||||||
|| ( ( Train->iCabn == 0 )
|
|| ( ( Train->mvOccupied == Train->mvPantographUnit )
|
||||||
&& ( Train->mvControlled == Train->mvOccupied ) ) };
|
&& ( Train->iCabn == 0 ) ) };
|
||||||
|
|
||||||
if( false == valveispresent ) {
|
if( false == valveispresent ) {
|
||||||
// tylko w maszynowym, unless actual device is present
|
// tylko w maszynowym, unless actual device is present
|
||||||
@@ -2458,8 +2458,8 @@ void TTrain::OnCommand_pantographcompressorvalvedisable( TTrain *Train, command_
|
|||||||
|
|
||||||
auto const valveispresent {
|
auto const valveispresent {
|
||||||
( Train->ggPantCompressorValve.SubModel != nullptr )
|
( Train->ggPantCompressorValve.SubModel != nullptr )
|
||||||
|| ( ( Train->iCabn == 0 )
|
|| ( ( Train->mvOccupied == Train->mvPantographUnit )
|
||||||
&& ( Train->mvControlled == Train->mvOccupied ) ) };
|
&& ( Train->iCabn == 0 ) ) };
|
||||||
|
|
||||||
if( false == valveispresent ) {
|
if( false == valveispresent ) {
|
||||||
// tylko w maszynowym, unless actual device is present
|
// tylko w maszynowym, unless actual device is present
|
||||||
@@ -2477,11 +2477,12 @@ void TTrain::OnCommand_pantographcompressorvalvedisable( TTrain *Train, command_
|
|||||||
|
|
||||||
void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( ( Train->ggPantCompressorValve.SubModel == nullptr )
|
// tylko w maszynowym, unless actual device is present
|
||||||
&& ( Train->mvControlled->TrainType == dt_EZT ?
|
auto const switchispresent {
|
||||||
( Train->mvOccupied == Train->mvPantographUnit ) :
|
( Train->m_controlmapper.contains( "pantcompressor_sw:" ) )
|
||||||
( Train->iCabn != 0 ) ) ) {
|
|| ( ( Train->mvOccupied == Train->mvPantographUnit )
|
||||||
// tylko w maszynowym
|
&& ( Train->iCabn == 0 ) ) };
|
||||||
|
if( false == switchispresent ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7869,7 +7870,8 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
tex->make_stub();
|
tex->make_stub();
|
||||||
}
|
}
|
||||||
|
|
||||||
tex->create();
|
tex->create( true ); // make the surface static so it doesn't get destroyed by garbage collector if the user spends long time outside cab
|
||||||
|
// TBD, TODO: keep texture handles around, so we can undo the static switch when the user changes cabs?
|
||||||
|
|
||||||
auto touch_list = std::make_shared<std::vector<glm::vec2>>();
|
auto touch_list = std::make_shared<std::vector<glm::vec2>>();
|
||||||
auto rt = std::make_shared<python_rt>();
|
auto rt = std::make_shared<python_rt>();
|
||||||
|
|||||||
@@ -369,6 +369,7 @@ timetable_panel::update() {
|
|||||||
( owner->iStationStart < table.StationIndex )
|
( owner->iStationStart < table.StationIndex )
|
||||||
&& ( i < table.StationIndex )
|
&& ( i < table.StationIndex )
|
||||||
&& ( ( tableline->Ah < 0 ) // pass-through, always valid
|
&& ( ( tableline->Ah < 0 ) // pass-through, always valid
|
||||||
|
|| ( tableline->is_maintenance ) // maintenance stop, always valid
|
||||||
|| ( time.wHour * 60 + time.wMinute + time.wSecond * 0.0167 >= tableline->Dh * 60 + tableline->Dm ) ) ) };
|
|| ( time.wHour * 60 + time.wMinute + time.wSecond * 0.0167 >= tableline->Dh * 60 + tableline->Dm ) ) ) };
|
||||||
auto const loadchangeinprogress { ( ( static_cast<int>( std::ceil( -1.0 * owner->fStopTime ) ) ) > 0 ) };
|
auto const loadchangeinprogress { ( ( static_cast<int>( std::ceil( -1.0 * owner->fStopTime ) ) ) > 0 ) };
|
||||||
auto const isatpassengerstop { ( true == owner->IsAtPassengerStop ) && ( vehicle->MoverParameters->Vel < 1.0 ) };
|
auto const isatpassengerstop { ( true == owner->IsAtPassengerStop ) && ( vehicle->MoverParameters->Vel < 1.0 ) };
|
||||||
|
|||||||
47
material.cpp
47
material.cpp
@@ -77,6 +77,7 @@ void opengl_material::finalize(bool Loadnow)
|
|||||||
|
|
||||||
if (key.size() > 0 && key[0] != '_')
|
if (key.size() > 0 && key[0] != '_')
|
||||||
{
|
{
|
||||||
|
key.erase( key.find_first_not_of( "-1234567890" ) );
|
||||||
size_t num = std::stoi(key) - 1;
|
size_t num = std::stoi(key) - 1;
|
||||||
if (num < gl::MAX_TEXTURES) {
|
if (num < gl::MAX_TEXTURES) {
|
||||||
textures[num] = GfxRenderer->Fetch_Texture(value, Loadnow);
|
textures[num] = GfxRenderer->Fetch_Texture(value, Loadnow);
|
||||||
@@ -99,10 +100,13 @@ void opengl_material::finalize(bool Loadnow)
|
|||||||
textures[ lookup->second ] = GfxRenderer->Fetch_Texture( value, Loadnow );
|
textures[ lookup->second ] = GfxRenderer->Fetch_Texture( value, Loadnow );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// ignore unrecognized texture bindings in legacy render mode, it's most likely data for more advanced shaders
|
||||||
|
if( Global.GfxRenderer == "default" ) {
|
||||||
log_error( "unknown texture binding: " + key );
|
log_error( "unknown texture binding: " + key );
|
||||||
is_good = false;
|
is_good = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
log_error("unrecognized texture binding: " + key);
|
log_error("unrecognized texture binding: " + key);
|
||||||
is_good = false;
|
is_good = false;
|
||||||
@@ -129,6 +133,9 @@ void opengl_material::finalize(bool Loadnow)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TBD, TODO: move material validation to renderer, to eliminate branching?
|
||||||
|
if( Global.GfxRenderer == "default" ) {
|
||||||
|
|
||||||
if( !shader ) {
|
if( !shader ) {
|
||||||
is_good = false;
|
is_good = false;
|
||||||
return;
|
return;
|
||||||
@@ -170,10 +177,23 @@ void opengl_material::finalize(bool Loadnow)
|
|||||||
is_good = false;
|
is_good = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
parse_info.reset();
|
parse_info.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( Global.GfxRenderer != "default" ) {
|
||||||
|
// basic texture validation for legacy branch
|
||||||
|
for( auto texturehandle : textures ) {
|
||||||
|
if( texturehandle == null_handle ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( GfxRenderer->Texture( texturehandle ).id <= 0 ) {
|
||||||
|
is_good = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( !shader ) {
|
if( !shader ) {
|
||||||
is_good = false;
|
is_good = false;
|
||||||
return;
|
return;
|
||||||
@@ -206,7 +226,10 @@ void opengl_material::finalize(bool Loadnow)
|
|||||||
{
|
{
|
||||||
gl::shader::texture_entry &entry = it.second;
|
gl::shader::texture_entry &entry = it.second;
|
||||||
texture_handle handle = textures[entry.id];
|
texture_handle handle = textures[entry.id];
|
||||||
if (handle) {
|
// NOTE: texture validation at this stage relies on forced texture load behaviour during its create() call
|
||||||
|
// TODO: move texture id validation to later stage if/when deferred texture loading is implemented
|
||||||
|
if( ( handle )
|
||||||
|
&& ( GfxRenderer->Texture( handle ).id > 0 ) ) {
|
||||||
GfxRenderer->Texture(handle).set_components_hint((GLint)entry.components);
|
GfxRenderer->Texture(handle).set_components_hint((GLint)entry.components);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -476,7 +499,9 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
|
|||||||
if( ( false == isgenerated )
|
if( ( false == isgenerated )
|
||||||
&& ( false == locator.first.empty() ) ) {
|
&& ( false == locator.first.empty() ) ) {
|
||||||
// try to parse located file resource
|
// try to parse located file resource
|
||||||
cParser materialparser( locator.first + locator.second, cParser::buffer_FILE );
|
cParser materialparser(
|
||||||
|
locator.first + locator.second,
|
||||||
|
cParser::buffer_FILE );
|
||||||
if( true == material.deserialize( materialparser, Loadnow ) ) {
|
if( true == material.deserialize( materialparser, Loadnow ) ) {
|
||||||
material.name = locator.first;
|
material.name = locator.first;
|
||||||
}
|
}
|
||||||
@@ -485,12 +510,11 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
|
|||||||
// if there's no .mat file, this can be either autogenerated texture,
|
// if there's no .mat file, this can be either autogenerated texture,
|
||||||
// or legacy method of referring just to diffuse texture directly.
|
// or legacy method of referring just to diffuse texture directly.
|
||||||
// wrap basic material around it in either case
|
// wrap basic material around it in either case
|
||||||
material.textures[0] = GfxRenderer->Fetch_Texture( Filename, Loadnow );
|
auto const texturehandle { GfxRenderer->Fetch_Texture( Filename, Loadnow ) };
|
||||||
if( material.textures[0] != null_handle )
|
if( texturehandle != null_handle ) {
|
||||||
{
|
|
||||||
// use texture path and name to tell the newly created materials apart
|
// use texture path and name to tell the newly created materials apart
|
||||||
material.name = GfxRenderer->Texture( material.textures[0] ).name;
|
material.name = GfxRenderer->Texture( texturehandle ).name;
|
||||||
|
/*
|
||||||
// material would attach default shader anyway, but it would spit to error log
|
// material would attach default shader anyway, but it would spit to error log
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -501,6 +525,13 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
|
|||||||
ErrorLog("invalid shader: " + std::string(e.what()));
|
ErrorLog("invalid shader: " + std::string(e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
// HACK: create parse info for material finalize() method
|
||||||
|
cParser materialparser(
|
||||||
|
"texture1: " + Filename,
|
||||||
|
cParser::buffer_TEXT );
|
||||||
|
material.deserialize( materialparser, Loadnow );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( false == material.name.empty() ) {
|
if( false == material.name.empty() ) {
|
||||||
|
|||||||
@@ -1779,7 +1779,7 @@ void opengl33_renderer::Bind_Material( material_handle const Material, TSubModel
|
|||||||
{
|
{
|
||||||
if (Material != null_handle)
|
if (Material != null_handle)
|
||||||
{
|
{
|
||||||
auto &material = m_materials.material(Material);
|
auto const &material { m_materials.material( Material ) };
|
||||||
|
|
||||||
if( false == material.is_good ) {
|
if( false == material.is_good ) {
|
||||||
// use failure indicator instead
|
// use failure indicator instead
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
m_reflectiontexture = Fetch_Texture( "fx/reflections" );
|
m_reflectiontexture = Fetch_Texture( "fx/reflections" );
|
||||||
}
|
}
|
||||||
m_smoketexture = Fetch_Texture( "fx/smoke" );
|
m_smoketexture = Fetch_Texture( "fx/smoke" );
|
||||||
|
m_invalid_material = Fetch_Material( "fx/invalid" );
|
||||||
|
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
// pick buffer resources
|
// pick buffer resources
|
||||||
@@ -1705,12 +1706,31 @@ opengl_renderer::Fetch_Material( std::string const &Filename, bool const Loadnow
|
|||||||
void
|
void
|
||||||
opengl_renderer::Bind_Material( material_handle const Material, TSubModel const *sm, lighting_data const *lighting ) {
|
opengl_renderer::Bind_Material( material_handle const Material, TSubModel const *sm, lighting_data const *lighting ) {
|
||||||
|
|
||||||
auto const &material = m_materials.material( Material );
|
if( Material != null_handle ) {
|
||||||
|
|
||||||
|
auto const &material { m_materials.material( Material ) };
|
||||||
|
|
||||||
|
if( false == material.is_good ) {
|
||||||
|
// use failure indicator instead
|
||||||
|
if( Material != m_invalid_material ) {
|
||||||
|
Bind_Material( m_invalid_material );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( false == Global.BasicRenderer ) {
|
if( false == Global.BasicRenderer ) {
|
||||||
m_textures.bind( m_normaltextureunit, material.textures[1] );
|
m_textures.bind( m_normaltextureunit, material.textures[1] );
|
||||||
}
|
}
|
||||||
m_textures.bind( m_diffusetextureunit, material.textures[0] );
|
m_textures.bind( m_diffusetextureunit, material.textures[0] );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// null material, unbind all textures
|
||||||
|
if( false == Global.BasicRenderer ) {
|
||||||
|
m_textures.bind( m_normaltextureunit, null_handle );
|
||||||
|
}
|
||||||
|
m_textures.bind( m_diffusetextureunit, null_handle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
opengl_material const &
|
opengl_material const &
|
||||||
opengl_renderer::Material( material_handle const Material ) const {
|
opengl_renderer::Material( material_handle const Material ) const {
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ private:
|
|||||||
texture_handle m_reflectiontexture { -1 };
|
texture_handle m_reflectiontexture { -1 };
|
||||||
texture_handle m_smoketexture { -1 };
|
texture_handle m_smoketexture { -1 };
|
||||||
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
||||||
|
material_handle m_invalid_material;
|
||||||
// TODO: refactor framebuffer stuff into an object
|
// TODO: refactor framebuffer stuff into an object
|
||||||
bool m_framebuffersupport { false };
|
bool m_framebuffersupport { false };
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
|
|||||||
Reference in New Issue
Block a user