mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 10:59:18 +02:00
Merge branch 'manul-staging' of https://github.com/wls50/maszyna-internal into manul-staging
This commit is contained in:
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -19,3 +19,7 @@
|
||||
[submodule "ref/asio"]
|
||||
path = ref/asio
|
||||
url = https://github.com/chriskohlhoff/asio.git
|
||||
[submodule "ref/discord-rpc"]
|
||||
path = ref/discord-rpc
|
||||
url = https://github.com/discord/discord-rpc.git
|
||||
branch = v3.4.0
|
||||
|
||||
@@ -318,6 +318,10 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
||||
LightsOff[5] = pModel->GetFromName("Light_Off05");
|
||||
LightsOff[6] = pModel->GetFromName("Light_Off06");
|
||||
LightsOff[7] = pModel->GetFromName("Light_Off07");
|
||||
sm_winter_variant = pModel->GetFromName("winter_variant");
|
||||
sm_spring_variant = pModel->GetFromName("spring_variant");
|
||||
sm_summer_variant = pModel->GetFromName("summer_variant");
|
||||
sm_autumn_variant = pModel->GetFromName("autumn_variant");
|
||||
}
|
||||
for (int i = 0; i < iMaxNumLights; ++i)
|
||||
if (LightsOn[i] || LightsOff[i]) // Ra: zlikwidowałem wymóg istnienia obu
|
||||
@@ -494,9 +498,59 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
|
||||
m_framestamp = Framestamp;
|
||||
}
|
||||
|
||||
// aktualizujemy submodele w zaleznosci od aktualnej porty roku
|
||||
void TAnimModel::on_season_update() {
|
||||
if (Global.Season == "winter:") // pokazujemy wariant zimowy
|
||||
{
|
||||
if (this->sm_winter_variant != nullptr)
|
||||
this->sm_winter_variant->SetVisibilityLevel(1.f, true, false);
|
||||
if (this->sm_spring_variant != nullptr)
|
||||
this->sm_spring_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_summer_variant != nullptr)
|
||||
this->sm_summer_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_autumn_variant != nullptr)
|
||||
this->sm_autumn_variant->SetVisibilityLevel(0.f, true, false);
|
||||
}
|
||||
else if (Global.Season == "spring:") // pokazujemy wariant wiosenny
|
||||
{
|
||||
if (this->sm_winter_variant != nullptr)
|
||||
this->sm_winter_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_spring_variant != nullptr)
|
||||
this->sm_spring_variant->SetVisibilityLevel(1.f, true, false);
|
||||
if (this->sm_summer_variant != nullptr)
|
||||
this->sm_summer_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_autumn_variant != nullptr)
|
||||
this->sm_autumn_variant->SetVisibilityLevel(0.f, true, false);
|
||||
}
|
||||
else if (Global.Season == "summer:") // pokazujemy wariant letni
|
||||
{
|
||||
if (this->sm_winter_variant != nullptr)
|
||||
this->sm_winter_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_spring_variant != nullptr)
|
||||
this->sm_spring_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_summer_variant != nullptr)
|
||||
this->sm_summer_variant->SetVisibilityLevel(1.f, true, false);
|
||||
if (this->sm_autumn_variant != nullptr)
|
||||
this->sm_autumn_variant->SetVisibilityLevel(0.f, true, false);
|
||||
}
|
||||
else if (Global.Season == "autumn:") // pokazujemy wariant jesienny
|
||||
{
|
||||
if (this->sm_winter_variant != nullptr)
|
||||
this->sm_winter_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_spring_variant != nullptr)
|
||||
this->sm_spring_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_summer_variant != nullptr)
|
||||
this->sm_summer_variant->SetVisibilityLevel(0.f, true, false);
|
||||
if (this->sm_autumn_variant != nullptr)
|
||||
this->sm_autumn_variant->SetVisibilityLevel(1.f, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void TAnimModel::RaPrepare()
|
||||
{ // ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza
|
||||
bool state; // stan światła
|
||||
if (Global.UpdateMaterials)
|
||||
on_season_update();
|
||||
for (int i = 0; i < iNumLights; ++i)
|
||||
{
|
||||
auto const lightmode { static_cast<int>( std::abs( lsLights[ i ] ) ) };
|
||||
@@ -656,9 +710,9 @@ TAnimModel::export_as_text_( std::ostream &Output ) const {
|
||||
// header
|
||||
Output << "model ";
|
||||
// location and rotation
|
||||
Output
|
||||
<< location().x << ' '
|
||||
<< location().y << ' '
|
||||
Output << std::fixed << std::setprecision(3) // ustawienie dokładnie 3 cyfr po przecinku
|
||||
<< location().x << ' '
|
||||
<< location().y << ' '
|
||||
<< location().z << ' ';
|
||||
Output
|
||||
<< "0 " ;
|
||||
|
||||
19
AnimModel.h
19
AnimModel.h
@@ -25,12 +25,14 @@ const int iMaxNumLights = 8;
|
||||
float const DefaultDarkThresholdLevel { 0.325f };
|
||||
|
||||
// typy stanu świateł
|
||||
enum TLightState {
|
||||
ls_Off = 0, // zgaszone
|
||||
ls_On = 1, // zapalone
|
||||
ls_Blink = 2, // migające
|
||||
ls_Dark = 3, // Ra: zapalajce się automatycznie, gdy zrobi się ciemno
|
||||
ls_Home = 4 // like ls_dark but off late at night
|
||||
enum TLightState
|
||||
{
|
||||
ls_Off = 0, // zgaszone
|
||||
ls_On = 1, // zapalone
|
||||
ls_Blink = 2, // migające
|
||||
ls_Dark = 3, // Ra: zapalajce się automatycznie, gdy zrobi się ciemno
|
||||
ls_Home = 4, // like ls_dark but off late at night
|
||||
ls_winter = 5 // turned on when its winter
|
||||
};
|
||||
|
||||
class TAnimVocaloidFrame
|
||||
@@ -125,6 +127,7 @@ public:
|
||||
int TerrainCount();
|
||||
TSubModel * TerrainSquare(int n);
|
||||
int Flags();
|
||||
void on_season_update();
|
||||
inline
|
||||
material_data const *
|
||||
Material() const {
|
||||
@@ -174,6 +177,10 @@ public:
|
||||
int iNumLights { 0 };
|
||||
std::array<TSubModel *, iMaxNumLights> LightsOn {}; // Ra: te wskaźniki powinny być w ramach TModel3d
|
||||
std::array<TSubModel *, iMaxNumLights> LightsOff {};
|
||||
TSubModel *sm_winter_variant {}; // submodel zimowego wariantu
|
||||
TSubModel *sm_spring_variant {}; // submodel wiosennego wariantu
|
||||
TSubModel *sm_summer_variant {}; // submodel letniego wariantu
|
||||
TSubModel *sm_autumn_variant {}; // submodel jesiennego wariantu
|
||||
std::array<float, iMaxNumLights> lsLights {}; // ls_Off
|
||||
std::array<glm::vec3, iMaxNumLights> m_lightcolors; // -1 in constructor
|
||||
std::array<float, iMaxNumLights> m_lighttimers {};
|
||||
|
||||
@@ -444,6 +444,12 @@ target_link_libraries(${PROJECT_NAME} Threads::Threads)
|
||||
find_package(GLM REQUIRED)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${GLM_INCLUDE_DIR})
|
||||
|
||||
# add ref/discord-rpc to the project in the same way other dependencies are added
|
||||
add_subdirectory(ref/discord-rpc)
|
||||
target_link_libraries(${PROJECT_NAME} discord-rpc)
|
||||
|
||||
|
||||
|
||||
find_package(OpenAL REQUIRED)
|
||||
if (TARGET OpenAL::OpenAL)
|
||||
target_link_libraries(${PROJECT_NAME} OpenAL::OpenAL)
|
||||
|
||||
@@ -5704,6 +5704,7 @@ void TController::TakeControl( bool const Aidriver, bool const Forcevehiclecheck
|
||||
{ // teraz AI prowadzi
|
||||
AIControllFlag = AIdriver;
|
||||
pVehicle->Controller = AIdriver;
|
||||
control_lights(); // reinicjalizacja swiatel
|
||||
mvOccupied->CabActivisation(true);
|
||||
iDirection = 0; // kierunek jazdy trzeba dopiero zgadnąć
|
||||
TableClear(); // ponowne utworzenie tabelki, bo człowiek mógł pojechać niezgodnie z sygnałami
|
||||
@@ -5740,6 +5741,8 @@ void TController::TakeControl( bool const Aidriver, bool const Forcevehiclecheck
|
||||
}
|
||||
else
|
||||
{ // a teraz użytkownik
|
||||
if (!is_train() || !is_car()) // gasimy swiatla jesli przejmujemy odstawione
|
||||
pVehicle->RaLightsSet(0, 0);
|
||||
AIControllFlag = Humandriver;
|
||||
pVehicle->Controller = Humandriver;
|
||||
if( eAction == TAction::actSleep ) {
|
||||
|
||||
404
DynObj.cpp
404
DynObj.cpp
@@ -97,8 +97,110 @@ void TAnimPant::AKP_4E()
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
void TAnimPant::WBL85()
|
||||
{ // ustawienie wymiarów dla pantografu WBL88
|
||||
vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów
|
||||
|
||||
// mnozniki animacji ramion dla pantografu WBL88
|
||||
rd1rf = 1.f;
|
||||
rd2rf = 1.2;
|
||||
rg1rf = 0.875;
|
||||
rg2rf = 1.0;
|
||||
slizgrf = 1.f;
|
||||
|
||||
fLenL1 = 1.98374;
|
||||
fLenU1 = 2.14199;
|
||||
fHoriz = 0.142; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem
|
||||
// osi obrotu dolnego ramienia
|
||||
fHeight = 0.09353; // wysokość ślizgu ponad oś obrotu
|
||||
fWidth = 0.4969; // połowa szerokości ślizgu
|
||||
fAngleL0 = DegToRad(2.8547285515689267247882521833308);
|
||||
fAngleL = fAngleL0; // początkowy kąt dolnego ramienia
|
||||
// fAngleU0=acos((1.22*cos(fAngleL)+0.535)/1.755); //górne ramię
|
||||
fAngleU0 = acos((fLenL1 * cos(fAngleL) + fHoriz) / fLenU1); // górne ramię
|
||||
fAngleU = fAngleU0; // początkowy kąt
|
||||
// PantWys=1.22*sin(fAngleL)+1.755*sin(fAngleU); //wysokość początkowa
|
||||
PantWys = fLenL1 * sin(fAngleL) + fLenU1 * sin(fAngleU) + fHeight; // wysokość początkowa
|
||||
PantTraction = PantWys;
|
||||
hvPowerWire = NULL;
|
||||
fWidthExtra = 0.381f; //(2.032m-1.027)/2
|
||||
// poza obszarem roboczym jest aproksymacja łamaną o 5 odcinkach
|
||||
fHeightExtra[0] = 0.0f; //+0.0762
|
||||
fHeightExtra[1] = -0.01f; //+0.1524
|
||||
fHeightExtra[2] = -0.03f; //+0.2286
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
void TAnimPant::EC160_200()
|
||||
{ // ustawienie wymiarów dla pantografow EC160 lub EC200
|
||||
vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów
|
||||
|
||||
// mnozniki animacji ramion dla pantografow EC160 lub EC200
|
||||
rd1rf = 1.f;
|
||||
rd2rf = 0.85;
|
||||
rg1rf = 1.f;
|
||||
rg2rf = 1.f; // 0.833
|
||||
slizgrf = 1.f;
|
||||
|
||||
fLenL1 = 1.98374;
|
||||
fLenU1 = 2.14199;
|
||||
fHoriz = 0.142; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem
|
||||
// osi obrotu dolnego ramienia
|
||||
fHeight = 0.09353; // wysokość ślizgu ponad oś obrotu
|
||||
fWidth = 0.4969; // połowa szerokości ślizgu
|
||||
fAngleL0 = DegToRad(2.8547285515689267247882521833308);
|
||||
fAngleL = fAngleL0; // początkowy kąt dolnego ramienia
|
||||
// fAngleU0=acos((1.22*cos(fAngleL)+0.535)/1.755); //górne ramię
|
||||
fAngleU0 = acos((fLenL1 * cos(fAngleL) + fHoriz) / fLenU1); // górne ramię
|
||||
fAngleU = fAngleU0; // początkowy kąt
|
||||
// PantWys=1.22*sin(fAngleL)+1.755*sin(fAngleU); //wysokość początkowa
|
||||
PantWys = fLenL1 * sin(fAngleL) + fLenU1 * sin(fAngleU) + fHeight; // wysokość początkowa
|
||||
PantTraction = PantWys;
|
||||
hvPowerWire = NULL;
|
||||
fWidthExtra = 0.381f; //(2.032m-1.027)/2
|
||||
// poza obszarem roboczym jest aproksymacja łamaną o 5 odcinkach
|
||||
fHeightExtra[0] = 0.0f; //+0.0762
|
||||
fHeightExtra[1] = -0.01f; //+0.1524
|
||||
fHeightExtra[2] = -0.03f; //+0.2286
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
void TAnimPant::DSAx()
|
||||
{ // ustawienie wymiarów dla pantografow z rodziny DSA
|
||||
vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów
|
||||
|
||||
// mnozniki animacji ramion dla pantografow z rodziny DSA
|
||||
rd1rf = 1.f;
|
||||
rd2rf = 1.025;
|
||||
rg1rf = 0.875;
|
||||
rg2rf = 1.f;
|
||||
slizgrf = 1.f;
|
||||
|
||||
fLenL1 = 1.98374;
|
||||
fLenU1 = 2.14199;
|
||||
fHoriz = 0.142; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem
|
||||
// osi obrotu dolnego ramienia
|
||||
fHeight = 0.09353; // wysokość ślizgu ponad oś obrotu
|
||||
fWidth = 0.4969; // połowa szerokości ślizgu
|
||||
fAngleL0 = DegToRad(2.8547285515689267247882521833308);
|
||||
fAngleL = fAngleL0; // początkowy kąt dolnego ramienia
|
||||
// fAngleU0=acos((1.22*cos(fAngleL)+0.535)/1.755); //górne ramię
|
||||
fAngleU0 = acos((fLenL1 * cos(fAngleL) + fHoriz) / fLenU1); // górne ramię
|
||||
fAngleU = fAngleU0; // początkowy kąt
|
||||
// PantWys=1.22*sin(fAngleL)+1.755*sin(fAngleU); //wysokość początkowa
|
||||
PantWys = fLenL1 * sin(fAngleL) + fLenU1 * sin(fAngleU) + fHeight; // wysokość początkowa
|
||||
PantTraction = PantWys;
|
||||
hvPowerWire = NULL;
|
||||
fWidthExtra = 0.381f; //(2.032m-1.027)/2
|
||||
// poza obszarem roboczym jest aproksymacja łamaną o 5 odcinkach
|
||||
fHeightExtra[0] = 0.0f; //+0.0762
|
||||
fHeightExtra[1] = -0.01f; //+0.1524
|
||||
fHeightExtra[2] = -0.03f; //+0.2286
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
int TAnim::TypeSet(int i, int fl)
|
||||
int TAnim::TypeSet(int i, TMoverParameters currentMover, int fl)
|
||||
{ // ustawienie typu animacji i zależnej od niego ilości animowanych submodeli
|
||||
fMaxDist = -1.0; // normalnie nie pokazywać
|
||||
switch (i)
|
||||
@@ -127,7 +229,21 @@ int TAnim::TypeSet(int i, int fl)
|
||||
case 5: // 5-pantograf - 5 submodeli
|
||||
iFlags = 0x055;
|
||||
fParamPants = new TAnimPant();
|
||||
fParamPants->AKP_4E();
|
||||
switch (currentMover.EnginePowerSource.CollectorParameters.PantographType) {
|
||||
case (TPantType::AKP_4E):
|
||||
fParamPants->AKP_4E();
|
||||
break;
|
||||
case(TPantType::DSAx):
|
||||
fParamPants->DSAx();
|
||||
break;
|
||||
case(TPantType::EC160_200):
|
||||
fParamPants->EC160_200();
|
||||
break;
|
||||
case(TPantType::WBL85):
|
||||
fParamPants->WBL85();
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 6:
|
||||
iFlags = 0x068;
|
||||
@@ -138,6 +254,9 @@ int TAnim::TypeSet(int i, int fl)
|
||||
case 8:
|
||||
iFlags = 0x080;
|
||||
break; // mirror
|
||||
case 9:
|
||||
iFlags = 0x023; // 2: Rotating/Motion-based, 8: Uses 3 submodels
|
||||
break;
|
||||
default:
|
||||
iFlags = 0;
|
||||
}
|
||||
@@ -576,20 +695,20 @@ void TDynamicObject::UpdateDoorPlug(TAnim *pAnim) {
|
||||
|
||||
void TDynamicObject::UpdatePant(TAnim *pAnim)
|
||||
{ // animacja pantografu - 4 obracane ramiona, ślizg piąty
|
||||
float a, b, c;
|
||||
a = RadToDeg(pAnim->fParamPants->fAngleL - pAnim->fParamPants->fAngleL0);
|
||||
b = RadToDeg(pAnim->fParamPants->fAngleU - pAnim->fParamPants->fAngleU0);
|
||||
c = a + b;
|
||||
if (pAnim->smElement[0])
|
||||
pAnim->smElement[0]->SetRotate(float3(-1, 0, 0), a); // dolne ramię
|
||||
if (pAnim->smElement[1])
|
||||
pAnim->smElement[1]->SetRotate(float3(1, 0, 0), a);
|
||||
if (pAnim->smElement[2])
|
||||
pAnim->smElement[2]->SetRotate(float3(1, 0, 0), c); // górne ramię
|
||||
if (pAnim->smElement[3])
|
||||
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c);
|
||||
if (pAnim->smElement[4])
|
||||
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b); //ślizg
|
||||
float a, b, c;
|
||||
a = RadToDeg(pAnim->fParamPants->fAngleL - pAnim->fParamPants->fAngleL0);
|
||||
b = RadToDeg(pAnim->fParamPants->fAngleU - pAnim->fParamPants->fAngleU0);
|
||||
c = a + b;
|
||||
if (pAnim->smElement[0])
|
||||
pAnim->smElement[0]->SetRotate(float3(-1, 0, 0), a); // dolne ramie 1
|
||||
if (pAnim->smElement[1])
|
||||
pAnim->smElement[1]->SetRotate(float3(1, 0, 0), a * pAnim->fParamPants->rd2rf); // dolne ramie 2
|
||||
if (pAnim->smElement[2])
|
||||
pAnim->smElement[2]->SetRotate(float3(1, 0, 0), c); // górne ramie 1
|
||||
if (pAnim->smElement[3])
|
||||
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c * pAnim->fParamPants->rg2rf); // gorne ramie 2
|
||||
if (pAnim->smElement[4])
|
||||
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b * pAnim->fParamPants->slizgrf); // ślizg
|
||||
}
|
||||
|
||||
// doorstep animation, shift
|
||||
@@ -645,6 +764,24 @@ void TDynamicObject::UpdateMirror( TAnim *pAnim ) {
|
||||
interpolate( 0.0, MoverParameters->MirrorMaxShift, dMirrorMoveL * isactive ) );
|
||||
}
|
||||
|
||||
// wipers
|
||||
void TDynamicObject::UpdateWiper(TAnim* pAnim)
|
||||
{
|
||||
if (!pAnim || !pAnim->smElement)
|
||||
return;
|
||||
|
||||
int i = pAnim->iNumber;
|
||||
// odwaramy animacje dla parzystych indexow
|
||||
const double rotateAngle = (i + 1) % 2 == 0 ? -MoverParameters->WiperAngle : MoverParameters->WiperAngle;
|
||||
|
||||
if (pAnim->smElement[0]) // ramie 1
|
||||
pAnim->smElement[0]->SetRotate(float3(0, 1, 0), smoothInterpolate(0.0, rotateAngle, dWiperPos[i]));
|
||||
if (pAnim->smElement[1]) // ramie 2
|
||||
pAnim->smElement[1]->SetRotate(float3(0, 1, 0), smoothInterpolate(0.0, rotateAngle, dWiperPos[i]));
|
||||
if (pAnim->smElement[2]) // pioro
|
||||
pAnim->smElement[2]->SetRotate(float3(0, 1, 0), smoothInterpolate(0.0, -rotateAngle, dWiperPos[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
void TDynamicObject::UpdateLeverDouble(TAnim *pAnim)
|
||||
{ // animacja gałki zależna od double
|
||||
@@ -1048,12 +1185,15 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
btnOn = true;
|
||||
}
|
||||
|
||||
// only external models ( external_only_on / external_only_off )
|
||||
btExteriorOnly.Turn(!bDisplayCab); // display only when cab is not rendered
|
||||
|
||||
if( ( false == bDisplayCab ) // edge case, lowpoly may act as a stand-in for the hi-fi cab, so make sure not to show the driver when inside
|
||||
&& ( Mechanik != nullptr )
|
||||
&& ( ( Mechanik->action() != TAction::actSleep )
|
||||
/* || ( MoverParameters->Battery ) */ ) ) {
|
||||
// rysowanie figurki mechanika
|
||||
btMechanik1.Turn( MoverParameters->CabOccupied > 0 );
|
||||
btMechanik1.Turn(MoverParameters->CabOccupied > 0);
|
||||
btMechanik2.Turn( MoverParameters->CabOccupied < 0 );
|
||||
if( MoverParameters->CabOccupied != 0 ) {
|
||||
btnOn = true;
|
||||
@@ -1168,6 +1308,28 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
}
|
||||
btnOn = true;
|
||||
}
|
||||
|
||||
// logika dlugich
|
||||
if (TestFlag(MoverParameters->iLights[end::front], light::highbeamlight_left))
|
||||
m_highbeam13.TurnxOnWithOnAsFallback();
|
||||
else
|
||||
m_highbeam13.TurnOff();
|
||||
|
||||
if (TestFlag(MoverParameters->iLights[end::front], light::highbeamlight_right))
|
||||
m_highbeam12.TurnxOnWithOnAsFallback();
|
||||
else
|
||||
m_highbeam12.TurnOff();
|
||||
|
||||
// i to samo od dupy strony
|
||||
if (TestFlag(MoverParameters->iLights[end::rear], light::highbeamlight_left))
|
||||
m_highbeam23.TurnxOnWithOnAsFallback();
|
||||
else
|
||||
m_highbeam23.TurnOff();
|
||||
|
||||
if (TestFlag(MoverParameters->iLights[end::rear], light::highbeamlight_right))
|
||||
m_highbeam22.TurnxOnWithOnAsFallback();
|
||||
else
|
||||
m_highbeam22.TurnOff();
|
||||
}
|
||||
// interior light levels
|
||||
auto sectionlightcolor { glm::vec4( 1.f ) };
|
||||
@@ -2197,9 +2359,13 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
m_headlamp11.Init( "headlamp11", mdModel ); // górne
|
||||
m_headlamp12.Init( "headlamp12", mdModel ); // prawe
|
||||
m_headlamp13.Init( "headlamp13", mdModel ); // lewe
|
||||
m_highbeam12.Init("highbeam12", mdModel); // prawe dlugie
|
||||
m_highbeam13.Init("highbeam13", mdModel); // lewe dlugie
|
||||
m_headlamp21.Init( "headlamp21", mdModel );
|
||||
m_headlamp22.Init( "headlamp22", mdModel );
|
||||
m_headlamp23.Init( "headlamp23", mdModel );
|
||||
m_highbeam22.Init("highbeam22", mdModel);
|
||||
m_highbeam23.Init("highbeam23", mdModel);
|
||||
m_headsignal12.Init( "headsignal12", mdModel );
|
||||
m_headsignal13.Init( "headsignal13", mdModel );
|
||||
m_headsignal22.Init( "headsignal22", mdModel );
|
||||
@@ -2216,6 +2382,10 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
iInventory[ end::front ] |= m_headlamp11.Active() ? light::headlight_upper : 0;
|
||||
iInventory[ end::front ] |= m_headlamp12.Active() ? light::headlight_right : 0;
|
||||
iInventory[ end::front ] |= m_headlamp13.Active() ? light::headlight_left : 0;
|
||||
|
||||
iInventory[end::front] |= m_highbeam12.Active() ? light::highbeamlight_right : 0;
|
||||
iInventory[end::front] |= m_highbeam13.Active() ? light::highbeamlight_left : 0;
|
||||
|
||||
iInventory[ end::rear ] |= m_headlamp21.Active() ? light::headlight_upper : 0;
|
||||
iInventory[ end::rear ] |= m_headlamp22.Active() ? light::headlight_right : 0;
|
||||
iInventory[ end::rear ] |= m_headlamp23.Active() ? light::headlight_left : 0;
|
||||
@@ -2223,8 +2393,15 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
iInventory[ end::front ] |= m_headsignal13.Active() ? light::auxiliary_left : 0;
|
||||
iInventory[ end::rear ] |= m_headsignal22.Active() ? light::auxiliary_right : 0;
|
||||
iInventory[ end::rear ] |= m_headsignal23.Active() ? light::auxiliary_left : 0;
|
||||
|
||||
iInventory[end::rear] |= m_highbeam22.Active() ? light::highbeamlight_right : 0;
|
||||
iInventory[end::rear] |= m_highbeam23.Active() ? light::highbeamlight_left : 0;
|
||||
|
||||
btExteriorOnly.Init("external_only", mdModel, false);
|
||||
|
||||
btMechanik1.Init( "mechanik1", mdLowPolyInt, false);
|
||||
btMechanik2.Init( "mechanik2", mdLowPolyInt, false);
|
||||
|
||||
if( MoverParameters->dizel_heat.water.config.shutters ) {
|
||||
btShutters1.Init( "shutters1", mdModel, false );
|
||||
}
|
||||
@@ -3949,6 +4126,70 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
MoverParameters->PantFrontVolt = 0.95 * MoverParameters->EnginePowerSource.MaxVoltage;
|
||||
}
|
||||
|
||||
// wipers
|
||||
if (dWiperPos.size() > 0) // tylko dla wozow ze zdefiniowanymi wycierakami
|
||||
{
|
||||
for (int i = 0; i < dWiperPos.size(); i++) // iteracja po kazdej wycieraczce
|
||||
{
|
||||
bool wipersActive;
|
||||
auto const bytesum = MoverParameters->WiperList[MoverParameters->wiperSwitchPos].byteSum;
|
||||
// rozroznienie kabinowe
|
||||
if (MoverParameters->CabActive == 1)
|
||||
{
|
||||
wipersActive = ((bytesum & (1 << i)) != 0) && MoverParameters->Battery;
|
||||
}
|
||||
else if (MoverParameters->CabActive == -1)
|
||||
{
|
||||
// odwroconie indexow wycieraczek
|
||||
wipersActive = ((bytesum & (1 << dWiperPos.size() - 1 - i)) != 0) && MoverParameters->Battery;
|
||||
}
|
||||
else {
|
||||
wipersActive = false;
|
||||
}
|
||||
|
||||
auto const currentWiperParams = MoverParameters->WiperList[workingSwitchPos[i]];
|
||||
|
||||
wiperOutTimer[i] += dt1; // aktualizujemy zegarek
|
||||
wiperParkTimer[i] += dt1; // aktualizujemy zegarek
|
||||
|
||||
if (wipersActive || dWiperPos[i] > 0.0) // zeby wrocily do trybu park
|
||||
{
|
||||
if (dWiperPos[i] > 0.0 && !wipersActive) // bezwzgledny powrot do zera
|
||||
{
|
||||
dWiperPos[i] = std::max(0.0, dWiperPos[i] - (1.f / currentWiperParams.WiperSpeed) * dt1);
|
||||
}
|
||||
else {
|
||||
|
||||
if (dWiperPos[i] < 1.0 && !wiperDirection[i] && wiperParkTimer[i] > currentWiperParams.interval)
|
||||
// go out
|
||||
{
|
||||
dWiperPos[i] = std::min(1.0, dWiperPos[i] + (1.f / currentWiperParams.WiperSpeed) * dt1);
|
||||
}
|
||||
if (dWiperPos[i] > 0.0 && wiperDirection[i] && wiperOutTimer[i] > currentWiperParams.outBackDelay)
|
||||
// return back
|
||||
{
|
||||
dWiperPos[i] = std::max(0.0, dWiperPos[i] - (1.f / currentWiperParams.WiperSpeed) * dt1);
|
||||
}
|
||||
if (dWiperPos[i] == 1.0) // we reached end
|
||||
{
|
||||
wiperParkTimer[i] = 0.0;
|
||||
wiperDirection[i] = true; // switch direction
|
||||
}
|
||||
if (dWiperPos[i] == 0.0)
|
||||
{
|
||||
// when in park position
|
||||
wiperOutTimer[i] = 0.0;
|
||||
wiperDirection[i] = false;
|
||||
workingSwitchPos[i] = MoverParameters->wiperSwitchPos; // update configuration
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// mirrors
|
||||
if( (MoverParameters->Vel > MoverParameters->MirrorVelClose)
|
||||
|| (MoverParameters->CabActive == 0) && (activation::mirrors)
|
||||
@@ -4162,6 +4403,10 @@ void TDynamicObject::TurnOff()
|
||||
m_headlamp21.TurnOff();
|
||||
m_headlamp22.TurnOff();
|
||||
m_headlamp23.TurnOff();
|
||||
m_highbeam12.TurnOff();
|
||||
m_highbeam13.TurnOff();
|
||||
m_highbeam22.TurnOff();
|
||||
m_highbeam23.TurnOff();
|
||||
m_headsignal12.TurnOff();
|
||||
m_headsignal13.TurnOff();
|
||||
m_headsignal22.TurnOff();
|
||||
@@ -5002,12 +5247,14 @@ TDynamicObject::radius() const {
|
||||
// McZapkie-250202
|
||||
// wczytywanie pliku z danymi multimedialnymi (dzwieki)
|
||||
void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string const &ReplacableSkin ) {
|
||||
|
||||
rTypeName = TypeName;
|
||||
rReplacableSkin = ReplacableSkin;
|
||||
Global.asCurrentDynamicPath = asBaseDir;
|
||||
std::string asFileName = asBaseDir + TypeName + ".mmd";
|
||||
std::string asAnimName;
|
||||
bool Stop_InternalData = false;
|
||||
pants = NULL; // wskaźnik pierwszego obiektu animującego dla pantografów
|
||||
wipers = NULL; // wskaznik pierwszego obiektu animujacego dla wycieraczek
|
||||
{
|
||||
// preliminary check whether the file exists
|
||||
cParser parser( TypeName + ".mmd", cParser::buffer_FILE, asBaseDir );
|
||||
@@ -5094,16 +5341,20 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
|
||||
pAnimations.resize( iAnimations );
|
||||
int i, j, k = 0, sm = 0;
|
||||
for (j = 0; j < ANIM_TYPES; ++j)
|
||||
for (i = 0; i < iAnimType[j]; ++i)
|
||||
for (j = 0; j < ANIM_TYPES; ++j) // petla po wszystkich wpisach w animations
|
||||
for (i = 0; i < iAnimType[j]; ++i) // petla iteruje sie tyle razy ile mamy wpisane w animations
|
||||
{
|
||||
if (j == ANIM_PANTS) // zliczamy poprzednie animacje
|
||||
if (!pants)
|
||||
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
||||
pants = &pAnimations[k]; // zapamiętanie na potrzeby wyszukania submodeli
|
||||
if (j == ANIM_WIPERS)
|
||||
if (!wipers)
|
||||
if (iAnimType[ANIM_WIPERS])
|
||||
wipers = &pAnimations[k];
|
||||
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
||||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||
}
|
||||
sm += pAnimations[k++].TypeSet(j, *MoverParameters); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||
}
|
||||
if (sm) // o ile są bardziej złożone animacje
|
||||
{
|
||||
pAnimated = new TSubModel *[sm]; // tabela na animowane submodele
|
||||
@@ -5673,6 +5924,52 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
}
|
||||
}
|
||||
|
||||
else if (token == "animwiperprefix:")
|
||||
{
|
||||
parser.getTokens(1, false);
|
||||
parser >> token;
|
||||
TSubModel *sm;
|
||||
if (wipers)
|
||||
{
|
||||
|
||||
for (int i = 0; i < iAnimType[ANIM_WIPERS]; i++) // zebranie wszystkich submodeli wycieraczek
|
||||
{
|
||||
dWiperPos.emplace_back(0.0); // dodajemy na koniec zeby sie miejsce tam zrobilo i nie bylo invalid addressow potem
|
||||
|
||||
asAnimName = token + std::to_string(i + 1);
|
||||
// element wycieraczki nr 1
|
||||
sm = GetSubmodelFromName(mdModel, asAnimName + "_p1");
|
||||
wipers[i].smElement[0] = sm;
|
||||
if (sm)
|
||||
{
|
||||
wipers[i].smElement[0]->WillBeAnimated();
|
||||
// auto const offset{wipers[i].smElement[0]->offset()};
|
||||
}
|
||||
|
||||
// element wycieraczki nr 2
|
||||
sm = GetSubmodelFromName(mdModel, asAnimName + "_p2");
|
||||
wipers[i].smElement[1] = sm;
|
||||
if (sm)
|
||||
{
|
||||
wipers[i].smElement[1]->WillBeAnimated();
|
||||
// auto const offset{wipers[i].smElement[0]->offset()};
|
||||
}
|
||||
|
||||
// element wycieraczki nr 3
|
||||
sm = GetSubmodelFromName(mdModel, asAnimName + "_p3");
|
||||
wipers[i].smElement[2] = sm;
|
||||
if (sm)
|
||||
{
|
||||
wipers[i].smElement[2]->WillBeAnimated();
|
||||
// auto const offset{wipers[i].smElement[0]->offset()};
|
||||
}
|
||||
wipers[i].yUpdate = std::bind(&TDynamicObject::UpdateWiper, this, std::placeholders::_1);
|
||||
wipers[i].fMaxDist = 150 * 150;
|
||||
wipers[i].iNumber = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while( ( token != "" )
|
||||
&& ( token != "endmodels" ) );
|
||||
|
||||
@@ -6424,6 +6721,19 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
|
||||
m_powertrainsounds.rsEngageSlippery.m_frequencyfactor /= ( 1 + MoverParameters->nmax );
|
||||
}
|
||||
|
||||
// dzwieki wycieraczkuf
|
||||
else if (token == "wiperFromPark:")
|
||||
{
|
||||
sWiperFromPark.deserialize(parser, sound_type::single);
|
||||
sWiperFromPark.owner(this);
|
||||
}
|
||||
else if (token == "wiperToPark:")
|
||||
{
|
||||
sWiperToPark.deserialize(parser, sound_type::single);
|
||||
sWiperToPark.owner(this);
|
||||
}
|
||||
|
||||
else if (token == "retarder:") {
|
||||
m_powertrainsounds.retarder.deserialize(parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency);
|
||||
m_powertrainsounds.retarder.owner(this);
|
||||
@@ -7000,7 +7310,6 @@ void TDynamicObject::Damage(char flag)
|
||||
};
|
||||
|
||||
void TDynamicObject::SetLights() {
|
||||
|
||||
auto const isfrontcaboccupied { MoverParameters->CabOccupied * DirectionGet() >= 0 };
|
||||
int const automaticmarkers { MoverParameters->CabActive == 0 && ( MoverParameters->InactiveCabFlag & activation::redmarkers )
|
||||
? light::redmarker_left + light::redmarker_right : 0 };
|
||||
@@ -7054,6 +7363,47 @@ void TDynamicObject::RaLightsSet(int head, int rear)
|
||||
if( head >= 0 ) {
|
||||
auto const vehicleend { iDirection > 0 ? end::front : end::rear };
|
||||
MoverParameters->iLights[ vehicleend ] = ( head & iInventory[ vehicleend ] );
|
||||
bool tLeft = MoverParameters->iLights[vehicleend] & (light::auxiliary_left | light::headlight_left); // roboczo czy jakiekolwiek swiatlo z lewej jest zapalone
|
||||
bool tRight = MoverParameters->iLights[vehicleend] & (light::auxiliary_right | light::headlight_right); // a tu z prawej
|
||||
if (Controller == Humandriver) {
|
||||
switch (MoverParameters->modernDimmerState)
|
||||
{
|
||||
case 0:
|
||||
// wylaczone
|
||||
MoverParameters->iLights[vehicleend] &= 0 | light::rearendsignals; // zostawiamy tylko tabliczki jesli sa
|
||||
HighBeamLights = false;
|
||||
DimHeadlights = false;
|
||||
break;
|
||||
case 1:
|
||||
// przyciemnione normalne
|
||||
DimHeadlights = true; // odpalamy przyciemnienie normalnych reflektorow
|
||||
HighBeamLights = false;
|
||||
break;
|
||||
case 3:
|
||||
// dlugie przyciemnione
|
||||
DimHeadlights = true;
|
||||
HighBeamLights = true;
|
||||
MoverParameters->iLights[vehicleend] &=
|
||||
light::headlight_upper | light::rearendsignals | light::redmarker_left | light::redmarker_right | light::rearendsignals; // nie ruszamy gornych i koncowek
|
||||
MoverParameters->iLights[vehicleend] |= tLeft ? light::highbeamlight_left : 0; // jesli swiatlo z lewej zapalone to odpal dlugie
|
||||
MoverParameters->iLights[vehicleend] |= tRight ? light::highbeamlight_right : 0; // a tu z prawej
|
||||
break;
|
||||
case 4:
|
||||
// zwykle dlugie
|
||||
DimHeadlights = false;
|
||||
HighBeamLights = true;
|
||||
MoverParameters->iLights[vehicleend] &=
|
||||
light::headlight_upper | light::rearendsignals | light::redmarker_left | light::redmarker_right | light::rearendsignals; // nie ruszamy gornych i koncowek
|
||||
MoverParameters->iLights[vehicleend] |= tLeft ? light::highbeamlight_left : 0; // jesli swiatlo z lewej zapalone to odpal dlugie
|
||||
MoverParameters->iLights[vehicleend] |= tRight ? light::highbeamlight_right : 0; // a tu z prawej
|
||||
break;
|
||||
default: // to case 2 - zwykle
|
||||
DimHeadlights = false;
|
||||
HighBeamLights = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if( rear >= 0 ) {
|
||||
auto const vehicleend{ iDirection > 0 ? end::rear : end::front };
|
||||
@@ -7660,9 +8010,9 @@ TDynamicObject::update_shake( double const Timedelta ) {
|
||||
if( iVel > 0.5 ) {
|
||||
// acceleration-driven base shake
|
||||
shakevector += Math3D::vector3(
|
||||
-MoverParameters->AccN * Timedelta * 5.0, // highlight side sway
|
||||
-MoverParameters->AccVert * Timedelta,
|
||||
-MoverParameters->AccSVBased * Timedelta * 1.5); // accent acceleration/deceleration
|
||||
-MoverParameters->AccN * Timedelta * 5.0 * Global.ShakingMultiplierRL, // highlight side sway
|
||||
-MoverParameters->AccVert * Timedelta * Global.ShakingMultiplierUD,
|
||||
-MoverParameters->AccSVBased * Timedelta * 1.5 * Global.ShakingMultiplierBF); // accent acceleration/deceleration
|
||||
}
|
||||
|
||||
auto shake { 1.25 * ShakeSpring.ComputateForces( shakevector, ShakeState.offset ) };
|
||||
@@ -7923,7 +8273,7 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
||||
// youBy - przenioslem, bo diesel tez moze miec turbo
|
||||
if( Vehicle.TurboTest > 0 ) {
|
||||
// udawanie turbo:
|
||||
auto const pitch_diesel { Vehicle.EngineType == TEngineType::DieselEngine ? Vehicle.enrot / Vehicle.dizel_nmax * Vehicle.dizel_fill : 1 };
|
||||
auto const pitch_diesel{(Vehicle.EngineType == TEngineType::DieselEngine || Vehicle.EngineType == TEngineType::DieselElectric) ? Vehicle.enrot / Vehicle.dizel_nmax * Vehicle.dizel_fill : 1};
|
||||
auto const goalpitch { std::max( 0.025, ( /*engine_volume **/ pitch_diesel + engine_turbo.m_frequencyoffset ) * engine_turbo.m_frequencyfactor ) };
|
||||
auto const goalvolume { (
|
||||
( ( Vehicle.MainCtrlPos >= Vehicle.TurboTest ) && ( Vehicle.enrot > 0.1 ) ) ?
|
||||
|
||||
47
DynObj.h
47
DynObj.h
@@ -22,6 +22,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "sound.h"
|
||||
#include "Spring.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define EU07_SOUND_BOGIESOUNDS
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -36,7 +38,8 @@ int const ANIM_PANTS = 5; // pantografy
|
||||
int const ANIM_STEAMS = 6; // napęd parowozu
|
||||
int const ANIM_DOORSTEPS = 7;
|
||||
int const ANIM_MIRRORS = 8;
|
||||
int const ANIM_TYPES = 9; // Ra: ilość typów animacji
|
||||
int const ANIM_WIPERS = 9;
|
||||
int const ANIM_TYPES = 10; // Ra: ilość typów animacji
|
||||
|
||||
class TAnim;
|
||||
//typedef void(__closure *TUpdate)(TAnim *pAnim); // typ funkcji aktualizującej położenie submodeli
|
||||
@@ -103,7 +106,17 @@ class TAnimPant
|
||||
float fWidthExtra; // dodatkowy rozmiar poziomy poza część roboczą (fWidth)
|
||||
float fHeightExtra[5]; //łamana symulująca kształt nabieżnika
|
||||
// double fHorizontal; //Ra 2015-01: położenie drutu względem osi pantografu
|
||||
|
||||
// factory ktore mozna nadpisac z fiza
|
||||
float rd1rf{1.f}; // mnoznik obrotu ramienia dolnego 1
|
||||
float rd2rf{1.f}; // mnoznik obrotu ramienia dolnego 2
|
||||
float rg1rf{1.f}; // mnoznik obrotu ramienia gornego 1
|
||||
float rg2rf{1.f}; // mnoznik obrotu ramienia gornego 2
|
||||
float slizgrf{1.f}; // mnoznik obrotu slizgacza
|
||||
void AKP_4E();
|
||||
void WBL85();
|
||||
void DSAx();
|
||||
void EC160_200();
|
||||
};
|
||||
|
||||
class TAnim
|
||||
@@ -115,8 +128,8 @@ public:
|
||||
// destructor
|
||||
~TAnim();
|
||||
// methods
|
||||
int TypeSet( int i, int fl = 0 ); // ustawienie typu
|
||||
// members
|
||||
int TypeSet(int i, TMoverParameters currentMover, int fl = 0); // ustawienie typu
|
||||
// members
|
||||
union
|
||||
{
|
||||
TSubModel *smAnimated; // animowany submodel (jeśli tylko jeden, np. oś)
|
||||
@@ -209,7 +222,11 @@ public:
|
||||
inline TDynamicObject *PrevConnected() const { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline int NextConnectedNo() const { return MoverParameters->Neighbours[ end::rear ].vehicle_end; }
|
||||
inline int PrevConnectedNo() const { return MoverParameters->Neighbours[ end::front ].vehicle_end; }
|
||||
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
|
||||
// Dev tools
|
||||
void Reload();
|
||||
|
||||
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
|
||||
// modele składowe pojazdu
|
||||
TModel3d *mdModel; // model pudła
|
||||
@@ -277,7 +294,8 @@ private:
|
||||
void UpdatePlatformTranslate(TAnim *pAnim); // doorstep animation, shift
|
||||
void UpdatePlatformRotate(TAnim *pAnim); // doorstep animation, rotate
|
||||
void UpdateMirror(TAnim *pAnim); // mirror animation
|
||||
/*
|
||||
void UpdateWiper(TAnim *pAnim); // wiper animation
|
||||
/*
|
||||
void UpdateLeverDouble(TAnim *pAnim); // animacja gałki zależna od double
|
||||
void UpdateLeverFloat(TAnim *pAnim); // animacja gałki zależna od float
|
||||
void UpdateLeverInt(TAnim *pAnim); // animacja gałki zależna od int (wartość)
|
||||
@@ -301,6 +319,14 @@ private:
|
||||
Math3D::vector3 vFloor; // podłoga dla ładunku
|
||||
public:
|
||||
TAnim *pants; // indeks obiektu animującego dla pantografu 0
|
||||
TAnim *wipers; // wycieraczki
|
||||
std::vector<double> wiperOutTimer = std::vector<double>(8, 0.0);
|
||||
std::vector<double> wiperParkTimer = std::vector<double>(8, 0.0);
|
||||
std::vector<int> workingSwitchPos = std::vector<int>(8, 0); // working switch position (to not break wipers when switching modes)
|
||||
std::vector<double> dWiperPos; // timing na osi czasu animacji wycieraczki
|
||||
std::vector<bool> wiperDirection = std::vector<bool>(8, false); // false - return direction; true - out direction
|
||||
std::vector<bool> wiper_playSoundFromStart = std::vector<bool>(8, false);
|
||||
std::vector<bool> wiper_playSoundToStart = std::vector<bool>(8, false);
|
||||
double NoVoltTime; // czas od utraty zasilania
|
||||
double dMirrorMoveL{ 0.0 };
|
||||
double dMirrorMoveR{ 0.0 };
|
||||
@@ -469,13 +495,18 @@ private:
|
||||
AirCoupler m_headlamp11; // oswietlenie czolowe - przod
|
||||
AirCoupler m_headlamp12;
|
||||
AirCoupler m_headlamp13;
|
||||
AirCoupler m_highbeam12; // dlugie
|
||||
AirCoupler m_highbeam13;
|
||||
AirCoupler m_headlamp21; // oswietlenie czolowe - tyl
|
||||
AirCoupler m_headlamp22;
|
||||
AirCoupler m_headlamp23;
|
||||
AirCoupler m_highbeam22;
|
||||
AirCoupler m_highbeam23;
|
||||
AirCoupler m_headsignal12;
|
||||
AirCoupler m_headsignal13;
|
||||
AirCoupler m_headsignal22;
|
||||
AirCoupler m_headsignal23;
|
||||
TButton btExteriorOnly;
|
||||
TButton btMechanik1;
|
||||
TButton btMechanik2;
|
||||
TButton btShutters1; // cooling shutters for primary water circuit
|
||||
@@ -515,6 +546,8 @@ private:
|
||||
springbrake_sounds m_springbrakesounds;
|
||||
sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
||||
sound_source sSand { sound_placement::external };
|
||||
sound_source sWiperToPark { sound_placement::internal };
|
||||
sound_source sWiperFromPark { sound_placement::internal };
|
||||
// moving part and other external sounds
|
||||
sound_source m_startjolt { sound_placement::general }; // movement start jolt, played once on initial acceleration at slow enough speed
|
||||
bool m_startjoltplayed { false };
|
||||
@@ -569,8 +602,12 @@ private:
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler ) const;
|
||||
void ABuCheckMyTrack();
|
||||
|
||||
std::string rTypeName; // nazwa typu pojazdu
|
||||
std::string rReplacableSkin; // nazwa tekstury pojazdu
|
||||
|
||||
public:
|
||||
bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches
|
||||
bool HighBeamLights { false }; // status of the highbeam toggle
|
||||
// checks whether there's unbroken connection of specified type to specified vehicle
|
||||
bool is_connected( TDynamicObject const *Vehicle, coupling const Coupling = coupling::coupler ) const;
|
||||
TDynamicObject * PrevAny() const;
|
||||
|
||||
@@ -211,6 +211,15 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
{
|
||||
Parser.getTokens();
|
||||
Parser >> MultipleLogs;
|
||||
}
|
||||
else if (token == "shakefactor")
|
||||
{
|
||||
Parser.getTokens();
|
||||
Parser >> ShakingMultiplierBF;
|
||||
Parser.getTokens();
|
||||
Parser >> ShakingMultiplierRL;
|
||||
Parser.getTokens();
|
||||
Parser >> ShakingMultiplierUD;
|
||||
}
|
||||
else if (token == "logs.filter")
|
||||
{
|
||||
|
||||
12
Globals.h
12
Globals.h
@@ -16,6 +16,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "light.h"
|
||||
#include "utilities.h"
|
||||
#include "motiontelemetry.h"
|
||||
#include "ref/discord-rpc/include/discord_rpc.h"
|
||||
#include <map>
|
||||
|
||||
#ifdef WITH_UART
|
||||
#include "uart.h"
|
||||
#endif
|
||||
@@ -27,6 +30,11 @@ struct global_settings {
|
||||
// members
|
||||
// data items
|
||||
// TODO: take these out of the settings
|
||||
|
||||
/// <summary>
|
||||
/// Mapa z watkami w formacie <std::string nazwa, std::thread watek>
|
||||
/// </summary>
|
||||
std::map<std::string, std::thread> threads = {};
|
||||
bool shiftState{ false }; //m7todo: brzydko
|
||||
bool ctrlState{ false };
|
||||
bool altState{ false };
|
||||
@@ -117,7 +125,9 @@ struct global_settings {
|
||||
glm::ivec2 window_size; // main window size in platform-specific virtual pixels
|
||||
glm::ivec2 cursor_pos; // cursor position in platform-specific virtual pixels
|
||||
glm::ivec2 fb_size; // main window framebuffer size
|
||||
|
||||
float ShakingMultiplierBF {1.f}; // mnożnik bujania kamera przod/tyl
|
||||
float ShakingMultiplierRL {1.f}; // mnożnik bujania kamera lewo/prawo
|
||||
float ShakingMultiplierUD {1.f}; // mnożnik bujania kamera gora/dol
|
||||
float fDistanceFactor{ 1.f }; // baza do przeliczania odległości dla LoD
|
||||
float targetfps{ 0.0f };
|
||||
bool bFullScreen{ false };
|
||||
|
||||
118
Logs.cpp
118
Logs.cpp
@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "winheaders.h"
|
||||
#include "utilities.h"
|
||||
#include "uilayer.h"
|
||||
#include <deque>
|
||||
|
||||
std::ofstream output; // standardowy "log.txt", można go wyłączyć
|
||||
std::ofstream errors; // lista błędów "errors.txt", zawsze działa
|
||||
@@ -68,61 +69,88 @@ std::string filename_scenery() {
|
||||
}
|
||||
}
|
||||
|
||||
// log service stacks
|
||||
std::deque<char *> InfoStack;
|
||||
std::deque<char *> ErrorStack;
|
||||
|
||||
|
||||
void LogService()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// loop for logging
|
||||
|
||||
// write logs and log.txt
|
||||
while (!InfoStack.empty())
|
||||
{
|
||||
char *msg = InfoStack.front(); // get first element of stack
|
||||
InfoStack.pop_front();
|
||||
if (Global.iWriteLogEnabled & 1)
|
||||
{
|
||||
if (!output.is_open())
|
||||
{
|
||||
|
||||
std::string const filename = (Global.MultipleLogs ? "logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" : "log.txt");
|
||||
output.open(filename, std::ios::trunc);
|
||||
}
|
||||
output << msg << "\n";
|
||||
output.flush();
|
||||
}
|
||||
|
||||
log_scrollback.emplace_back(std::string(msg));
|
||||
if (log_scrollback.size() > 200)
|
||||
log_scrollback.pop_front();
|
||||
|
||||
if (Global.iWriteLogEnabled & 2)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
||||
DWORD wr = 0;
|
||||
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), msg, (DWORD)strlen(msg), &wr, NULL);
|
||||
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), endstring, (DWORD)strlen(endstring), &wr, NULL);
|
||||
#else
|
||||
printf("%s\n", msg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// write to errors.txt
|
||||
while (!ErrorStack.empty())
|
||||
{
|
||||
char *msg = ErrorStack.front();
|
||||
ErrorStack.pop_front();
|
||||
|
||||
if (!(Global.iWriteLogEnabled & 1))
|
||||
return;
|
||||
|
||||
if (!errors.is_open())
|
||||
{
|
||||
|
||||
std::string const filename = (Global.MultipleLogs ? "logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" : "errors.txt");
|
||||
errors.open(filename, std::ios::trunc);
|
||||
errors << "EU07.EXE " + Global.asVersion << "\n";
|
||||
}
|
||||
|
||||
errors << msg << "\n";
|
||||
errors.flush();
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5)); // dont burn cpu so much
|
||||
}
|
||||
}
|
||||
|
||||
void WriteLog( const char *str, logtype const Type ) {
|
||||
|
||||
if( str == nullptr ) { return; }
|
||||
if( true == TestFlag( Global.DisabledLogTypes, static_cast<unsigned int>( Type ) ) ) { return; }
|
||||
|
||||
if (Global.iWriteLogEnabled & 1) {
|
||||
if( !output.is_open() ) {
|
||||
|
||||
std::string const filename =
|
||||
( Global.MultipleLogs ?
|
||||
"logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" :
|
||||
"log.txt" );
|
||||
output.open( filename, std::ios::trunc );
|
||||
}
|
||||
output << str << "\n";
|
||||
output.flush();
|
||||
}
|
||||
|
||||
log_scrollback.emplace_back(std::string(str));
|
||||
if (log_scrollback.size() > 200)
|
||||
log_scrollback.pop_front();
|
||||
|
||||
if( Global.iWriteLogEnabled & 2 ) {
|
||||
#ifdef _WIN32
|
||||
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
|
||||
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN | FOREGROUND_INTENSITY );
|
||||
DWORD wr = 0;
|
||||
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), str, (DWORD)strlen( str ), &wr, NULL );
|
||||
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), endstring, (DWORD)strlen( endstring ), &wr, NULL );
|
||||
#else
|
||||
printf("%s\n", str);
|
||||
#endif
|
||||
}
|
||||
InfoStack.emplace_back(strdup(str));
|
||||
}
|
||||
|
||||
void ErrorLog( const char *str, logtype const Type ) {
|
||||
|
||||
if( str == nullptr ) { return; }
|
||||
if( true == TestFlag( Global.DisabledLogTypes, static_cast<unsigned int>( Type ) ) ) { return; }
|
||||
|
||||
if (!(Global.iWriteLogEnabled & 1))
|
||||
return;
|
||||
|
||||
if (!errors.is_open()) {
|
||||
|
||||
std::string const filename =
|
||||
( Global.MultipleLogs ?
|
||||
"logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" :
|
||||
"errors.txt" );
|
||||
errors.open( filename, std::ios::trunc );
|
||||
errors << "EU07.EXE " + Global.asVersion << "\n";
|
||||
}
|
||||
|
||||
errors << str << "\n";
|
||||
errors.flush();
|
||||
ErrorStack.emplace_back(strdup(str));
|
||||
};
|
||||
|
||||
void Error(const std::string &asMessage, bool box)
|
||||
|
||||
2
Logs.h
2
Logs.h
@@ -23,7 +23,7 @@ enum class logtype : unsigned int {
|
||||
traction = ( 1 << 9 ),
|
||||
powergrid = ( 1 << 10 ),
|
||||
};
|
||||
|
||||
void LogService();
|
||||
void WriteLog( const char *str, logtype const Type = logtype::generic );
|
||||
void Error( const std::string &asMessage, bool box = false );
|
||||
void Error( const char* &asMessage, bool box = false );
|
||||
|
||||
1278
McZapkie/MOVER.h
1278
McZapkie/MOVER.h
File diff suppressed because it is too large
Load Diff
@@ -8927,7 +8927,7 @@ bool startBPT;
|
||||
bool startMPT, startMPT0;
|
||||
bool startRLIST, startUCLIST;
|
||||
bool startDIZELMOMENTUMLIST, startDIZELV2NMAXLIST, startHYDROTCLIST, startPMAXLIST;
|
||||
bool startDLIST, startFFLIST, startWWLIST;
|
||||
bool startDLIST, startFFLIST, startWWLIST, startWiperList;
|
||||
bool startLIGHTSLIST;
|
||||
bool startCOMPRESSORLIST;
|
||||
int LISTLINE;
|
||||
@@ -9279,6 +9279,25 @@ bool TMoverParameters::readFFList( std::string const &line ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// parsowanie wiperList
|
||||
bool TMoverParameters::readWiperList(std::string const& line)
|
||||
{
|
||||
cParser parser(line);
|
||||
if (false == parser.getTokens(4, false))
|
||||
{
|
||||
WriteLog("Read WiperList: arguments missing in line " + std::to_string(LISTLINE + 1));
|
||||
return false;
|
||||
}
|
||||
int idx = LISTLINE++;
|
||||
if (idx >= sizeof(WiperList) / sizeof(TWiperScheme))
|
||||
{
|
||||
WriteLog("Read WiperList: number of entries exceeded capacity of the data table");
|
||||
return false;
|
||||
}
|
||||
parser >> WiperList[idx].byteSum >> WiperList[idx].WiperSpeed >> WiperList[idx].interval >> WiperList[idx].outBackDelay;
|
||||
return true;
|
||||
}
|
||||
|
||||
// parsowanie WWList
|
||||
bool TMoverParameters::readWWList( std::string const &line ) {
|
||||
|
||||
@@ -9308,7 +9327,6 @@ bool TMoverParameters::readWWList( std::string const &line ) {
|
||||
SST[ idx ].Pmin = std::sqrt( std::pow( SST[ idx ].Umin, 2 ) / 47.6 );
|
||||
SST[ idx ].Pmax = std::min( SST[ idx ].Pmax, std::pow( SST[ idx ].Umax, 2 ) / 47.6 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9444,6 +9462,7 @@ void TMoverParameters::BrakeSubsystemDecode()
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
{
|
||||
chkPath = chkpath; // assign class path for reloading
|
||||
const int param_ok = 1;
|
||||
const int wheels_ok = 2;
|
||||
const int dimensions_ok = 4;
|
||||
@@ -9462,6 +9481,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
startPMAXLIST = false;
|
||||
startFFLIST = false;
|
||||
startWWLIST = false;
|
||||
startWiperList = false;
|
||||
startLIGHTSLIST = false;
|
||||
startCOMPRESSORLIST = false;
|
||||
std::string file = TypeName + ".fiz";
|
||||
@@ -9562,6 +9582,13 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
startFFLIST = false;
|
||||
continue;
|
||||
}
|
||||
if (issection("endwl", inputline))
|
||||
{
|
||||
// skonczylismy czytac liste konfiguracji wycieraczek
|
||||
startBPT = false;
|
||||
startWiperList = false;
|
||||
continue;
|
||||
}
|
||||
if( issection( "END-WWL", inputline ) ) {
|
||||
startBPT = false;
|
||||
startWWLIST = false;
|
||||
@@ -9666,6 +9693,14 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (issection("Headlights:", inputline))
|
||||
{
|
||||
startBPT = false;
|
||||
fizlines.emplace("Headlights", inputline);
|
||||
LoadFIZ_Headlights(inputline);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (issection("Blending:", inputline)) {
|
||||
|
||||
startBPT = false; LISTLINE = 0;
|
||||
@@ -9845,9 +9880,22 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
{
|
||||
startBPT = false;
|
||||
startWWLIST = true; LISTLINE = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (issection("WiperList:", inputline))
|
||||
{
|
||||
startBPT = false;
|
||||
fizlines.emplace("WiperList", inputline);
|
||||
startWiperList = true;
|
||||
LISTLINE = 0;
|
||||
LoadFIZ_WiperList(inputline);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( issection( "LightsList:", inputline ) ) {
|
||||
startBPT = false;
|
||||
fizlines.emplace( "LightsList", inputline );
|
||||
@@ -9914,6 +9962,11 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
readWWList( inputline );
|
||||
continue;
|
||||
}
|
||||
if (true == startWiperList)
|
||||
{
|
||||
readWiperList(inputline);
|
||||
continue;
|
||||
}
|
||||
if( true == startLIGHTSLIST ) {
|
||||
readLightsList( inputline );
|
||||
continue;
|
||||
@@ -9935,6 +9988,13 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
else
|
||||
result = false;
|
||||
|
||||
if (!modernContainOffPos)
|
||||
modernDimmerState = 2; // jak nie ma opcji wylaczonej to niech sie odpali normalnie
|
||||
if (!enableModernDimmer)
|
||||
{
|
||||
modernDimmerState = 2;
|
||||
}
|
||||
|
||||
WriteLog("CERROR: " + to_string(ConversionError) + ", SUCCES: " + to_string(result));
|
||||
return result;
|
||||
}
|
||||
@@ -10026,6 +10086,18 @@ void TMoverParameters::LoadFIZ_Load( std::string const &line ) {
|
||||
extract_value( UnLoadSpeed, "UnLoadSpeed", line, "" );
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_Headlights(std::string const &line)
|
||||
{
|
||||
extract_value(refR, "LampRed", line, "");
|
||||
extract_value(refG, "LampGreen", line, "");
|
||||
extract_value(refB, "LampBlue", line, "");
|
||||
|
||||
extract_value(dimMultiplier, "DimmedMultiplier", line, "");
|
||||
extract_value(normMultiplier, "NormalMultiplier", line, "");
|
||||
extract_value(highDimMultiplier, "HighbeamDimmedMultiplier", line, "");
|
||||
extract_value(highMultiplier, "HighBeamMultiplier", line, "");
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_Dimensions( std::string const &line ) {
|
||||
|
||||
extract_value( Dim.L, "L", line, "" );
|
||||
@@ -10602,6 +10674,12 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
||||
|
||||
extract_value(HideDirStatusWhenMoving, "HideDirStatusWhenMoving", line, "");
|
||||
extract_value(HideDirStatusSpeed, "HideDirStatusSpeed", line, "");
|
||||
extract_value(isDoubleClickForMeasureNeeded, "DCMB", line, "");
|
||||
extract_value(DistanceCounterDoublePressPeriod, "DCDPP", line, "");
|
||||
|
||||
extract_value(isBatteryButtonImpulse, "IBTB", line, "");
|
||||
extract_value(shouldHoldBatteryButton, "SBBBH", line, "");
|
||||
extract_value(BatteryButtonHoldTime, "BBHT", line, "");
|
||||
|
||||
std::map<std::string, start_t> starts {
|
||||
{ "Disabled", start_t::disabled },
|
||||
@@ -11120,6 +11198,8 @@ void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
|
||||
extract_value( UniversalResetButtonFlag[ 0 ], "RelayResetButton1", Input, "" );
|
||||
extract_value( UniversalResetButtonFlag[ 1 ], "RelayResetButton2", Input, "" );
|
||||
extract_value( UniversalResetButtonFlag[ 2 ], "RelayResetButton3", Input, "" );
|
||||
extract_value(enableModernDimmer, "ModernDimmer", Input, "");
|
||||
extract_value(modernContainOffPos, "ModernDimmerOffPosition", Input, "");
|
||||
// pantograph presets
|
||||
{
|
||||
auto &presets { PantsPreset.first };
|
||||
@@ -11242,6 +11322,13 @@ void TMoverParameters::LoadFIZ_FFList( std::string const &Input ) {
|
||||
extract_value( RlistSize, "Size", Input, "" );
|
||||
}
|
||||
|
||||
|
||||
void TMoverParameters::LoadFIZ_WiperList(std::string const &Input)
|
||||
{
|
||||
extract_value(WiperListSize, "Size", Input, "");
|
||||
extract_value(WiperAngle, "Angle", Input, "");
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_LightsList( std::string const &Input ) {
|
||||
|
||||
extract_value( LightsPosNo, "Size", Input, "" );
|
||||
@@ -11306,6 +11393,17 @@ void TMoverParameters::LoadFIZ_PowerParamsDecode( TPowerParameters &Powerparamet
|
||||
auto &collectorparameters = Powerparameters.CollectorParameters;
|
||||
|
||||
collectorparameters = TCurrentCollector { 0, 0, 0, 0, 0, 0, false, 0, 0, 0, false, 0 };
|
||||
|
||||
std::string PantType = "";
|
||||
extract_value(PantType, "PantType", Line, "");
|
||||
if (PantType == "AKP_4E")
|
||||
collectorparameters.PantographType = TPantType::AKP_4E;
|
||||
if (PantType._Starts_with("DSA")) // zakladam ze wszystkie pantografy DSA sa takie same
|
||||
collectorparameters.PantographType = TPantType::DSAx;
|
||||
if (PantType == "EC160" || PantType == "EC200")
|
||||
collectorparameters.PantographType = TPantType::EC160_200;
|
||||
if (PantType == "WBL85")
|
||||
collectorparameters.PantographType = TPantType::WBL85;
|
||||
|
||||
extract_value( collectorparameters.CollectorsNo, "CollectorsNo", Line, "" );
|
||||
extract_value( collectorparameters.MinH, "MinH", Line, "" );
|
||||
@@ -12442,6 +12540,24 @@ double TMoverParameters::ShowCurrentP(int AmpN) const
|
||||
}
|
||||
}
|
||||
|
||||
bool TMoverParameters::reload_FIZ() {
|
||||
WriteLog("[DEV] Reloading FIZ for " + Name);
|
||||
// pause simulation
|
||||
Global.iPause |= 0b1000;
|
||||
bool result = LoadFIZ(chkPath);
|
||||
if (result == true)
|
||||
{
|
||||
// jesli sie udalo przeladowac FIZ
|
||||
Global.iPause &= 0b0111;
|
||||
WriteLog("[DEV] FIZ reloaded for " + Name);
|
||||
}
|
||||
else {
|
||||
// failed to reload - exit simulator
|
||||
ErrorLog("[DEV] Failed to reload fiz for vehicle " + Name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace simulation {
|
||||
|
||||
weights_table Weights;
|
||||
|
||||
69
PyInt.cpp
69
PyInt.cpp
@@ -105,6 +105,38 @@ void render_task::run() {
|
||||
if( outputwidth != nullptr ) { Py_DECREF( outputwidth ); }
|
||||
Py_DECREF( output );
|
||||
}
|
||||
|
||||
// get commands from renderer
|
||||
auto *commandsPO = PyObject_CallMethod(m_renderer, "getCommands", nullptr);
|
||||
if (commandsPO != nullptr)
|
||||
{
|
||||
std::vector<std::string> commands = python_external_utils::PyObjectToStringArray(commandsPO);
|
||||
|
||||
Py_DECREF(commandsPO);
|
||||
// we perform any actions ONLY when there are any commands in buffer
|
||||
if (!commands.empty())
|
||||
{
|
||||
for (const auto &command : commands)
|
||||
{
|
||||
auto it = simulation::commandMap.find(command);
|
||||
if (it != simulation::commandMap.end())
|
||||
{
|
||||
// command found
|
||||
command_data cd;
|
||||
cd.command = it->second;
|
||||
cd.action = GLFW_PRESS;
|
||||
simulation::Commands.push(cd, static_cast<std::size_t>(command_target::vehicle) | 1); // player train is always 1
|
||||
}
|
||||
else
|
||||
ErrorLog("Python: Command [" + command + "] not found!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void render_task::upload()
|
||||
@@ -470,6 +502,43 @@ python_taskqueue::error() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> python_external_utils::PyObjectToStringArray(PyObject *pyList)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::vector<std::string> emptyIfError = {};
|
||||
if (!PySequence_Check(pyList))
|
||||
{
|
||||
ErrorLog("Python: Failed to convert PyObject -> vector<string>");
|
||||
return emptyIfError;
|
||||
}
|
||||
|
||||
Py_ssize_t size = PySequence_Size(pyList);
|
||||
for (Py_ssize_t i = 0; i < size; ++i)
|
||||
{
|
||||
PyObject *item = PySequence_GetItem(pyList, i); // Increments reference count
|
||||
if (item == nullptr)
|
||||
{
|
||||
ErrorLog("Python: Failed to get item from sequence.");
|
||||
return emptyIfError;
|
||||
}
|
||||
|
||||
const char *str = PyString_AsString(item);
|
||||
if (str == nullptr)
|
||||
{
|
||||
Py_DECREF(item);
|
||||
ErrorLog("Python: Failed to convert item to string.");
|
||||
return emptyIfError;
|
||||
}
|
||||
|
||||
result.push_back(std::string(str));
|
||||
Py_DECREF(item); // Decrease reference count for the item
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
10
PyInt.h
10
PyInt.h
@@ -130,7 +130,8 @@ private:
|
||||
auto fetch_renderer( std::string const Renderer ) -> PyObject *;
|
||||
void run(GLFWwindow *Context, rendertask_sequence &Tasks, uploadtask_sequence &Upload_Tasks, threading::condition_variable &Condition, std::atomic<bool> &Exit );
|
||||
void error();
|
||||
// members
|
||||
|
||||
// members
|
||||
PyObject *m_main { nullptr };
|
||||
PyObject *m_stderr { nullptr };
|
||||
PyThreadState *m_mainthread{ nullptr };
|
||||
@@ -143,4 +144,11 @@ private:
|
||||
bool m_initialized { false };
|
||||
};
|
||||
|
||||
class python_external_utils
|
||||
{
|
||||
public:
|
||||
static std::vector<std::string> PyObjectToStringArray(PyObject *pyList);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,7 +50,7 @@ MaSzyna should work and compile natively under **Linux** and **Windows**. Other
|
||||
Commands will be written in [`Bash`](https://www.gnu.org/software/bash/). No-Linux users must do in corresponding technology.
|
||||
|
||||
0. Clone source code.
|
||||
You may download source code [as ZIP archive](https://github.com/eu07/maszyna/archive/master.zip), or clone it by [`Git`](https://git-scm.com/). We won't provide tutorial to second one, the only note worth mention is that, repository doesn't contain submodules, so `--recursive` is not needed. From now, it is assumed that your working directory is inside directory with unpacked source code.
|
||||
You may download source code [as ZIP archive](https://github.com/eu07/maszyna/archive/master.zip), or clone it by [`Git`](https://git-scm.com/). We won't provide tutorial to second one, the only note worth mention is that, repository contain submodules, so `--recursive` is needed. From now, it is assumed that your working directory is inside directory with unpacked source code.
|
||||
1. Make directory, where build files will be stored, then enter inside it.
|
||||
|
||||
$ mkdir build
|
||||
|
||||
@@ -40,7 +40,7 @@ Math3D::vector3 TSpring::ComputateForces( Math3D::vector3 const &pPosition1, Mat
|
||||
|
||||
// ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector
|
||||
// ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force
|
||||
springForce = deltaP / dist * ( -( Hterm + Dterm ) );
|
||||
springForce = deltaP / dist * ( -( Hterm + Dterm ));
|
||||
// VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1
|
||||
// VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2
|
||||
}
|
||||
|
||||
424
Train.cpp
424
Train.cpp
@@ -288,6 +288,10 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
{ user_command::pantographraiserear, &TTrain::OnCommand_pantographraiserear },
|
||||
{ user_command::pantographlowerfront, &TTrain::OnCommand_pantographlowerfront },
|
||||
{ user_command::pantographlowerrear, &TTrain::OnCommand_pantographlowerrear },
|
||||
|
||||
{user_command::wiperswitchincrease, &TTrain::OnCommand_wiperswitchincrease},
|
||||
{user_command::wiperswitchdecrease, &TTrain::OnCommand_wiperswitchdecrease},
|
||||
|
||||
{ user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall },
|
||||
{ user_command::pantographselectnext, &TTrain::OnCommand_pantographselectnext },
|
||||
{ user_command::pantographselectprevious, &TTrain::OnCommand_pantographselectprevious },
|
||||
@@ -375,6 +379,8 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
{ user_command::headlighttogglerearupper, &TTrain::OnCommand_headlighttogglerearupper },
|
||||
{ user_command::headlightenablerearupper, &TTrain::OnCommand_headlightenablerearupper },
|
||||
{ user_command::headlightdisablerearupper, &TTrain::OnCommand_headlightdisablerearupper },
|
||||
{user_command::modernlightdimmerdecrease, &TTrain::OnCommand_modernlightdimmerdecrease},
|
||||
{user_command::modernlightdimmerincrease, &TTrain::OnCommand_modernlightdimmerincrease},
|
||||
{ user_command::redmarkertogglerearleft, &TTrain::OnCommand_redmarkertogglerearleft },
|
||||
{ user_command::redmarkerenablerearleft, &TTrain::OnCommand_redmarkerenablerearleft },
|
||||
{ user_command::redmarkerdisablerearleft, &TTrain::OnCommand_redmarkerdisablerearleft },
|
||||
@@ -1313,7 +1319,17 @@ void TTrain::OnCommand_distancecounteractivate( TTrain *Train, command_data cons
|
||||
// visual feedback
|
||||
Train->ggDistanceCounterButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
// activate or start anew
|
||||
Train->m_distancecounter = 0.f;
|
||||
if (Train->mvOccupied->isDoubleClickForMeasureNeeded) {
|
||||
// handler tempomatu dla podwojnego kliku
|
||||
if (Train->trainLenghtMeasureTimer >= 0.f) // jesli zdazylismy w czasie sekundy
|
||||
Train->m_distancecounter = 0.f; // rozpoczynamy pomiar
|
||||
else
|
||||
Train->trainLenghtMeasureTimer = Train->mvOccupied->DistanceCounterDoublePressPeriod; // odpalamy zegarek od nowa
|
||||
}
|
||||
else {
|
||||
// dla pojedynczego kliku
|
||||
Train->m_distancecounter = 0.f;
|
||||
}
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// visual feedback
|
||||
@@ -2171,6 +2187,31 @@ void TTrain::OnCommand_mubrakingindicatortoggle( TTrain *Train, command_data con
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_wiperswitchincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
Train->mvOccupied->wiperSwitchPos++;
|
||||
if (Train->mvOccupied->wiperSwitchPos > Train->mvOccupied->WiperListSize - 1)
|
||||
Train->mvOccupied->wiperSwitchPos = Train->mvOccupied->WiperListSize - 1;
|
||||
|
||||
// Visual feedback
|
||||
Train->ggWiperSw.UpdateValue(Train->mvOccupied->wiperSwitchPos, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
void TTrain::OnCommand_wiperswitchdecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
Train->mvOccupied->wiperSwitchPos--;
|
||||
if (Train->mvOccupied->wiperSwitchPos < 0)
|
||||
Train->mvOccupied->wiperSwitchPos = 0;
|
||||
|
||||
// visual feedback
|
||||
Train->ggWiperSw.UpdateValue(Train->mvOccupied->wiperSwitchPos, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_reverserincrease( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -2356,7 +2397,8 @@ void TTrain::OnCommand_cabsignalacknowledge( TTrain *Train, command_data const &
|
||||
|
||||
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command )
|
||||
{
|
||||
if( Command.action != GLFW_REPEAT ) {
|
||||
if (Train->allowBatteryToggle || Command.action != GLFW_REPEAT)
|
||||
{
|
||||
// keep the switch from flipping back and forth if key is held down
|
||||
if( false == Train->mvOccupied->Power24vIsAvailable ) {
|
||||
// turn on
|
||||
@@ -2370,44 +2412,160 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_batteryenable( TTrain *Train, command_data const &Command ) {
|
||||
if (!Train->mvOccupied->isBatteryButtonImpulse)
|
||||
{ // regular button behavior
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
Train->ggBatteryOnButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
|
||||
Train->mvOccupied->BatterySwitch( true );
|
||||
|
||||
// side-effects
|
||||
if( Train->mvOccupied->LightsPosNo > 0 ) {
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
Train->mvOccupied->BatterySwitch(true);
|
||||
Train->allowBatteryToggle = false;
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
if (Train->ggBatteryButton.type() == TGaugeType::push)
|
||||
{
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue(0.5f);
|
||||
}
|
||||
Train->ggBatteryOnButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->allowBatteryToggle = true;
|
||||
}
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
if( Train->ggBatteryButton.type() == TGaugeType::push ) {
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue( 0.5f );
|
||||
else // impulse button behavior
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// jesli przycisk trzeba przytrzymac
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->fBatteryTimer = Train->mvOccupied->BatteryButtonHoldTime; // start timer
|
||||
}
|
||||
else
|
||||
{
|
||||
// jesli przycisk dziala od razu
|
||||
Train->mvOccupied->BatterySwitch(true);
|
||||
Train->allowBatteryToggle = false;
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
Train->ggBatteryOnButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->fBatteryTimer = -1.f; //
|
||||
Train->allowBatteryToggle = true;
|
||||
}
|
||||
else if (Command.action == GLFW_REPEAT && Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// trzymamy przycisk
|
||||
if (Train->fBatteryTimer <= 0.0 && Train->mvOccupied->Battery == false) {
|
||||
Train->mvOccupied->BatterySwitch(true);
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
Train->allowBatteryToggle = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_batterydisable( TTrain *Train, command_data const &Command ) {
|
||||
// TBD, TODO: ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
Train->ggBatteryOffButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
if (!Train->mvOccupied->isBatteryButtonImpulse)
|
||||
{ // regular button behavior
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
|
||||
Train->mvOccupied->BatterySwitch( false );
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
if( Train->ggBatteryButton.type() == TGaugeType::push ) {
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue( 0.5f );
|
||||
}
|
||||
Train->ggBatteryOffButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
}
|
||||
Train->mvOccupied->BatterySwitch(false);
|
||||
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
if (Train->ggBatteryButton.type() == TGaugeType::push)
|
||||
{
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue(0.5f);
|
||||
}
|
||||
Train->ggBatteryOffButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else // impulse button behavior
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// jesli przycisk trzeba przytrzymac
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->fBatteryTimer = Train->mvOccupied->BatteryButtonHoldTime; // start timer
|
||||
}
|
||||
else
|
||||
{
|
||||
// jesli przycisk dziala od razu
|
||||
Train->mvOccupied->BatterySwitch(false);
|
||||
Train->allowBatteryToggle = false;
|
||||
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->allowBatteryToggle = true;
|
||||
}
|
||||
else if (Command.action == GLFW_REPEAT && Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// trzymamy przycisk
|
||||
if (Train->fBatteryTimer <= 0.0 && Train->mvOccupied->Battery == true) {
|
||||
Train->mvOccupied->BatterySwitch(false);
|
||||
Train->allowBatteryToggle = false;
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_cabactivationtoggle(TTrain *Train, command_data const &Command) {
|
||||
@@ -2816,23 +2974,43 @@ void TTrain::change_pantograph_selection( int const Change ) {
|
||||
|
||||
void TTrain::OnCommand_pantographvalvesupdate( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
bool hasSeparateSwitches = Train->m_controlmapper.contains("pantvalvesupdate_bt:") &&
|
||||
Train->m_controlmapper.contains("pantvalvesoff_bt:");
|
||||
|
||||
if( Command.action == GLFW_REPEAT ) { return; }
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// implement action
|
||||
Train->update_pantograph_valves();
|
||||
// visual feedback
|
||||
Train->ggPantValvesButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
if (hasSeparateSwitches)
|
||||
{
|
||||
// implement action
|
||||
Train->update_pantograph_valves();
|
||||
// visual feedback
|
||||
Train->ggPantValvesUpdate.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
|
||||
// Old logic to maintain compatibility
|
||||
else
|
||||
{
|
||||
Train->update_pantograph_valves();
|
||||
Train->ggPantValvesButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// visual feedback
|
||||
// NOTE: pantvalves_sw: is a specialized button, with no toggle behavior support
|
||||
Train->ggPantValvesButton.UpdateValue( 0.5, Train->dsbSwitch );
|
||||
if (hasSeparateSwitches)
|
||||
Train->ggPantValvesUpdate.UpdateValue(0.5, Train->dsbSwitch);
|
||||
|
||||
// Old logic to maintain compatibility
|
||||
else
|
||||
Train->ggPantValvesButton.UpdateValue(0.5, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_pantographvalvesoff( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
bool hasSeparateSwitches = Train->m_controlmapper.contains("pantvalvesupdate_bt:") && Train->m_controlmapper.contains("pantvalvesoff_bt:");
|
||||
|
||||
if( Command.action == GLFW_REPEAT ) { return; }
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -2840,12 +3018,18 @@ void TTrain::OnCommand_pantographvalvesoff( TTrain *Train, command_data const &C
|
||||
Train->mvOccupied->OperatePantographValve( end::front, operation_t::disable );
|
||||
Train->mvOccupied->OperatePantographValve( end::rear, operation_t::disable );
|
||||
// visual feedback
|
||||
Train->ggPantValvesButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
if (hasSeparateSwitches)
|
||||
Train->ggPantValvesOff.UpdateValue(1.0, Train->dsbSwitch);
|
||||
else
|
||||
Train->ggPantValvesButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// visual feedback
|
||||
// NOTE: pantvalves_sw: is a specialized button, with no toggle behavior support
|
||||
Train->ggPantValvesButton.UpdateValue( 0.5, Train->dsbSwitch );
|
||||
// NOTE: pantvalves_sw: is a speciali zed button, with no toggle behavior support
|
||||
if (hasSeparateSwitches)
|
||||
Train->ggPantValvesOff.UpdateValue(0.f, Train->dsbSwitch);
|
||||
else
|
||||
Train->ggPantValvesButton.UpdateValue( 0.5, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4669,6 +4853,44 @@ void TTrain::OnCommand_headlightdisablerearupper( TTrain *Train, command_data co
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_modernlightdimmerincrease(TTrain* Train, command_data const& Command)
|
||||
{
|
||||
if (!Train->mvOccupied->enableModernDimmer)
|
||||
return; // if modern dimmer is disabled, skip entire command
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// update modern dimmer state
|
||||
if (Train->mvOccupied->modernDimmerState < 4)
|
||||
Train->mvOccupied->modernDimmerState++;
|
||||
Train->Dynamic()->SetLights();
|
||||
// visual feedback
|
||||
if (Train->ggModernLightDimSw.SubModel != nullptr)
|
||||
if (Train->mvOccupied->modernContainOffPos)
|
||||
Train->ggModernLightDimSw.UpdateValue(Train->mvOccupied->modernDimmerState, Train->dsbSwitch);
|
||||
else
|
||||
Train->ggModernLightDimSw.UpdateValue(Train->mvOccupied->modernDimmerState - 1, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
void TTrain::OnCommand_modernlightdimmerdecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (!Train->mvOccupied->enableModernDimmer)
|
||||
return; // if modern dimmer is disabled, skip entire command
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
byte minPos = (Train->mvOccupied->modernContainOffPos) ? 0 : 1; // prevent switching to 0 if its not enabled
|
||||
// update modern dimmer state
|
||||
if (Train->mvOccupied->modernDimmerState > minPos)
|
||||
Train->mvOccupied->modernDimmerState--;
|
||||
Train->Dynamic()->SetLights();
|
||||
// visual feedback
|
||||
if (Train->ggModernLightDimSw.SubModel != nullptr)
|
||||
if (Train->mvOccupied->modernContainOffPos)
|
||||
Train->ggModernLightDimSw.UpdateValue(Train->mvOccupied->modernDimmerState, Train->dsbSwitch);
|
||||
else
|
||||
Train->ggModernLightDimSw.UpdateValue(Train->mvOccupied->modernDimmerState - 1, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_redmarkertogglerearleft( TTrain *Train, command_data const &Command ) {
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc
|
||||
@@ -4848,10 +5070,12 @@ void TTrain::OnCommand_endsignalstoggle( TTrain *Train, command_data const &Comm
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if (Train->DynamicObject->MoverParameters->enableModernDimmer)
|
||||
return;
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->DynamicObject->DimHeadlights ) {
|
||||
if (Train->DynamicObject->MoverParameters->modernDimmerState == 2)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_headlightsdimenable( Train, Command );
|
||||
}
|
||||
@@ -4864,37 +5088,57 @@ void TTrain::OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &C
|
||||
|
||||
void TTrain::OnCommand_headlightsdimenable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if (Train->DynamicObject->MoverParameters->enableModernDimmer)
|
||||
return;
|
||||
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->ggDimHeadlightsButton.SubModel == nullptr ) {
|
||||
if( Train->ggDimHeadlightsButton.SubModel != nullptr ) {
|
||||
// TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels
|
||||
WriteLog( "Dim Headlights switch is missing, or wasn't defined" );
|
||||
return;
|
||||
// visual feedback
|
||||
Train->ggDimHeadlightsButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggDimHeadlightsButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
|
||||
if( true == Train->DynamicObject->DimHeadlights ) { return; } // already enabled
|
||||
/* // to jest stara logika
|
||||
if (true == Train->DynamicObject->DimHeadlights)
|
||||
{
|
||||
return;
|
||||
} // already enabled
|
||||
|
||||
Train->DynamicObject->DimHeadlights = true;
|
||||
*/
|
||||
WriteLog("Switch do 1");
|
||||
Train->DynamicObject->MoverParameters->modernDimmerState = 1; // ustawiamy modern dimmer na flage przyciemnienia
|
||||
Train->DynamicObject->RaLightsSet(Train->DynamicObject->MoverParameters->iLights[0],
|
||||
Train->DynamicObject->MoverParameters->iLights[1]
|
||||
); // aktualizacja swiatelek
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_headlightsdimdisable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if (Train->DynamicObject->MoverParameters->enableModernDimmer) // nie wiem dlaczego to tak dziala ze jest odwrocona logika
|
||||
return;
|
||||
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->ggDimHeadlightsButton.SubModel == nullptr ) {
|
||||
if( Train->ggDimHeadlightsButton.SubModel != nullptr ) {
|
||||
// TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels
|
||||
WriteLog( "Dim Headlights switch is missing, or wasn't defined" );
|
||||
return;
|
||||
// visual feedback
|
||||
Train->ggDimHeadlightsButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggDimHeadlightsButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
|
||||
|
||||
/* // stara logika przyciemniania
|
||||
if( false == Train->DynamicObject->DimHeadlights ) { return; } // already enabled
|
||||
|
||||
Train->DynamicObject->DimHeadlights = false;
|
||||
|
||||
*/
|
||||
WriteLog("Switch do 2");
|
||||
Train->DynamicObject->MoverParameters->modernDimmerState = 2; // ustawiamy modern dimmer na flage rozjasnienia
|
||||
Train->DynamicObject->RaLightsSet(
|
||||
Train->DynamicObject->MoverParameters->iLights[0],
|
||||
Train->DynamicObject->MoverParameters->iLights[1]
|
||||
); // aktualizacja swiatelek
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6748,6 +6992,7 @@ void TTrain::OnCommand_vehicleboost(TTrain *Train, const command_data &Command)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// cab movement update, fixed step part
|
||||
void TTrain::UpdateCab() {
|
||||
|
||||
@@ -6834,6 +7079,21 @@ bool TTrain::Update( double const Deltatime )
|
||||
mvOccupied->OperateDoors( static_cast<side>( idx ), true );
|
||||
}
|
||||
}
|
||||
|
||||
// train measurement timer
|
||||
if (trainLenghtMeasureTimer >= 0.f) {
|
||||
trainLenghtMeasureTimer -= Deltatime;
|
||||
if (trainLenghtMeasureTimer < 0.f)
|
||||
trainLenghtMeasureTimer = -1.f;
|
||||
}
|
||||
|
||||
// battery timer
|
||||
if (fBatteryTimer >= 0.f) {
|
||||
fBatteryTimer -= Deltatime;
|
||||
if (fBatteryTimer < 0.f)
|
||||
fBatteryTimer = -1.f;
|
||||
}
|
||||
|
||||
// helper variables
|
||||
if( DynamicObject->Mechanik != nullptr ) {
|
||||
m_doors = (
|
||||
@@ -7350,6 +7610,12 @@ bool TTrain::Update( double const Deltatime )
|
||||
else
|
||||
btCompressors.Turn(false);
|
||||
|
||||
// Lampka zezwolenia na hamowanie ED
|
||||
if (mvControlled->EpFuse)
|
||||
btEDenabled.Turn(true);
|
||||
else
|
||||
btEDenabled.Turn(false);
|
||||
|
||||
// Lampka aktywowanej kabiny
|
||||
if (mvControlled->CabActive != 0) {
|
||||
btCabActived.Turn(true);
|
||||
@@ -7358,6 +7624,11 @@ bool TTrain::Update( double const Deltatime )
|
||||
btCabActived.Turn(false);
|
||||
}
|
||||
|
||||
if (mvControlled->Battery && mvControlled->CabActive != 0)
|
||||
btAKLVents.Turn(true);
|
||||
else
|
||||
btAKLVents.Turn(false);
|
||||
|
||||
if( true == lowvoltagepower ) {
|
||||
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
|
||||
if( mvOccupied->SecuritySystem.is_vigilance_blinking() ) {
|
||||
@@ -7893,6 +8164,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggBrakeProfileG.Update();
|
||||
ggBrakeProfileR.Update();
|
||||
ggBrakeOperationModeCtrl.Update();
|
||||
ggWiperSw.Update();
|
||||
ggMaxCurrentCtrl.UpdateValue(
|
||||
( true == mvControlled->ShuntModeAllow ?
|
||||
( true == mvControlled->ShuntMode ?
|
||||
@@ -7989,12 +8261,16 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggPantCompressorButton.Update();
|
||||
ggPantCompressorValve.Update();
|
||||
|
||||
ggPantValvesOff.Update();
|
||||
ggPantValvesUpdate.Update();
|
||||
|
||||
ggLightsButton.Update();
|
||||
ggUpperLightButton.Update();
|
||||
ggLeftLightButton.Update();
|
||||
ggRightLightButton.Update();
|
||||
ggLeftEndLightButton.Update();
|
||||
ggRightEndLightButton.Update();
|
||||
ggModernLightDimSw.Update();
|
||||
// hunter-230112
|
||||
ggRearUpperLightButton.Update();
|
||||
ggRearLeftLightButton.Update();
|
||||
@@ -8002,6 +8278,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggRearLeftEndLightButton.Update();
|
||||
ggRearRightEndLightButton.Update();
|
||||
ggDimHeadlightsButton.Update();
|
||||
ggDimHeadlightsButton.Update();
|
||||
//------------
|
||||
ggConverterButton.Update();
|
||||
ggConverterLocalButton.Update();
|
||||
@@ -9367,6 +9644,7 @@ void TTrain::clear_cab_controls()
|
||||
ggBrakeProfileG.Clear();
|
||||
ggBrakeProfileR.Clear();
|
||||
ggBrakeOperationModeCtrl.Clear();
|
||||
ggWiperSw.Clear();
|
||||
ggMaxCurrentCtrl.Clear();
|
||||
ggMainOffButton.Clear();
|
||||
ggMainOnButton.Clear();
|
||||
@@ -9469,6 +9747,10 @@ void TTrain::clear_cab_controls()
|
||||
ggPantValvesButton.Clear();
|
||||
ggPantCompressorButton.Clear();
|
||||
ggPantCompressorValve.Clear();
|
||||
|
||||
ggPantValvesOff.Clear();
|
||||
ggPantValvesUpdate.Clear();
|
||||
|
||||
ggI1B.Clear();
|
||||
ggI2B.Clear();
|
||||
ggI3B.Clear();
|
||||
@@ -9580,6 +9862,7 @@ void TTrain::clear_cab_controls()
|
||||
ggRightLightButton.Clear();
|
||||
ggUpperLightButton.Clear();
|
||||
ggDimHeadlightsButton.Clear();
|
||||
ggModernLightDimSw.Clear();
|
||||
ggLeftEndLightButton.Clear();
|
||||
ggRightEndLightButton.Clear();
|
||||
ggLightsButton.Clear();
|
||||
@@ -9611,6 +9894,24 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
m_linebreakerstate > 0 ? 1.f :
|
||||
0.f ) );
|
||||
}
|
||||
|
||||
if (ggModernLightDimSw.SubModel != nullptr) {
|
||||
if (mvOccupied->modernContainOffPos)
|
||||
ggModernLightDimSw.PutValue(mvOccupied->modernDimmerState);
|
||||
else
|
||||
ggModernLightDimSw.PutValue(mvOccupied->modernDimmerState - 1);
|
||||
}
|
||||
|
||||
// Init separate buttons
|
||||
if (ggPantValvesUpdate.SubModel != nullptr)
|
||||
{
|
||||
ggPantValvesUpdate.PutValue(0.f);
|
||||
}
|
||||
if (ggPantValvesOff.SubModel != nullptr)
|
||||
{
|
||||
ggPantValvesOff.PutValue(0.f);
|
||||
}
|
||||
|
||||
// motor connectors
|
||||
ggStLinOffButton.PutValue(
|
||||
( mvControlled->StLinSwitchOff ?
|
||||
@@ -9669,6 +9970,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
0.f ) );
|
||||
}
|
||||
ggPantValvesButton.PutValue( 0.5f );
|
||||
|
||||
// auxiliary compressor
|
||||
ggPantCompressorValve.PutValue(
|
||||
mvControlled->bPantKurek3 ?
|
||||
@@ -9738,7 +10040,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
ggRightLightButton.PutValue( -1.f );
|
||||
}
|
||||
}
|
||||
if( true == DynamicObject->DimHeadlights ) {
|
||||
if( 1 == DynamicObject->MoverParameters->modernDimmerState ) {
|
||||
ggDimHeadlightsButton.PutValue( 1.f );
|
||||
}
|
||||
// cab lights
|
||||
@@ -9812,6 +10114,12 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
1.f :
|
||||
0.f );
|
||||
}
|
||||
|
||||
if (ggWiperSw.SubModel != nullptr)
|
||||
{
|
||||
ggWiperSw.PutValue(mvOccupied->wiperSwitchPos);
|
||||
}
|
||||
|
||||
if (ggBrakeOperationModeCtrl.SubModel != nullptr) {
|
||||
ggBrakeOperationModeCtrl.PutValue(
|
||||
(mvOccupied->BrakeOpModeFlag > 0 ?
|
||||
@@ -10051,7 +10359,9 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
{ "i-universal8:", btUniversals[ 8 ] },
|
||||
{ "i-universal9:", btUniversals[ 9 ] },
|
||||
{ "i-cabactived:", btCabActived },
|
||||
{"i-compressorany:", btCompressors }
|
||||
{"i-aklvents:", btAKLVents},
|
||||
{"i-compressorany:", btCompressors },
|
||||
{"i-edenabled", btEDenabled },
|
||||
};
|
||||
{
|
||||
auto lookup = lights.find( Label );
|
||||
@@ -10172,6 +10482,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "leftend_sw:", ggLeftEndLightButton },
|
||||
{ "rightend_sw:", ggRightEndLightButton },
|
||||
{ "lights_sw:", ggLightsButton },
|
||||
{ "moderndimmer_sw:", ggModernLightDimSw },
|
||||
{ "rearupperlight_sw:", ggRearUpperLightButton },
|
||||
{ "rearleftlight_sw:", ggRearLeftLightButton },
|
||||
{ "rearrightlight_sw:", ggRearRightLightButton },
|
||||
@@ -10282,6 +10593,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "invertertoggle10_bt:", ggInverterToggleButtons[9] },
|
||||
{ "invertertoggle11_bt:", ggInverterToggleButtons[10] },
|
||||
{ "invertertoggle12_bt:", ggInverterToggleButtons[11] },
|
||||
{"pantvalvesupdate_bt:", ggPantValvesUpdate},
|
||||
{"pantvalvesoff_bt:", ggPantValvesOff},
|
||||
{"wipers_sw:", ggWiperSw}
|
||||
};
|
||||
{
|
||||
auto const lookup { gauges.find( Label ) };
|
||||
|
||||
18
Train.h
18
Train.h
@@ -226,6 +226,8 @@ class TTrain {
|
||||
// command handlers
|
||||
// NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis
|
||||
// TBD, TODO: consider this approach if we ever want to have customized consist behaviour to received commands, based on the consist/vehicle type or whatever
|
||||
static void OnCommand_wiperswitchincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_wiperswitchdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_aidriverdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_jointcontrollerset( TTrain *Train, command_data const &Command );
|
||||
@@ -399,6 +401,8 @@ class TTrain {
|
||||
static void OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenablerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisablerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_modernlightdimmerincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_modernlightdimmerdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_redmarkertogglerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisablerearleft( TTrain *Train, command_data const &Command );
|
||||
@@ -542,6 +546,8 @@ public: // reszta może by?publiczna
|
||||
TGauge ggBrakeProfileR; // nastawiacz PR - hamowanie dwustopniowe
|
||||
TGauge ggBrakeOperationModeCtrl; //przełącznik trybu pracy PS/PN/EP/MED
|
||||
|
||||
TGauge ggWiperSw; // przelacznik wycieraczek
|
||||
|
||||
TGauge ggMaxCurrentCtrl;
|
||||
|
||||
TGauge ggMainOffButton;
|
||||
@@ -578,6 +584,7 @@ public: // reszta może by?publiczna
|
||||
TGauge ggRightEndLightButton;
|
||||
TGauge ggLightsButton; // przelacznik reflektorow (wszystkich)
|
||||
TGauge ggDimHeadlightsButton; // headlights dimming switch
|
||||
TGauge ggModernLightDimSw; // modern lights dimmer
|
||||
|
||||
// hunter-230112: przelacznik swiatel tylnich
|
||||
TGauge ggRearUpperLightButton;
|
||||
@@ -658,6 +665,8 @@ public: // reszta może by?publiczna
|
||||
TGauge ggPantValvesButton;
|
||||
TGauge ggPantCompressorButton;
|
||||
TGauge ggPantCompressorValve;
|
||||
TGauge ggPantValvesUpdate;
|
||||
TGauge ggPantValvesOff;
|
||||
// Winger 020304 - wlacznik ogrzewania
|
||||
TGauge ggTrainHeatingButton;
|
||||
TGauge ggSignallingButton;
|
||||
@@ -769,8 +778,10 @@ public: // reszta może by?publiczna
|
||||
TButton btLampkaRearRightLight;
|
||||
TButton btLampkaRearLeftEndLight;
|
||||
TButton btLampkaRearRightEndLight;
|
||||
TButton btCabActived;
|
||||
TButton btCompressors; // lampka pracy jakiejkolwiek sprezarki
|
||||
TButton btCabActived;
|
||||
TButton btAKLVents;
|
||||
TButton btCompressors; // lampka pracy jakiejkolwiek sprezarki
|
||||
TButton btEDenabled; // czy wlaczony jest hamulec ED (czy dostepny)
|
||||
// other
|
||||
TButton btLampkaMalfunction;
|
||||
TButton btLampkaMalfunctionB;
|
||||
@@ -833,6 +844,8 @@ private:
|
||||
float fHaslerTimer;
|
||||
float fConverterTimer; // hunter-261211: dla przekaznika
|
||||
float fMainRelayTimer; // hunter-141211: zalaczanie WSa z opoznieniem
|
||||
float fBatteryTimer = {-1.f}; // Hirek: zalaczanie baterii z opoznieniem (tylko gdy zdefiniowano takie zachowanie w fiz)
|
||||
bool allowBatteryToggle = true; // Hirek: zabezpieczenie przed przelaczaniem bateri on/off
|
||||
int ScreenUpdateRate { 0 }; // vehicle specific python screen update rate override
|
||||
|
||||
// McZapkie-240302 - przyda sie do tachometru
|
||||
@@ -875,6 +888,7 @@ private:
|
||||
bool m_dirbackward{ false }; // helper, true if direction set to backward
|
||||
bool m_doorpermits{ false }; // helper, true if any door permit is active
|
||||
float m_doorpermittimers[2] = { -1.f, -1.f };
|
||||
float trainLenghtMeasureTimer = { -1.f };
|
||||
// ld substitute
|
||||
bool m_couplingdisconnect { false };
|
||||
bool m_couplingdisconnectback { false };
|
||||
|
||||
@@ -29,6 +29,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Timer.h"
|
||||
#include "dictionary.h"
|
||||
#include "version_info.h"
|
||||
#include "ref/discord-rpc/include/discord_rpc.h"
|
||||
#include <chrono>
|
||||
#include "translation.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma comment (lib, "dsound.lib")
|
||||
@@ -174,6 +177,83 @@ int eu07_application::run_crashgui()
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
void eu07_application::DiscordRPCService()
|
||||
{
|
||||
// initialize discord-rpc
|
||||
WriteLog("Initializing Discord Rich Presence...");
|
||||
static const char *discord_app_id = "1343662664504840222";
|
||||
DiscordEventHandlers handlers;
|
||||
memset(&handlers, 0, sizeof(handlers));
|
||||
Discord_Initialize(discord_app_id, &handlers, 1, nullptr);
|
||||
|
||||
std::string rpcScnName = Global.SceneryFile;
|
||||
if (rpcScnName[0] == '$')
|
||||
rpcScnName.erase(0, 1);
|
||||
rpcScnName.erase(rpcScnName.size() - 4, 4);
|
||||
if (rpcScnName.find('_') != std::string::npos)
|
||||
{
|
||||
std::replace(rpcScnName.begin(), rpcScnName.end(), '_', ' ');
|
||||
}
|
||||
|
||||
// calculate startup timestamp
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto now_c = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
// Init RPC object
|
||||
static DiscordRichPresence discord_rpc;
|
||||
memset(&discord_rpc, 0, sizeof(discord_rpc));
|
||||
// realworld timestamp from datetime
|
||||
discord_rpc.startTimestamp = static_cast<int64_t>(now_c);
|
||||
static std::string state = Translations.lookup_s("Scenery: ") + rpcScnName;
|
||||
discord_rpc.state = state.c_str();
|
||||
discord_rpc.details = Translations.lookup_c("Loading scenery...");
|
||||
discord_rpc.largeImageKey = "logo";
|
||||
discord_rpc.largeImageText = "MaSzyna";
|
||||
|
||||
// First RPC upload
|
||||
Discord_UpdatePresence(&discord_rpc);
|
||||
|
||||
// run loop
|
||||
while (!glfwWindowShouldClose(m_windows.front()) && !m_modestack.empty())
|
||||
{
|
||||
// Discord RPC updater
|
||||
if (simulation::is_ready)
|
||||
{
|
||||
std::string PlayerVehicle;
|
||||
if (simulation::Train != nullptr)
|
||||
{
|
||||
PlayerVehicle = simulation::Train->name();
|
||||
// make to upper
|
||||
for (auto &c : PlayerVehicle)
|
||||
c = toupper(c);
|
||||
|
||||
PlayerVehicle = Translations.lookup_s("Driving: ") + PlayerVehicle;
|
||||
discord_rpc.details = PlayerVehicle.c_str();
|
||||
|
||||
uint16_t playerTrainVelocity = simulation::Train->Dynamic()->GetVelocity();
|
||||
if (playerTrainVelocity > 1)
|
||||
{
|
||||
// ikonka ze jedziemy i nie spimy
|
||||
discord_rpc.smallImageKey = "driving";
|
||||
std::string smallText = Translations.lookup_s("Speed: ") + std::to_string(playerTrainVelocity) + " km/h";
|
||||
discord_rpc.smallImageText = smallText.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
// krecimy postoj
|
||||
discord_rpc.smallImageKey = "halt";
|
||||
discord_rpc.smallImageText = Translations.lookup_c("Stopped");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Discord_UpdatePresence(&discord_rpc);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // update RPC every 5 secs
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eu07_application::init( int Argc, char *Argv[] ) {
|
||||
@@ -186,6 +266,10 @@ eu07_application::init( int Argc, char *Argv[] ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// start logging service
|
||||
std::thread sLoggingService(LogService);
|
||||
Global.threads.emplace("LogService", std::move(sLoggingService));
|
||||
|
||||
WriteLog( "Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" );
|
||||
WriteLog( "For online documentation and additional files refer to: http://eu07.pl" );
|
||||
WriteLog( "Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
||||
@@ -239,9 +323,15 @@ eu07_application::init( int Argc, char *Argv[] ) {
|
||||
if (!init_network())
|
||||
return -1;
|
||||
|
||||
// Run DiscordRPC service
|
||||
std::thread sDiscordRPC(&eu07_application::DiscordRPCService, this);
|
||||
Global.threads.emplace("DiscordRPC", std::move(sDiscordRPC));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double eu07_application::generate_sync() {
|
||||
if (Timer::GetDeltaTime() == 0.0)
|
||||
return 0.0;
|
||||
@@ -433,7 +523,8 @@ eu07_application::run() {
|
||||
std::this_thread::sleep_for( Global.minframetime - frametime );
|
||||
}
|
||||
}
|
||||
|
||||
Global.threads["LogService"].~thread(); // kill log service
|
||||
Global.threads["DiscordRPC"].~thread(); // kill DiscordRPC service
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ public:
|
||||
int
|
||||
run();
|
||||
// issues request for a worker thread to perform specified task. returns: true if task was scheduled
|
||||
|
||||
void eu07_application::DiscordRPCService(); // discord rich presence service function (runs as separate thread)
|
||||
bool
|
||||
request( python_taskqueue::task_request const &Task );
|
||||
// ensures the main thread holds the python gil and can safely execute python calls
|
||||
|
||||
@@ -3,10 +3,10 @@ image: Visual Studio 2017
|
||||
clone_depth: 1
|
||||
build_script:
|
||||
- ps: >-
|
||||
git submodule update --init --recursive
|
||||
|
||||
cd ref
|
||||
|
||||
git clone "https://github.com/chriskohlhoff/asio" --depth 1 --branch asio-1-16-1 -q
|
||||
|
||||
|
||||
curl -o crashpad86.zip "http://get.backtrace.io/crashpad/builds/release/x86/crashpad-2020-07-01-release-x86-558c9614e3819179f30b92541450f5ac643afce5.zip"
|
||||
|
||||
7z x crashpad86.zip
|
||||
|
||||
1061
command.cpp
1061
command.cpp
File diff suppressed because it is too large
Load Diff
551
command.h
551
command.h
@@ -13,273 +13,279 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include <queue>
|
||||
#include <unordered_set>
|
||||
|
||||
enum class user_command {
|
||||
enum class user_command
|
||||
{
|
||||
|
||||
aidriverenable = 0,
|
||||
aidriverdisable,
|
||||
jointcontrollerset,
|
||||
mastercontrollerincrease,
|
||||
mastercontrollerincreasefast,
|
||||
mastercontrollerdecrease,
|
||||
mastercontrollerdecreasefast,
|
||||
mastercontrollerset,
|
||||
secondcontrollerincrease,
|
||||
secondcontrollerincreasefast,
|
||||
secondcontrollerdecrease,
|
||||
secondcontrollerdecreasefast,
|
||||
secondcontrollerset,
|
||||
mucurrentindicatorothersourceactivate,
|
||||
independentbrakeincrease,
|
||||
independentbrakeincreasefast,
|
||||
independentbrakedecrease,
|
||||
independentbrakedecreasefast,
|
||||
independentbrakeset,
|
||||
independentbrakebailoff,
|
||||
aidriverdisable,
|
||||
jointcontrollerset,
|
||||
mastercontrollerincrease,
|
||||
mastercontrollerincreasefast,
|
||||
mastercontrollerdecrease,
|
||||
mastercontrollerdecreasefast,
|
||||
mastercontrollerset,
|
||||
secondcontrollerincrease,
|
||||
secondcontrollerincreasefast,
|
||||
secondcontrollerdecrease,
|
||||
secondcontrollerdecreasefast,
|
||||
secondcontrollerset,
|
||||
mucurrentindicatorothersourceactivate,
|
||||
independentbrakeincrease,
|
||||
independentbrakeincreasefast,
|
||||
independentbrakedecrease,
|
||||
independentbrakedecreasefast,
|
||||
independentbrakeset,
|
||||
independentbrakebailoff,
|
||||
universalbrakebutton1,
|
||||
universalbrakebutton2,
|
||||
universalbrakebutton3,
|
||||
trainbrakeincrease,
|
||||
trainbrakedecrease,
|
||||
trainbrakeset,
|
||||
trainbrakecharging,
|
||||
trainbrakerelease,
|
||||
trainbrakefirstservice,
|
||||
trainbrakeservice,
|
||||
trainbrakefullservice,
|
||||
trainbrakehandleoff,
|
||||
trainbrakeemergency,
|
||||
trainbrakebasepressureincrease,
|
||||
trainbrakebasepressuredecrease,
|
||||
trainbrakebasepressurereset,
|
||||
trainbrakeoperationtoggle,
|
||||
manualbrakeincrease,
|
||||
manualbrakedecrease,
|
||||
alarmchaintoggle,
|
||||
trainbrakeincrease,
|
||||
trainbrakedecrease,
|
||||
trainbrakeset,
|
||||
trainbrakecharging,
|
||||
trainbrakerelease,
|
||||
trainbrakefirstservice,
|
||||
trainbrakeservice,
|
||||
trainbrakefullservice,
|
||||
trainbrakehandleoff,
|
||||
trainbrakeemergency,
|
||||
trainbrakebasepressureincrease,
|
||||
trainbrakebasepressuredecrease,
|
||||
trainbrakebasepressurereset,
|
||||
trainbrakeoperationtoggle,
|
||||
manualbrakeincrease,
|
||||
manualbrakedecrease,
|
||||
alarmchaintoggle,
|
||||
alarmchainenable,
|
||||
alarmchaindisable,
|
||||
wheelspinbrakeactivate,
|
||||
sandboxactivate,
|
||||
wheelspinbrakeactivate,
|
||||
sandboxactivate,
|
||||
autosandboxtoggle,
|
||||
autosandboxactivate,
|
||||
autosandboxdeactivate,
|
||||
reverserincrease,
|
||||
reverserdecrease,
|
||||
reverserforwardhigh,
|
||||
reverserforward,
|
||||
reverserneutral,
|
||||
reverserbackward,
|
||||
waterpumpbreakertoggle,
|
||||
waterpumpbreakerclose,
|
||||
waterpumpbreakeropen,
|
||||
waterpumptoggle,
|
||||
waterpumpenable,
|
||||
waterpumpdisable,
|
||||
waterheaterbreakertoggle,
|
||||
waterheaterbreakerclose,
|
||||
waterheaterbreakeropen,
|
||||
waterheatertoggle,
|
||||
waterheaterenable,
|
||||
waterheaterdisable,
|
||||
watercircuitslinktoggle,
|
||||
watercircuitslinkenable,
|
||||
watercircuitslinkdisable,
|
||||
fuelpumptoggle,
|
||||
fuelpumpenable,
|
||||
fuelpumpdisable,
|
||||
oilpumptoggle,
|
||||
oilpumpenable,
|
||||
oilpumpdisable,
|
||||
linebreakertoggle,
|
||||
linebreakeropen,
|
||||
linebreakerclose,
|
||||
convertertoggle,
|
||||
converterenable,
|
||||
converterdisable,
|
||||
convertertogglelocal,
|
||||
converteroverloadrelayreset,
|
||||
compressortoggle,
|
||||
compressorenable,
|
||||
compressordisable,
|
||||
compressortogglelocal,
|
||||
reverserincrease,
|
||||
reverserdecrease,
|
||||
reverserforwardhigh,
|
||||
reverserforward,
|
||||
reverserneutral,
|
||||
reverserbackward,
|
||||
waterpumpbreakertoggle,
|
||||
waterpumpbreakerclose,
|
||||
waterpumpbreakeropen,
|
||||
waterpumptoggle,
|
||||
waterpumpenable,
|
||||
waterpumpdisable,
|
||||
waterheaterbreakertoggle,
|
||||
waterheaterbreakerclose,
|
||||
waterheaterbreakeropen,
|
||||
waterheatertoggle,
|
||||
waterheaterenable,
|
||||
waterheaterdisable,
|
||||
watercircuitslinktoggle,
|
||||
watercircuitslinkenable,
|
||||
watercircuitslinkdisable,
|
||||
fuelpumptoggle,
|
||||
fuelpumpenable,
|
||||
fuelpumpdisable,
|
||||
oilpumptoggle,
|
||||
oilpumpenable,
|
||||
oilpumpdisable,
|
||||
linebreakertoggle,
|
||||
linebreakeropen,
|
||||
linebreakerclose,
|
||||
convertertoggle,
|
||||
converterenable,
|
||||
converterdisable,
|
||||
convertertogglelocal,
|
||||
converteroverloadrelayreset,
|
||||
compressortoggle,
|
||||
compressorenable,
|
||||
compressordisable,
|
||||
compressortogglelocal,
|
||||
compressorpresetactivatenext,
|
||||
compressorpresetactivateprevious,
|
||||
compressorpresetactivatedefault,
|
||||
motoroverloadrelaythresholdtoggle,
|
||||
motoroverloadrelaythresholdsetlow,
|
||||
motoroverloadrelaythresholdsethigh,
|
||||
motoroverloadrelayreset,
|
||||
universalrelayreset1,
|
||||
universalrelayreset2,
|
||||
universalrelayreset3,
|
||||
notchingrelaytoggle,
|
||||
epbrakecontroltoggle,
|
||||
motoroverloadrelaythresholdtoggle,
|
||||
motoroverloadrelaythresholdsetlow,
|
||||
motoroverloadrelaythresholdsethigh,
|
||||
motoroverloadrelayreset,
|
||||
universalrelayreset1,
|
||||
universalrelayreset2,
|
||||
universalrelayreset3,
|
||||
notchingrelaytoggle,
|
||||
epbrakecontroltoggle,
|
||||
epbrakecontrolenable,
|
||||
epbrakecontroldisable,
|
||||
trainbrakeoperationmodeincrease,
|
||||
trainbrakeoperationmodedecrease,
|
||||
brakeactingspeedincrease,
|
||||
brakeactingspeeddecrease,
|
||||
brakeactingspeedsetcargo,
|
||||
brakeactingspeedsetpassenger,
|
||||
brakeactingspeedsetrapid,
|
||||
brakeloadcompensationincrease,
|
||||
brakeloadcompensationdecrease,
|
||||
mubrakingindicatortoggle,
|
||||
alerteracknowledge,
|
||||
brakeactingspeedincrease,
|
||||
brakeactingspeeddecrease,
|
||||
brakeactingspeedsetcargo,
|
||||
brakeactingspeedsetpassenger,
|
||||
brakeactingspeedsetrapid,
|
||||
brakeloadcompensationincrease,
|
||||
brakeloadcompensationdecrease,
|
||||
mubrakingindicatortoggle,
|
||||
alerteracknowledge,
|
||||
cabsignalacknowledge,
|
||||
hornlowactivate,
|
||||
hornhighactivate,
|
||||
whistleactivate,
|
||||
radiotoggle,
|
||||
radioenable,
|
||||
radiodisable,
|
||||
radiochannelincrease,
|
||||
radiochanneldecrease,
|
||||
radiochannelset,
|
||||
radiostopsend,
|
||||
radiostopenable,
|
||||
radiostopdisable,
|
||||
radiostoptest,
|
||||
radiocall3send,
|
||||
hornlowactivate,
|
||||
hornhighactivate,
|
||||
whistleactivate,
|
||||
radiotoggle,
|
||||
radioenable,
|
||||
radiodisable,
|
||||
radiochannelincrease,
|
||||
radiochanneldecrease,
|
||||
radiochannelset,
|
||||
radiostopsend,
|
||||
radiostopenable,
|
||||
radiostopdisable,
|
||||
radiostoptest,
|
||||
radiocall3send,
|
||||
radiovolumeincrease,
|
||||
radiovolumedecrease,
|
||||
radiovolumeset,
|
||||
cabchangeforward,
|
||||
cabchangebackward,
|
||||
cabchangeforward,
|
||||
cabchangebackward,
|
||||
|
||||
viewturn,
|
||||
movehorizontal,
|
||||
movehorizontalfast,
|
||||
movevertical,
|
||||
moveverticalfast,
|
||||
moveleft,
|
||||
moveright,
|
||||
moveforward,
|
||||
moveback,
|
||||
moveup,
|
||||
movedown,
|
||||
modernlightdimmerdecrease,
|
||||
modernlightdimmerincrease,
|
||||
|
||||
nearestcarcouplingincrease,
|
||||
nearestcarcouplingdisconnect,
|
||||
nearestcarcoupleradapterattach,
|
||||
nearestcarcoupleradapterremove,
|
||||
occupiedcarcouplingdisconnect,
|
||||
viewturn,
|
||||
movehorizontal,
|
||||
movehorizontalfast,
|
||||
movevertical,
|
||||
moveverticalfast,
|
||||
moveleft,
|
||||
moveright,
|
||||
moveforward,
|
||||
moveback,
|
||||
moveup,
|
||||
movedown,
|
||||
|
||||
nearestcarcouplingincrease,
|
||||
nearestcarcouplingdisconnect,
|
||||
nearestcarcoupleradapterattach,
|
||||
nearestcarcoupleradapterremove,
|
||||
occupiedcarcouplingdisconnect,
|
||||
occupiedcarcouplingdisconnectback,
|
||||
doortoggleleft,
|
||||
doortoggleright,
|
||||
doorpermitleft,
|
||||
doorpermitright,
|
||||
doorpermitpresetactivatenext,
|
||||
doorpermitpresetactivateprevious,
|
||||
dooropenleft,
|
||||
dooropenright,
|
||||
dooropenall,
|
||||
doorcloseleft,
|
||||
doorcloseright,
|
||||
doorcloseall,
|
||||
doorsteptoggle,
|
||||
doormodetoggle,
|
||||
doortoggleleft,
|
||||
doortoggleright,
|
||||
doorpermitleft,
|
||||
doorpermitright,
|
||||
doorpermitpresetactivatenext,
|
||||
doorpermitpresetactivateprevious,
|
||||
dooropenleft,
|
||||
dooropenright,
|
||||
dooropenall,
|
||||
doorcloseleft,
|
||||
doorcloseright,
|
||||
doorcloseall,
|
||||
doorsteptoggle,
|
||||
doormodetoggle,
|
||||
mirrorstoggle,
|
||||
departureannounce,
|
||||
doorlocktoggle,
|
||||
pantographcompressorvalvetoggle,
|
||||
pantographcompressorvalveenable,
|
||||
pantographcompressorvalvedisable,
|
||||
pantographcompressoractivate,
|
||||
pantographtogglefront,
|
||||
pantographtogglerear,
|
||||
pantographraisefront,
|
||||
pantographraiserear,
|
||||
pantographlowerfront,
|
||||
pantographlowerrear,
|
||||
pantographlowerall,
|
||||
pantographselectnext,
|
||||
pantographselectprevious,
|
||||
pantographtoggleselected,
|
||||
pantographraiseselected,
|
||||
pantographlowerselected,
|
||||
pantographvalvesupdate,
|
||||
pantographvalvesoff,
|
||||
heatingtoggle,
|
||||
heatingenable,
|
||||
heatingdisable,
|
||||
lightspresetactivatenext,
|
||||
lightspresetactivateprevious,
|
||||
headlighttoggleleft,
|
||||
headlightenableleft,
|
||||
headlightdisableleft,
|
||||
headlighttoggleright,
|
||||
headlightenableright,
|
||||
headlightdisableright,
|
||||
headlighttoggleupper,
|
||||
headlightenableupper,
|
||||
headlightdisableupper,
|
||||
redmarkertoggleleft,
|
||||
redmarkerenableleft,
|
||||
redmarkerdisableleft,
|
||||
redmarkertoggleright,
|
||||
redmarkerenableright,
|
||||
redmarkerdisableright,
|
||||
headlighttogglerearleft,
|
||||
headlightenablerearleft,
|
||||
headlightdisablerearleft,
|
||||
headlighttogglerearright,
|
||||
headlightenablerearright,
|
||||
headlightdisablerearright,
|
||||
headlighttogglerearupper,
|
||||
headlightenablerearupper,
|
||||
headlightdisablerearupper,
|
||||
redmarkertogglerearleft,
|
||||
redmarkerenablerearleft,
|
||||
redmarkerdisablerearleft,
|
||||
redmarkertogglerearright,
|
||||
redmarkerenablerearright,
|
||||
redmarkerdisablerearright,
|
||||
redmarkerstoggle,
|
||||
endsignalstoggle,
|
||||
headlightsdimtoggle,
|
||||
headlightsdimenable,
|
||||
headlightsdimdisable,
|
||||
motorconnectorsopen,
|
||||
motorconnectorsclose,
|
||||
motordisconnect,
|
||||
interiorlighttoggle,
|
||||
interiorlightenable,
|
||||
interiorlightdisable,
|
||||
interiorlightdimtoggle,
|
||||
interiorlightdimenable,
|
||||
interiorlightdimdisable,
|
||||
compartmentlightstoggle,
|
||||
compartmentlightsenable,
|
||||
compartmentlightsdisable,
|
||||
instrumentlighttoggle,
|
||||
instrumentlightenable,
|
||||
instrumentlightdisable,
|
||||
dashboardlighttoggle,
|
||||
dashboardlightenable,
|
||||
dashboardlightdisable,
|
||||
timetablelighttoggle,
|
||||
timetablelightenable,
|
||||
timetablelightdisable,
|
||||
generictoggle0,
|
||||
generictoggle1,
|
||||
generictoggle2,
|
||||
generictoggle3,
|
||||
generictoggle4,
|
||||
generictoggle5,
|
||||
generictoggle6,
|
||||
generictoggle7,
|
||||
generictoggle8,
|
||||
generictoggle9,
|
||||
batterytoggle,
|
||||
batteryenable,
|
||||
batterydisable,
|
||||
departureannounce,
|
||||
doorlocktoggle,
|
||||
pantographcompressorvalvetoggle,
|
||||
pantographcompressorvalveenable,
|
||||
pantographcompressorvalvedisable,
|
||||
pantographcompressoractivate,
|
||||
pantographtogglefront,
|
||||
pantographtogglerear,
|
||||
pantographraisefront,
|
||||
pantographraiserear,
|
||||
pantographlowerfront,
|
||||
pantographlowerrear,
|
||||
pantographlowerall,
|
||||
pantographselectnext,
|
||||
pantographselectprevious,
|
||||
pantographtoggleselected,
|
||||
pantographraiseselected,
|
||||
pantographlowerselected,
|
||||
pantographvalvesupdate,
|
||||
pantographvalvesoff,
|
||||
heatingtoggle,
|
||||
heatingenable,
|
||||
heatingdisable,
|
||||
lightspresetactivatenext,
|
||||
lightspresetactivateprevious,
|
||||
headlighttoggleleft,
|
||||
headlightenableleft,
|
||||
headlightdisableleft,
|
||||
headlighttoggleright,
|
||||
headlightenableright,
|
||||
headlightdisableright,
|
||||
headlighttoggleupper,
|
||||
headlightenableupper,
|
||||
headlightdisableupper,
|
||||
redmarkertoggleleft,
|
||||
redmarkerenableleft,
|
||||
redmarkerdisableleft,
|
||||
redmarkertoggleright,
|
||||
redmarkerenableright,
|
||||
redmarkerdisableright,
|
||||
headlighttogglerearleft,
|
||||
headlightenablerearleft,
|
||||
headlightdisablerearleft,
|
||||
headlighttogglerearright,
|
||||
headlightenablerearright,
|
||||
headlightdisablerearright,
|
||||
headlighttogglerearupper,
|
||||
headlightenablerearupper,
|
||||
headlightdisablerearupper,
|
||||
redmarkertogglerearleft,
|
||||
redmarkerenablerearleft,
|
||||
redmarkerdisablerearleft,
|
||||
redmarkertogglerearright,
|
||||
redmarkerenablerearright,
|
||||
redmarkerdisablerearright,
|
||||
redmarkerstoggle,
|
||||
endsignalstoggle,
|
||||
headlightsdimtoggle,
|
||||
headlightsdimenable,
|
||||
headlightsdimdisable,
|
||||
motorconnectorsopen,
|
||||
motorconnectorsclose,
|
||||
motordisconnect,
|
||||
interiorlighttoggle,
|
||||
interiorlightenable,
|
||||
interiorlightdisable,
|
||||
interiorlightdimtoggle,
|
||||
interiorlightdimenable,
|
||||
interiorlightdimdisable,
|
||||
compartmentlightstoggle,
|
||||
compartmentlightsenable,
|
||||
compartmentlightsdisable,
|
||||
instrumentlighttoggle,
|
||||
instrumentlightenable,
|
||||
instrumentlightdisable,
|
||||
dashboardlighttoggle,
|
||||
dashboardlightenable,
|
||||
dashboardlightdisable,
|
||||
timetablelighttoggle,
|
||||
timetablelightenable,
|
||||
timetablelightdisable,
|
||||
generictoggle0,
|
||||
generictoggle1,
|
||||
generictoggle2,
|
||||
generictoggle3,
|
||||
generictoggle4,
|
||||
generictoggle5,
|
||||
generictoggle6,
|
||||
generictoggle7,
|
||||
generictoggle8,
|
||||
generictoggle9,
|
||||
batterytoggle,
|
||||
batteryenable,
|
||||
batterydisable,
|
||||
cabactivationtoggle,
|
||||
cabactivationenable,
|
||||
cabactivationdisable,
|
||||
motorblowerstogglefront,
|
||||
motorblowerstogglerear,
|
||||
motorblowersdisableall,
|
||||
coolingfanstoggle,
|
||||
tempomattoggle,
|
||||
motorblowerstogglefront,
|
||||
motorblowerstogglerear,
|
||||
motorblowersdisableall,
|
||||
coolingfanstoggle,
|
||||
tempomattoggle,
|
||||
springbraketoggle,
|
||||
springbrakeenable,
|
||||
springbrakedisable,
|
||||
@@ -287,7 +293,7 @@ enum class user_command {
|
||||
springbrakeshutoffenable,
|
||||
springbrakeshutoffdisable,
|
||||
springbrakerelease,
|
||||
distancecounteractivate,
|
||||
distancecounteractivate,
|
||||
speedcontrolincrease,
|
||||
speedcontroldecrease,
|
||||
speedcontrolpowerincrease,
|
||||
@@ -338,36 +344,38 @@ enum class user_command {
|
||||
invertertoggle10,
|
||||
invertertoggle11,
|
||||
invertertoggle12,
|
||||
globalradiostop,
|
||||
timejump,
|
||||
timejumplarge,
|
||||
timejumpsmall,
|
||||
setdatetime,
|
||||
setweather,
|
||||
settemperature,
|
||||
vehiclemoveforwards,
|
||||
vehiclemovebackwards,
|
||||
vehicleboost,
|
||||
debugtoggle,
|
||||
focuspauseset,
|
||||
pausetoggle,
|
||||
entervehicle,
|
||||
resetconsist,
|
||||
fillcompressor,
|
||||
consistreleaser,
|
||||
queueevent,
|
||||
setlight,
|
||||
insertmodel,
|
||||
deletemodel,
|
||||
dynamicmove,
|
||||
consistteleport,
|
||||
pullalarmchain,
|
||||
sendaicommand,
|
||||
spawntrainset,
|
||||
destroytrainset,
|
||||
quitsimulation,
|
||||
globalradiostop,
|
||||
timejump,
|
||||
timejumplarge,
|
||||
timejumpsmall,
|
||||
setdatetime,
|
||||
setweather,
|
||||
settemperature,
|
||||
vehiclemoveforwards,
|
||||
vehiclemovebackwards,
|
||||
vehicleboost,
|
||||
debugtoggle,
|
||||
focuspauseset,
|
||||
pausetoggle,
|
||||
entervehicle,
|
||||
resetconsist,
|
||||
fillcompressor,
|
||||
consistreleaser,
|
||||
queueevent,
|
||||
setlight,
|
||||
insertmodel,
|
||||
deletemodel,
|
||||
dynamicmove,
|
||||
consistteleport,
|
||||
pullalarmchain,
|
||||
sendaicommand,
|
||||
spawntrainset,
|
||||
destroytrainset,
|
||||
quitsimulation,
|
||||
wiperswitchincrease,
|
||||
wiperswitchdecrease,
|
||||
|
||||
none = -1
|
||||
none = -1
|
||||
};
|
||||
|
||||
enum class command_target {
|
||||
@@ -481,6 +489,7 @@ extern command_queue Commands;
|
||||
// TODO: add name to command map, and wrap these two into helper object
|
||||
extern commanddescription_sequence Commands_descriptions;
|
||||
|
||||
extern std::unordered_map<std::string, user_command> commandMap;
|
||||
}
|
||||
|
||||
// command_relay: composite class component, passes specified command to appropriate command stack
|
||||
|
||||
@@ -506,7 +506,7 @@ drivermouse_input::bindings( std::string const &Control ) const {
|
||||
|
||||
void
|
||||
drivermouse_input::default_bindings() {
|
||||
|
||||
// pierwsza komenda jest od zwiekszania a druga od zmniejszania - ewentualnie kolejno lewy i prawy przycisk
|
||||
m_buttonbindings = {
|
||||
{ "jointctrl:", {
|
||||
user_command::jointcontrollerset,
|
||||
@@ -731,6 +731,9 @@ drivermouse_input::default_bindings() {
|
||||
{ "dimheadlights_sw:", {
|
||||
user_command::headlightsdimtoggle,
|
||||
user_command::none } },
|
||||
{"moderndimmer_sw:", {
|
||||
user_command::modernlightdimmerincrease,
|
||||
user_command::modernlightdimmerdecrease } },
|
||||
{ "leftend_sw:", {
|
||||
user_command::redmarkertoggleleft,
|
||||
user_command::none } },
|
||||
@@ -845,6 +848,12 @@ drivermouse_input::default_bindings() {
|
||||
{ "pantvalves_sw:", {
|
||||
user_command::pantographvalvesupdate,
|
||||
user_command::pantographvalvesoff } },
|
||||
{ "pantvalvesupdate_bt:", {
|
||||
user_command::pantographvalvesupdate,
|
||||
user_command::none}},
|
||||
{ "pantvalvesoff_bt:", {
|
||||
user_command::pantographvalvesoff,
|
||||
user_command::none}},
|
||||
{ "pantcompressor_sw:", {
|
||||
user_command::pantographcompressoractivate,
|
||||
user_command::none } },
|
||||
@@ -1100,6 +1109,10 @@ drivermouse_input::default_bindings() {
|
||||
{ "invertertoggle12_bt:",{
|
||||
user_command::invertertoggle12,
|
||||
user_command::none } },
|
||||
{ "wipers_sw:",{
|
||||
user_command::wiperswitchincrease,
|
||||
user_command::wiperswitchdecrease
|
||||
} },
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -617,8 +617,9 @@ debug_panel::render() {
|
||||
ImGui::Checkbox( "Debug Traction", &DebugTractionFlag );
|
||||
}
|
||||
render_section( "Camera", m_cameralines );
|
||||
render_section( "Gfx Renderer", m_rendererlines );
|
||||
render_section( "Gfx Renderer / Statistics", m_rendererlines );
|
||||
render_section_settings();
|
||||
render_section_developer(); // Developer tools
|
||||
#ifdef WITH_UART
|
||||
if(true == render_section( "UART", m_uartlines)) {
|
||||
int ports_num = UartStatus.available_ports.size();
|
||||
@@ -1452,6 +1453,14 @@ debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
|
||||
// renderer stats
|
||||
Output.emplace_back( GfxRenderer->info_times(), Global.UITextColor );
|
||||
Output.emplace_back( GfxRenderer->info_stats(), Global.UITextColor );
|
||||
|
||||
// CPU related
|
||||
Output.emplace_back("CPU:", Global.UITextColor);
|
||||
|
||||
// thread counter
|
||||
textline = "Running threads: " + std::to_string(Global.threads.size() + 1);
|
||||
Output.emplace_back(textline, Global.UITextColor);
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1475,6 +1484,19 @@ debug_panel::render_section( std::vector<text_line> const &Lines ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool debug_panel::render_section_developer()
|
||||
{
|
||||
if (false == ImGui::CollapsingHeader("Developer tools"))
|
||||
return false;
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, {Global.UITextColor.r, Global.UITextColor.g, Global.UITextColor.b, Global.UITextColor.a});
|
||||
ImGui::TextUnformatted("Warning! These tools are only for developers.\nDo not use them if you are NOT sure what they do!");
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "These settings may crash your simulator!");
|
||||
if (ImGui::Button("Reload current vehicle .fiz") == true)
|
||||
{
|
||||
m_input.vehicle->MoverParameters->reload_FIZ(); // reload fiz
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
debug_panel::render_section_settings() {
|
||||
|
||||
|
||||
@@ -104,7 +104,8 @@ private:
|
||||
bool render_section_uart();
|
||||
#endif
|
||||
bool render_section_settings();
|
||||
// members
|
||||
bool render_section_developer();
|
||||
// members
|
||||
std::array<char, 1024> m_buffer;
|
||||
std::array<char, 128> m_eventsearch;
|
||||
input_data m_input;
|
||||
|
||||
@@ -206,7 +206,7 @@ editor_mode::on_key( int const Key, int const Scancode, int const Action, int co
|
||||
|
||||
m_node = nullptr;
|
||||
m_dragging = false;
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
//Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
static_cast<editor_ui*>( m_userinterface.get() )->set_node(nullptr);
|
||||
|
||||
simulation::State.delete_model(model);
|
||||
@@ -318,10 +318,14 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
if( Action == GLFW_PRESS ) {
|
||||
// left button press
|
||||
auto const mode = static_cast<editor_ui*>( m_userinterface.get() )->mode();
|
||||
auto const rotation_mode = static_cast<editor_ui*>( m_userinterface.get() )->rot_mode();
|
||||
auto const fixed_rotation_value =
|
||||
static_cast<editor_ui *>(m_userinterface.get())->rot_val();
|
||||
|
||||
m_node = nullptr;
|
||||
|
||||
GfxRenderer->Pick_Node_Callback([this, mode,Action,Button](scene::basic_node *node) {
|
||||
GfxRenderer->Pick_Node_Callback([this, mode, rotation_mode, fixed_rotation_value,
|
||||
Action, Button](scene::basic_node *node) {
|
||||
editor_ui *ui = static_cast<editor_ui *>(m_userinterface.get());
|
||||
|
||||
if (mode == nodebank_panel::MODIFY) {
|
||||
@@ -329,10 +333,10 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
return;
|
||||
|
||||
m_node = node;
|
||||
if( m_node )
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
else
|
||||
m_dragging = false;
|
||||
//if( m_node )
|
||||
//Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
//else
|
||||
//m_dragging = false;
|
||||
ui->set_node(m_node);
|
||||
}
|
||||
else if (mode == nodebank_panel::COPY) {
|
||||
@@ -360,8 +364,24 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
if (!m_dragging)
|
||||
return;
|
||||
|
||||
m_node = cloned;
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
|
||||
m_node = cloned;
|
||||
|
||||
if (rotation_mode == functions_panel::RANDOM)
|
||||
{
|
||||
auto const rotation{glm::vec3{0, LocalRandom(0.0, 360.0), 0}};
|
||||
|
||||
m_editor.rotate(m_node, rotation, 1);
|
||||
}
|
||||
else if (rotation_mode == functions_panel::FIXED)
|
||||
{
|
||||
|
||||
auto const rotation{glm::vec3{0, fixed_rotation_value, 0}};
|
||||
|
||||
m_editor.rotate(m_node, rotation, 0);
|
||||
|
||||
}
|
||||
//Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
ui->set_node( m_node );
|
||||
}
|
||||
});
|
||||
@@ -370,8 +390,8 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
}
|
||||
else {
|
||||
// left button release
|
||||
if( m_node )
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
//if( m_node )
|
||||
//Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
m_dragging = false;
|
||||
// prime history stack for another snapshot
|
||||
m_takesnapshot = true;
|
||||
|
||||
@@ -21,6 +21,7 @@ editor_ui::editor_ui() {
|
||||
|
||||
add_external_panel( &m_itempropertiespanel );
|
||||
add_external_panel( &m_nodebankpanel );
|
||||
add_external_panel( &m_functionspanel );
|
||||
}
|
||||
|
||||
// updates state of UI elements
|
||||
@@ -41,6 +42,7 @@ editor_ui::update() {
|
||||
|
||||
ui_layer::update();
|
||||
m_itempropertiespanel.update( m_node );
|
||||
m_functionspanel.update( m_node );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -63,3 +65,17 @@ nodebank_panel::edit_mode
|
||||
editor_ui::mode() {
|
||||
return m_nodebankpanel.mode;
|
||||
}
|
||||
|
||||
functions_panel::rotation_mode
|
||||
editor_ui::rot_mode() {
|
||||
return m_functionspanel.rot_mode;
|
||||
}
|
||||
float
|
||||
editor_ui::rot_val() {
|
||||
return m_functionspanel.rot_value;
|
||||
}
|
||||
bool
|
||||
editor_ui::rot_from_last()
|
||||
{
|
||||
return m_functionspanel.rot_from_last;
|
||||
}
|
||||
@@ -31,6 +31,12 @@ public:
|
||||
set_node( scene::basic_node * Node );
|
||||
void
|
||||
add_node_template(const std::string &desc);
|
||||
float
|
||||
rot_val();
|
||||
bool
|
||||
rot_from_last();
|
||||
functions_panel::rotation_mode
|
||||
rot_mode();
|
||||
const std::string *
|
||||
get_active_node_template();
|
||||
nodebank_panel::edit_mode
|
||||
@@ -39,6 +45,7 @@ public:
|
||||
private:
|
||||
// members
|
||||
itemproperties_panel m_itempropertiespanel { "Node Properties", true };
|
||||
functions_panel m_functionspanel { "Functions", true };
|
||||
nodebank_panel m_nodebankpanel{ "Node Bank", true };
|
||||
scene::basic_node * m_node { nullptr }; // currently bound scene node, if any
|
||||
};
|
||||
|
||||
@@ -420,8 +420,6 @@ nodebank_panel::render() {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Insert from bank", (int*)&mode, ADD);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Brush", (int*)&mode, BRUSH);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton( "Copy to bank", (int*)&mode, COPY );
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Reload Nodebank"))
|
||||
@@ -493,3 +491,64 @@ nodebank_panel::generate_node_label( std::string Input ) const {
|
||||
model :
|
||||
model + " (" + texture + ")" );
|
||||
}
|
||||
|
||||
void functions_panel::update(scene::basic_node const *Node)
|
||||
{
|
||||
m_node = Node;
|
||||
|
||||
if (false == is_open)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
text_lines.clear();
|
||||
m_grouplines.clear();
|
||||
|
||||
std::string textline;
|
||||
|
||||
// scenario inspector
|
||||
auto const *node{Node};
|
||||
auto const &camera{Global.pCamera};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
functions_panel::render() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
auto flags =
|
||||
ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||
|
||||
if( size.x > 0 ) {
|
||||
ImGui::SetNextWindowSize( ImVec2S( size.x, size.y ) );
|
||||
}
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2S( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
m_name :
|
||||
title )
|
||||
+ "###" + m_name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), nullptr, flags ) ) {
|
||||
// header section
|
||||
|
||||
ImGui::RadioButton("Random rotation", (int *)&rot_mode, RANDOM);
|
||||
ImGui::RadioButton("Fixed rotation", (int *)&rot_mode, FIXED);
|
||||
if(rot_mode == FIXED){
|
||||
//ImGui::Checkbox("Get rotation from last object", &rot_from_last);
|
||||
ImGui::SliderFloat("Rotation Value", &rot_value, 0.0f, 360.0f, "%.1f");
|
||||
};
|
||||
ImGui::RadioButton("Default rotation", (int *)&rot_mode, DEFAULT);
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -73,3 +73,35 @@ private:
|
||||
char m_nodesearch[ 128 ];
|
||||
std::shared_ptr<std::string> m_selectedtemplate;
|
||||
};
|
||||
|
||||
class functions_panel : public ui_panel
|
||||
{
|
||||
|
||||
public:
|
||||
enum rotation_mode
|
||||
{
|
||||
RANDOM,
|
||||
FIXED,
|
||||
DEFAULT
|
||||
};
|
||||
rotation_mode rot_mode = DEFAULT;
|
||||
|
||||
float rot_value = 0.0f;
|
||||
bool rot_from_last = false;
|
||||
|
||||
functions_panel(std::string const &Name, bool const Isopen) : ui_panel(Name, Isopen) {}
|
||||
|
||||
void update(scene::basic_node const *Node);
|
||||
void render() override;
|
||||
|
||||
|
||||
private:
|
||||
// methods
|
||||
|
||||
|
||||
// members
|
||||
scene::basic_node const *m_node{nullptr}; // scene node bound to the panel
|
||||
scene::group_handle m_grouphandle{null_handle}; // scene group bound to the panel
|
||||
std::string m_groupprefix;
|
||||
std::vector<text_line> m_grouplines;
|
||||
};
|
||||
@@ -65,17 +65,42 @@ light_array::update() {
|
||||
light.count = 0
|
||||
+ ( ( lights & light::headlight_left ) ? 1 : 0 )
|
||||
+ ( ( lights & light::headlight_right ) ? 1 : 0 )
|
||||
+ ( ( lights & light::headlight_upper ) ? 1 : 0 );
|
||||
+ ( ( lights & light::headlight_upper ) ? 1 : 0 )
|
||||
+ ( ( lights & light::highbeamlight_left ) ? 1: 0)
|
||||
+ ( ( lights & light::highbeamlight_right ) ? 1 : 0);
|
||||
|
||||
if( light.count > 0 ) {
|
||||
light.intensity = std::max( 0.0f, std::log( (float)light.count + 1.0f ) );
|
||||
light.intensity *= ( light.owner->DimHeadlights ? 0.6f : 1.0f );
|
||||
light.intensity = std::max(0.0f, std::log((float)light.count + 1.0f));
|
||||
if (light.owner->DimHeadlights && !light.owner->HighBeamLights) // tylko przyciemnione
|
||||
light.intensity *= light.owner->MoverParameters->dimMultiplier;
|
||||
else if (!light.owner->DimHeadlights && !light.owner->HighBeamLights) // normalne
|
||||
light.intensity *= light.owner->MoverParameters->normMultiplier;
|
||||
else if (light.owner->DimHeadlights && light.owner->HighBeamLights) // przyciemnione dlugie
|
||||
light.intensity *= light.owner->MoverParameters->highDimMultiplier;
|
||||
else if (!light.owner->DimHeadlights && light.owner->HighBeamLights) // dlugie zwykle
|
||||
light.intensity *= light.owner->MoverParameters->highMultiplier;
|
||||
|
||||
// TBD, TODO: intensity can be affected further by other factors
|
||||
light.state = {
|
||||
( ( lights & light::headlight_left ) ? 1.f : 0.f ),
|
||||
( ( lights & light::headlight_upper ) ? 1.f : 0.f ),
|
||||
( ( lights & light::headlight_right ) ? 1.f : 0.f ) };
|
||||
light.state *= ( light.owner->DimHeadlights ? 0.6f : 1.0f );
|
||||
( ( lights & light::headlight_left | light::highbeamlight_left ) ? 1.f : 0.f ),
|
||||
( ( lights & light::headlight_upper ) ? 1.f : 0.f ),
|
||||
( ( lights & light::headlight_right | light::highbeamlight_right) ? 1.f : 0.f ) };
|
||||
|
||||
light.color = {
|
||||
static_cast<float>(light.owner->MoverParameters->refR) / 255.0f,
|
||||
static_cast<float>(light.owner->MoverParameters->refG) / 255.0f,
|
||||
static_cast<float>(light.owner->MoverParameters->refB) / 255.0f
|
||||
};
|
||||
|
||||
if (light.owner->DimHeadlights && !light.owner->HighBeamLights) // tylko przyciemnione
|
||||
light.state *= light.owner->MoverParameters->dimMultiplier;
|
||||
else if (!light.owner->DimHeadlights && !light.owner->HighBeamLights)
|
||||
light.state *= light.owner->MoverParameters->normMultiplier;
|
||||
else if (light.owner->DimHeadlights && light.owner->HighBeamLights) // przyciemnione dlugie
|
||||
light.state *= light.owner->MoverParameters->highDimMultiplier;
|
||||
else if (!light.owner->DimHeadlights && light.owner->HighBeamLights) // dlugie zwykle
|
||||
light.state *= light.owner->MoverParameters->highMultiplier;
|
||||
|
||||
}
|
||||
else {
|
||||
light.intensity = 0.0f;
|
||||
|
||||
1
ref/discord-rpc
Submodule
1
ref/discord-rpc
Submodule
Submodule ref/discord-rpc added at 963aa9f3e5
@@ -47,8 +47,7 @@ operator!=( lighting_data const &Left, lighting_data const &Right ) {
|
||||
namespace scene {
|
||||
|
||||
struct bounding_area {
|
||||
|
||||
glm::dvec3 center; // mid point of the rectangle
|
||||
glm::highp_dvec3 center; // mid point of the rectangle
|
||||
float radius { -1.0f }; // radius of the bounding sphere
|
||||
|
||||
bounding_area() = default;
|
||||
@@ -94,7 +93,7 @@ public:
|
||||
material_handle material { null_handle };
|
||||
lighting_data lighting;
|
||||
// geometry data
|
||||
glm::dvec3 origin; // world position of the relative coordinate system origin
|
||||
glm::highp_dvec3 origin; // world position of the relative coordinate system origin
|
||||
gfx::geometry_handle geometry { 0, 0 }; // relative origin-centered chunk of geometry held by gfx renderer
|
||||
std::vector<world_vertex> vertices; // world space source data of the geometry
|
||||
// methods:
|
||||
|
||||
2
thread_list.txt
Normal file
2
thread_list.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
- DiscordRPC - Thread for refreshing discord rich presence
|
||||
- LogService - Service that logs data to files and console
|
||||
@@ -249,6 +249,7 @@ std::string locale::label_cab_control(std::string const &Label)
|
||||
{ "leftlight_sw:", STRN("left headlight") },
|
||||
{ "rightlight_sw:", STRN("right headlight") },
|
||||
{ "dimheadlights_sw:", STRN("headlights dimmer") },
|
||||
{ "moderndimmer_sw:", STRN("headlights dimmer") },
|
||||
{ "leftend_sw:", STRN("left marker light") },
|
||||
{ "rightend_sw:", STRN("right marker light") },
|
||||
{ "lights_sw:", STRN("light pattern") },
|
||||
@@ -282,6 +283,8 @@ std::string locale::label_cab_control(std::string const &Label)
|
||||
{ "pantselectedoff_sw:", STRN("selected pantograph") },
|
||||
{ "pantselect_sw:", STRN("selected pantograph") },
|
||||
{ "pantvalves_sw:", STRN("selected pantograph") },
|
||||
{ "pantvalvesoff_bt:", STRN("all pantographs down") },
|
||||
{ "pantvalvesupdate_bt:", STRN("selected pantographs up") },
|
||||
{ "pantcompressor_sw:", STRN("pantograph compressor") },
|
||||
{ "pantcompressorvalve_sw:", STRN("pantograph 3 way valve") },
|
||||
{ "trainheating_sw:", STRN("heating") },
|
||||
@@ -319,7 +322,8 @@ std::string locale::label_cab_control(std::string const &Label)
|
||||
{ "universal6:", STRN("interactive part") },
|
||||
{ "universal7:", STRN("interactive part") },
|
||||
{ "universal8:", STRN("interactive part") },
|
||||
{ "universal9:", STRN("interactive part") }
|
||||
{ "universal9:", STRN("interactive part") },
|
||||
{ "wipers_sw:", STRN("wipers mode selector") },
|
||||
};
|
||||
|
||||
auto const it = cabcontrols_labels.find( Label );
|
||||
|
||||
@@ -335,6 +335,14 @@ interpolate( Type_ const &First, Type_ const &Second, double const Factor ) {
|
||||
return static_cast<Type_>( ( First * ( 1.0 - Factor ) ) + ( Second * Factor ) );
|
||||
}
|
||||
|
||||
template <typename Type_> Type_ smoothInterpolate(Type_ const &First, Type_ const &Second, double Factor)
|
||||
{
|
||||
// Apply smoothing (ease-in-out quadratic)
|
||||
Factor = Factor * Factor * (3 - 2 * Factor);
|
||||
|
||||
return static_cast<Type_>((First * (1.0 - Factor)) + (Second * Factor));
|
||||
}
|
||||
|
||||
// tests whether provided points form a degenerate triangle
|
||||
template <typename VecType_>
|
||||
bool
|
||||
|
||||
Reference in New Issue
Block a user