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

framerate-independent cab camera shake, minor bug fixes

This commit is contained in:
tmj-fstate
2017-03-05 16:11:23 +01:00
parent 39b8fbfb86
commit d920644af8
6 changed files with 168 additions and 176 deletions

View File

@@ -2441,8 +2441,8 @@ bool TController::IncSpeed()
if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // jeśli gada, to nie jedziemy if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // jeśli gada, to nie jedziemy
return false; return false;
bool OK = true; bool OK = true;
if ((iDrivigFlags & moveDoorOpened) if ( ( iDrivigFlags & moveDoorOpened )
&&(mvOccupied->Vel > 0.1)) // added velocity threshold to prevent door shuffle on stop && ( VelDesired > 0.0 ) ) // to prevent door shuffle on stop
Doors(false); // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime) Doors(false); // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
if (fActionTime < 0.0) // gdy jest nakaz poczekać z jazdą, to nie ruszać if (fActionTime < 0.0) // gdy jest nakaz poczekać z jazdą, to nie ruszać
return false; return false;

View File

@@ -81,9 +81,12 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
switch( key ) switch( key )
{ {
case GLFW_KEY_ESCAPE: { case GLFW_KEY_ESCAPE: {
//[Esc] pauzuje tylko bez Debugmode
if( DebugModeFlag ) if( ( DebugModeFlag ) //[Esc] pauzuje tylko bez Debugmode
&& ( Global::iPause == 0 ) ) { // but unpausing should work always
break; break;
}
if( Global::iPause & 1 ) // jeśli pauza startowa if( Global::iPause & 1 ) // jeśli pauza startowa
Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować

View File

@@ -1977,7 +1977,8 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
if( tmp->DynamicObject->MoverParameters->LightPowerSource.SourceType != TPowerSource::NotDefined ) { if( tmp->DynamicObject->MoverParameters->LightPowerSource.SourceType != TPowerSource::NotDefined ) {
// if the vehicle has defined light source, it can (potentially) emit light, so add it to the light array // if the vehicle has defined light source, it can (potentially) emit light, so add it to the light array
*/ */
if( tmp->DynamicObject->MoverParameters->SecuritySystem.SystemType != 0 ) { if( ( tmp != nullptr )
&& ( tmp->DynamicObject->MoverParameters->SecuritySystem.SystemType != 0 ) ) {
// we check for presence of security system, as a way to determine whether the vehicle is a controllable engine // we check for presence of security system, as a way to determine whether the vehicle is a controllable engine
// NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights // NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights
m_lights.insert( tmp->DynamicObject ); m_lights.insert( tmp->DynamicObject );
@@ -4009,6 +4010,7 @@ bool TGround::EventConditon(TEvent *e)
{ // sprawdzenie spelnienia warunków dla eventu { // sprawdzenie spelnienia warunków dla eventu
if (e->iFlags <= update_only) if (e->iFlags <= update_only)
return true; // bezwarunkowo return true; // bezwarunkowo
if (e->iFlags & conditional_trackoccupied) if (e->iFlags & conditional_trackoccupied)
return (!e->Params[9].asTrack->IsEmpty()); return (!e->Params[9].asTrack->IsEmpty());
else if (e->iFlags & conditional_trackfree) else if (e->iFlags & conditional_trackfree)
@@ -4022,6 +4024,11 @@ bool TGround::EventConditon(TEvent *e)
} }
else if (e->iFlags & conditional_memcompare) else if (e->iFlags & conditional_memcompare)
{ // porównanie wartości { // porównanie wartości
if( nullptr == e->Params[9].asMemCell ) {
ErrorLog( "Event " + e->asName + " trying conditional_memcompare with nonexistent memcell" );
return true; // though this is technically error, we report success to maintain backward compatibility
}
if (tmpEvent->Params[9].asMemCell->Compare(e->Params[10].asText, e->Params[11].asdouble, if (tmpEvent->Params[9].asMemCell->Compare(e->Params[10].asText, e->Params[11].asdouble,
e->Params[12].asdouble, e->iFlags)) e->Params[12].asdouble, e->iFlags))
{ //logowanie spełnionych warunków { //logowanie spełnionych warunków

135
Train.cpp
View File

@@ -2384,7 +2384,7 @@ if
{ {
// McZapkie: poruszanie sie po kabinie, w updatemechpos zawarte sa wiezy // McZapkie: poruszanie sie po kabinie, w updatemechpos zawarte sa wiezy
auto step = 1.5f; auto step = 1.0f;
auto const camerayaw = Global::pCamera->Yaw; auto const camerayaw = Global::pCamera->Yaw;
Math3D::vector3 direction( 0.0f, 0.0f, step ); Math3D::vector3 direction( 0.0f, 0.0f, step );
direction.RotateY( camerayaw ); direction.RotateY( camerayaw );
@@ -2501,6 +2501,7 @@ void TTrain::OnKeyUp(int cKey)
} }
}; };
// cab movement update, fixed step part
void TTrain::UpdateMechPosition(double dt) void TTrain::UpdateMechPosition(double dt)
{ // Ra: mechanik powinien być { // Ra: mechanik powinien być
// telepany niezależnie od pozycji // telepany niezależnie od pozycji
@@ -2514,19 +2515,18 @@ void TTrain::UpdateMechPosition(double dt)
// - na postoju horyzont prosto, kabina skosem // - na postoju horyzont prosto, kabina skosem
// - przy szybkiej jeździe kabina prosto, horyzont pochylony // - przy szybkiej jeździe kabina prosto, horyzont pochylony
vector3 pNewMechPosition;
Math3D::vector3 shake; Math3D::vector3 shake;
// McZapkie: najpierw policzę pozycję w/m kabiny // McZapkie: najpierw policzę pozycję w/m kabiny
// ABu: rzucamy kabina tylko przy duzym FPS! // ABu: rzucamy kabina tylko przy duzym FPS!
// Mala histereza, zeby bez przerwy nie przelaczalo przy FPS~17 // Mala histereza, zeby bez przerwy nie przelaczalo przy FPS~17
// Granice mozna ustalic doswiadczalnie. Ja proponuje 14:20 // Granice mozna ustalic doswiadczalnie. Ja proponuje 14:20
double const iVel = std::min(DynamicObject->GetVelocity(), 150.0); double const iVel = std::min( DynamicObject->GetVelocity(), 150.0 );
if (!Global::iSlowMotion // musi być pełna prędkość if( !Global::iSlowMotion // musi być pełna prędkość
&& (pMechOffset.y < 4.0)) // Ra 15-01: przy oglądaniu pantografu bujanie przeszkadza && ( pMechOffset.y < 4.0 ) ) // Ra 15-01: przy oglądaniu pantografu bujanie przeszkadza
{ {
if( iVel > 0.0 ) { if( iVel > 0.5 ) {
// acceleration-driven base shake // acceleration-driven base shake
shake += 1.25 * MechSpring.ComputateForces( shake += 1.25 * MechSpring.ComputateForces(
vector3( vector3(
@@ -2541,96 +2541,85 @@ void TTrain::UpdateMechPosition(double dt)
vector3( vector3(
( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringX, ( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringX,
( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringY, ( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringY,
( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringZ ), ( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringZ )
* 1.25,
pMechShake ); pMechShake );
// * (( 200 - DynamicObject->MyTrack->iQualityFlag ) * 0.0075 ); // scale to 75-150% based on track quality // * (( 200 - DynamicObject->MyTrack->iQualityFlag ) * 0.0075 ); // scale to 75-150% based on track quality
} }
// shake *= 1.25; // shake *= 0.85;
} }
vMechVelocity -= (shake + vMechVelocity * 100) * (fMechSpringX + fMechSpringY + fMechSpringZ) / (200); vMechVelocity -= ( shake + vMechVelocity * 100 ) * ( fMechSpringX + fMechSpringY + fMechSpringZ ) / ( 200 );
// vMechVelocity -= vMechVelocity * iVel * dt; // shake *= 0.95 * dt; // shake damping
// shake *= 0.95 * dt; // shake damping
// McZapkie: // McZapkie:
pMechShake += vMechVelocity * dt; pMechShake += vMechVelocity * dt;
// Ra 2015-01: dotychczasowe rzucanie // Ra 2015-01: dotychczasowe rzucanie
pMechOffset += vMechMovement * dt; pMechOffset += vMechMovement * dt;
if ((pMechShake.y > fMechMaxSpring) || (pMechShake.y < -fMechMaxSpring)) if( ( pMechShake.y > fMechMaxSpring ) || ( pMechShake.y < -fMechMaxSpring ) )
vMechVelocity.y = -vMechVelocity.y; vMechVelocity.y = -vMechVelocity.y;
// ABu011104: 5*pMechShake.y, zeby ladnie pudlem rzucalo :) // ABu011104: 5*pMechShake.y, zeby ladnie pudlem rzucalo :)
pNewMechPosition = pMechOffset + vector3(1.5 * pMechShake.x, 2.0 * pMechShake.y, 1.5 * pMechShake.z); pMechPosition = pMechOffset + vector3( 1.5 * pMechShake.x, 2.0 * pMechShake.y, 1.5 * pMechShake.z );
// vMechMovement = 0.5 * vMechMovement; vMechMovement = 0.5 * vMechMovement;
} }
else else { // hamowanie rzucania przy spadku FPS
{ // hamowanie rzucania przy spadku FPS pMechShake -= pMechShake * std::min( dt, 1.0 ); // po tym chyba potrafią zostać jakieś ułamki, które powodują zjazd
pMechShake -= pMechShake * std::min(dt, 1.0); // po tym chyba potrafią zostać jakieś ułamki, które powodują zjazd
pMechOffset += vMechMovement * dt; pMechOffset += vMechMovement * dt;
vMechVelocity.y -= vMechVelocity.y * 50.0 * dt; vMechVelocity.y = 0.5 * vMechVelocity.y;
pNewMechPosition = pMechOffset + vector3(pMechShake.x, 5 * pMechShake.y, pMechShake.z); pMechPosition = pMechOffset + vector3( pMechShake.x, 5 * pMechShake.y, pMechShake.z );
// vMechMovement = 0.5 * vMechMovement; vMechMovement = 0.5 * vMechMovement;
} }
// numer kabiny (-1: kabina B) // numer kabiny (-1: kabina B)
if (DynamicObject->Mechanik) // może nie być? if( DynamicObject->Mechanik ) // może nie być?
if (DynamicObject->Mechanik->AIControllFlag) // jeśli prowadzi AI if( DynamicObject->Mechanik->AIControllFlag ) // jeśli prowadzi AI
{ // Ra: przesiadka, jeśli AI zmieniło kabinę (a człon?)... { // Ra: przesiadka, jeśli AI zmieniło kabinę (a człon?)...
if (iCabn != (DynamicObject->MoverParameters->ActiveCab == -1 ? if( iCabn != ( DynamicObject->MoverParameters->ActiveCab == -1 ?
2 : 2 :
DynamicObject->MoverParameters->ActiveCab)) DynamicObject->MoverParameters->ActiveCab ) )
InitializeCab(DynamicObject->MoverParameters->ActiveCab, InitializeCab( DynamicObject->MoverParameters->ActiveCab,
DynamicObject->asBaseDir + DynamicObject->MoverParameters->TypeName + DynamicObject->asBaseDir + DynamicObject->MoverParameters->TypeName +
".mmd"); ".mmd" );
} }
iCabn = (DynamicObject->MoverParameters->ActiveCab == -1 ? iCabn = ( DynamicObject->MoverParameters->ActiveCab == -1 ?
2 : 2 :
DynamicObject->MoverParameters->ActiveCab); DynamicObject->MoverParameters->ActiveCab );
if (!DebugModeFlag) if( !DebugModeFlag ) { // sprawdzaj więzy //Ra: nie tu!
{ // sprawdzaj więzy //Ra: nie tu! if( pMechPosition.x < Cabine[ iCabn ].CabPos1.x )
if (pNewMechPosition.x < Cabine[iCabn].CabPos1.x) pMechPosition.x = Cabine[ iCabn ].CabPos1.x;
pNewMechPosition.x = Cabine[iCabn].CabPos1.x; if( pMechPosition.x > Cabine[ iCabn ].CabPos2.x )
if (pNewMechPosition.x > Cabine[iCabn].CabPos2.x) pMechPosition.x = Cabine[ iCabn ].CabPos2.x;
pNewMechPosition.x = Cabine[iCabn].CabPos2.x; if( pMechPosition.z < Cabine[ iCabn ].CabPos1.z )
if (pNewMechPosition.z < Cabine[iCabn].CabPos1.z) pMechPosition.z = Cabine[ iCabn ].CabPos1.z;
pNewMechPosition.z = Cabine[iCabn].CabPos1.z; if( pMechPosition.z > Cabine[ iCabn ].CabPos2.z )
if (pNewMechPosition.z > Cabine[iCabn].CabPos2.z) pMechPosition.z = Cabine[ iCabn ].CabPos2.z;
pNewMechPosition.z = Cabine[iCabn].CabPos2.z; if( pMechPosition.y > Cabine[ iCabn ].CabPos1.y + 1.8 )
if (pNewMechPosition.y > Cabine[iCabn].CabPos1.y + 1.8) pMechPosition.y = Cabine[ iCabn ].CabPos1.y + 1.8;
pNewMechPosition.y = Cabine[iCabn].CabPos1.y + 1.8; if( pMechPosition.y < Cabine[ iCabn ].CabPos1.y + 0.5 )
if (pNewMechPosition.y < Cabine[iCabn].CabPos1.y + 0.5) pMechPosition.y = Cabine[ iCabn ].CabPos2.y + 0.5;
pNewMechPosition.y = Cabine[iCabn].CabPos2.y + 0.5;
if (pMechOffset.x < Cabine[iCabn].CabPos1.x) if( pMechOffset.x < Cabine[ iCabn ].CabPos1.x )
pMechOffset.x = Cabine[iCabn].CabPos1.x; pMechOffset.x = Cabine[ iCabn ].CabPos1.x;
if (pMechOffset.x > Cabine[iCabn].CabPos2.x) if( pMechOffset.x > Cabine[ iCabn ].CabPos2.x )
pMechOffset.x = Cabine[iCabn].CabPos2.x; pMechOffset.x = Cabine[ iCabn ].CabPos2.x;
if (pMechOffset.z < Cabine[iCabn].CabPos1.z) if( pMechOffset.z < Cabine[ iCabn ].CabPos1.z )
pMechOffset.z = Cabine[iCabn].CabPos1.z; pMechOffset.z = Cabine[ iCabn ].CabPos1.z;
if (pMechOffset.z > Cabine[iCabn].CabPos2.z) if( pMechOffset.z > Cabine[ iCabn ].CabPos2.z )
pMechOffset.z = Cabine[iCabn].CabPos2.z; pMechOffset.z = Cabine[ iCabn ].CabPos2.z;
if (pMechOffset.y > Cabine[iCabn].CabPos1.y + 1.8) if( pMechOffset.y > Cabine[ iCabn ].CabPos1.y + 1.8 )
pMechOffset.y = Cabine[iCabn].CabPos1.y + 1.8; pMechOffset.y = Cabine[ iCabn ].CabPos1.y + 1.8;
if (pMechOffset.y < Cabine[iCabn].CabPos1.y + 0.5) if( pMechOffset.y < Cabine[ iCabn ].CabPos1.y + 0.5 )
pMechOffset.y = Cabine[iCabn].CabPos2.y + 0.5; pMechOffset.y = Cabine[ iCabn ].CabPos2.y + 0.5;
} }
pMechPosition = DynamicObject->mMatrix *
pNewMechPosition; // położenie względem środka pojazdu w układzie scenerii
pMechPosition += DynamicObject->GetPosition();
// framerate-independent speed reduction that doesn't break at high framerates...
Math3D::vector3 movementslowdown = vMechMovement * 35 * dt;
if( movementslowdown.LengthSquared() >= vMechMovement.LengthSquared() ) {
// if the reduction vector exceeds speed movement we're running at low fps,
// fallback on the old behaviour
vMechMovement *= 0.5;
}
else {
vMechMovement -= movementslowdown;
if( vMechMovement.LengthSquared() < 0.01 ) {
vMechMovement = Math3D::vector3();
}
}
}; };
// returns position of the mechanic in the scene coordinates
vector3
TTrain::GetWorldMechPosition() {
vector3 position = DynamicObject->mMatrix *pMechPosition; // położenie względem środka pojazdu w układzie scenerii
position += DynamicObject->GetPosition();
return position;
}
bool TTrain::Update( double const Deltatime ) bool TTrain::Update( double const Deltatime )
{ {
DWORD stat; DWORD stat;

View File

@@ -94,6 +94,7 @@ class TTrain
return DynamicObject->VectorUp(); return DynamicObject->VectorUp();
}; };
void UpdateMechPosition(double dt); void UpdateMechPosition(double dt);
vector3 GetWorldMechPosition();
bool Update( double const Deltatime ); bool Update( double const Deltatime );
bool m_updated = false; bool m_updated = false;
void MechStop(); void MechStop();

116
World.cpp
View File

@@ -359,8 +359,6 @@ bool TWorld::Init( GLFWwindow *w ) {
WriteLog("Display Lists font used."); //+AnsiString(glGetError()) WriteLog("Display Lists font used."); //+AnsiString(glGetError())
WriteLog("Font init OK"); //+AnsiString(glGetError()) WriteLog("Font init OK"); //+AnsiString(glGetError())
Timer::ResetTimers();
glColor4f(1.0f, 3.0f, 3.0f, 0.0f); glColor4f(1.0f, 3.0f, 3.0f, 0.0f);
// SwapBuffers(hDC); // Swap Buffers (Double Buffering) // SwapBuffers(hDC); // Swap Buffers (Double Buffering)
// glClear(GL_COLOR_BUFFER_BIT); // glClear(GL_COLOR_BUFFER_BIT);
@@ -552,7 +550,6 @@ bool TWorld::Init( GLFWwindow *w ) {
else else
light = GfxRenderer.GetTextureId( "smuga2.tga", szTexturePath ); light = GfxRenderer.GetTextureId( "smuga2.tga", szTexturePath );
// Camera.Reset(); // Camera.Reset();
Timer::ResetTimers();
WriteLog( "Load time: " + WriteLog( "Load time: " +
std::to_string( std::chrono::duration_cast<std::chrono::seconds>(( std::chrono::system_clock::now() - timestart )).count() ) std::to_string( std::chrono::duration_cast<std::chrono::seconds>(( std::chrono::system_clock::now() - timestart )).count() )
+ " seconds"); + " seconds");
@@ -560,6 +557,9 @@ bool TWorld::Init( GLFWwindow *w ) {
if (Train) if (Train)
if (Train->Dynamic()->Mechanik) if (Train->Dynamic()->Mechanik)
Train->Dynamic()->Mechanik->TakeControl(true); Train->Dynamic()->Mechanik->TakeControl(true);
Timer::ResetTimers();
return true; return true;
}; };
@@ -719,7 +719,7 @@ void TWorld::OnKeyDown(int cKey)
} }
if( Global::iTextMode == GLFW_KEY_F10 ) // wyświetlone napisy klawiszem F10 if( Global::iTextMode == GLFW_KEY_F10 ) // wyświetlone napisy klawiszem F10
{ // i potwierdzenie { // i potwierdzenie
if( cKey == 'Y' ) { if( cKey == GLFW_KEY_Y ) {
// flaga wyjścia z programu // flaga wyjścia z programu
::PostQuitMessage( 0 ); ::PostQuitMessage( 0 );
// Global::iTextMode = -1; // Global::iTextMode = -1;
@@ -730,9 +730,9 @@ void TWorld::OnKeyDown(int cKey)
{ // tryb konfiguracji debugmode (przestawianie kamery już wyłączone { // tryb konfiguracji debugmode (przestawianie kamery już wyłączone
if (!Global::shiftState) // bez [Shift] if (!Global::shiftState) // bez [Shift]
{ {
if (cKey == '1') if (cKey == GLFW_KEY_1)
Global::iWriteLogEnabled ^= 1; // włącz/wyłącz logowanie do pliku Global::iWriteLogEnabled ^= 1; // włącz/wyłącz logowanie do pliku
else if (cKey == '2') else if (cKey == GLFW_KEY_2)
{ // włącz/wyłącz okno konsoli { // włącz/wyłącz okno konsoli
Global::iWriteLogEnabled ^= 2; Global::iWriteLogEnabled ^= 2;
if ((Global::iWriteLogEnabled & 2) == 0) // nie było okienka if ((Global::iWriteLogEnabled & 2) == 0) // nie było okienka
@@ -745,7 +745,7 @@ void TWorld::OnKeyDown(int cKey)
// else if (cKey=='3') Global::iWriteLogEnabled^=4; //wypisywanie nazw torów // else if (cKey=='3') Global::iWriteLogEnabled^=4; //wypisywanie nazw torów
} }
} }
else if (cKey == 3) //[Ctrl]+[Break] else if( cKey == GLFW_KEY_3 ) //[Ctrl]+[Break]
{ // hamowanie wszystkich pojazdów w okolicy { // hamowanie wszystkich pojazdów w okolicy
if (Controlled->MoverParameters->Radio) if (Controlled->MoverParameters->Radio)
Ground.RadioStop(Camera.Pos); Ground.RadioStop(Camera.Pos);
@@ -753,7 +753,7 @@ void TWorld::OnKeyDown(int cKey)
else if (!Global::iPause) //||(cKey==VK_F4)) //podczas pauzy sterownaie nie działa, F4 tak else if (!Global::iPause) //||(cKey==VK_F4)) //podczas pauzy sterownaie nie działa, F4 tak
if (Train) if (Train)
if (Controlled) if (Controlled)
if ((Controlled->Controller == Humandriver) ? true : DebugModeFlag || (cKey == 'Q')) if ((Controlled->Controller == Humandriver) ? true : DebugModeFlag || (cKey == GLFW_KEY_Q))
Train->OnKeyDown(cKey); // przekazanie klawisza do kabiny Train->OnKeyDown(cKey); // przekazanie klawisza do kabiny
if (FreeFlyModeFlag) // aby nie odluźniało wagonu za lokomotywą if (FreeFlyModeFlag) // aby nie odluźniało wagonu za lokomotywą
{ // operacje wykonywane na dowolnym pojeździe, przeniesione tu z kabiny { // operacje wykonywane na dowolnym pojeździe, przeniesione tu z kabiny
@@ -971,25 +971,19 @@ void TWorld::FollowView(bool wycisz)
} }
else if (Train) else if (Train)
{ // korekcja ustawienia w kabinie - OK { // korekcja ustawienia w kabinie - OK
vector3 camStara = vector3 camStara = Camera.Pos; // przestawianie kamery jest bez sensu: do przerobienia na potem
Camera.Pos; // przestawianie kamery jest bez sensu: do przerobienia na potem
// Ra: czy to tu jest potrzebne, bo przelicza się kawałek dalej? // Ra: czy to tu jest potrzebne, bo przelicza się kawałek dalej?
Camera.Pos = Train->pMechPosition; // Train.GetPosition1(); Camera.Pos = Train->pMechPosition; // Train.GetPosition1();
Camera.Roll = atan(Train->pMechShake.x * Train->fMechRoll); // hustanie kamery na boki Camera.Roll = std::atan(Train->pMechShake.x * Train->fMechRoll); // hustanie kamery na boki
Camera.Pitch -= Camera.Pitch -= 0.5 * std::atan(Train->vMechVelocity.z * Train->fMechPitch); // hustanie kamery przod tyl
atan(Train->vMechVelocity.z * Train->fMechPitch); // hustanie kamery przod tyl
if (Train->Dynamic()->MoverParameters->ActiveCab == 0) if (Train->Dynamic()->MoverParameters->ActiveCab == 0)
Camera.LookAt = Train->pMechPosition + Train->GetDirection(); Camera.LookAt = Train->pMechPosition + Train->GetDirection() * 5.0;
else // patrz w strone wlasciwej kabiny else // patrz w strone wlasciwej kabiny
Camera.LookAt = Camera.LookAt = Train->pMechPosition + Train->GetDirection() * 5.0 * Train->Dynamic()->MoverParameters->ActiveCab;
Train->pMechPosition +
Train->GetDirection() * Train->Dynamic()->MoverParameters->ActiveCab;
Train->pMechOffset.x = Train->pMechSittingPosition.x; Train->pMechOffset.x = Train->pMechSittingPosition.x;
Train->pMechOffset.y = Train->pMechSittingPosition.y; Train->pMechOffset.y = Train->pMechSittingPosition.y;
Train->pMechOffset.z = Train->pMechSittingPosition.z; Train->pMechOffset.z = Train->pMechSittingPosition.z;
Global::SetCameraPosition( Global::SetCameraPosition( Train->Dynamic() ->GetPosition()); // tu ustawić nową, bo od niej liczą się odległości
Train->Dynamic()
->GetPosition()); // tu ustawić nową, bo od niej liczą się odległości
if (wycisz) // trzymanie prawego w kabinie daje marny efekt if (wycisz) // trzymanie prawego w kabinie daje marny efekt
Ground.Silence(camStara); // wyciszenie dźwięków z poprzedniej pozycji Ground.Silence(camStara); // wyciszenie dźwięków z poprzedniej pozycji
} }
@@ -1105,8 +1099,8 @@ bool TWorld::Update()
} }
*/ */
/* /*
// NOTE: until we have no physics state interpolation during render, we need to rely on the old code // NOTE: until we have no physics state interpolation during render, we need to rely on the old code,
// doing fixed step calculations but flexible step render results in ugly mini jitter // as doing fixed step calculations but flexible step render results in ugly mini jitter
// core routines (physics) // core routines (physics)
int updatecount = 0; int updatecount = 0;
while( ( m_primaryupdateaccumulator >= m_primaryupdaterate ) while( ( m_primaryupdateaccumulator >= m_primaryupdaterate )
@@ -1150,7 +1144,12 @@ bool TWorld::Update()
iPause = Global::iPause; iPause = Global::iPause;
} }
// TODO: add fixed step part of the camera update here // fixed step part of the camera update
if( (Train != nullptr)
&& (Camera.Type == tp_Follow )) {
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
Train->UpdateMechPosition( m_secondaryupdaterate / Global::fTimeSpeed ); // ograniczyć telepanie po przyspieszeniu
}
m_secondaryupdateaccumulator -= m_secondaryupdaterate; // these should be inexpensive enough we have no cap m_secondaryupdateaccumulator -= m_secondaryupdaterate; // these should be inexpensive enough we have no cap
} }
@@ -1173,9 +1172,9 @@ bool TWorld::Update()
// fixed step render time routines // fixed step render time routines
fTime50Hz += dt; // w pauzie też trzeba zliczać czas, bo przy dużym FPS będzie problem z odczytem ramek fTime50Hz += dt; // w pauzie też trzeba zliczać czas, bo przy dużym FPS będzie problem z odczytem ramek
if( fTime50Hz >= 0.2 ) { while( fTime50Hz >= 1.0 / 50.0 ) {
Console::Update(); // to i tak trzeba wywoływać Console::Update(); // to i tak trzeba wywoływać
fTime50Hz -= 0.2; fTime50Hz -= 1.0 / 50.0;
} }
// variable step render time routines // variable step render time routines
@@ -1253,56 +1252,52 @@ TWorld::Update_Camera( double const Deltatime ) {
} }
*/ */
Camera.Update(); // uwzględnienie ruchu wywołanego klawiszami Camera.Update(); // uwzględnienie ruchu wywołanego klawiszami
/*
if( Camera.Type == tp_Follow ) { if( Camera.Type == tp_Follow ) {
if( Train ) { // jeśli jazda w kabinie, przeliczyć trzeba parametry kamery if( Train ) { // jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
Train->UpdateMechPosition( Deltatime / Train->UpdateMechPosition( Deltatime /
Global::fTimeSpeed ); // ograniczyć telepanie po przyspieszeniu Global::fTimeSpeed ); // ograniczyć telepanie po przyspieszeniu
vector3 tempangle; */
double modelrotate; if( (Train != nullptr)
tempangle = && (Camera.Type == tp_Follow )) {
Controlled->VectorFront() * ( Controlled->MoverParameters->ActiveCab == -1 ? -1 : 1 ); // jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
modelrotate = atan2( -tempangle.x, tempangle.z ); vector3 tempangle = Controlled->VectorFront() * ( Controlled->MoverParameters->ActiveCab == -1 ? -1 : 1 );
if( Global::ctrlState ? ( Console::Pressed( Global::Keys[ k_MechLeft ] ) || double modelrotate = atan2( -tempangle.x, tempangle.z );
Console::Pressed( Global::Keys[ k_MechRight ] ) ) :
false ) { // jeśli lusterko lewe albo prawe (bez rzucania na razie) if( (Global::ctrlState)
&& ( (Console::Pressed( Global::Keys[ k_MechLeft ])
|| (Console::Pressed( Global::Keys[ k_MechRight ]))))) {
// jeśli lusterko lewe albo prawe (bez rzucania na razie)
bool lr = Console::Pressed( Global::Keys[ k_MechLeft ] ); bool lr = Console::Pressed( Global::Keys[ k_MechLeft ] );
// Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu // Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu
Camera.Pos = Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka
Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka
Camera.Yaw = 0; // odchylenie na bok od Camera.LookAt Camera.Yaw = 0; // odchylenie na bok od Camera.LookAt
if( Train->Dynamic()->MoverParameters->ActiveCab == 0 ) if( Train->Dynamic()->MoverParameters->ActiveCab == 0 )
Camera.LookAt = Camera.Pos - Train->GetDirection(); // gdy w korytarzu Camera.LookAt = Camera.Pos - Train->GetDirection(); // gdy w korytarzu
else if( Global::shiftState ) { // patrzenie w bok przez szybę else if( Global::shiftState ) {
Camera.LookAt = Camera.Pos - // patrzenie w bok przez szybę
( lr ? -1 : 1 ) * Train->Dynamic()->VectorLeft() * Camera.LookAt = Camera.Pos - ( lr ? -1 : 1 ) * Train->Dynamic()->VectorLeft() * Train->Dynamic()->MoverParameters->ActiveCab;
Train->Dynamic()->MoverParameters->ActiveCab;
Global::SetCameraRotation( -modelrotate ); Global::SetCameraRotation( -modelrotate );
} }
else { // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny - jakby z lusterka, else { // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny - jakby z lusterka,
// ale bez odbicia // ale bez odbicia
Camera.LookAt = Camera.Pos - Camera.LookAt = Camera.Pos - Train->GetDirection() * Train->Dynamic()->MoverParameters->ActiveCab; //-1 albo 1
Train->GetDirection() * Global::SetCameraRotation( M_PI - modelrotate ); // tu już trzeba uwzględnić lusterka
Train->Dynamic()->MoverParameters->ActiveCab; //-1 albo 1
Global::SetCameraRotation( M_PI -
modelrotate ); // tu już trzeba uwzględnić lusterka
} }
Camera.Roll = Camera.Roll = std::atan( Train->pMechShake.x * Train->fMechRoll ); // hustanie kamery na boki
atan( Train->pMechShake.x * Train->fMechRoll ); // hustanie kamery na boki Camera.Pitch = 0.5 * std::atan( Train->vMechVelocity.z * Train->fMechPitch ); // hustanie kamery przod tyl
Camera.Pitch =
atan( Train->vMechVelocity.z * Train->fMechPitch ); // hustanie kamery przod tyl
Camera.vUp = Controlled->VectorUp(); Camera.vUp = Controlled->VectorUp();
} }
else { // patrzenie standardowe else {
Camera.Pos = Train->pMechPosition; // Train.GetPosition1(); // patrzenie standardowe
Camera.Pos = Train->GetWorldMechPosition(); // Train.GetPosition1();
if( !Global::iPause ) { // podczas pauzy nie przeliczać kątów przypadkowymi wartościami if( !Global::iPause ) { // podczas pauzy nie przeliczać kątów przypadkowymi wartościami
Camera.Roll = Camera.Roll = atan( Train->pMechShake.x * Train->fMechRoll ); // hustanie kamery na boki
atan( Train->pMechShake.x * Train->fMechRoll ); // hustanie kamery na boki Camera.Pitch -= 0.5 * atan( Train->vMechVelocity.z * Train->fMechPitch ); // hustanie kamery przod tyl //Ra: tu
Camera.Pitch -= atan( Train->vMechVelocity.z *
Train->fMechPitch ); // hustanie kamery przod tyl //Ra: tu
// jest uciekanie kamery w górę!!! // jest uciekanie kamery w górę!!!
} }
// ABu011104: rzucanie pudlem // ABu011104: rzucanie pudlem
/*
vector3 temp; vector3 temp;
if( abs( Train->pMechShake.y ) < 0.25 ) if( abs( Train->pMechShake.y ) < 0.25 )
temp = vector3( 0, 0, 6 * Train->pMechShake.y ); temp = vector3( 0, 0, 6 * Train->pMechShake.y );
@@ -1313,17 +1308,14 @@ TWorld::Update_Camera( double const Deltatime ) {
if( Controlled ) if( Controlled )
Controlled->ABuSetModelShake( temp ); Controlled->ABuSetModelShake( temp );
// ABu: koniec rzucania // ABu: koniec rzucania
*/
if( Train->Dynamic()->MoverParameters->ActiveCab == 0 ) if( Train->Dynamic()->MoverParameters->ActiveCab == 0 )
Camera.LookAt = Train->pMechPosition + Train->GetDirection(); // gdy w korytarzu Camera.LookAt = Train->GetWorldMechPosition() + Train->GetDirection() * 5.0; // gdy w korytarzu
else // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny else // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny
Camera.LookAt = Train->pMechPosition + Camera.LookAt = Train->GetWorldMechPosition() + Train->GetDirection() * 5.0 * Train->Dynamic()->MoverParameters->ActiveCab; //-1 albo 1
Train->GetDirection() *
Train->Dynamic()->MoverParameters->ActiveCab; //-1 albo 1
Camera.vUp = Train->GetUp(); Camera.vUp = Train->GetUp();
Global::SetCameraRotation( Camera.Yaw - Global::SetCameraRotation( Camera.Yaw - modelrotate ); // tu już trzeba uwzględnić lusterka
modelrotate ); // tu już trzeba uwzględnić lusterka
}
} }
} }
else { // kamera nieruchoma else { // kamera nieruchoma