mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-25 02:07:37 +02:00
Merge branch 'master' of https://github.com/tmj-fstate/maszyna into tmj-master
This commit is contained in:
113
Driver.cpp
113
Driver.cpp
@@ -1988,6 +1988,8 @@ void TController::AutoRewident()
|
||||
break;
|
||||
}
|
||||
}
|
||||
// potentially release manual brake
|
||||
d->MoverParameters->DecManualBrakeLevel( ManualBrakePosNo );
|
||||
}
|
||||
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
|
||||
}
|
||||
@@ -2347,6 +2349,10 @@ bool TController::CheckVehicles(TOrders user)
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
if( OrderCurrentGet() & ( Shunt | Loose_shunt | Obey_train | Bank ) ) {
|
||||
// nastawianie hamulca do jazdy pociągowej
|
||||
AutoRewident();
|
||||
}
|
||||
}
|
||||
// Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod kątem SN61
|
||||
if( ( mvOccupied->TrainType == dt_EZT )
|
||||
@@ -2767,7 +2773,14 @@ bool TController::ReleaseEngine() {
|
||||
}
|
||||
// gasimy światła
|
||||
Lights( 0, 0 );
|
||||
// activate parking brake
|
||||
// TBD: do it earlier?
|
||||
mvOccupied->SpringBrakeActivate(true);
|
||||
if( ( mvOccupied->LocalBrake == TLocalBrake::ManualBrake )
|
||||
|| ( mvOccupied->MBrake == true ) ) {
|
||||
mvOccupied->IncManualBrakeLevel( ManualBrakePosNo );
|
||||
}
|
||||
// switch off remaining power
|
||||
mvOccupied->BatterySwitch( false );
|
||||
}
|
||||
}
|
||||
@@ -2959,7 +2972,14 @@ bool TController::IncBrakeEIM()
|
||||
switch (mvOccupied->EIMCtrlType)
|
||||
{
|
||||
case 0: {
|
||||
OK = mvOccupied->IncLocalBrakeLevel( 1 );
|
||||
if( mvOccupied->MED_amax != 9.81 ) {
|
||||
auto const brakeposition{ clamp( -1.0 * mvOccupied->AIHintLocalBrakeAccFactor * AccDesired / mvOccupied->MED_amax, 0.0, 1.0 ) };
|
||||
OK = ( brakeposition != mvOccupied->LocalBrakePosA );
|
||||
mvOccupied->LocalBrakePosA = brakeposition;
|
||||
}
|
||||
else {
|
||||
OK = mvOccupied->IncLocalBrakeLevel( 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
@@ -3067,24 +3087,35 @@ bool TController::DecBrakeEIM()
|
||||
bool OK = false;
|
||||
switch (mvOccupied->EIMCtrlType)
|
||||
{
|
||||
case 0:
|
||||
OK = mvOccupied->DecLocalBrakeLevel(1);
|
||||
break;
|
||||
case 1:
|
||||
OK = mvOccupied->MainCtrlPos < 2;
|
||||
if (OK)
|
||||
mvOccupied->MainCtrlPos = 2;
|
||||
break;
|
||||
case 2:
|
||||
OK = mvOccupied->MainCtrlPos < 3;
|
||||
if (OK)
|
||||
mvOccupied->MainCtrlPos = 3;
|
||||
break;
|
||||
case 3:
|
||||
OK = mvOccupied->MainCtrlPos < mvOccupied->MainCtrlMaxDirChangePos;
|
||||
if( OK )
|
||||
mvOccupied->MainCtrlPos = mvOccupied->MainCtrlMaxDirChangePos;
|
||||
break;
|
||||
case 0: {
|
||||
if( mvOccupied->MED_amax != 9.81 ) {
|
||||
auto const brakeposition { clamp( -1.0 * mvOccupied->AIHintLocalBrakeAccFactor * AccDesired / mvOccupied->MED_amax, 0.0, 1.0 ) };
|
||||
OK = ( brakeposition != mvOccupied->LocalBrakePosA );
|
||||
mvOccupied->LocalBrakePosA = brakeposition;
|
||||
}
|
||||
else {
|
||||
OK = mvOccupied->DecLocalBrakeLevel( 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
OK = mvOccupied->MainCtrlPos < 2;
|
||||
if( OK )
|
||||
mvOccupied->MainCtrlPos = 2;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
OK = mvOccupied->MainCtrlPos < 3;
|
||||
if( OK )
|
||||
mvOccupied->MainCtrlPos = 3;
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
OK = mvOccupied->MainCtrlPos < mvOccupied->MainCtrlMaxDirChangePos;
|
||||
if( OK )
|
||||
mvOccupied->MainCtrlPos = mvOccupied->MainCtrlMaxDirChangePos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@@ -4468,6 +4499,7 @@ void TController::PhysicsLog()
|
||||
void
|
||||
TController::UpdateSituation(double dt) {
|
||||
// uruchamiać przynajmniej raz na sekundę
|
||||
if( false == simulation::is_ready ) { return; }
|
||||
if( ( iDrivigFlags & movePrimary ) == 0 ) { return; } // pasywny nic nie robi
|
||||
|
||||
// update timers
|
||||
@@ -5068,18 +5100,30 @@ TController::UpdateSituation(double dt) {
|
||||
int const end { ( vehicle->DirectionGet() > 0 ? end::front : end::rear ) };
|
||||
auto const &neighbour { vehicleparameters->Neighbours[ end ] };
|
||||
if( neighbour.vehicle != nullptr ) {
|
||||
// próba podczepienia
|
||||
vehicleparameters->Attach(
|
||||
end, neighbour.vehicle_end,
|
||||
neighbour.vehicle->MoverParameters,
|
||||
iCoupler );
|
||||
if( vehicleparameters->Couplers[ end ].CouplingFlag == iCoupler ) {
|
||||
// jeżeli został podłączony
|
||||
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||
SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie
|
||||
CheckVehicles( Connect ); // sprawdzić światła nowego składu
|
||||
JumpToNextOrder(); // wykonanie następnej komendy
|
||||
if( neighbour.distance < 10 ) {
|
||||
// check whether we don't need to attach coupler adapter
|
||||
auto &coupler{ vehicleparameters->Couplers[ end ] };
|
||||
if( coupler.type() != TCouplerType::Automatic ) {
|
||||
auto &othercoupler = neighbour.vehicle->MoverParameters->Couplers[ ( neighbour.vehicle_end != 2 ? neighbour.vehicle_end : coupler.ConnectedNr ) ];
|
||||
if( othercoupler.type() == TCouplerType::Automatic ) {
|
||||
vehicle->attach_coupler_adapter( end );
|
||||
}
|
||||
}
|
||||
if( neighbour.distance < 2 ) {
|
||||
// próba podczepienia
|
||||
vehicleparameters->Attach(
|
||||
end, neighbour.vehicle_end,
|
||||
neighbour.vehicle->MoverParameters,
|
||||
iCoupler );
|
||||
if( vehicleparameters->Couplers[ end ].CouplingFlag == iCoupler ) {
|
||||
// jeżeli został podłączony
|
||||
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||
SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie
|
||||
CheckVehicles( Connect ); // sprawdzić światła nowego składu
|
||||
JumpToNextOrder(); // wykonanie następnej komendy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if (AIControllFlag) //koniec zblokowania, bo była zmienna lokalna
|
||||
@@ -5463,7 +5507,12 @@ TController::UpdateSituation(double dt) {
|
||||
// tylko jeśli odepnie
|
||||
WriteLog( mvOccupied->Name + " odczepiony." );
|
||||
iVehicleCount = -2;
|
||||
CheckVehicles( Disconnect ); // update trainset state
|
||||
// potentially remove coupler adapter
|
||||
if( p->MoverParameters->Couplers[ d ].has_adapter() ) {
|
||||
p->remove_coupler_adapter( d );
|
||||
}
|
||||
// update trainset state
|
||||
CheckVehicles( Disconnect );
|
||||
} // a jak nie, to dociskać dalej
|
||||
}
|
||||
if ((mvOccupied->Vel < 0.01) && !(iDrivigFlags & movePress))
|
||||
|
||||
119
DynObj.cpp
119
DynObj.cpp
@@ -747,14 +747,16 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
// ABu-240105: Dodatkowy warunek: if (...).Render, zeby rysowal tylko
|
||||
// jeden
|
||||
// z polaczonych sprzegow
|
||||
if ((TestFlag(MoverParameters->Couplers[end::front].CouplingFlag, ctrain_coupler)) &&
|
||||
if ((false == MoverParameters->Couplers[ end::front ].has_adapter()) &&
|
||||
(TestFlag(MoverParameters->Couplers[end::front].CouplingFlag, ctrain_coupler)) &&
|
||||
(MoverParameters->Couplers[end::front].Render))
|
||||
{
|
||||
btCoupler1.Turn( true );
|
||||
btnOn = true;
|
||||
}
|
||||
// else btCoupler1.TurnOff();
|
||||
if ((TestFlag(MoverParameters->Couplers[end::rear].CouplingFlag, ctrain_coupler)) &&
|
||||
if ((false == MoverParameters->Couplers[ end::rear ].has_adapter()) &&
|
||||
(TestFlag(MoverParameters->Couplers[end::rear].CouplingFlag, ctrain_coupler)) &&
|
||||
(MoverParameters->Couplers[end::rear].Render))
|
||||
{
|
||||
btCoupler2.Turn( true );
|
||||
@@ -903,6 +905,12 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
// uginanie zderzakow
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
|
||||
if( MoverParameters->Couplers[ i ].has_adapter() ) {
|
||||
// HACK: if there's coupler adapter on this side, we presume there's additional distance put between vehicles
|
||||
// which prevents buffers from clashing against each other (or the other vehicle doesn't have buffers to begin with)
|
||||
continue;
|
||||
}
|
||||
|
||||
auto const dist { clamp( MoverParameters->Couplers[ i ].Dist / 2.0, -MoverParameters->Couplers[ i ].DmaxB, 0.0 ) };
|
||||
|
||||
if( dist >= 0.0 ) { continue; }
|
||||
@@ -1539,6 +1547,64 @@ TDynamicObject::uncouple( int const Side ) {
|
||||
return couplingflag;
|
||||
}
|
||||
|
||||
bool
|
||||
TDynamicObject::attach_coupler_adapter( int const Side ) {
|
||||
|
||||
auto &coupler { MoverParameters->Couplers[ Side ] };
|
||||
// sanity check(s)
|
||||
if( coupler.type() == TCouplerType::Automatic ) { return false; }
|
||||
auto const *neighbour { MoverParameters->Neighbours[ Side ].vehicle };
|
||||
if( ( neighbour == nullptr )
|
||||
|| ( MoverParameters->Neighbours[ Side ].distance > 25.0 ) ) {
|
||||
// can only acquire the adapter from a nearby enough vehicle
|
||||
return false;
|
||||
}
|
||||
// TBD: empty struct instead of fallback defaults, to allow vehicles without adapter?
|
||||
auto adapterdata {
|
||||
coupleradapter_data {
|
||||
{ 0.085f, 0.95f },
|
||||
"tabor/polsprzeg" } };
|
||||
if( false == neighbour->m_coupleradapter.model.empty() ) {
|
||||
// explicit coupler adapter definition overrides default parameters
|
||||
adapterdata = neighbour->m_coupleradapter;
|
||||
}
|
||||
if( MoverParameters->Neighbours[ Side ].distance - adapterdata.position.x < 0.5 ) {
|
||||
// arbitrary amount of free room required to install the adapter
|
||||
// NOTE: this also covers cases with established physical connection
|
||||
return false;
|
||||
}
|
||||
|
||||
coupler.adapter_type = TCouplerType::Automatic;
|
||||
coupler.adapter_length = adapterdata.position.x;
|
||||
coupler.adapter_height = adapterdata.position.y;
|
||||
// audio flag, visuals update
|
||||
coupler.sounds |= sound::attachadapter;
|
||||
m_coupleradapters[ Side ] = TModelsManager::GetModel( adapterdata.model );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TDynamicObject::remove_coupler_adapter( int const Side ) {
|
||||
|
||||
auto &coupler{ MoverParameters->Couplers[ Side ] };
|
||||
|
||||
if( coupler.adapter_type == TCouplerType::NoCoupler ) { return false; }
|
||||
// TODO: sanity check(s)
|
||||
if( coupler.Connected != nullptr ) {
|
||||
// TBD: disallow instead adapter removal if it's coupled with another vehicle?
|
||||
uncouple( Side );
|
||||
}
|
||||
coupler.adapter_type = TCouplerType::NoCoupler;
|
||||
coupler.adapter_length = 0.0;
|
||||
coupler.adapter_height = 0.0;
|
||||
// audio flag, visuals update
|
||||
coupler.sounds |= sound::removeadapter;
|
||||
m_coupleradapters[ Side ] = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TDynamicObject::TDynamicObject() {
|
||||
modelShake = Math3D::vector3(0, 0, 0);
|
||||
// fTrackBlock = 10000.0; // brak przeszkody na drodze
|
||||
@@ -3367,7 +3433,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
double fCurrent = (
|
||||
( MoverParameters->DynamicBrakeFlag && MoverParameters->ResistorsFlag ) ?
|
||||
0 :
|
||||
std::abs( MoverParameters->Itot ) )
|
||||
std::abs( MoverParameters->Itot ) * MoverParameters->IsVehicleEIMBrakingFactor() )
|
||||
+ MoverParameters->TotalCurrent; // prąd pobierany przez pojazd - bez sensu z tym (TotalCurrent)
|
||||
// TotalCurrent to bedzie prad nietrakcyjny (niezwiazany z napedem)
|
||||
// fCurrent+=fabs(MoverParameters->Voltage)*1e-6; //prąd płynący przez woltomierz, rozładowuje kondensator orgromowy 4µF
|
||||
@@ -4394,6 +4460,12 @@ void TDynamicObject::RenderSounds() {
|
||||
m_couplersounds[ couplerindex ].dsbCouplerAttach.play();
|
||||
m_couplersounds[ couplerindex ].dsbCouplerDetach.play();
|
||||
}
|
||||
if( true == TestFlag( coupler.sounds, sound::attachadapter ) ) {
|
||||
m_couplersounds[ couplerindex ].dsbAdapterAttach.play();
|
||||
}
|
||||
if( true == TestFlag( coupler.sounds, sound::removeadapter ) ) {
|
||||
m_couplersounds[ couplerindex ].dsbAdapterRemove.play();
|
||||
}
|
||||
|
||||
++couplerindex;
|
||||
coupler.sounds = 0;
|
||||
@@ -4566,6 +4638,17 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
mdLowPolyInt = TModelsManager::GetModel(asModel, true);
|
||||
}
|
||||
|
||||
else if(token == "coupleradapter:") {
|
||||
// coupling adapter data
|
||||
parser.getTokens( 3 );
|
||||
parser
|
||||
>> m_coupleradapter.model
|
||||
>> m_coupleradapter.position.x
|
||||
>> m_coupleradapter.position.y;
|
||||
replace_slashes( m_coupleradapter.model );
|
||||
erase_leading_slashes( m_coupleradapter.model );
|
||||
}
|
||||
|
||||
else if(token == "attachments:") {
|
||||
// additional 3d models attached to main body
|
||||
// content provided as a series of values together enclosed in "{}"
|
||||
@@ -5784,6 +5867,24 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
couplersounds.dsbBufferClamp_loud = bufferclash;
|
||||
}
|
||||
}
|
||||
else if( token == "coupleradapterattach:" ) {
|
||||
// laczenie:
|
||||
sound_source adapterattach { sound_placement::external };
|
||||
adapterattach.deserialize( parser, sound_type::single );
|
||||
adapterattach.owner( this );
|
||||
for( auto &couplersounds : m_couplersounds ) {
|
||||
couplersounds.dsbAdapterAttach = adapterattach;
|
||||
}
|
||||
}
|
||||
else if( token == "coupleradapterremove:" ) {
|
||||
// rozlaczanie:
|
||||
sound_source adapterremove { sound_placement::external };
|
||||
adapterremove.deserialize( parser, sound_type::single );
|
||||
adapterremove.owner( this );
|
||||
for( auto &couplersounds : m_couplersounds ) {
|
||||
couplersounds.dsbAdapterRemove = adapterremove;
|
||||
}
|
||||
}
|
||||
else if( token == "startjolt:" ) {
|
||||
// movement start jolt
|
||||
m_startjolt.deserialize( parser, sound_type::single );
|
||||
@@ -5972,6 +6073,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
m_couplersounds[ end::front ].dsbCouplerStretch_loud.offset( frontcoupleroffset );
|
||||
m_couplersounds[ end::front ].dsbBufferClamp.offset( frontcoupleroffset );
|
||||
m_couplersounds[ end::front ].dsbBufferClamp_loud.offset( frontcoupleroffset );
|
||||
m_couplersounds[ end::front ].dsbAdapterAttach.offset( frontcoupleroffset );
|
||||
m_couplersounds[ end::front ].dsbAdapterRemove.offset( frontcoupleroffset );
|
||||
auto const rearcoupleroffset { glm::vec3{ 0.f, 1.f, MoverParameters->Dim.L * -0.5f } };
|
||||
m_couplersounds[ end::rear ].dsbCouplerAttach.offset( rearcoupleroffset );
|
||||
m_couplersounds[ end::rear ].dsbCouplerDetach.offset( rearcoupleroffset );
|
||||
@@ -5979,6 +6082,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
m_couplersounds[ end::rear ].dsbCouplerStretch_loud.offset( rearcoupleroffset );
|
||||
m_couplersounds[ end::rear ].dsbBufferClamp.offset( rearcoupleroffset );
|
||||
m_couplersounds[ end::rear ].dsbBufferClamp_loud.offset( rearcoupleroffset );
|
||||
m_couplersounds[ end::rear ].dsbAdapterAttach.offset( rearcoupleroffset );
|
||||
m_couplersounds[ end::rear ].dsbAdapterRemove.offset( rearcoupleroffset );
|
||||
}
|
||||
|
||||
TModel3d *
|
||||
@@ -6258,6 +6363,10 @@ TDynamicObject::update_neighbours() {
|
||||
// neighbour.vehicle = coupler.Connected;
|
||||
// neighbour.vehicle_end = coupler.ConnectedNr;
|
||||
neighbour.distance = TMoverParameters::CouplerDist( MoverParameters, coupler.Connected );
|
||||
// take into account potential adapters attached to the couplers
|
||||
auto const &othercoupler { neighbour.vehicle->MoverParameters->Couplers[ neighbour.vehicle_end ] };
|
||||
neighbour.distance -= coupler.adapter_length;
|
||||
neighbour.distance -= othercoupler.adapter_length;
|
||||
}
|
||||
else {
|
||||
// if there's no connected vehicle check for potential collision sources in the vicinity
|
||||
@@ -6276,6 +6385,10 @@ TDynamicObject::update_neighbours() {
|
||||
if( neighbour.distance < ( neighbour.vehicle->MoverParameters->CategoryFlag == 2 ? 50 : 100 ) ) {
|
||||
// at short distances (re)calculate range between couplers directly
|
||||
neighbour.distance = TMoverParameters::CouplerDist( MoverParameters, neighbour.vehicle->MoverParameters );
|
||||
// take into account potential adapters attached to the couplers
|
||||
auto const &othercoupler { neighbour.vehicle->MoverParameters->Couplers[ neighbour.vehicle_end ] };
|
||||
neighbour.distance -= coupler.adapter_length;
|
||||
neighbour.distance -= othercoupler.adapter_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
DynObj.h
16
DynObj.h
@@ -311,6 +311,11 @@ private:
|
||||
float time { 0.f }; // time spent on the operation
|
||||
};
|
||||
|
||||
struct coupleradapter_data {
|
||||
glm::vec2 position; // adapter placement; offset from vehicle end and height
|
||||
std::string model; // 3d model of the adapter
|
||||
};
|
||||
|
||||
struct coupler_sounds {
|
||||
sound_source dsbCouplerAttach { sound_placement::external }; // moved from cab
|
||||
sound_source dsbCouplerDetach { sound_placement::external }; // moved from cab
|
||||
@@ -318,6 +323,8 @@ private:
|
||||
sound_source dsbCouplerStretch_loud { sound_placement::external };
|
||||
sound_source dsbBufferClamp { sound_placement::external }; // moved from cab
|
||||
sound_source dsbBufferClamp_loud { sound_placement::external };
|
||||
sound_source dsbAdapterAttach { sound_placement::external };
|
||||
sound_source dsbAdapterRemove { sound_placement::external };
|
||||
};
|
||||
|
||||
struct pantograph_sounds {
|
||||
@@ -394,6 +401,7 @@ private:
|
||||
// members
|
||||
TButton btCoupler1; // sprzegi
|
||||
TButton btCoupler2;
|
||||
std::array<TModel3d *, 2> m_coupleradapters = { nullptr, nullptr };
|
||||
TAirCoupler btCPneumatic1; // sprzegi powietrzne //yB - zmienione z Button na AirCoupler - krzyzyki
|
||||
TAirCoupler btCPneumatic2;
|
||||
TAirCoupler btCPneumatic1r; // ABu: to zeby nie bylo problemow przy laczeniu wagonow,
|
||||
@@ -469,12 +477,14 @@ private:
|
||||
sound_source m_outernoise { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
#endif
|
||||
sound_source m_wheelflat { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source rscurve { sound_placement::external, 2 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
|
||||
sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
|
||||
sound_source rsDerailment { sound_placement::external, 2 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // McZapkie-051202
|
||||
|
||||
exchange_data m_exchange; // state of active load exchange procedure, if any
|
||||
exchange_sounds m_exchangesounds; // sounds associated with the load exchange
|
||||
|
||||
coupleradapter_data m_coupleradapter;
|
||||
|
||||
bool renderme; // yB - czy renderowac
|
||||
float ModCamRot;
|
||||
int iInventory[ 2 ] { 0, 0 }; // flagi bitowe posiadanych submodeli (np. świateł)
|
||||
@@ -583,6 +593,8 @@ private:
|
||||
// pobranie współrzędnych tyłu
|
||||
inline Math3D::vector3 RearPosition() {
|
||||
return vCoulpler[iDirection]; };
|
||||
inline Math3D::vector3 CouplerPosition( end const End ) const {
|
||||
return vCoulpler[ End ]; }
|
||||
inline Math3D::vector3 AxlePositionGet() {
|
||||
return iAxleFirst ?
|
||||
Axle1.pPosition :
|
||||
@@ -647,6 +659,8 @@ private:
|
||||
|
||||
void couple( int const Side );
|
||||
int uncouple( int const Side );
|
||||
bool attach_coupler_adapter( int const Side );
|
||||
bool remove_coupler_adapter( int const Side );
|
||||
void RadioStop();
|
||||
void Damage(char flag);
|
||||
void RaLightsSet(int head, int rear);
|
||||
|
||||
@@ -193,7 +193,7 @@ basic_event::event_conditions::deserialize( cParser &Input ) {
|
||||
flags |= flags::text;
|
||||
}
|
||||
Input.getTokens();
|
||||
if( Input.peek() != "*" ) //"*" - nie brac val1 pod uwage
|
||||
if( Input.peek() != "*" ) //"*" - nie brac pod uwage
|
||||
{ // two tokens, operator followed by comparison value
|
||||
std::string operatorstring;
|
||||
Input >> operatorstring;
|
||||
@@ -203,13 +203,14 @@ basic_event::event_conditions::deserialize( cParser &Input ) {
|
||||
flags |= flags::value1;
|
||||
}
|
||||
Input.getTokens();
|
||||
if( Input.peek() != "*" ) //"*" - nie brac pod uwage
|
||||
{ // two tokens, operator followed by comparison value
|
||||
std::string operatorstring;
|
||||
Input >> operatorstring;
|
||||
memcompare_value2_operator = comparison_operator_from_string( operatorstring );
|
||||
Input.getTokens();
|
||||
Input >> memcompare_value2;
|
||||
flags |= flags::value1;
|
||||
flags |= flags::value2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,9 @@ enum sound {
|
||||
attachmainhose = 1 << 10,
|
||||
attachcontrol = 1 << 11,
|
||||
attachgangway = 1 << 12,
|
||||
attachheating = 1 << 13
|
||||
attachheating = 1 << 13,
|
||||
attachadapter = 1 << 14,
|
||||
removeadapter = 1 << 15,
|
||||
};
|
||||
|
||||
//szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType
|
||||
@@ -673,7 +675,8 @@ struct TCoupling {
|
||||
double FmaxC = 1000.0;
|
||||
double beta = 0.0;
|
||||
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
|
||||
int AllowedFlag = 3; //Ra: maska dostępnych
|
||||
int AutomaticCouplingFlag = coupling::coupler;
|
||||
int AllowedFlag = coupling::coupler | coupling::brakehose; //Ra: maska dostępnych
|
||||
/*zmienne*/
|
||||
int CouplingFlag = 0; /*0 - wirtualnie, 1 - sprzegi, 2 - pneumatycznie, 4 - sterowanie, 8 - kabel mocy*/
|
||||
class TMoverParameters *Connected = nullptr; /*co jest podlaczone*/
|
||||
@@ -682,12 +685,26 @@ struct TCoupling {
|
||||
double Dist = 0.0; /*strzalka ugiecia zderzaków*/
|
||||
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
||||
float stretch_duration { 0.f }; // seconds, elapsed time with excessive force applied to the coupler
|
||||
// optional adapter piece
|
||||
double adapter_length { 0.0 }; // meters, value added on the given end to standard vehicle (half)length
|
||||
double adapter_height { 0.0 }; // meters, distance from rail level
|
||||
TCouplerType adapter_type = TCouplerType::NoCoupler; // CouplerType override if other than NoCoupler
|
||||
|
||||
power_coupling power_high;
|
||||
// power_coupling power_low; // TODO: implement this
|
||||
|
||||
int sounds { 0 }; // sounds emitted by the coupling devices
|
||||
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
|
||||
|
||||
inline bool
|
||||
has_adapter() const {
|
||||
return ( adapter_type != TCouplerType::NoCoupler ); }
|
||||
inline TCouplerType const
|
||||
type() const {
|
||||
return (
|
||||
adapter_type == TCouplerType::NoCoupler ?
|
||||
CouplerType :
|
||||
adapter_type ); }
|
||||
};
|
||||
|
||||
struct neighbour_data {
|
||||
@@ -1543,6 +1560,7 @@ public:
|
||||
int iLights[2]; // bity zapalonych świateł tutaj, żeby dało się liczyć pobór prądu
|
||||
|
||||
int AIHintPantstate{ 0 }; // suggested pantograph setup
|
||||
double AIHintLocalBrakeAccFactor{ 1.05 }; // suggested acceleration weight for local brake operation
|
||||
|
||||
public:
|
||||
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
|
||||
@@ -1557,6 +1575,8 @@ public:
|
||||
bool DirectionForward();
|
||||
bool DirectionBackward( void );/*! kierunek ruchu*/
|
||||
bool EIMDirectionChangeAllow( void ) const;
|
||||
inline double IsVehicleEIMBrakingFactor() {
|
||||
return eimv[ eimv_Ipoj ] < 0 ? -1.0 : 1.0; }
|
||||
void BrakeLevelSet(double b);
|
||||
bool BrakeLevelAdd(double b);
|
||||
bool IncBrakeLevel(); // wersja na użytek AI
|
||||
|
||||
@@ -22,7 +22,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
// Jeśli jakieś zmienne nie są używane w mover.pas, też można je przenosić.
|
||||
// Przeniesienie wszystkiego na raz zrobiło by zbyt wielki chaos do ogarnięcia.
|
||||
|
||||
const double dEpsilon = 0.01; // 1cm (zależy od typu sprzęgu...)
|
||||
const double dEpsilon = 0.025; // 1cm (zależy od typu sprzęgu...)
|
||||
const double CouplerTune = 0.1; // skalowanie tlumiennosci
|
||||
|
||||
int ConversionError = 0;
|
||||
@@ -438,13 +438,13 @@ bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *
|
||||
|
||||
auto &coupler { Couplers[ ConnectNo ] };
|
||||
auto &othercoupler = ConnectTo->Couplers[ ( ConnectToNr != 2 ? ConnectToNr : coupler.ConnectedNr ) ];
|
||||
auto const distance { CouplerDist( this, ConnectTo ) };
|
||||
auto const distance { CouplerDist( this, ConnectTo ) - ( coupler.adapter_length + othercoupler.adapter_length ) };
|
||||
|
||||
auto const couplercheck {
|
||||
( Forced )
|
||||
|| ( ( distance <= dEpsilon )
|
||||
&& ( coupler.CouplerType != TCouplerType::NoCoupler )
|
||||
&& ( coupler.CouplerType == othercoupler.CouplerType ) ) };
|
||||
&& ( coupler.type() != TCouplerType::NoCoupler )
|
||||
&& ( coupler.type() == othercoupler.type() ) ) };
|
||||
|
||||
if( false == couplercheck ) { return false; }
|
||||
|
||||
@@ -495,7 +495,7 @@ int TMoverParameters::DettachStatus(int ConnectNo)
|
||||
if (TestFlag(DamageFlag, dtrain_coupling))
|
||||
return -Couplers[ConnectNo].CouplingFlag; // hak urwany - rozłączanie jest OK
|
||||
// CouplerDist(ConnectNo);
|
||||
if (Couplers[ConnectNo].CouplerType == TCouplerType::Screw ? Neighbours[ConnectNo].distance < 0.01 : true)
|
||||
if ( (Couplers[ConnectNo].type() != TCouplerType::Screw) || (Neighbours[ConnectNo].distance < 0.01) )
|
||||
return -Couplers[ConnectNo].CouplingFlag; // można rozłączać, jeśli dociśnięty
|
||||
return (Neighbours[ConnectNo].distance > 0.2) ? -Couplers[ConnectNo].CouplingFlag :
|
||||
Couplers[ConnectNo].CouplingFlag;
|
||||
@@ -1102,7 +1102,7 @@ TMoverParameters::damage_coupler( int const End ) {
|
||||
|
||||
auto &coupler{ Couplers[ End ] };
|
||||
|
||||
if( coupler.CouplerType == TCouplerType::Articulated ) { return; } // HACK: don't break articulated couplings no matter what
|
||||
if( coupler.type() == TCouplerType::Articulated ) { return; } // HACK: don't break articulated couplings no matter what
|
||||
|
||||
if( SetFlag( DamageFlag, dtrain_coupling ) )
|
||||
EventFlag = true;
|
||||
@@ -1595,7 +1595,7 @@ void TMoverParameters::PowerCouplersCheck( double const Deltatime ) {
|
||||
// bez napiecia...
|
||||
if( couplervoltage != 0.0 ) {
|
||||
// ...ale jest cos na sprzegach:
|
||||
coupler.power_high.current = ( std::abs( Itot ) + TotalCurrent ) * coupler.power_high.voltage / couplervoltage; // obciążenie rozkladane stosownie do napiec
|
||||
coupler.power_high.current = ( std::abs( Itot ) * IsVehicleEIMBrakingFactor() + TotalCurrent ) * coupler.power_high.voltage / couplervoltage; // obciążenie rozkladane stosownie do napiec
|
||||
if( true == coupler.power_high.is_live ) {
|
||||
coupler.power_high.current += connectedothercoupler.power_high.current;
|
||||
}
|
||||
@@ -4837,7 +4837,8 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
||||
// potentially generate sounds on clash or stretch
|
||||
if( ( newdistance < 0.0 )
|
||||
&& ( coupler.Dist > newdistance )
|
||||
&& ( dV < -0.1 ) ) {
|
||||
&& ( dV < -0.1 )
|
||||
&& ( false == coupler.has_adapter() ) ) { // HACK: with adapter present we presume buffers won't clash
|
||||
// 090503: dzwieki pracy zderzakow
|
||||
SetFlag(
|
||||
coupler.sounds,
|
||||
@@ -4866,7 +4867,7 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
||||
if( ( coupler.CouplingFlag != coupling::faux )
|
||||
|| ( initialdistance < 0 ) ) {
|
||||
|
||||
coupler.Dist = clamp( newdistance, -coupler.DmaxB, coupler.DmaxC );
|
||||
coupler.Dist = clamp( newdistance, ( coupler.has_adapter() ? 0 : -coupler.DmaxB ), coupler.DmaxC );
|
||||
|
||||
double BetaAvg = 0;
|
||||
double Fmax = 0;
|
||||
@@ -4923,16 +4924,19 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
||||
- Fmax * dV * BetaAvg;
|
||||
}
|
||||
// liczenie sily ze sprezystosci zderzaka
|
||||
if( -newdistance > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
|
||||
auto const collisiondistance { (
|
||||
( coupler.has_adapter() || othercoupler.has_adapter() ) ?
|
||||
std::min( coupler.DmaxB, othercoupler.DmaxB ) : // HACK: only take into account buffering ability of automatic coupler
|
||||
coupler.DmaxB + othercoupler.DmaxB
|
||||
) };
|
||||
if( -newdistance > collisiondistance ) {
|
||||
// zderzenie
|
||||
coupler.CheckCollision = true;
|
||||
if( ( coupler.CouplerType == TCouplerType::Automatic )
|
||||
&& ( coupler.CouplerType == othercoupler.CouplerType )
|
||||
if( ( coupler.type() == TCouplerType::Automatic )
|
||||
&& ( coupler.type() == othercoupler.type() )
|
||||
&& ( coupler.CouplingFlag == coupling::faux ) ) {
|
||||
// sprzeganie wagonow z samoczynnymi sprzegami
|
||||
// EN57
|
||||
// TBD, TODO: configurable flag for automatic coupling
|
||||
coupler.CouplingFlag = coupling::coupler /*| coupling::brakehose | coupling::mainhose | coupling::control*/;
|
||||
coupler.CouplingFlag = ( coupler.AutomaticCouplingFlag & othercoupler.AutomaticCouplingFlag );
|
||||
SetFlag( coupler.sounds, sound::attachcoupler );
|
||||
}
|
||||
}
|
||||
@@ -5898,10 +5902,10 @@ double TMoverParameters::TractionForce( double dt ) {
|
||||
else if ((std::abs(EngineVoltage) < EnginePowerSource.CollectorParameters.MaxV))
|
||||
Vadd *= (1.0 - dt);
|
||||
else
|
||||
Vadd = Max0R(
|
||||
Vadd = std::max(
|
||||
Vadd * (1.0 - 0.2 * dt),
|
||||
0.007 * (std::abs(EngineVoltage) - (EnginePowerSource.CollectorParameters.MaxV - 100)));
|
||||
Itot = eimv[eimv_Ipoj] * (0.01 + Min0R(0.99, 0.99 - Vadd));
|
||||
Itot = eimv[eimv_Ipoj] * (0.01 + std::min(0.99, 0.99 - Vadd));
|
||||
|
||||
EnginePower = abs(eimv[eimv_Ic] * eimv[eimv_U] * NPoweredAxles) / 1000;
|
||||
// power inverters
|
||||
@@ -9498,8 +9502,8 @@ void TMoverParameters::LoadFIZ_BuffCoupl( std::string const &line, int const Ind
|
||||
auto lookup = couplertypes.find( extract_value( "CType", line ) );
|
||||
coupler->CouplerType = (
|
||||
lookup != couplertypes.end() ?
|
||||
lookup->second :
|
||||
TCouplerType::NoCoupler );
|
||||
lookup->second :
|
||||
TCouplerType::NoCoupler );
|
||||
|
||||
extract_value( coupler->SpringKC, "kC", line, "" );
|
||||
extract_value( coupler->DmaxC, "DmaxC", line, "" );
|
||||
@@ -9508,6 +9512,7 @@ void TMoverParameters::LoadFIZ_BuffCoupl( std::string const &line, int const Ind
|
||||
extract_value( coupler->DmaxB, "DmaxB", line, "" );
|
||||
extract_value( coupler->FmaxB, "FmaxB", line, "" );
|
||||
extract_value( coupler->beta, "beta", line, "" );
|
||||
extract_value( coupler->AutomaticCouplingFlag, "AutomaticFlag", line, "" );
|
||||
extract_value( coupler->AllowedFlag, "AllowedFlag", line, "" );
|
||||
|
||||
if( coupler->AllowedFlag < 0 ) {
|
||||
@@ -10255,6 +10260,8 @@ void TMoverParameters::LoadFIZ_Circuit( std::string const &Input ) {
|
||||
void TMoverParameters::LoadFIZ_AI( std::string const &Input ) {
|
||||
|
||||
extract_value( AIHintPantstate, "Pantstate", Input, "" );
|
||||
extract_value( AIHintLocalBrakeAccFactor, "LocalBrakeAccFactor", Input, "" );
|
||||
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_RList( std::string const &Input ) {
|
||||
@@ -10763,6 +10770,13 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
||||
LocalBrakePosA = 0.0;
|
||||
BrakeCtrlPos = static_cast<int>( Handle->GetPos( bh_NP ) );
|
||||
LimPipePress = LowPipePress;
|
||||
if( ( LocalBrake == TLocalBrake::ManualBrake )
|
||||
|| ( MBrake == true ) ) {
|
||||
IncManualBrakeLevel( ManualBrakePosNo );
|
||||
}
|
||||
if( SpringBrake.MaxBrakeForce > 0.0 ) {
|
||||
SpringBrake.Activate = true;
|
||||
}
|
||||
}
|
||||
|
||||
ActFlowSpeed = 0.0;
|
||||
|
||||
@@ -157,12 +157,12 @@ bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1,
|
||||
checkfailed |= ( !result );
|
||||
}
|
||||
if( TestFlag( CheckMask, basic_event::flags::value1 ) ) {
|
||||
auto const result { compare( fValue1, fTestValue1, TextOperator ) };
|
||||
auto const result { compare( fValue1, fTestValue1, Value1Operator ) };
|
||||
checkpassed |= result;
|
||||
checkfailed |= ( !result );
|
||||
}
|
||||
if( TestFlag( CheckMask, basic_event::flags::value2 ) ) {
|
||||
auto const result { compare( fValue2, fTestValue2, TextOperator ) };
|
||||
auto const result { compare( fValue2, fTestValue2, Value2Operator ) };
|
||||
checkpassed |= result;
|
||||
checkfailed |= ( !result );
|
||||
}
|
||||
|
||||
@@ -448,9 +448,13 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
*/
|
||||
{
|
||||
// if material has opacity set, replace submodel opacity with it
|
||||
// NOTE: reverted to use base opacity, this allows to define opacity threshold in material
|
||||
// without it causing the translucent models to become opaque
|
||||
auto const opacity { (
|
||||
/*
|
||||
false == std::isnan( mat.opacity ) ?
|
||||
mat.opacity :
|
||||
*/
|
||||
Opacity ) };
|
||||
iFlags &= ~0x30;
|
||||
iFlags |= (
|
||||
|
||||
103
Train.cpp
103
Train.cpp
@@ -360,6 +360,8 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
{ user_command::doormodetoggle, &TTrain::OnCommand_doormodetoggle },
|
||||
{ user_command::carcouplingincrease, &TTrain::OnCommand_carcouplingincrease },
|
||||
{ user_command::carcouplingdisconnect, &TTrain::OnCommand_carcouplingdisconnect },
|
||||
{ user_command::carcoupleradapterattach, &TTrain::OnCommand_carcoupleradapterattach },
|
||||
{ user_command::carcoupleradapterremove, &TTrain::OnCommand_carcoupleradapterremove },
|
||||
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
|
||||
{ user_command::hornlowactivate, &TTrain::OnCommand_hornlowactivate },
|
||||
{ user_command::hornhighactivate, &TTrain::OnCommand_hornhighactivate },
|
||||
@@ -2430,22 +2432,20 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data
|
||||
return;
|
||||
}
|
||||
|
||||
if( ( Train->mvControlled->PantPress > 4.8 )
|
||||
|| ( false == Train->mvControlled->Battery ) ) {
|
||||
// needs live power source and low enough pressure to work
|
||||
return;
|
||||
}
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// press or hold to activate
|
||||
Train->mvControlled->PantCompFlag = true;
|
||||
// visual feedback:
|
||||
if( ( Train->mvControlled->PantPress < 4.8 )
|
||||
&& ( true == Train->mvControlled->Battery ) ) {
|
||||
// needs live power source and low enough pressure to work
|
||||
Train->mvControlled->PantCompFlag = true;
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggPantCompressorButton.UpdateValue( 1.0 );
|
||||
}
|
||||
else {
|
||||
// release to disable
|
||||
Train->mvControlled->PantCompFlag = false;
|
||||
// visual feedback:
|
||||
// visual feedback
|
||||
Train->ggPantCompressorButton.UpdateValue( 0.0 );
|
||||
}
|
||||
}
|
||||
@@ -2480,6 +2480,8 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
||||
OnCommand_linebreakerclose( Train, Command );
|
||||
}
|
||||
}
|
||||
// HACK: ignition key ignores lack of submodel, so we can start vehicles without any modeled controls
|
||||
Train->ggIgnitionKey.UpdateValue( 0.0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2543,6 +2545,8 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
|
||||
}
|
||||
else {
|
||||
// no switch capable of doing the job
|
||||
// HACK: ignition key ignores lack of submodel, so we can start vehicles without any modeled controls
|
||||
Train->ggIgnitionKey.UpdateValue( 1.0 );
|
||||
return;
|
||||
}
|
||||
// the actual closing of the line breaker is handled in the train update routine
|
||||
@@ -4271,14 +4275,11 @@ void TTrain::OnCommand_interiorlightenable( TTrain *Train, command_data const &C
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( Train->ggCabLightButton.SubModel == nullptr ) {
|
||||
if( false == Train->m_controlmapper.contains( "cablight_sw:" ) ) {
|
||||
// TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels
|
||||
WriteLog( "Interior Light switch is missing, or wasn't defined" );
|
||||
return;
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggCabLightButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
Train->btCabLight.Turn( true );
|
||||
// store lighting switch states
|
||||
if( false == Train->DynamicObject->JointCabs ) {
|
||||
// vehicles with separate cabs get separate lighting switch states
|
||||
@@ -4297,14 +4298,11 @@ void TTrain::OnCommand_interiorlightdisable( TTrain *Train, command_data const &
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( Train->ggCabLightButton.SubModel == nullptr ) {
|
||||
if( false == Train->m_controlmapper.contains( "cablight_sw:" ) ) {
|
||||
// TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels
|
||||
WriteLog( "Interior Light switch is missing, or wasn't defined" );
|
||||
return;
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggCabLightButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
Train->btCabLight.Turn( false );
|
||||
// store lighting switch states
|
||||
if( false == Train->DynamicObject->JointCabs ) {
|
||||
// vehicles with separate cabs get separate lighting switch states
|
||||
@@ -5406,6 +5404,40 @@ void TTrain::OnCommand_carcouplingdisconnect( TTrain *Train, command_data const
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_carcoupleradapterattach( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( ( true == FreeFlyModeFlag )
|
||||
&& ( Command.action == GLFW_PRESS ) ) {
|
||||
// tryb freefly, press only
|
||||
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Command.location, 50, false, true ) ) };
|
||||
if( vehicle == nullptr ) { return; }
|
||||
|
||||
auto const coupler = (
|
||||
glm::length2( glm::vec3 { vehicle->CouplerPosition( end::front ) } - Command.location ) < glm::length2( glm::vec3 { vehicle->CouplerPosition( end::rear ) } - Command.location ) ?
|
||||
end::front :
|
||||
end::rear );
|
||||
|
||||
vehicle->attach_coupler_adapter( coupler );
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_carcoupleradapterremove( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( ( true == FreeFlyModeFlag )
|
||||
&& ( Command.action == GLFW_PRESS ) ) {
|
||||
// tryb freefly, press only
|
||||
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Command.location, 50, false, true ) ) };
|
||||
if( vehicle == nullptr ) { return; }
|
||||
|
||||
auto const coupler = (
|
||||
glm::length2( glm::vec3 { vehicle->CouplerPosition( end::front ) } - Command.location ) < glm::length2( glm::vec3 { vehicle->CouplerPosition( end::rear ) } - Command.location ) ?
|
||||
end::front :
|
||||
end::rear );
|
||||
|
||||
vehicle->remove_coupler_adapter( coupler );
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_departureannounce( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Train->ggDepartureSignalButton.SubModel == nullptr ) {
|
||||
@@ -5803,7 +5835,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
}
|
||||
|
||||
if( ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) )
|
||||
|| ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) ) {
|
||||
|| ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 )
|
||||
|| ( ggIgnitionKey.GetDesiredValue() > 0.95 ) ) ) { // HACK: fallback
|
||||
// keep track of period the line breaker button is held down, to determine when/if circuit closes
|
||||
if( ( mvControlled->MainsInitTimeCountdown <= 0.0 )
|
||||
&& ( ( fHVoltage > 0.5 * mvControlled->EnginePowerSource.MaxVoltage )
|
||||
@@ -6800,10 +6833,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
}
|
||||
ggLocalBrake.Update();
|
||||
}
|
||||
if (ggManualBrake.SubModel != nullptr) {
|
||||
ggManualBrake.UpdateValue(double(mvOccupied->ManualBrakePos));
|
||||
ggManualBrake.Update();
|
||||
}
|
||||
ggAlarmChain.Update();
|
||||
ggBrakeProfileCtrl.Update();
|
||||
ggBrakeProfileG.Update();
|
||||
@@ -6940,7 +6969,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggInstrumentLightButton.Update();
|
||||
ggDashboardLightButton.Update();
|
||||
ggTimetableLightButton.Update();
|
||||
ggCabLightButton.Update();
|
||||
ggCabLightDimButton.Update();
|
||||
ggCompartmentLightsButton.Update();
|
||||
ggCompartmentLightsOnButton.Update();
|
||||
@@ -7617,6 +7645,8 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
||||
cabindex = 0;
|
||||
break;
|
||||
}
|
||||
iCabn = cabindex;
|
||||
|
||||
std::string cabstr("cab" + std::to_string(cabindex) + "definition:");
|
||||
|
||||
cParser parser(asFileName, cParser::buffer_FILE);
|
||||
@@ -8212,7 +8242,6 @@ void TTrain::clear_cab_controls()
|
||||
ggDirKey.Clear();
|
||||
ggBrakeCtrl.Clear();
|
||||
ggLocalBrake.Clear();
|
||||
ggManualBrake.Clear();
|
||||
ggAlarmChain.Clear();
|
||||
ggBrakeProfileCtrl.Clear();
|
||||
ggBrakeProfileG.Clear();
|
||||
@@ -8253,7 +8282,6 @@ void TTrain::clear_cab_controls()
|
||||
ggDashboardLightButton.Clear();
|
||||
ggTimetableLightButton.Clear();
|
||||
// hunter-091012
|
||||
ggCabLightButton.Clear();
|
||||
ggCabLightDimButton.Clear();
|
||||
ggCompartmentLightsButton.Clear();
|
||||
ggCompartmentLightsOnButton.Clear();
|
||||
@@ -8403,7 +8431,6 @@ void TTrain::clear_cab_controls()
|
||||
btLampkaRearRightLight.Clear();
|
||||
btLampkaRearLeftEndLight.Clear();
|
||||
btLampkaRearRightEndLight.Clear();
|
||||
btCabLight.Clear(); // hunter-171012
|
||||
// others
|
||||
btLampkaMalfunction.Clear();
|
||||
btLampkaMalfunctionB.Clear();
|
||||
@@ -8579,9 +8606,6 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
ggDimHeadlightsButton.PutValue( 1.f );
|
||||
}
|
||||
// cab lights
|
||||
if( true == Cabine[Cab].bLight ) {
|
||||
ggCabLightButton.PutValue( 1.f );
|
||||
}
|
||||
if( true == Cabine[Cab].bLightDim ) {
|
||||
ggCabLightDimButton.PutValue( 1.f );
|
||||
}
|
||||
@@ -8833,7 +8857,6 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
{ "i-rearrightend:", btLampkaRearRightEndLight },
|
||||
{ "i-dashboardlight:", btDashboardLight },
|
||||
{ "i-timetablelight:", btTimetableLight },
|
||||
{ "i-cablight:", btCabLight },
|
||||
{ "i-universal0:", btUniversals[ 0 ] },
|
||||
{ "i-universal1:", btUniversals[ 1 ] },
|
||||
{ "i-universal2:", btUniversals[ 2 ] },
|
||||
@@ -8859,7 +8882,8 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit },
|
||||
{ "i-doorstep:", &mvOccupied->Doors.step_enabled },
|
||||
{ "i-mainpipelock:", &mvOccupied->LockPipe },
|
||||
{ "i-battery:", &mvOccupied->Battery }
|
||||
{ "i-battery:", &mvOccupied->Battery },
|
||||
{ "i-cablight:", &Cabine[ iCabn ].bLight },
|
||||
};
|
||||
{
|
||||
auto lookup = autolights.find( Label );
|
||||
@@ -8918,7 +8942,6 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "dirkey:" , ggDirKey },
|
||||
{ "brakectrl:", ggBrakeCtrl },
|
||||
{ "localbrake:", ggLocalBrake },
|
||||
{ "manualbrake:", ggManualBrake },
|
||||
{ "alarmchain:", ggAlarmChain },
|
||||
{ "brakeprofile_sw:", ggBrakeProfileCtrl },
|
||||
{ "brakeprofileg_sw:", ggBrakeProfileG },
|
||||
@@ -9015,7 +9038,6 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "instrumentlight_sw:", ggInstrumentLightButton },
|
||||
{ "dashboardlight_sw:", ggDashboardLightButton },
|
||||
{ "timetablelight_sw:", ggTimetableLightButton },
|
||||
{ "cablight_sw:", ggCabLightButton },
|
||||
{ "cablightdim_sw:", ggCabLightDimButton },
|
||||
{ "compartmentlights_sw:", ggCompartmentLightsButton },
|
||||
{ "compartmentlightson_sw:", ggCompartmentLightsOnButton },
|
||||
@@ -9084,6 +9106,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "pantfrontoff_sw:", &mvControlled->Pantographs[end::front].valve.is_disabled },
|
||||
{ "pantrearoff_sw:", &mvControlled->Pantographs[end::rear].valve.is_disabled },
|
||||
{ "radio_sw:", &mvOccupied->Radio },
|
||||
{ "cablight_sw:", &Cabine[ iCabn ].bLight },
|
||||
};
|
||||
{
|
||||
auto lookup = autoboolgauges.find( Label );
|
||||
@@ -9095,6 +9118,20 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// TODO: move viable dedicated gauges to the automatic array
|
||||
std::unordered_map<std::string, int *> const autointgauges = {
|
||||
{ "manualbrake:", &mvOccupied->ManualBrakePos },
|
||||
};
|
||||
{
|
||||
auto lookup = autointgauges.find( Label );
|
||||
if( lookup != autointgauges.end() ) {
|
||||
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna lampka
|
||||
gauge.Load( Parser, DynamicObject );
|
||||
gauge.AssignInt( lookup->second );
|
||||
m_controlmapper.insert( gauge, lookup->first );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ABu 090305: uniwersalne przyciski lub inne rzeczy
|
||||
if( Label == "mainctrlact:" ) {
|
||||
|
||||
7
Train.h
7
Train.h
@@ -386,6 +386,8 @@ class TTrain {
|
||||
static void OnCommand_doormodetoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcoupleradapterattach( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcoupleradapterremove( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
|
||||
@@ -459,7 +461,6 @@ public: // reszta może by?publiczna
|
||||
TGauge ggDirKey;
|
||||
TGauge ggBrakeCtrl;
|
||||
TGauge ggLocalBrake;
|
||||
TGauge ggManualBrake;
|
||||
TGauge ggAlarmChain;
|
||||
TGauge ggBrakeProfileCtrl; // nastawiacz GPR - przelacznik obrotowy
|
||||
TGauge ggBrakeProfileG; // nastawiacz GP - hebelek towarowy
|
||||
@@ -539,7 +540,7 @@ public: // reszta może by?publiczna
|
||||
TGauge ggInstrumentLightButton;
|
||||
TGauge ggDashboardLightButton;
|
||||
TGauge ggTimetableLightButton;
|
||||
TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny
|
||||
// TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny
|
||||
TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia
|
||||
// oswietlenia kabiny
|
||||
TGauge ggCompartmentLightsButton;
|
||||
@@ -691,7 +692,7 @@ public: // reszta może by?publiczna
|
||||
TButton btLampkaTempomat;
|
||||
TButton btLampkaDistanceCounter;
|
||||
|
||||
TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine
|
||||
// TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine
|
||||
// Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys
|
||||
TButton btHaslerBrakes; // ciśnienie w cylindrach
|
||||
TButton btHaslerCurrent; // prąd na silnikach
|
||||
|
||||
@@ -155,6 +155,8 @@ commanddescription_sequence Commands_descriptions = {
|
||||
// TBD, TODO: make coupling controls entity-centric
|
||||
{ "carcouplingincrease", command_target::vehicle },
|
||||
{ "carcouplingdisconnect", command_target::vehicle },
|
||||
{ "carcoupleradapterattach", command_target::vehicle },
|
||||
{ "carcoupleradapterremove", command_target::vehicle },
|
||||
{ "doortoggleleft", command_target::vehicle },
|
||||
{ "doortoggleright", command_target::vehicle },
|
||||
{ "doorpermitleft", command_target::vehicle },
|
||||
|
||||
@@ -146,6 +146,8 @@ enum class user_command {
|
||||
|
||||
carcouplingincrease,
|
||||
carcouplingdisconnect,
|
||||
carcoupleradapterattach,
|
||||
carcoupleradapterremove,
|
||||
doortoggleleft,
|
||||
doortoggleright,
|
||||
doorpermitleft,
|
||||
|
||||
@@ -155,6 +155,8 @@ driverkeyboard_input::default_bindings() {
|
||||
{ user_command::movedown, GLFW_KEY_PAGE_DOWN },
|
||||
{ user_command::carcouplingincrease, GLFW_KEY_INSERT },
|
||||
{ user_command::carcouplingdisconnect, GLFW_KEY_DELETE },
|
||||
{ user_command::carcoupleradapterattach, GLFW_KEY_INSERT | keymodifier::control },
|
||||
{ user_command::carcoupleradapterremove, GLFW_KEY_DELETE | keymodifier::control },
|
||||
{ user_command::doortoggleleft, GLFW_KEY_COMMA },
|
||||
{ user_command::doortoggleright, GLFW_KEY_PERIOD },
|
||||
{ user_command::doorpermitleft, GLFW_KEY_COMMA | keymodifier::shift },
|
||||
|
||||
@@ -797,18 +797,23 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
std::string
|
||||
debug_panel::update_vehicle_coupler( int const Side ) {
|
||||
// NOTE: mover and vehicle are guaranteed to be valid by the caller
|
||||
auto const &mover { *( m_input.mover ) };
|
||||
|
||||
std::string couplerstatus { locale::strings[ locale::string::debug_vehicle_none ] };
|
||||
std::string const adapterstatus { ( mover.Couplers[ Side ].adapter_type == TCouplerType::NoCoupler ? "" : "[A]" ) };
|
||||
|
||||
auto const *connected { m_input.vehicle->MoverParameters->Neighbours[ Side ].vehicle };
|
||||
|
||||
if( connected == nullptr ) { return couplerstatus; }
|
||||
|
||||
auto const &mover { *( m_input.mover ) };
|
||||
if( connected == nullptr ) {
|
||||
|
||||
return couplerstatus + " " + adapterstatus;
|
||||
}
|
||||
|
||||
std::snprintf(
|
||||
m_buffer.data(), m_buffer.size(),
|
||||
"%s [%d] (%.1f m)",
|
||||
"%s %s[%d] (%.1f m)",
|
||||
connected->name().c_str(),
|
||||
adapterstatus.c_str(),
|
||||
mover.Couplers[ Side ].CouplingFlag,
|
||||
mover.Neighbours[ Side ].distance );
|
||||
|
||||
|
||||
@@ -1083,6 +1083,30 @@ bool opengl33_renderer::Render_lowpoly( TDynamicObject *Dynamic, float const Squ
|
||||
return true;
|
||||
}
|
||||
|
||||
bool opengl33_renderer::Render_coupler_adapter( TDynamicObject *Dynamic, float const Squaredistance, int const End, bool const Alpha ) {
|
||||
|
||||
if( Dynamic->m_coupleradapters[ End ] == nullptr ) { return false; }
|
||||
|
||||
auto const position { Math3D::vector3 {
|
||||
0.f,
|
||||
Dynamic->MoverParameters->Couplers[ End ].adapter_height,
|
||||
( Dynamic->MoverParameters->Couplers[ End ].adapter_length + Dynamic->MoverParameters->Dim.L * 0.5 ) * ( End == end::front ? 1 : -1 ) } };
|
||||
|
||||
auto const angle { glm::vec3{
|
||||
0,
|
||||
( End == end::front ? 0 : 180 ),
|
||||
0 } };
|
||||
|
||||
if( Alpha ) {
|
||||
Render_Alpha( Dynamic->m_coupleradapters[ End ], Dynamic->Material(), Squaredistance, position, angle );
|
||||
}
|
||||
else {
|
||||
Render( Dynamic->m_coupleradapters[ End ], Dynamic->Material(), Squaredistance, position, angle );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// creates dynamic environment cubemap
|
||||
bool opengl33_renderer::Render_reflections(viewport_config &vp)
|
||||
{
|
||||
@@ -1813,13 +1837,17 @@ void opengl33_renderer::Bind_Material( material_handle const Material, TSubModel
|
||||
// material-based parameters
|
||||
switch( entry.defaultparam ) {
|
||||
case gl::shader::defaultparam_e::glossiness: {
|
||||
src = glm::vec4( material.glossiness );
|
||||
src = glm::vec4 { material.glossiness };
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( entry.size == 1 ) {
|
||||
// HACK: convert color to luminosity, if it's passed as single value
|
||||
src == glm::vec4 { colors::RGBtoHSV( glm::vec3 { src } ).s };
|
||||
}
|
||||
for (size_t j = 0; j < entry.size; j++)
|
||||
model_ubs.param[entry.location][entry.offset + j] = src[j];
|
||||
}
|
||||
@@ -2487,8 +2515,11 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic)
|
||||
for( auto *attachment : Dynamic->mdAttachments ) {
|
||||
Render( attachment, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
// optional coupling adapters
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::front );
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::rear );
|
||||
|
||||
// post-render cleanup
|
||||
// post-render cleanup
|
||||
if (Dynamic->fShade > 0.0f)
|
||||
{
|
||||
// restore regular light level
|
||||
@@ -2510,6 +2541,9 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic)
|
||||
for( auto *attachment : Dynamic->mdAttachments ) {
|
||||
Render( attachment, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
// optional coupling adapters
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::front );
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::rear );
|
||||
if( Dynamic->mdLoad ) {
|
||||
// renderowanie nieprzezroczystego ładunku
|
||||
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
||||
@@ -2687,11 +2721,6 @@ void opengl33_renderer::Render(TSubModel *Submodel)
|
||||
|
||||
if ((Submodel->iVisible) && (TSubModel::fSquareDist >= Submodel->fSquareMinDist) && (TSubModel::fSquareDist < Submodel->fSquareMaxDist))
|
||||
{
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
glm::mat4 future_stack = model_ubs.future;
|
||||
|
||||
if (Submodel->iFlags & 0xC000)
|
||||
@@ -2714,6 +2743,11 @@ void opengl33_renderer::Render(TSubModel *Submodel)
|
||||
if (Submodel->iAlpha & Submodel->iFlags & 0x1F)
|
||||
{
|
||||
// rysuj gdy element nieprzezroczysty
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::color:
|
||||
@@ -3440,6 +3474,9 @@ bool opengl33_renderer::Render_Alpha(TDynamicObject *Dynamic)
|
||||
for( auto *attachment : Dynamic->mdAttachments ) {
|
||||
Render_Alpha( attachment, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
// optional coupling adapters
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::front, true );
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::rear, true );
|
||||
if( Dynamic->mdLoad ) {
|
||||
// renderowanie nieprzezroczystego ładunku
|
||||
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
||||
@@ -3512,11 +3549,6 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
|
||||
// renderowanie przezroczystych przez DL
|
||||
if ((Submodel->iVisible) && (TSubModel::fSquareDist >= Submodel->fSquareMinDist) && (TSubModel::fSquareDist < Submodel->fSquareMaxDist))
|
||||
{
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
glm::mat4 future_stack = model_ubs.future;
|
||||
|
||||
if (Submodel->iFlags & 0xC000)
|
||||
@@ -3538,7 +3570,12 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
|
||||
// renderowanie obiektów OpenGL
|
||||
if (Submodel->iAlpha & Submodel->iFlags & 0x2F)
|
||||
{
|
||||
// rysuj gdy element przezroczysty
|
||||
// rysuj gdy element przezroczysty
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
switch (m_renderpass.draw_mode)
|
||||
{
|
||||
case rendermode::color:
|
||||
|
||||
@@ -242,6 +242,7 @@ class opengl33_renderer : public gfx_renderer {
|
||||
bool Render_cab(TDynamicObject const *Dynamic, float const Lightlevel, bool const Alpha = false);
|
||||
bool Render_interior( bool const Alpha = false );
|
||||
bool Render_lowpoly( TDynamicObject *Dynamic, float const Squaredistance, bool const Setup, bool const Alpha = false );
|
||||
bool Render_coupler_adapter( TDynamicObject *Dynamic, float const Squaredistance, int const End, bool const Alpha = false );
|
||||
void Render(TMemCell *Memcell);
|
||||
void Render_particles();
|
||||
void Render_precipitation();
|
||||
|
||||
@@ -845,6 +845,27 @@ bool opengl_renderer::Render_lowpoly( TDynamicObject *Dynamic, float const Squar
|
||||
return true;
|
||||
}
|
||||
|
||||
bool opengl_renderer::Render_coupler_adapter( TDynamicObject *Dynamic, float const Squaredistance, int const End, bool const Alpha ) {
|
||||
|
||||
if( Dynamic->m_coupleradapters[ End ] == nullptr ) { return false; }
|
||||
|
||||
auto const position { Math3D::vector3 {
|
||||
0.f,
|
||||
Dynamic->MoverParameters->Couplers[ End ].adapter_height,
|
||||
( Dynamic->MoverParameters->Couplers[ End ].adapter_length + Dynamic->MoverParameters->Dim.L * 0.5 ) * ( End == end::front ? 1 : -1 ) } };
|
||||
|
||||
auto const angle{ glm::vec3{ 0, ( End == end::front ? 0 : 180 ), 0 } };
|
||||
|
||||
if( Alpha ) {
|
||||
Render_Alpha( Dynamic->m_coupleradapters[ End ], Dynamic->Material(), Squaredistance, position, angle );
|
||||
}
|
||||
else {
|
||||
Render( Dynamic->m_coupleradapters[ End ], Dynamic->Material(), Squaredistance, position, angle );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// creates dynamic environment cubemap
|
||||
bool
|
||||
opengl_renderer::Render_reflections() {
|
||||
@@ -2318,6 +2339,9 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
for( auto *attachment : Dynamic->mdAttachments ) {
|
||||
Render( attachment, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
// optional coupling adapters
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::front );
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::rear );
|
||||
// post-render cleanup
|
||||
m_renderspecular = false;
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
@@ -2342,6 +2366,9 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
for( auto *attachment : Dynamic->mdAttachments ) {
|
||||
Render( attachment, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
// optional coupling adapters
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::front );
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::rear );
|
||||
if( Dynamic->mdLoad ) {
|
||||
// renderowanie nieprzezroczystego ładunku
|
||||
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
||||
@@ -2524,10 +2551,6 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
|
||||
&& ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
if( Submodel->iFlags & 0xC000 ) {
|
||||
::glPushMatrix();
|
||||
if( Submodel->fMatrix )
|
||||
@@ -2540,6 +2563,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// renderowanie obiektów OpenGL
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F ) {
|
||||
// rysuj gdy element nieprzezroczysty
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::color:
|
||||
case rendermode::reflections: {
|
||||
@@ -3491,6 +3519,9 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
for( auto *attachment : Dynamic->mdAttachments ) {
|
||||
Render_Alpha( attachment, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
// optional coupling adapters
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::front, true );
|
||||
Render_coupler_adapter( Dynamic, squaredistance, end::rear, true );
|
||||
if( Dynamic->mdLoad ) {
|
||||
// renderowanie nieprzezroczystego ładunku
|
||||
Render_Alpha( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
||||
@@ -3569,10 +3600,6 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
|
||||
&& ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
if( Submodel->iFlags & 0xC000 ) {
|
||||
::glPushMatrix();
|
||||
if( Submodel->fMatrix )
|
||||
@@ -3585,6 +3612,11 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
// renderowanie obiektów OpenGL
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x2F ) {
|
||||
// rysuj gdy element przezroczysty
|
||||
|
||||
// debug data
|
||||
++m_renderpass.draw_stats.submodels;
|
||||
++m_renderpass.draw_stats.drawcalls;
|
||||
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::color: {
|
||||
|
||||
|
||||
@@ -223,6 +223,8 @@ private:
|
||||
Render_interior( bool const Alpha = false );
|
||||
bool
|
||||
Render_lowpoly( TDynamicObject *Dynamic, float const Squaredistance, bool const Setup, bool const Alpha = false );
|
||||
bool
|
||||
Render_coupler_adapter( TDynamicObject *Dynamic, float const Squaredistance, int const End, bool const Alpha = false );
|
||||
void
|
||||
Render( TMemCell *Memcell );
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user