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

build 170911. right mouse view panning during mouse picking in external view, signal distance calculation fix, AI car braking improvements, cab camera position retains position between view swaps, physics calculations mode switch, consist brake status report in whois event

This commit is contained in:
tmj-fstate
2017-09-12 04:30:51 +02:00
parent 24221163cc
commit d75c9ff14d
19 changed files with 300 additions and 218 deletions

View File

@@ -25,17 +25,13 @@ void TCamera::Init(vector3 NPos, vector3 NAngle)
{ {
vUp = vector3(0, 1, 0); vUp = vector3(0, 1, 0);
// pOffset= vector3(-0.8,0,0);
CrossDist = 10;
Velocity = vector3(0, 0, 0); Velocity = vector3(0, 0, 0);
Pitch = NAngle.x; Pitch = NAngle.x;
Yaw = NAngle.y; Yaw = NAngle.y;
Roll = NAngle.z; Roll = NAngle.z;
Pos = NPos; Pos = NPos;
// Type= tp_Follow;
Type = (Global::bFreeFly ? tp_Free : tp_Follow); Type = (Global::bFreeFly ? tp_Free : tp_Follow);
// Type= tp_Free;
}; };
void TCamera::OnCursorMove(double x, double y) void TCamera::OnCursorMove(double x, double y)

View File

@@ -46,13 +46,10 @@ class TCamera
vector3 LookAt; // współrzędne punktu, na który ma patrzeć vector3 LookAt; // współrzędne punktu, na który ma patrzeć
vector3 vUp; vector3 vUp;
vector3 Velocity; vector3 Velocity;
vector3 CrossPos;
double CrossDist;
void Init(vector3 NPos, vector3 NAngle); void Init(vector3 NPos, vector3 NAngle);
void Reset() inline
{ void Reset() {
Pitch = Yaw = Roll = 0; Pitch = Yaw = Roll = 0; };
};
void OnCursorMove(double const x, double const y); void OnCursorMove(double const x, double const y);
void OnCommand( command_data const &Command ); void OnCommand( command_data const &Command );
void Update(); void Update();

View File

@@ -64,12 +64,12 @@ double GetDistanceToEvent(TTrack const *track, TEvent const *event, double scan_
seg_len += scan_dir > 0 ? dzielnik : -dzielnik; seg_len += scan_dir > 0 ? dzielnik : -dzielnik;
len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared(); len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared();
++krok; ++krok;
} while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1 - dzielnik)))); } while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1.0 - dzielnik))));
//trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy //trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy
// trzeba sprawdzić tor obok // trzeba sprawdzić tor obok
if (1 == krok) if (1 == krok)
sd = -sd; // jeśli tylko jeden krok tzn, że event przy poprzednim sprawdzaym torze sd = -sd; // jeśli tylko jeden krok tzn, że event przy poprzednim sprawdzaym torze
if (((seg_len <= dzielnik) || (seg_len > (1 - dzielnik))) && (iter < 3)) if (((1 == krok) || (seg_len <= dzielnik) || (seg_len > (1.0 - dzielnik))) && (iter < 3))
{ // przejście na inny tor { // przejście na inny tor
track = track->Connected(int(sd), sd); track = track->Connected(int(sd), sd);
start_dist += (1 == krok) ? 0 : back ? -segment->GetLength() : segment->GetLength(); start_dist += (1 == krok) ? 0 : back ? -segment->GetLength() : segment->GetLength();
@@ -3919,6 +3919,13 @@ TController::UpdateSituation(double dt) {
fStopTime = 0.0; // nie ma na co czekać z odczepianiem fStopTime = 0.0; // nie ma na co czekać z odczepianiem
} }
} }
else {
if( mvOccupied->Vel > 0.0 ) {
// 1st phase(?)
// bring it to stop if it's not already stopped
SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie
}
}
} // odczepiania } // odczepiania
else // to poniżej jeśli ilość wagonów ujemna else // to poniżej jeśli ilość wagonów ujemna
if (iDrivigFlags & movePress) if (iDrivigFlags & movePress)
@@ -3985,8 +3992,8 @@ TController::UpdateSituation(double dt) {
} }
else { else {
// samochod (sokista też) // samochod (sokista też)
fMinProximityDist = std::max( 4.0, mvOccupied->Vel * 0.2 ); fMinProximityDist = std::max( 3.0, mvOccupied->Vel * 0.2 );
fMaxProximityDist = std::max( 8.0, mvOccupied->Vel * 0.375 ); //[m] fMaxProximityDist = std::max( 9.0, mvOccupied->Vel * 0.375 ); //[m]
// margines prędkości powodujący załączenie napędu // margines prędkości powodujący załączenie napędu
fVelMinus = 2.0; fVelMinus = 2.0;
// dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
@@ -4259,12 +4266,17 @@ TController::UpdateSituation(double dt) {
&& ( coupler->CouplingFlag == coupling::faux ) ) { && ( coupler->CouplingFlag == coupling::faux ) ) {
// mamy coś z przodu podłączone sprzęgiem wirtualnym // mamy coś z przodu podłączone sprzęgiem wirtualnym
// wyliczanie optymalnego przyspieszenia do jazdy na widoczność // wyliczanie optymalnego przyspieszenia do jazdy na widoczność
/*
ActualProximityDist = std::min( ActualProximityDist = std::min(
ActualProximityDist, ActualProximityDist,
vehicle->fTrackBlock - ( vehicle->fTrackBlock - (
mvOccupied->CategoryFlag & 2 ? mvOccupied->CategoryFlag & 2 ?
fMinProximityDist : // cars can bunch up tighter fMinProximityDist : // cars can bunch up tighter
fMaxProximityDist ) ); // other vehicle types less so fMaxProximityDist ) ); // other vehicle types less so
*/
ActualProximityDist = std::min(
ActualProximityDist,
vehicle->fTrackBlock );
double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając, double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając,
// że jedzie w tę samą stronę!!!) // że jedzie w tę samą stronę!!!)
if( k < vel + 10 ) { if( k < vel + 10 ) {
@@ -4323,36 +4335,47 @@ TController::UpdateSituation(double dt) {
} }
// sprawdzamy możliwe ograniczenia prędkości // sprawdzamy możliwe ograniczenia prędkości
if (OrderCurrentGet() & (Shunt | Obey_train)) // w Connect nie, bo moveStopHere if( OrderCurrentGet() & ( Shunt | Obey_train ) ) {
// odnosi się do stanu po połączeniu // w Connect nie, bo moveStopHere odnosi się do stanu po połączeniu
if (iDrivigFlags & moveStopHere) // jeśli ma czekać na wolną drogę if( ( iDrivigFlags & moveStopHere )
if (vel == 0.0) // a stoi && ( vel == 0.0 )
if (VelNext == 0.0) // a wyjazdu nie ma && ( VelNext == 0.0 ) ) {
VelDesired = 0.0; // to ma stać // jeśli ma czekać na wolną drogę, stoi a wyjazdu nie ma, to ma stać
if (fStopTime < 0) // czas postoju przed dalszą jazdą (np. na przystanku) VelDesired = 0.0;
}
}
if( fStopTime < 0 ) {
// czas postoju przed dalszą jazdą (np. na przystanku)
VelDesired = 0.0; // jak ma czekać, to nie ma jazdy VelDesired = 0.0; // jak ma czekać, to nie ma jazdy
// else if (VelSignal<0) }
// VelDesired=fVelMax; //ile fabryka dala (Ra: uwzględione wagony) else if( VelSignal >= 0 ) {
else if (VelSignal >= 0) // jeśli skład był zatrzymany na początku i teraz już może jechać // jeśli skład był zatrzymany na początku i teraz już może jechać
VelDesired = Global::Min0RSpeed(VelDesired, VelSignal);
if (mvOccupied->RunningTrack.Velmax >=
0) // ograniczenie prędkości z trajektorii ruchu
VelDesired = VelDesired =
Global::Min0RSpeed(VelDesired, Global::Min0RSpeed(
mvOccupied->RunningTrack.Velmax); // uwaga na ograniczenia szlakowej! VelDesired,
if (VelforDriver >= 0) // tu jest zero przy zmianie kierunku jazdy VelSignal );
VelDesired = Global::Min0RSpeed(VelDesired, VelforDriver); // Ra: tu może być 40, jeśli }
// mechanik nie ma znajomości if( mvOccupied->RunningTrack.Velmax >= 0 ) {
// szlaaku, albo kierowca jeździ // ograniczenie prędkości z trajektorii ruchu
// 70 VelDesired =
if (TrainParams) Global::Min0RSpeed(
if (TrainParams->CheckTrainLatency() < 5.0) VelDesired,
if (TrainParams->TTVmax > 0.0) mvOccupied->RunningTrack.Velmax ); // uwaga na ograniczenia szlakowej!
VelDesired = Global::Min0RSpeed( }
VelDesired, if( VelforDriver >= 0 ) {
TrainParams // tu jest zero przy zmianie kierunku jazdy
->TTVmax); // jesli nie spozniony to nie przekraczać rozkladowej // Ra: tu może być 40, jeśli mechanik nie ma znajomości szlaaku, albo kierowca jeździ 70
VelDesired = Global::Min0RSpeed( VelDesired, VelforDriver );
}
if( ( TrainParams != nullptr )
&& ( TrainParams->CheckTrainLatency() < 5.0 )
&& ( TrainParams->TTVmax > 0.0 ) ) {
// jesli nie spozniony to nie przekraczać rozkladowej
VelDesired =
Global::Min0RSpeed(
VelDesired,
TrainParams->TTVmax );
}
if (VelDesired > 0.0) if (VelDesired > 0.0)
if( ( ( iDrivigFlags & moveStopHere ) == 0 ) if( ( ( iDrivigFlags & moveStopHere ) == 0 )
|| ( ( SemNextIndex != -1 ) || ( ( SemNextIndex != -1 )
@@ -4448,10 +4471,16 @@ TController::UpdateSituation(double dt) {
VelDesired = Global::Min0RSpeed( VelDesired, VelNext ); VelDesired = Global::Min0RSpeed( VelDesired, VelNext );
*/ */
if( VelNext == 0.0 ) { if( VelNext == 0.0 ) {
// hamowanie tak, aby stanąć if( mvOccupied->CategoryFlag & 1 ) {
VelDesired = VelNext; // hamowanie tak, aby stanąć
AccDesired = ( VelNext * VelNext - vel * vel ) / ( 25.92 * ( ActualProximityDist + 0.1 - 0.5*fMinProximityDist ) ); VelDesired = VelNext;
AccDesired = std::min( AccDesired, fAccThreshold ); AccDesired = ( VelNext * VelNext - vel * vel ) / ( 25.92 * ( ActualProximityDist + 0.1 - 0.5*fMinProximityDist ) );
AccDesired = std::min( AccDesired, fAccThreshold );
}
else {
// for cars (and others) coast at low speed until we hit min proximity range
VelDesired = Global::Min0RSpeed( VelDesired, 5.0 );
}
} }
} }
else { else {

View File

@@ -212,13 +212,12 @@ private: // parametry aktualnego składu
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca
public:
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
private:
double fReady = 0.0; // poziom odhamowania wagonów double fReady = 0.0; // poziom odhamowania wagonów
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
private:
double LastUpdatedTime = 0.0; // czas od ostatniego logu double LastUpdatedTime = 0.0; // czas od ostatniego logu
double ElapsedTime = 0.0; // czas od poczatku logu double ElapsedTime = 0.0; // czas od poczatku logu
double deltalog = 0.05; // przyrost czasu double deltalog = 0.05; // przyrost czasu
@@ -227,26 +226,21 @@ private: // parametry aktualnego składu
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
TAction eAction = actSleep; // aktualny stan TAction eAction = actSleep; // aktualny stan
public: public:
inline TAction GetAction() inline
{ TAction GetAction() {
return eAction; return eAction; }
}
bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista
int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala
// migacz lub czeka na stan zwrotnicy // migacz lub czeka na stan zwrotnicy
private: private:
TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący
TDynamicObject TDynamicObject *pVehicles[2]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
*pVehicles[2]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT) TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT)
TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje
TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty
// int TrainNumber; //numer rozkladowy tego pociagu
// AnsiString OrderCommand; //komenda pobierana z pojazdu
// double OrderValue; //argument komendy
int iRadioChannel = 1; // numer aktualnego kanału radiowego int iRadioChannel = 1; // numer aktualnego kanału radiowego
TTextSound *tsGuardSignal = nullptr; // komunikat od kierownika
int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia)
TTextSound *tsGuardSignal = nullptr; // komunikat od kierownika
public: public:
double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji) double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji)
double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj) double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj)

View File

@@ -1331,15 +1331,7 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance )
// pojazdu // pojazdu
// ScanDir=1 - od strony Coupler0, ScanDir=-1 - od strony Coupler1 // ScanDir=1 - od strony Coupler0, ScanDir=-1 - od strony Coupler1
auto const initialdirection = Direction; // zapamiętanie kierunku poszukiwań na torze początkowym, względem sprzęgów auto const initialdirection = Direction; // zapamiętanie kierunku poszukiwań na torze początkowym, względem sprzęgów
/*
TTrackFollower const *firstaxle = (initialdirection > 0 ? &Axle0 : &Axle1); // można by to trzymać w trainset
TTrack const *track = firstaxle->GetTrack(); // tor na którym "stoi" skrajny wózek
// (może być inny niż tor pojazdu)
if( firstaxle->GetDirection() < 0 ) {
// czy oś jest ustawiona w stronę Point1?
Direction = -Direction; // jeśli tak, to kierunek szukania będzie przeciwny
}
*/
TTrack const *track = RaTrackGet(); TTrack const *track = RaTrackGet();
if( RaDirectionGet() < 0 ) { if( RaDirectionGet() < 0 ) {
// czy oś jest ustawiona w stronę Point1? // czy oś jest ustawiona w stronę Point1?
@@ -1458,18 +1450,18 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance )
} }
} }
// odległość do najbliższego pojazdu w linii prostej // NOTE: the distance we get is approximated as it's measured between active axles, not vehicle ends
// Ra: jeśli dwa samochody się mijają na odcinku przed zawrotką, to odległość między nimi nie może być liczona w linii prostej! fTrackBlock = distance;
fTrackBlock = MoverParameters->Couplers[mycoupler].CoupleDist; if( distance < 100.0 ) {
if( track->iCategoryFlag & 254 ) { // at short distances start to calculate range between couplers directly
// jeśli samochód // odległość do najbliższego pojazdu w linii prostej
if( distance > MoverParameters->Dim.L + foundobject->MoverParameters->Dim.L ) { fTrackBlock = std::min( fTrackBlock, MoverParameters->Couplers[ mycoupler ].CoupleDist );
// przeskanowana odległość większa od długości pojazdów }
// else if (ActDist<ScanDist) //dla samochodów musi być uwzględniona if( ( false == TestFlag( track->iCategoryFlag, 1 ) )
// droga do && ( distance > 50.0 ) ) {
// zawrócenia // Ra: jeśli dwa samochody się mijają na odcinku przed zawrotką, to odległość między nimi nie może być liczona w linii prostej!
fTrackBlock = distance; // ta odległość jest wiecej warta // NOTE: the distance is approximated, and additionally less accurate for cars heading in opposite direction
} fTrackBlock = distance - ( 0.5 * ( MoverParameters->Dim.L + foundobject->MoverParameters->Dim.L ) );
} }
} }
else { else {

View File

@@ -136,6 +136,7 @@ double Global::fFpsAverage = 20.0; // oczekiwana wartosć FPS
double Global::fFpsDeviation = 5.0; // odchylenie standardowe FPS double Global::fFpsDeviation = 5.0; // odchylenie standardowe FPS
double Global::fFpsMin = 30.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany double Global::fFpsMin = 30.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scenerii będzie zwiększany double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scenerii będzie zwiększany
bool Global::FullPhysics { true }; // full calculations performed for each simulation step
// parametry testowe (do testowania scenerii i obiektów) // parametry testowe (do testowania scenerii i obiektów)
bool Global::bWireFrame = false; bool Global::bWireFrame = false;
@@ -308,11 +309,11 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens(); Parser.getTokens();
Parser >> WriteLogFlag; Parser >> WriteLogFlag;
} }
else if (token == "physicsdeactivation") else if (token == "fullphysics")
{ // McZapkie-291103 - usypianie fizyki { // McZapkie-291103 - usypianie fizyki
Parser.getTokens(); Parser.getTokens();
Parser >> PhysicActivationFlag; Parser >> Global::FullPhysics;
} }
else if (token == "debuglog") else if (token == "debuglog")
{ {

View File

@@ -214,15 +214,22 @@ class Global
float depth; float depth;
float distance; float distance;
} shadowtune; } shadowtune;
static bool bUseVBO; // czy jest VBO w karcie graficznej
static float AnisotropicFiltering; // requested level of anisotropic filtering. TODO: move it to renderer object
static int ScreenWidth; // current window dimensions. TODO: move it to renderer
static int ScreenHeight;
static float ZoomFactor; // determines current camera zoom level. TODO: move it to the renderer
static float FieldOfView; // vertical field of view for the camera. TODO: move it to the renderer
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
static bool FullPhysics; // full calculations performed for each simulation step
static int iSlowMotion; static int iSlowMotion;
static TDynamicObject *changeDynObj; static TDynamicObject *changeDynObj;
static double ABuDebug; static double ABuDebug;
static std::string asSky; static std::string asSky;
static bool bnewAirCouplers; static bool bnewAirCouplers;
// Ra: nowe zmienne globalne // Ra: nowe zmienne globalne
static float AnisotropicFiltering; // requested level of anisotropic filtering. TODO: move it to renderer object
static bool bUseVBO; // czy jest VBO w karcie graficznej
static std::string LastGLError; static std::string LastGLError;
static int iFeedbackMode; // tryb pracy informacji zwrotnej static int iFeedbackMode; // tryb pracy informacji zwrotnej
static int iFeedbackPort; // dodatkowy adres dla informacji zwrotnych static int iFeedbackPort; // dodatkowy adres dla informacji zwrotnych
@@ -233,13 +240,8 @@ class Global
static GLFWwindow *window; static GLFWwindow *window;
static bool shiftState; //m7todo: brzydko static bool shiftState; //m7todo: brzydko
static bool ctrlState; static bool ctrlState;
static int ScreenWidth; // current window dimensions. TODO: move it to renderer
static int ScreenHeight;
static float ZoomFactor; // determines current camera zoom level. TODO: move it to the renderer
static float FieldOfView; // vertical field of view for the camera. TODO: move it to the renderer
static int iCameraLast; static int iCameraLast;
static std::string asVersion; // z opisem static std::string asVersion; // z opisem
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
static bool ControlPicking; // indicates controls pick mode is active static bool ControlPicking; // indicates controls pick mode is active
static bool InputMouse; // whether control pick mode can be activated static bool InputMouse; // whether control pick mode can be activated
static int iTextMode; // tryb pracy wyświetlacza tekstowego static int iTextMode; // tryb pracy wyświetlacza tekstowego
@@ -254,7 +256,6 @@ class Global
static double fLatitudeDeg; // szerokość geograficzna static double fLatitudeDeg; // szerokość geograficzna
static std::string szTexturesTGA; // lista tekstur od TGA static std::string szTexturesTGA; // lista tekstur od TGA
static std::string szTexturesDDS; // lista tekstur od DDS static std::string szTexturesDDS; // lista tekstur od DDS
static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
static bool DLFont; // switch indicating presence of basic font static bool DLFont; // switch indicating presence of basic font
static bool bGlutFont; // tekst generowany przez GLUT static bool bGlutFont; // tekst generowany przez GLUT
static int iPause; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie static int iPause; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie

View File

@@ -1870,7 +1870,7 @@ bool TGround::Init(std::string File)
} }
else else
{ {
ErrorLog("Scene parsing error in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() ) + "), unexpected token \"" + token + "\""); ErrorLog("Bad node: node parsing error, encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")");
// break; // break;
} }
} }
@@ -3386,46 +3386,76 @@ bool TGround::CheckQuery()
} }
} }
break; break;
case tp_WhoIs: // pobranie nazwy pociągu do komórki pamięci case tp_WhoIs: {
if (tmpEvent->iFlags & update_load) // pobranie nazwy pociągu do komórki pamięci
{ // jeśli pytanie o ładunek if (tmpEvent->iFlags & update_load) {
if (tmpEvent->iFlags & update_memadd) // jeśli typ pojazdu // jeśli pytanie o ładunek
if( tmpEvent->iFlags & update_memadd ) {
// jeśli typ pojazdu
// TODO: define and recognize individual request types
auto const owner = (
( ( tmpEvent->Activator->Mechanik != nullptr ) && ( tmpEvent->Activator->Mechanik->Primary() ) ) ?
tmpEvent->Activator->Mechanik :
tmpEvent->Activator->ctOwner );
auto const consistbrakelevel = (
owner != nullptr ?
owner->fReady :
-1.0 );
tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Params[ 9 ].asMemCell->UpdateValues(
tmpEvent->Activator->MoverParameters->TypeName, // typ pojazdu tmpEvent->Activator->MoverParameters->TypeName, // typ pojazdu
consistbrakelevel,
0, // na razie nic 0, // na razie nic
0, // na razie nic tmpEvent->iFlags & ( update_memstring | update_memval1 | update_memval2 ) );
tmpEvent->iFlags &
(update_memstring | update_memval1 | update_memval2)); WriteLog(
else // jeśli parametry ładunku "whois request (" + to_string( tmpEvent->iFlags ) + ") "
+ "[name: " + tmpEvent->Activator->MoverParameters->TypeName + "], "
+ "[consist brake level: " + to_string( consistbrakelevel, 2 ) + "], "
+ "[]" );
}
else {
// jeśli parametry ładunku
tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Params[ 9 ].asMemCell->UpdateValues(
tmpEvent->Activator->MoverParameters->LoadType, // nazwa ładunku tmpEvent->Activator->MoverParameters->LoadType, // nazwa ładunku
tmpEvent->Activator->MoverParameters->Load, // aktualna ilość tmpEvent->Activator->MoverParameters->Load, // aktualna ilość
tmpEvent->Activator->MoverParameters->MaxLoad, // maksymalna ilość tmpEvent->Activator->MoverParameters->MaxLoad, // maksymalna ilość
tmpEvent->iFlags & tmpEvent->iFlags & ( update_memstring | update_memval1 | update_memval2 ) );
(update_memstring | update_memval1 | update_memval2));
WriteLog(
"whois request (" + to_string( tmpEvent->iFlags ) + ") "
+ "[load type: " + tmpEvent->Activator->MoverParameters->LoadType + "], "
+ "[current load: " + to_string( tmpEvent->Activator->MoverParameters->Load, 2 ) + "], "
+ "[max load: " + to_string( tmpEvent->Activator->MoverParameters->MaxLoad, 2 ) + "]" );
}
} }
else if (tmpEvent->iFlags & update_memadd) else if (tmpEvent->iFlags & update_memadd)
{ // jeśli miejsce docelowe pojazdu { // jeśli miejsce docelowe pojazdu
tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Params[ 9 ].asMemCell->UpdateValues(
tmpEvent->Activator->asDestination, // adres docelowy tmpEvent->Activator->asDestination, // adres docelowy
tmpEvent->Activator->DirectionGet(), // kierunek pojazdu względem czoła składu (1=zgodny,-1=przeciwny) tmpEvent->Activator->DirectionGet(), // kierunek pojazdu względem czoła składu (1=zgodny,-1=przeciwny)
tmpEvent->Activator->MoverParameters ->Power, // moc pojazdu silnikowego: 0 dla wagonu tmpEvent->Activator->MoverParameters->Power, // moc pojazdu silnikowego: 0 dla wagonu
tmpEvent->iFlags & (update_memstring | update_memval1 | update_memval2)); tmpEvent->iFlags & (update_memstring | update_memval1 | update_memval2));
WriteLog(
"whois request (" + to_string( tmpEvent->iFlags ) + ") "
+ "[destination: " + tmpEvent->Activator->asDestination + "], "
+ "[direction: " + to_string( tmpEvent->Activator->DirectionGet() ) + "], "
+ "[engine power: " + to_string( tmpEvent->Activator->MoverParameters->Power, 2 ) + "]" );
} }
else if (tmpEvent->Activator->Mechanik) else if (tmpEvent->Activator->Mechanik)
if (tmpEvent->Activator->Mechanik->Primary()) if (tmpEvent->Activator->Mechanik->Primary())
{ // tylko jeśli ktoś tam siedzi - nie powinno dotyczyć pasażera! { // tylko jeśli ktoś tam siedzi - nie powinno dotyczyć pasażera!
tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Params[ 9 ].asMemCell->UpdateValues(
tmpEvent->Activator->Mechanik->TrainName(), tmpEvent->Activator->Mechanik->TrainName(),
tmpEvent->Activator->Mechanik->StationCount() - tmpEvent->Activator->Mechanik->StationCount() - tmpEvent->Activator->Mechanik->StationIndex(), // ile przystanków do końca
tmpEvent->Activator->Mechanik
->StationIndex(), // ile przystanków do końca
tmpEvent->Activator->Mechanik->IsStop() ? 1 : tmpEvent->Activator->Mechanik->IsStop() ? 1 :
0, // 1, gdy ma tu zatrzymanie 0, // 1, gdy ma tu zatrzymanie
tmpEvent->iFlags); tmpEvent->iFlags);
WriteLog("Train detected: " + tmpEvent->Activator->Mechanik->TrainName()); WriteLog("Train detected: " + tmpEvent->Activator->Mechanik->TrainName());
} }
break; break;
}
case tp_LogValues: // zapisanie zawartości komórki pamięci do logu case tp_LogValues: // zapisanie zawartości komórki pamięci do logu
if (tmpEvent->Params[9].asMemCell) // jeśli była podana nazwa komórki if (tmpEvent->Params[9].asMemCell) // jeśli była podana nazwa komórki
WriteLog("Memcell \"" + tmpEvent->asNodeName + "\": " + WriteLog("Memcell \"" + tmpEvent->asNodeName + "\": " +

View File

@@ -191,8 +191,6 @@ static int const sound_relay = 16;
static int const sound_manyrelay = 32; static int const sound_manyrelay = 32;
static int const sound_brakeacc = 64; static int const sound_brakeacc = 64;
static bool PhysicActivationFlag = false;
//szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType //szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType
//zamienione na flagi bitowe, aby szybko wybierać grupę (np. EZT+SZT) //zamienione na flagi bitowe, aby szybko wybierać grupę (np. EZT+SZT)
static int const dt_Default = 0; static int const dt_Default = 0;

View File

@@ -3791,9 +3791,6 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
// McZapkie-031103: sprawdzanie czy warto liczyc fizyke i inne updaty // McZapkie-031103: sprawdzanie czy warto liczyc fizyke i inne updaty
// ABu 300105: cos tu mieszalem , dziala teraz troche lepiej, wiec zostawiam // ABu 300105: cos tu mieszalem , dziala teraz troche lepiej, wiec zostawiam
// zakomentowalem PhysicActivationFlag bo cos nie dzialalo i fizyka byla liczona zawsze.
// if (PhysicActivationFlag)
//{
if ((CabNo == 0) && (Vel < 0.0001) && (abs(AccS) < 0.0001) && (TrainType != dt_EZT)) if ((CabNo == 0) && (Vel < 0.0001) && (abs(AccS) < 0.0001) && (TrainType != dt_EZT))
{ {
if (!PhysicActivation) if (!PhysicActivation)
@@ -3812,7 +3809,6 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
} }
else else
PhysicActivation = true; PhysicActivation = true;
//};
} }
double TMoverParameters::BrakeForceR(double ratio, double velocity) double TMoverParameters::BrakeForceR(double ratio, double velocity)
@@ -3971,7 +3967,7 @@ double TMoverParameters::Adhesive(double staticfriction)
} }
// WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3 // WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3
return adhesion; return adhesion;
*/
//wersja druga //wersja druga
if( true == SlippingWheels ) { if( true == SlippingWheels ) {
@@ -3984,14 +3980,14 @@ double TMoverParameters::Adhesive(double staticfriction)
else { adhesion = staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ); } else { adhesion = staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ); }
} }
// adhesion *= ( 0.9 + 0.2 * Random() ); // adhesion *= ( 0.9 + 0.2 * Random() );
/* */
//wersja3 by youBy - uwzględnia naturalne mikropoślizgi i wpływ piasecznicy, usuwa losowość z pojazdu //wersja3 by youBy - uwzględnia naturalne mikropoślizgi i wpływ piasecznicy, usuwa losowość z pojazdu
double Vwheels = nrot * M_PI * WheelDiameter; // predkosc liniowa koła wynikająca z obrotowej double Vwheels = nrot * M_PI * WheelDiameter; // predkosc liniowa koła wynikająca z obrotowej
double deltaV = V - Vwheels; //poślizg - różnica prędkości w punkcie styku koła i szyny double deltaV = V - Vwheels; //poślizg - różnica prędkości w punkcie styku koła i szyny
deltaV = std::max(0.0, std::abs(deltaV) - 0.25); //mikropoślizgi do ok. 0,25 m/s nie zrywają przyczepności deltaV = std::max(0.0, std::abs(deltaV) - 0.25); //mikropoślizgi do ok. 0,25 m/s nie zrywają przyczepności
Vwheels = std::abs( Vwheels ); Vwheels = std::abs( Vwheels );
adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor))); adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor)));
*/
return adhesion; return adhesion;
} }
@@ -6804,7 +6800,6 @@ void TMoverParameters::LoadFIZ_Wheels( std::string const &line ) {
extract_value( TrackW, "Tw", line, "" ); extract_value( TrackW, "Tw", line, "" );
extract_value( AxleInertialMoment, "AIM", line, "" ); extract_value( AxleInertialMoment, "AIM", line, "" );
if( AxleInertialMoment <= 0.0 ) { AxleInertialMoment = 1.0; }
extract_value( AxleArangement, "Axle", line, "" ); extract_value( AxleArangement, "Axle", line, "" );
NPoweredAxles = s2NPW( AxleArangement ); NPoweredAxles = s2NPW( AxleArangement );
@@ -6812,11 +6807,21 @@ void TMoverParameters::LoadFIZ_Wheels( std::string const &line ) {
BearingType = BearingType =
( extract_value( "BearingType", line ) == "Roll" ) ? ( extract_value( "BearingType", line ) == "Roll" ) ?
1 : 1 :
0; 0;
extract_value( ADist, "Ad", line, "" ); extract_value( ADist, "Ad", line, "" );
extract_value( BDist, "Bd", line, "" ); extract_value( BDist, "Bd", line, "" );
if( AxleInertialMoment <= 0.0 ) {
/*
AxleInertialMoment = 1.0;
*/
// approximation formula by youby
auto const k = 472.0; // arbitrary constant
AxleInertialMoment = k / 4.0 * std::pow( WheelDiameter, 4.0 ) * NAxles;
Mred = k * std::pow( WheelDiameter, 2.0 ) * NAxles;
}
} }
void TMoverParameters::LoadFIZ_Brake( std::string const &line ) { void TMoverParameters::LoadFIZ_Brake( std::string const &line ) {

View File

@@ -19,6 +19,7 @@ Copyright (C) 2007-2014 Maciej Cierniak
bool DebugModeFlag = false; bool DebugModeFlag = false;
bool FreeFlyModeFlag = false; bool FreeFlyModeFlag = false;
bool EditorModeFlag = true;
bool DebugCameraFlag = false; bool DebugCameraFlag = false;
double Max0R(double x1, double x2) double Max0R(double x1, double x2)

View File

@@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/.
extern bool DebugModeFlag; extern bool DebugModeFlag;
extern bool FreeFlyModeFlag; extern bool FreeFlyModeFlag;
extern bool EditorModeFlag;
extern bool DebugCameraFlag; extern bool DebugCameraFlag;
/*funkcje matematyczne*/ /*funkcje matematyczne*/

View File

@@ -296,7 +296,6 @@ TTrain::TTrain() {
fPPress = fNPress = 0; fPPress = fNPress = 0;
// asMessage=""; // asMessage="";
fMechCroach = 0.25;
pMechShake = vector3(0, 0, 0); pMechShake = vector3(0, 0, 0);
vMechMovement = vector3(0, 0, 0); vMechMovement = vector3(0, 0, 0);
pMechOffset = vector3(0, 0, 0); pMechOffset = vector3(0, 0, 0);
@@ -389,8 +388,7 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
*/ */
MechSpring.Init(0.015, 250); MechSpring.Init(0.015, 250);
vMechVelocity = vector3(0, 0, 0); vMechVelocity = vector3(0, 0, 0);
pMechOffset = vector3(-0.4, 3.3, 5.5); pMechOffset = vector3( 0, 0, 0 );
fMechCroach = 0.5;
fMechSpringX = 1; fMechSpringX = 1;
fMechSpringY = 0.5; fMechSpringY = 0.5;
fMechSpringZ = 0.5; fMechSpringZ = 0.5;
@@ -6286,8 +6284,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
} }
void TTrain::MechStop() void TTrain::MechStop()
{ // likwidacja ruchu kamery w kabinie (po powrocie { // likwidacja ruchu kamery w kabinie (po powrocie przez [F4])
// przez [F4])
pMechPosition = vector3(0, 0, 0); pMechPosition = vector3(0, 0, 0);
pMechShake = vector3(0, 0, 0); pMechShake = vector3(0, 0, 0);
vMechMovement = vector3(0, 0, 0); vMechMovement = vector3(0, 0, 0);

View File

@@ -378,7 +378,6 @@ public: // reszta może by?publiczna
vector3 pMechShake; vector3 pMechShake;
vector3 vMechVelocity; vector3 vMechVelocity;
// McZapkie: do poruszania sie po kabinie // McZapkie: do poruszania sie po kabinie
double fMechCroach;
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc // McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
TCab Cabine[maxcab + 1]; // przedzial maszynowy, kabina 1 (A), kabina 2 (B) TCab Cabine[maxcab + 1]; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
int iCabn; int iCabn;

View File

@@ -772,12 +772,14 @@ void TWorld::OnMouseMove(double x, double y)
void TWorld::InOutKey( bool const Near ) void TWorld::InOutKey( bool const Near )
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie { // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
FreeFlyModeFlag = !FreeFlyModeFlag; // zmiana widoku FreeFlyModeFlag = !FreeFlyModeFlag; // zmiana widoku
if (FreeFlyModeFlag) if (FreeFlyModeFlag) {
{ // jeżeli poza kabiną, przestawiamy w jej okolicę - OK // jeżeli poza kabiną, przestawiamy w jej okolicę - OK
Global::pUserDynamic = NULL; // bez renderowania względem kamery Global::pUserDynamic = NULL; // bez renderowania względem kamery
if (Train) if (Train) {
{ // Train->Dynamic()->ABuSetModelShake(vector3(0,0,0)); // cache current cab position so there's no need to set it all over again after each out-in switch
Train->Silence(); // wyłączenie dźwięków kabiny Train->pMechSittingPosition = Train->pMechOffset;
// wyłączenie dźwięków kabiny
Train->Silence();
Train->Dynamic()->bDisplayCab = false; Train->Dynamic()->bDisplayCab = false;
DistantView( Near ); DistantView( Near );
} }
@@ -983,8 +985,15 @@ bool TWorld::Update()
// this means at count > 20 simulation and render are going to desync. is that right? // this means at count > 20 simulation and render are going to desync. is that right?
// NOTE: experimentally changing this to prevent the desync. // NOTE: experimentally changing this to prevent the desync.
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps // TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
for( int updateidx = 0; updateidx < updatecount; ++updateidx ) { if( true == Global::FullPhysics ) {
Ground.Update( dt / updatecount, 1 ); // tu zrobić tylko coklatkową aktualizację przesunięć // default calculation mode, each step calculated separately
for( int updateidx = 0; updateidx < updatecount; ++updateidx ) {
Ground.Update( dt / updatecount, 1 );
}
}
else {
// slightly simplified calculation mode; can lead to errors
Ground.Update( dt / updatecount, updatecount );
} }
// yB dodał przyspieszacz fizyki // yB dodał przyspieszacz fizyki

View File

@@ -68,93 +68,105 @@ void
mouse_input::button( int const Button, int const Action ) { mouse_input::button( int const Button, int const Action ) {
if( false == Global::ControlPicking ) { return; } if( false == Global::ControlPicking ) { return; }
if( true == FreeFlyModeFlag ) { if( true == FreeFlyModeFlag ) {
// for now we're only interested in cab controls // world editor controls
return; // currently we only handle view panning in this mode
} if( Action == GLFW_RELEASE ) {
// if it's the right mouse button that got released we were potentially in view panning mode; stop it
user_command &mousecommand = (
Button == GLFW_MOUSE_BUTTON_LEFT ?
m_mousecommandleft :
m_mousecommandright
);
if( Action == GLFW_RELEASE ) {
if( mousecommand != user_command::none ) {
// NOTE: basic keyboard controls don't have any parameters
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( mousecommand, 0, 0, Action, 0 );
mousecommand = user_command::none;
}
else {
// if it's the right mouse button that got released and we had no command active, we were potentially in view panning mode; stop it
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) { if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
m_pickmodepanning = false; m_pickmodepanning = false;
} }
} }
// if we were in varying command repeat rate, we can stop that now. done without any conditions, to catch some unforeseen edge cases else {
m_varyingpollrate = false; // button press
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
// the right button activates mouse panning mode
m_pickmodepanning = true;
}
}
} }
else { else {
// if not release then it's press // cab controls mode
auto train = World.train(); user_command &mousecommand = (
if( train != nullptr ) { Button == GLFW_MOUSE_BUTTON_LEFT ?
auto lookup = m_mousecommands.find( train->GetLabel( GfxRenderer.Update_Pick_Control() ) ); m_mousecommandleft :
if( lookup != m_mousecommands.end() ) { m_mousecommandright
mousecommand = ( );
Button == GLFW_MOUSE_BUTTON_LEFT ?
lookup->second.left : if( Action == GLFW_RELEASE ) {
lookup->second.right if( mousecommand != user_command::none ) {
); // NOTE: basic keyboard controls don't have any parameters
if( mousecommand != user_command::none ) { // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// check manually for commands which have 'fast' variants launched with shift modifier // TODO: pass correct entity id once the missing systems are in place
if( Global::shiftState ) { m_relay.post( mousecommand, 0, 0, Action, 0 );
mousecommand = user_command::none;
}
else {
// if it's the right mouse button that got released and we had no command active, we were potentially in view panning mode; stop it
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
m_pickmodepanning = false;
}
}
// if we were in varying command repeat rate, we can stop that now. done without any conditions, to catch some unforeseen edge cases
m_varyingpollrate = false;
}
else {
// if not release then it's press
auto train = World.train();
if( train != nullptr ) {
auto lookup = m_mousecommands.find( train->GetLabel( GfxRenderer.Update_Pick_Control() ) );
if( lookup != m_mousecommands.end() ) {
mousecommand = (
Button == GLFW_MOUSE_BUTTON_LEFT ?
lookup->second.left :
lookup->second.right
);
if( mousecommand != user_command::none ) {
// check manually for commands which have 'fast' variants launched with shift modifier
if( Global::shiftState ) {
switch( mousecommand ) {
case user_command::mastercontrollerincrease: { mousecommand = user_command::mastercontrollerincreasefast; break; }
case user_command::mastercontrollerdecrease: { mousecommand = user_command::mastercontrollerdecreasefast; break; }
case user_command::secondcontrollerincrease: { mousecommand = user_command::secondcontrollerincreasefast; break; }
case user_command::secondcontrollerdecrease: { mousecommand = user_command::secondcontrollerdecreasefast; break; }
case user_command::independentbrakeincrease: { mousecommand = user_command::independentbrakeincreasefast; break; }
case user_command::independentbrakedecrease: { mousecommand = user_command::independentbrakedecreasefast; break; }
default: { break; }
}
}
// NOTE: basic keyboard controls don't have any parameters
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( mousecommand, 0, 0, Action, 0 );
m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one
switch( mousecommand ) { switch( mousecommand ) {
case user_command::mastercontrollerincrease: { mousecommand = user_command::mastercontrollerincreasefast; break; } case user_command::mastercontrollerincrease:
case user_command::mastercontrollerdecrease: { mousecommand = user_command::mastercontrollerdecreasefast; break; } case user_command::mastercontrollerdecrease:
case user_command::secondcontrollerincrease: { mousecommand = user_command::secondcontrollerincreasefast; break; } case user_command::secondcontrollerincrease:
case user_command::secondcontrollerdecrease: { mousecommand = user_command::secondcontrollerdecreasefast; break; } case user_command::secondcontrollerdecrease:
case user_command::independentbrakeincrease: { mousecommand = user_command::independentbrakeincreasefast; break; } case user_command::trainbrakeincrease:
case user_command::independentbrakedecrease: { mousecommand = user_command::independentbrakedecreasefast; break; } case user_command::trainbrakedecrease:
default: { break; } case user_command::independentbrakeincrease:
} case user_command::independentbrakedecrease: {
} // these commands trigger varying repeat rate mode,
// NOTE: basic keyboard controls don't have any parameters // which scales the rate based on the distance of the cursor from its point when the command was first issued
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 m_commandstartcursor = m_cursorposition;
// TODO: pass correct entity id once the missing systems are in place m_varyingpollrate = true;
m_relay.post( mousecommand, 0, 0, Action, 0 ); break;
m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one }
/* default: {
if( mousecommand == user_command::mastercontrollerincrease ) { break;
m_updateaccumulator -= 0.15; // extra pause on first increase of master controller }
}
*/
switch( mousecommand ) {
case user_command::mastercontrollerincrease:
case user_command::mastercontrollerdecrease:
case user_command::secondcontrollerincrease:
case user_command::secondcontrollerdecrease:
case user_command::trainbrakeincrease:
case user_command::trainbrakedecrease:
case user_command::independentbrakeincrease:
case user_command::independentbrakedecrease: {
// these commands trigger varying repeat rate mode,
// which scales the rate based on the distance of the cursor from its point when the command was first issued
m_commandstartcursor = m_cursorposition;
m_varyingpollrate = true;
break;
}
default: {
break;
} }
} }
} }
} else {
else { // if we don't have any recognized element under the cursor and the right button was pressed, enter view panning mode
// if we don't have any recognized element under the cursor and the right button was pressed, enter view panning mode if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) { m_pickmodepanning = true;
m_pickmodepanning = true; }
} }
} }
} }

View File

@@ -423,14 +423,23 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
::glEnable( GL_TEXTURE_2D ); ::glEnable( GL_TEXTURE_2D );
} }
#endif #endif
#ifdef EU07_NEW_CAB_RENDERCODE
if( World.Train != nullptr ) {
// cab render is performed without shadows, due to low resolution and number of models without windows :|
switch_units( true, false, false );
Render_cab( World.Train->Dynamic(), false );
}
#endif
switch_units( true, true, true );
Render( &World.Ground ); Render( &World.Ground );
// ...translucent parts // ...translucent parts
setup_drawing( true ); setup_drawing( true );
Render_Alpha( &World.Ground ); Render_Alpha( &World.Ground );
// cab render is performed without shadows, due to low resolution and number of models without windows :| if( World.Train != nullptr ) {
switch_units( true, false, false ); // cab render is performed without shadows, due to low resolution and number of models without windows :|
// cab render is done in translucent phase to deal with badly configured vehicles switch_units( true, false, false );
if( World.Train != nullptr ) { Render_cab( World.Train->Dynamic() ); } Render_cab( World.Train->Dynamic(), true );
}
if( m_environmentcubetexturesupport ) { if( m_environmentcubetexturesupport ) {
// restore default texture matrix for reflections cube map // restore default texture matrix for reflections cube map
@@ -1621,8 +1630,8 @@ opengl_renderer::Render( TGroundNode *Node ) {
break; break;
} }
} }
if( ( distancesquared > Node->fSquareRadius ) if( ( distancesquared < Node->fSquareMinRadius )
|| ( distancesquared < Node->fSquareMinRadius ) ) { || ( distancesquared >= Node->fSquareRadius ) ) {
return false; return false;
} }
@@ -1906,7 +1915,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana // rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
bool bool
opengl_renderer::Render_cab( TDynamicObject *Dynamic ) { opengl_renderer::Render_cab( TDynamicObject *Dynamic, bool const Alpha ) {
if( Dynamic == nullptr ) { if( Dynamic == nullptr ) {
@@ -1943,8 +1952,19 @@ opengl_renderer::Render_cab( TDynamicObject *Dynamic ) {
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) ); ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) );
} }
// render // render
#ifdef EU07_NEW_CAB_RENDERCODE
if( true == Alpha ) {
// translucent parts
Render_Alpha( Dynamic->mdKabina, Dynamic->Material(), 0.0 );
}
else {
// opaque parts
Render( Dynamic->mdKabina, Dynamic->Material(), 0.0 );
}
#else
Render( Dynamic->mdKabina, Dynamic->Material(), 0.0 ); Render( Dynamic->mdKabina, Dynamic->Material(), 0.0 );
Render_Alpha( Dynamic->mdKabina, Dynamic->Material(), 0.0 ); Render_Alpha( Dynamic->mdKabina, Dynamic->Material(), 0.0 );
#endif
// post-render restore // post-render restore
if( Dynamic->fShade > 0.0f ) { if( Dynamic->fShade > 0.0f ) {
// change light level based on light level of the occupied track // change light level based on light level of the occupied track
@@ -2030,7 +2050,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
if( ( Submodel->iVisible ) if( ( Submodel->iVisible )
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist ) && ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
&& ( TSubModel::fSquareDist <= Submodel->fSquareMaxDist ) ) { && ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
if( Submodel->iFlags & 0xC000 ) { if( Submodel->iFlags & 0xC000 ) {
::glPushMatrix(); ::glPushMatrix();
@@ -2412,8 +2432,8 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
break; break;
} }
} }
if( ( distancesquared > Node->fSquareRadius ) if( ( distancesquared < Node->fSquareMinRadius )
|| ( distancesquared < Node->fSquareMinRadius ) ) { || ( distancesquared >= Node->fSquareRadius ) ) {
return false; return false;
} }
@@ -2675,7 +2695,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// renderowanie przezroczystych przez DL // renderowanie przezroczystych przez DL
if( ( Submodel->iVisible ) if( ( Submodel->iVisible )
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist ) && ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
&& ( TSubModel::fSquareDist <= Submodel->fSquareMaxDist ) ) { && ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
if( Submodel->iFlags & 0xC000 ) { if( Submodel->iFlags & 0xC000 ) {
::glPushMatrix(); ::glPushMatrix();

View File

@@ -285,7 +285,7 @@ private:
void void
Render( TTrack *Track ); Render( TTrack *Track );
bool bool
Render_cab( TDynamicObject *Dynamic ); Render_cab( TDynamicObject *Dynamic, bool const Alpha = false );
void void
Render( TMemCell *Memcell ); Render( TMemCell *Memcell );
bool bool

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 908 #define VERSION_MINOR 911
#define VERSION_REVISION 0 #define VERSION_REVISION 0