mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
fixed animation rate of scene elements
This commit is contained in:
@@ -205,8 +205,9 @@ void TAnimContainer::AnimSetVMD(double fNewSpeed)
|
||||
// "+AnsiString(pMovementData->f3Vector.y)+" "+AnsiString(pMovementData->f3Vector.z));
|
||||
}
|
||||
|
||||
void TAnimContainer::UpdateModel()
|
||||
{ // przeliczanie animacji wykonać tylko raz na model
|
||||
// przeliczanie animacji wykonać tylko raz na model
|
||||
void TAnimContainer::UpdateModel() {
|
||||
|
||||
if (pSubModel) // pozbyć się tego - sprawdzać wcześniej
|
||||
{
|
||||
if (fTranslateSpeed != 0.0)
|
||||
@@ -236,7 +237,7 @@ void TAnimContainer::UpdateModel()
|
||||
// zakończeniu
|
||||
}
|
||||
}
|
||||
if (fRotateSpeed != 0)
|
||||
if (fRotateSpeed != 0.0)
|
||||
{
|
||||
|
||||
/*
|
||||
@@ -303,8 +304,9 @@ void TAnimContainer::UpdateModel()
|
||||
// zakończeniu
|
||||
}
|
||||
}
|
||||
if (fAngleSpeed != 0.0)
|
||||
{ // obrót kwaternionu (interpolacja)
|
||||
if( fAngleSpeed != 0.f ) {
|
||||
// NOTE: this is angle- not quaternion-based rotation TBD, TODO: switch to quaternion rotations?
|
||||
fAngleCurrent += fAngleSpeed * Timer::GetDeltaTime(); // aktualny parametr interpolacji
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -322,15 +324,14 @@ void TAnimContainer::PrepareModel()
|
||||
{
|
||||
if (fAngleSpeed > 0.0f)
|
||||
{
|
||||
fAngleCurrent +=
|
||||
fAngleSpeed * Timer::GetDeltaTime(); // aktualny parametr interpolacji
|
||||
if (fAngleCurrent >= 1.0f)
|
||||
{ // interpolacja zakończona, ustawienie na pozycję końcową
|
||||
qCurrent = qDesired;
|
||||
fAngleSpeed = 0.0; // wyłączenie przeliczania wektora
|
||||
if (evDone)
|
||||
Global::AddToQuery(evDone,
|
||||
NULL); // wykonanie eventu informującego o zakończeniu
|
||||
if( evDone ) {
|
||||
// wykonanie eventu informującego o zakończeniu
|
||||
Global::AddToQuery( evDone, NULL );
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // obliczanie pozycji pośredniej
|
||||
@@ -412,9 +413,9 @@ TAnimModel::TAnimModel()
|
||||
iNumLights = 0;
|
||||
fBlinkTimer = 0;
|
||||
|
||||
for (int i = 0; i < iMaxNumLights; i++)
|
||||
for (int i = 0; i < iMaxNumLights; ++i)
|
||||
{
|
||||
LightsOn[i] = LightsOff[i] = NULL; // normalnie nie ma
|
||||
LightsOn[i] = LightsOff[i] = nullptr; // normalnie nie ma
|
||||
lsLights[i] = ls_Off; // a jeśli są, to wyłączone
|
||||
}
|
||||
vAngle.x = vAngle.y = vAngle.z = 0.0; // zerowanie obrotów egzemplarza
|
||||
@@ -550,8 +551,15 @@ TAnimContainer * TAnimModel::GetContainer(char *pName)
|
||||
return AddContainer(pName);
|
||||
}
|
||||
|
||||
void TAnimModel::RaAnimate()
|
||||
{ // przeliczenie animacji - jednorazowo na klatkę
|
||||
// przeliczenie animacji - jednorazowo na klatkę
|
||||
void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
|
||||
|
||||
if( Framestamp == m_framestamp ) { return; }
|
||||
|
||||
fBlinkTimer -= Timer::GetDeltaTime();
|
||||
if( fBlinkTimer <= 0 )
|
||||
fBlinkTimer += fOffTime;
|
||||
|
||||
// Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość
|
||||
TAnimContainer *pCurrent;
|
||||
for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext)
|
||||
@@ -560,15 +568,14 @@ void TAnimModel::RaAnimate()
|
||||
// if () //tylko dla modeli z IK !!!!
|
||||
for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext) // albo osobny łańcuch
|
||||
pCurrent->UpdateModelIK(); // przeliczenie odwrotnej kinematyki
|
||||
|
||||
m_framestamp = Framestamp;
|
||||
};
|
||||
|
||||
void TAnimModel::RaPrepare()
|
||||
{ // ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza
|
||||
fBlinkTimer -= Timer::GetDeltaTime();
|
||||
if (fBlinkTimer <= 0)
|
||||
fBlinkTimer = fOffTime;
|
||||
bool state; // stan światła
|
||||
for (int i = 0; i < iNumLights; i++)
|
||||
for (int i = 0; i < iNumLights; ++i)
|
||||
{
|
||||
switch (lsLights[i])
|
||||
{
|
||||
|
||||
@@ -149,8 +149,9 @@ class TAnimModel {
|
||||
TLightState lsLights[iMaxNumLights];
|
||||
float fDark; // poziom zapalanie światła (powinno być chyba powiązane z danym światłem?)
|
||||
float fOnTime, fOffTime; // były stałymi, teraz mogą być zmienne dla każdego egzemplarza
|
||||
private:
|
||||
void RaAnimate(); // przeliczenie animacji egzemplarza
|
||||
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
|
||||
private:
|
||||
void RaAnimate( unsigned int const Framestamp ); // przeliczenie animacji egzemplarza
|
||||
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
|
||||
public:
|
||||
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
|
||||
|
||||
14
Driver.cpp
14
Driver.cpp
@@ -1253,7 +1253,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
if( fBrakeDist > 0.0 ) {
|
||||
// maintain desired acc while we have enough room to brake safely, when close enough start paying attention
|
||||
// try to make a smooth transition instead of sharp change
|
||||
a = interpolate( a, fAcc, clamp( ( d - fBrakeDist ) / fBrakeDist, 0.0, 1.0 ) );
|
||||
a = interpolate( a, AccPreferred, clamp( ( d - fBrakeDist ) / fBrakeDist, 0.0, 1.0 ) );
|
||||
}
|
||||
if( ( d < fMinProximityDist )
|
||||
&& ( v < fVelDes ) ) {
|
||||
@@ -4059,17 +4059,13 @@ bool TController::UpdateSituation(double dt)
|
||||
switch (comm)
|
||||
{ // ustawienie VelSignal - trochę proteza = do przemyślenia
|
||||
case cm_Ready: // W4 zezwolił na jazdę
|
||||
TableCheck(
|
||||
scanmax); // ewentualne doskanowanie trasy za W4, który zezwolił na jazdę
|
||||
TableUpdate(VelDesired, ActualProximityDist, VelNext,
|
||||
AccDesired); // aktualizacja po skanowaniu
|
||||
// if (comm!=cm_SetVelocity) //jeśli dalej jest kolejny W4, to ma zwrócić
|
||||
// cm_SetVelocity
|
||||
// ewentualne doskanowanie trasy za W4, który zezwolił na jazdę
|
||||
TableCheck( scanmax);
|
||||
TableUpdate(VelDesired, ActualProximityDist, VelNext, AccDesired); // aktualizacja po skanowaniu
|
||||
if (VelNext == 0.0)
|
||||
break; // ale jak coś z przodu zamyka, to ma stać
|
||||
if (iDrivigFlags & moveStopCloser)
|
||||
VelSignal = -1.0; // niech jedzie, jak W4 puściło - nie, ma czekać na
|
||||
// sygnał z sygnalizatora!
|
||||
VelSignal = -1.0; // ma czekać na sygnał z sygnalizatora!
|
||||
case cm_SetVelocity: // od wersji 357 semafor nie budzi wyłączonej lokomotywy
|
||||
if (!(OrderList[OrderPos] &
|
||||
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
||||
|
||||
12
Ground.cpp
12
Ground.cpp
@@ -356,13 +356,17 @@ bool TSubRect::RaTrackAnimAdd(TTrack *t)
|
||||
return false; // będzie animowane...
|
||||
}
|
||||
|
||||
void TSubRect::RaAnimate()
|
||||
{ // wykonanie animacji
|
||||
if( tTrackAnim == nullptr ) {
|
||||
// wykonanie animacji
|
||||
void TSubRect::RaAnimate( unsigned int const Framestamp ) {
|
||||
|
||||
if( ( tTrackAnim == nullptr )
|
||||
|| ( Framestamp == m_framestamp ) ) {
|
||||
// nie ma nic do animowania
|
||||
return;
|
||||
}
|
||||
tTrackAnim = tTrackAnim->RaAnimate(); // przeliczenie animacji kolejnego
|
||||
|
||||
m_framestamp = Framestamp;
|
||||
};
|
||||
|
||||
TTraction * TSubRect::FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude)
|
||||
@@ -431,8 +435,6 @@ void TSubRect::RenderSounds()
|
||||
//---------------------------------------------------------------------------
|
||||
//------------------ Kwadrat kilometrowy ------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
int TGroundRect::iFrameNumber = 0; // licznik wyświetlanych klatek
|
||||
|
||||
TGroundRect::~TGroundRect()
|
||||
{
|
||||
SafeDeleteArray(pSubRects);
|
||||
|
||||
8
Ground.h
8
Ground.h
@@ -171,6 +171,7 @@ class TSubRect : /*public Resource,*/ public CMesh
|
||||
{ // sektor składowy kwadratu kilometrowego
|
||||
public:
|
||||
bounding_area m_area;
|
||||
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
|
||||
int iTracks = 0; // ilość torów w (tTracks)
|
||||
TTrack **tTracks = nullptr; // tory do renderowania pojazdów
|
||||
protected:
|
||||
@@ -192,15 +193,12 @@ class TSubRect : /*public Resource,*/ public CMesh
|
||||
void LoadNodes(); // utworzenie VBO sektora
|
||||
public:
|
||||
virtual ~TSubRect();
|
||||
/*
|
||||
virtual void Release(); // zwalnianie VBO sektora
|
||||
*/
|
||||
virtual void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory
|
||||
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
|
||||
TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
|
||||
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude);
|
||||
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
|
||||
void RaAnimate(); // przeliczenie animacji torów
|
||||
void RaAnimate( unsigned int const Framestamp ); // przeliczenie animacji torów
|
||||
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
|
||||
};
|
||||
|
||||
@@ -221,7 +219,6 @@ class TGroundRect : public TSubRect
|
||||
|
||||
private:
|
||||
TSubRect *pSubRects { nullptr };
|
||||
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
|
||||
|
||||
void Init();
|
||||
|
||||
@@ -251,7 +248,6 @@ public:
|
||||
// optymalizacja obiektów w sektorach
|
||||
pSubRects[ i ].Sort(); } } };
|
||||
|
||||
static int iFrameNumber; // numer kolejny wyświetlanej klatki
|
||||
TGroundNode *nTerrain { nullptr }; // model terenu z E3D - użyć nRootMesh?
|
||||
};
|
||||
|
||||
|
||||
113
renderer.cpp
113
renderer.cpp
@@ -320,6 +320,7 @@ opengl_renderer::Render() {
|
||||
|
||||
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
||||
m_debuginfo.clear();
|
||||
++m_framestamp;
|
||||
Render_pass( rendermode::color );
|
||||
|
||||
m_drawcount = m_drawqueue.size();
|
||||
@@ -1330,8 +1331,6 @@ opengl_renderer::Texture( texture_handle const Texture ) const {
|
||||
bool
|
||||
opengl_renderer::Render( TGround *Ground ) {
|
||||
|
||||
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
||||
|
||||
m_drawqueue.clear();
|
||||
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
@@ -1440,73 +1439,70 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||
|
||||
bool result { false }; // will be true if we do any rendering
|
||||
|
||||
if( Groundcell->iLastDisplay != Groundcell->iFrameNumber ) {
|
||||
// tylko jezeli dany kwadrat nie był jeszcze renderowany
|
||||
Groundcell->LoadNodes(); // ewentualne tworzenie siatek
|
||||
Groundcell->LoadNodes(); // ewentualne tworzenie siatek
|
||||
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::pickscenery: {
|
||||
// non-interactive scenery elements get neutral colour
|
||||
::glColor3fv( glm::value_ptr( colors::none ) );
|
||||
}
|
||||
case rendermode::color:
|
||||
case rendermode::reflections: {
|
||||
if( Groundcell->nRenderRect != nullptr ) {
|
||||
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
for( TGroundNode *node = Groundcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
||||
Render( node );
|
||||
}
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::pickscenery: {
|
||||
// non-interactive scenery elements get neutral colour
|
||||
::glColor3fv( glm::value_ptr( colors::none ) );
|
||||
}
|
||||
case rendermode::color:
|
||||
case rendermode::reflections: {
|
||||
if( Groundcell->nRenderRect != nullptr ) {
|
||||
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
for( TGroundNode *node = Groundcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
||||
Render( node );
|
||||
}
|
||||
break;
|
||||
result = true;
|
||||
}
|
||||
case rendermode::shadows: {
|
||||
if( Groundcell->nRenderRect != nullptr ) {
|
||||
// experimental, for shadows render both back and front faces, to supply back faces of the 'forest strips'
|
||||
::glDisable( GL_CULL_FACE );
|
||||
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
for( TGroundNode *node = Groundcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
||||
Render( node );
|
||||
}
|
||||
::glEnable( GL_CULL_FACE );
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows: {
|
||||
if( Groundcell->nRenderRect != nullptr ) {
|
||||
// experimental, for shadows render both back and front faces, to supply back faces of the 'forest strips'
|
||||
::glDisable( GL_CULL_FACE );
|
||||
// nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
for( TGroundNode *node = Groundcell->nRenderRect; node != nullptr; node = node->nNext3 ) {
|
||||
Render( node );
|
||||
}
|
||||
}
|
||||
case rendermode::pickcontrols:
|
||||
default: {
|
||||
break;
|
||||
result = true;
|
||||
::glEnable( GL_CULL_FACE );
|
||||
}
|
||||
}
|
||||
case rendermode::pickcontrols:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||
if( Groundcell->nTerrain ) {
|
||||
if( Groundcell->nTerrain ) {
|
||||
|
||||
Render( Groundcell->nTerrain );
|
||||
}
|
||||
Render( Groundcell->nTerrain );
|
||||
}
|
||||
#endif
|
||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
||||
result = true;
|
||||
|
||||
// add the subcells of the cell to the draw queue
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::color:
|
||||
case rendermode::shadows:
|
||||
case rendermode::pickscenery: {
|
||||
if( Groundcell->pSubRects != nullptr ) {
|
||||
for( std::size_t subcellindex = 0; subcellindex < iNumSubRects * iNumSubRects; ++subcellindex ) {
|
||||
auto subcell = Groundcell->pSubRects + subcellindex;
|
||||
if( subcell->iNodeCount ) {
|
||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||
m_drawqueue.emplace_back(
|
||||
glm::length2( m_renderpass.camera.position() - glm::dvec3( subcell->m_area.center ) ),
|
||||
subcell );
|
||||
}
|
||||
// add the subcells of the cell to the draw queue
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::color:
|
||||
case rendermode::shadows:
|
||||
case rendermode::pickscenery: {
|
||||
if( Groundcell->pSubRects != nullptr ) {
|
||||
for( std::size_t subcellindex = 0; subcellindex < iNumSubRects * iNumSubRects; ++subcellindex ) {
|
||||
auto subcell = Groundcell->pSubRects + subcellindex;
|
||||
if( subcell->iNodeCount ) {
|
||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||
m_drawqueue.emplace_back(
|
||||
glm::length2( m_renderpass.camera.position() - glm::dvec3( subcell->m_area.center ) ),
|
||||
subcell );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rendermode::reflections:
|
||||
case rendermode::pickcontrols:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rendermode::reflections:
|
||||
case rendermode::pickcontrols:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -1518,7 +1514,8 @@ opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
||||
// oznaczanie aktywnych sektorów
|
||||
Groundsubcell->LoadNodes();
|
||||
|
||||
Groundsubcell->RaAnimate(); // przeliczenia animacji torów w sektorze
|
||||
// przeliczenia animacji torów w sektorze
|
||||
Groundsubcell->RaAnimate( m_framestamp );
|
||||
|
||||
TGroundNode *node;
|
||||
|
||||
@@ -1667,7 +1664,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Node->Model->RaAnimate(); // jednorazowe przeliczenie animacji
|
||||
Node->Model->RaAnimate( m_framestamp ); // jednorazowe przeliczenie animacji
|
||||
Node->Model->RaPrepare();
|
||||
if( Node->Model->pModel ) {
|
||||
// renderowanie rekurencyjne submodeli
|
||||
|
||||
@@ -350,6 +350,7 @@ private:
|
||||
int m_diffusetextureunit{ GL_TEXTURE3 };
|
||||
units_state m_unitstate;
|
||||
|
||||
unsigned int m_framestamp; // id of currently rendered gfx frame
|
||||
float m_drawtime { 1000.f / 30.f * 20.f }; // start with presumed 'neutral' average of 30 fps
|
||||
std::chrono::steady_clock::time_point m_drawstart; // cached start time of previous frame
|
||||
float m_framerate;
|
||||
|
||||
Reference in New Issue
Block a user