mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 16:19:19 +02:00
Merge remote-tracking branch 'tmj-fstate/mover_in_c++' into mover_in_c++
This commit is contained in:
@@ -472,8 +472,10 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
|||||||
if( name.substr( name.rfind( '.' ) ) == ".t3d" ) {
|
if( name.substr( name.rfind( '.' ) ) == ".t3d" ) {
|
||||||
name[ name.length() - 3 ] = 'e';
|
name[ name.length() - 3 ] = 'e';
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
Global::asTerrainModel = name;
|
Global::asTerrainModel = name;
|
||||||
WriteLog("Terrain model \"" + name + "\" will be created.");
|
WriteLog("Terrain model \"" + name + "\" will be created.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ErrorLog("Missed file: " + name);
|
ErrorLog("Missed file: " + name);
|
||||||
@@ -632,13 +634,7 @@ TSubModel * TAnimModel::TerrainSquare(int n)
|
|||||||
{ // pobieranie wskaźników do pierwszego submodelu
|
{ // pobieranie wskaźników do pierwszego submodelu
|
||||||
return pModel ? pModel->TerrainSquare(n) : 0;
|
return pModel ? pModel->TerrainSquare(n) : 0;
|
||||||
};
|
};
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
void TAnimModel::TerrainRenderVBO(int n)
|
|
||||||
{ // renderowanie terenu z VBO
|
|
||||||
if (pModel)
|
|
||||||
pModel->TerrainRenderVBO(n);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void TAnimModel::Advanced()
|
void TAnimModel::Advanced()
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ class TAnimModel {
|
|||||||
material_data m_materialdata;
|
material_data m_materialdata;
|
||||||
|
|
||||||
std::string asText; // tekst dla wyświetlacza znakowego
|
std::string asText; // tekst dla wyświetlacza znakowego
|
||||||
TAnimAdvanced *pAdvanced;
|
TAnimAdvanced *pAdvanced { nullptr };
|
||||||
void Advanced();
|
void Advanced();
|
||||||
TLightState lsLights[iMaxNumLights];
|
TLightState lsLights[iMaxNumLights];
|
||||||
float fDark; // poziom zapalanie światła (powinno być chyba powiązane z danym światłem?)
|
float fDark; // poziom zapalanie światła (powinno być chyba powiązane z danym światłem?)
|
||||||
|
|||||||
40
Camera.cpp
40
Camera.cpp
@@ -352,7 +352,8 @@ void TCamera::Update()
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if( ( Type == tp_Free )
|
if( ( Type == tp_Free )
|
||||||
|| ( false == Global::ctrlState ) ) {
|
|| ( false == Global::ctrlState )
|
||||||
|
|| ( true == DebugCameraFlag) ) {
|
||||||
// ctrl is used for mirror view, so we ignore the controls when in vehicle if ctrl is pressed
|
// ctrl is used for mirror view, so we ignore the controls when in vehicle if ctrl is pressed
|
||||||
if( m_keys.up )
|
if( m_keys.up )
|
||||||
Velocity.y = clamp( Velocity.y + m_moverate.y * 10.0 * deltatime, -m_moverate.y, m_moverate.y );
|
Velocity.y = clamp( Velocity.y + m_moverate.y * 10.0 * deltatime, -m_moverate.y, m_moverate.y );
|
||||||
@@ -371,7 +372,8 @@ void TCamera::Update()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( Type == tp_Free ) {
|
if( ( Type == tp_Free )
|
||||||
|
|| ( true == DebugCameraFlag ) ) {
|
||||||
// free movement position update is handled here, movement while in vehicle is handled by train update
|
// free movement position update is handled here, movement while in vehicle is handled by train update
|
||||||
vector3 Vec = Velocity;
|
vector3 Vec = Velocity;
|
||||||
Vec.RotateY( Yaw );
|
Vec.RotateY( Yaw );
|
||||||
@@ -379,35 +381,9 @@ void TCamera::Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector3 TCamera::GetDirection()
|
vector3 TCamera::GetDirection() {
|
||||||
{
|
|
||||||
matrix4x4 mat;
|
|
||||||
vector3 Vec;
|
|
||||||
Vec = vector3(0, 0, 1);
|
|
||||||
Vec.RotateY(Yaw);
|
|
||||||
|
|
||||||
return (Normalize(Vec));
|
return glm::normalize( glm::rotateY<float>( glm::vec3{ 0.f, 0.f, 1.f }, Yaw ) );
|
||||||
}
|
|
||||||
|
|
||||||
bool TCamera::SetMatrix()
|
|
||||||
{
|
|
||||||
glRotated( -Roll * 180.0 / M_PI, 0.0, 0.0, 1.0 ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
|
|
||||||
glRotated( -Pitch * 180.0 / M_PI, 1.0, 0.0, 0.0 );
|
|
||||||
glRotated( -Yaw * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // w zewnętrznym widoku: kierunek patrzenia
|
|
||||||
|
|
||||||
if( Type == tp_Follow )
|
|
||||||
{
|
|
||||||
gluLookAt(
|
|
||||||
Pos.x, Pos.y, Pos.z,
|
|
||||||
LookAt.x, LookAt.y, LookAt.z,
|
|
||||||
vUp.x, vUp.y, vUp.z); // Ra: pOffset is zero
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
glTranslated( -Pos.x, -Pos.y, -Pos.z ); // nie zmienia kierunku patrzenia
|
|
||||||
}
|
|
||||||
|
|
||||||
Global::SetCameraPosition(Pos); // było +pOffset
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
|
bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
|
||||||
@@ -416,7 +392,7 @@ bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
|
|||||||
Matrix = glm::rotate( Matrix, -Pitch, glm::dvec3( 1.0, 0.0, 0.0 ) );
|
Matrix = glm::rotate( Matrix, -Pitch, glm::dvec3( 1.0, 0.0, 0.0 ) );
|
||||||
Matrix = glm::rotate( Matrix, -Yaw, glm::dvec3( 0.0, 1.0, 0.0 ) ); // w zewnętrznym widoku: kierunek patrzenia
|
Matrix = glm::rotate( Matrix, -Yaw, glm::dvec3( 0.0, 1.0, 0.0 ) ); // w zewnętrznym widoku: kierunek patrzenia
|
||||||
|
|
||||||
if( Type == tp_Follow ) {
|
if( ( Type == tp_Follow ) && ( false == DebugCameraFlag ) ) {
|
||||||
|
|
||||||
Matrix *= glm::lookAt(
|
Matrix *= glm::lookAt(
|
||||||
glm::dvec3{ Pos },
|
glm::dvec3{ Pos },
|
||||||
@@ -427,7 +403,6 @@ bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
|
|||||||
Matrix = glm::translate( Matrix, glm::dvec3{ -Pos } ); // nie zmienia kierunku patrzenia
|
Matrix = glm::translate( Matrix, glm::dvec3{ -Pos } ); // nie zmienia kierunku patrzenia
|
||||||
}
|
}
|
||||||
|
|
||||||
Global::SetCameraPosition( Pos ); // było +pOffset
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,4 +421,3 @@ void TCamera::Stop()
|
|||||||
Type = tp_Follow;
|
Type = tp_Follow;
|
||||||
Velocity = vector3(0, 0, 0);
|
Velocity = vector3(0, 0, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
1
Camera.h
1
Camera.h
@@ -57,7 +57,6 @@ class TCamera
|
|||||||
void OnCommand( command_data const &Command );
|
void OnCommand( command_data const &Command );
|
||||||
void Update();
|
void Update();
|
||||||
vector3 GetDirection();
|
vector3 GetDirection();
|
||||||
bool SetMatrix();
|
|
||||||
bool SetMatrix(glm::dmat4 &Matrix);
|
bool SetMatrix(glm::dmat4 &Matrix);
|
||||||
void RaLook();
|
void RaLook();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|||||||
@@ -1335,7 +1335,7 @@ void TController::TablePurger()
|
|||||||
for( std::size_t idx = 0; idx < sSpeedTable.size() - 1; ++idx ) {
|
for( std::size_t idx = 0; idx < sSpeedTable.size() - 1; ++idx ) {
|
||||||
auto const &speedpoint = sSpeedTable[ idx ];
|
auto const &speedpoint = sSpeedTable[ idx ];
|
||||||
if( ( 0 == ( speedpoint.iFlags & spEnabled ) )
|
if( ( 0 == ( speedpoint.iFlags & spEnabled ) )
|
||||||
|| ( ( speedpoint.iFlags & ( spElapsed | spTrack | spCurve | spSwitch ) == ( spElapsed | spTrack | spCurve ) )
|
|| ( ( ( speedpoint.iFlags & ( spElapsed | spTrack | spCurve | spSwitch ) ) == ( spElapsed | spTrack | spCurve ) )
|
||||||
&& ( speedpoint.fVelNext < 0.0 ) ) ) {
|
&& ( speedpoint.fVelNext < 0.0 ) ) ) {
|
||||||
// NOTE: we could break out early here, but running through entire thing gives us exact size needed for new table
|
// NOTE: we could break out early here, but running through entire thing gives us exact size needed for new table
|
||||||
++trimcount;
|
++trimcount;
|
||||||
@@ -1357,7 +1357,7 @@ void TController::TablePurger()
|
|||||||
}
|
}
|
||||||
auto const &speedpoint = sSpeedTable[ idx ];
|
auto const &speedpoint = sSpeedTable[ idx ];
|
||||||
if( ( 0 == ( speedpoint.iFlags & spEnabled ) )
|
if( ( 0 == ( speedpoint.iFlags & spEnabled ) )
|
||||||
|| ( ( speedpoint.iFlags & ( spElapsed | spTrack | spCurve | spSwitch ) == ( spElapsed | spTrack | spCurve ) )
|
|| ( ( ( speedpoint.iFlags & ( spElapsed | spTrack | spCurve | spSwitch ) ) == ( spElapsed | spTrack | spCurve ) )
|
||||||
&& ( speedpoint.fVelNext < 0.0 ) ) ) {
|
&& ( speedpoint.fVelNext < 0.0 ) ) ) {
|
||||||
// if the trimmed point happens to be currently active semaphor we need to invalidate their placements
|
// if the trimmed point happens to be currently active semaphor we need to invalidate their placements
|
||||||
if( idx == SemNextIndex ) {
|
if( idx == SemNextIndex ) {
|
||||||
|
|||||||
126
DynObj.cpp
126
DynObj.cpp
@@ -185,9 +185,10 @@ float TDynamicObject::GetEPP()
|
|||||||
// od strony sprzegu (coupler_nr) obiektu (start)
|
// od strony sprzegu (coupler_nr) obiektu (start)
|
||||||
TDynamicObject *temp = this;
|
TDynamicObject *temp = this;
|
||||||
int coupler_nr = 0;
|
int coupler_nr = 0;
|
||||||
float eq = 0, am = 0;
|
double eq = 0.0;
|
||||||
|
double am = 0.0;
|
||||||
|
|
||||||
for (int i = 0; i < 300; i++) // ograniczenie do 300 na wypadek zapętlenia składu
|
for (int i = 0; i < 300; ++i) // ograniczenie do 300 na wypadek zapętlenia składu
|
||||||
{
|
{
|
||||||
if (!temp)
|
if (!temp)
|
||||||
break; // Ra: zabezpieczenie przed ewentaulnymi błędami sprzęgów
|
break; // Ra: zabezpieczenie przed ewentaulnymi błędami sprzęgów
|
||||||
@@ -2732,26 +2733,20 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
if (Mechanik)
|
if (Mechanik)
|
||||||
{ // Ra 2F3F: do Driver.cpp to przenieść?
|
{ // Ra 2F3F: do Driver.cpp to przenieść?
|
||||||
MoverParameters->EqvtPipePress = GetEPP(); // srednie cisnienie w PG
|
MoverParameters->EqvtPipePress = GetEPP(); // srednie cisnienie w PG
|
||||||
if ((Mechanik->Primary()) &&
|
if( ( Mechanik->Primary() )
|
||||||
(MoverParameters->EngineType == ElectricInductionMotor)) // jesli glowny i z
|
&& ( MoverParameters->EngineType == ElectricInductionMotor ) ) {
|
||||||
// asynchronami, to
|
// jesli glowny i z asynchronami, to niech steruje hamulcem lacznie dla calego pociagu/ezt
|
||||||
// niech steruje
|
auto const kier = (DirectionGet() * MoverParameters->ActiveCab > 0);
|
||||||
{ // hamulcem lacznie dla calego pociagu/ezt
|
auto FED { 0.0 };
|
||||||
bool kier = (DirectionGet() * MoverParameters->ActiveCab > 0);
|
auto np { 0 };
|
||||||
float FED = 0;
|
auto masa { 0.0 };
|
||||||
int np = 0;
|
auto FrED { 0.0 };
|
||||||
float masa = 0;
|
auto masamax { 0.0 };
|
||||||
float FrED = 0;
|
auto FmaxPN { 0.0 };
|
||||||
float masamax = 0;
|
auto FfulED { 0.0 };
|
||||||
float FmaxPN = 0;
|
auto FmaxED { 0.0 };
|
||||||
float FfulED = 0;
|
auto Frj { 0.0 };
|
||||||
float FmaxED = 0;
|
auto osie { 0 };
|
||||||
float Fzad = 0;
|
|
||||||
float FzadED = 0;
|
|
||||||
float FzadPN = 0;
|
|
||||||
float Frj = 0;
|
|
||||||
float amax = 0;
|
|
||||||
float osie = 0;
|
|
||||||
// 1. ustal wymagana sile hamowania calego pociagu
|
// 1. ustal wymagana sile hamowania calego pociagu
|
||||||
// - opoznienie moze byc ustalane na podstawie charakterystyki
|
// - opoznienie moze byc ustalane na podstawie charakterystyki
|
||||||
// - opoznienie moze byc ustalane na podstawie mas i cisnien granicznych
|
// - opoznienie moze byc ustalane na podstawie mas i cisnien granicznych
|
||||||
@@ -2762,11 +2757,14 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
(kier ? p = p->NextC(4) : p = p->PrevC(4)))
|
(kier ? p = p->NextC(4) : p = p->PrevC(4)))
|
||||||
{
|
{
|
||||||
np++;
|
++np;
|
||||||
masamax += p->MoverParameters->MBPM +
|
masamax +=
|
||||||
(p->MoverParameters->MBPM > 1 ? 0 : p->MoverParameters->Mass) +
|
p->MoverParameters->MBPM
|
||||||
p->MoverParameters->Mred;
|
+ ( p->MoverParameters->MBPM > 1.0 ?
|
||||||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
0.0 :
|
||||||
|
p->MoverParameters->Mass )
|
||||||
|
+ p->MoverParameters->Mred;
|
||||||
|
auto const Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||||||
p->MoverParameters->BrakeCylSpring) *
|
p->MoverParameters->BrakeCylSpring) *
|
||||||
p->MoverParameters->BrakeCylMult[0] -
|
p->MoverParameters->BrakeCylMult[0] -
|
||||||
p->MoverParameters->BrakeSlckAdj) *
|
p->MoverParameters->BrakeSlckAdj) *
|
||||||
@@ -2780,18 +2778,19 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
0) ?
|
0) ?
|
||||||
p->MoverParameters->eimc[eimc_p_Fh] * 1000 :
|
p->MoverParameters->eimc[eimc_p_Fh] * 1000 :
|
||||||
0); // chwilowy max ED -> do rozdzialu sil
|
0); // chwilowy max ED -> do rozdzialu sil
|
||||||
FED -= Min0R(p->MoverParameters->eimv[eimv_Fmax], 0) *
|
FED -= std::min(p->MoverParameters->eimv[eimv_Fmax], 0.0) *
|
||||||
1000; // chwilowy max ED -> do rozdzialu sil
|
1000; // chwilowy max ED -> do rozdzialu sil
|
||||||
FfulED = Min0R(p->MoverParameters->eimv[eimv_Fful], 0) *
|
FfulED = std::min(p->MoverParameters->eimv[eimv_Fful], 0.0) *
|
||||||
1000; // chwilowy max ED -> do rozdzialu sil
|
1000; // chwilowy max ED -> do rozdzialu sil
|
||||||
FrED -= Min0R(p->MoverParameters->eimv[eimv_Fr], 0) *
|
FrED -= std::min(p->MoverParameters->eimv[eimv_Fr], 0.0) *
|
||||||
1000; // chwilowo realizowane ED -> do pneumatyki
|
1000; // chwilowo realizowane ED -> do pneumatyki
|
||||||
Frj += Max0R(p->MoverParameters->eimv[eimv_Fr], 0) *
|
Frj += std::max(p->MoverParameters->eimv[eimv_Fr], 0.0) *
|
||||||
1000;// chwilowo realizowany napęd -> do utrzymującego
|
1000;// chwilowo realizowany napęd -> do utrzymującego
|
||||||
masa += p->MoverParameters->TotalMass;
|
masa += p->MoverParameters->TotalMass;
|
||||||
osie += p->MoverParameters->NAxles;
|
osie += p->MoverParameters->NAxles;
|
||||||
}
|
}
|
||||||
amax = FmaxPN / masamax;
|
|
||||||
|
auto const amax = FmaxPN / masamax;
|
||||||
if ((MoverParameters->Vel < 0.5) && (MoverParameters->BrakePress > 0.2) ||
|
if ((MoverParameters->Vel < 0.5) && (MoverParameters->BrakePress > 0.2) ||
|
||||||
(dDoorMoveL > 0.001) || (dDoorMoveR > 0.001))
|
(dDoorMoveL > 0.001) || (dDoorMoveR > 0.001))
|
||||||
{
|
{
|
||||||
@@ -2808,24 +2807,28 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
MoverParameters->ShuntModeAllow = (MoverParameters->BrakePress > 0.2) &&
|
MoverParameters->ShuntModeAllow = (MoverParameters->BrakePress > 0.2) &&
|
||||||
(MoverParameters->LocalBrakeRatio() < 0.01);
|
(MoverParameters->LocalBrakeRatio() < 0.01);
|
||||||
}
|
}
|
||||||
Fzad = amax * MoverParameters->LocalBrakeRatio() * masa;
|
auto Fzad = amax * MoverParameters->LocalBrakeRatio() * masa;
|
||||||
if ((MoverParameters->ScndS) &&
|
if ((MoverParameters->ScndS) &&
|
||||||
(MoverParameters->Vel > MoverParameters->eimc[eimc_p_Vh1]) && (FmaxED > 0))
|
(MoverParameters->Vel > MoverParameters->eimc[eimc_p_Vh1]) && (FmaxED > 0))
|
||||||
{
|
{
|
||||||
Fzad = Min0R(MoverParameters->LocalBrakeRatio() * FmaxED, FfulED);
|
Fzad = std::min(MoverParameters->LocalBrakeRatio() * FmaxED, FfulED);
|
||||||
}
|
}
|
||||||
if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) ||
|
if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) ||
|
||||||
(MoverParameters->V * MoverParameters->DirAbsolute < -0.2))
|
(MoverParameters->V * MoverParameters->DirAbsolute < -0.2))
|
||||||
{
|
{
|
||||||
Fzad = Max0R(MoverParameters->StopBrakeDecc * masa, Fzad);
|
Fzad = std::max(MoverParameters->StopBrakeDecc * masa, Fzad);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MoverParameters->BrakeHandle == MHZ_EN57?MoverParameters->BrakeOpModeFlag & bom_MED:MoverParameters->EpFuse)
|
auto FzadED { 0.0 };
|
||||||
FzadED = Min0R(Fzad, FmaxED);
|
if( ( MoverParameters->EpFuse )
|
||||||
else
|
|| ( ( MoverParameters->BrakeHandle == MHZ_EN57 )
|
||||||
FzadED = 0;
|
&& ( MoverParameters->BrakeOpModeFlag & bom_MED ) ) ) {
|
||||||
FzadPN = Fzad - FrED;
|
FzadED = std::min( Fzad, FmaxED );
|
||||||
|
}
|
||||||
|
auto const FzadPN = Fzad - FrED;
|
||||||
//np = 0;
|
//np = 0;
|
||||||
|
// BUG: likely memory leak, allocation per inner loop, deleted only once outside
|
||||||
|
// TODO: sort this shit out
|
||||||
bool* PrzekrF = new bool[np];
|
bool* PrzekrF = new bool[np];
|
||||||
float nPrzekrF = 0;
|
float nPrzekrF = 0;
|
||||||
bool test = true;
|
bool test = true;
|
||||||
@@ -2849,7 +2852,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||||||
p = (kier == true ? p->NextC(4) : p->PrevC(4)) )
|
p = (kier == true ? p->NextC(4) : p->PrevC(4)) )
|
||||||
{
|
{
|
||||||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
auto const Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||||||
p->MoverParameters->BrakeCylSpring) *
|
p->MoverParameters->BrakeCylSpring) *
|
||||||
p->MoverParameters->BrakeCylMult[0] -
|
p->MoverParameters->BrakeCylMult[0] -
|
||||||
p->MoverParameters->BrakeSlckAdj) *
|
p->MoverParameters->BrakeSlckAdj) *
|
||||||
@@ -2864,8 +2867,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
FzED[i] = (FmaxED > 0 ? FzadED / FmaxED : 0);
|
FzED[i] = (FmaxED > 0 ? FzadED / FmaxED : 0);
|
||||||
p->MoverParameters->AnPos =
|
p->MoverParameters->AnPos =
|
||||||
(MoverParameters->ScndS ? MoverParameters->LocalBrakeRatio() : FzED[i]);
|
(MoverParameters->ScndS ? MoverParameters->LocalBrakeRatio() : FzED[i]);
|
||||||
FzEP[i] = FzadPN * p->MoverParameters->NAxles / osie;
|
FzEP[ i ] = static_cast<float>( FzadPN * p->MoverParameters->NAxles ) / static_cast<float>( osie );
|
||||||
i++;
|
++i;
|
||||||
p->MoverParameters->ShuntMode = MoverParameters->ShuntMode;
|
p->MoverParameters->ShuntMode = MoverParameters->ShuntMode;
|
||||||
p->MoverParameters->ShuntModeAllow = MoverParameters->ShuntModeAllow;
|
p->MoverParameters->ShuntModeAllow = MoverParameters->ShuntModeAllow;
|
||||||
}
|
}
|
||||||
@@ -2896,7 +2899,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
FzEP[i] = 0;
|
FzEP[i] = 0;
|
||||||
przek += przek1;
|
przek += przek1;
|
||||||
}
|
}
|
||||||
i++;
|
++i;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
przek = przek / (np - nPrzekrF);
|
przek = przek / (np - nPrzekrF);
|
||||||
@@ -2907,7 +2910,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
{
|
{
|
||||||
FzEP[i] += przek;
|
FzEP[i] += przek;
|
||||||
}
|
}
|
||||||
i++;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
@@ -2938,31 +2941,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
p->MoverParameters->LocalBrakePosA = p->MoverParameters->LocalBrakePosA;
|
p->MoverParameters->LocalBrakePosA = p->MoverParameters->LocalBrakePosA;
|
||||||
else
|
else
|
||||||
p->MoverParameters->LocalBrakePosA = 0;
|
p->MoverParameters->LocalBrakePosA = 0;
|
||||||
i++;
|
++i;
|
||||||
}
|
}
|
||||||
/* ////ALGORYTM 1 - KAZDEMU PO ROWNO
|
|
||||||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0); p;
|
|
||||||
(iDirection > 0 ? p = p->NextC(4) : p = p->PrevC(4)))
|
|
||||||
{
|
|
||||||
|
|
||||||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
|
||||||
p->MoverParameters->BrakeCylSpring) *
|
|
||||||
p->MoverParameters->BrakeCylMult[0] -
|
|
||||||
p->MoverParameters->BrakeSlckAdj) *
|
|
||||||
p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff;
|
|
||||||
float FmaxPoj = Nmax *
|
|
||||||
p->MoverParameters->Hamulec->GetFC(
|
|
||||||
Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA),
|
|
||||||
p->MoverParameters->Vel) *
|
|
||||||
1000; // sila hamowania pn
|
|
||||||
// Fpoj=(FED>0?-FzadED*p->MoverParameters->eimv[eimv_Fmax]*1000/FED:0);
|
|
||||||
// p->MoverParameters->AnPos=(p->MoverParameters->eimc[eimc_p_Fh]>1?0.001f*Fpoj/(p->MoverParameters->eimc[eimc_p_Fh]):0);
|
|
||||||
p->MoverParameters->AnPos = (FmaxED > 0 ? FzadED / FmaxED : 0);
|
|
||||||
// Fpoj = FzadPN * Min0R(p->MoverParameters->TotalMass / masa, 1);
|
|
||||||
// p->MoverParameters->LocalBrakePosA =
|
|
||||||
// (p->MoverParameters->SlippingWheels ? 0 : Min0R(Max0R(Fpoj / FmaxPoj, 0), 1));
|
|
||||||
p->MoverParameters->LocalBrakePosA = (p->MoverParameters->SlippingWheels ? 0 : FzadPN / FmaxPN);
|
|
||||||
} */
|
|
||||||
|
|
||||||
MED[0][0] = masa*0.001;
|
MED[0][0] = masa*0.001;
|
||||||
MED[0][1] = amax;
|
MED[0][1] = amax;
|
||||||
@@ -2979,14 +2959,6 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
delete[] FmaxEP;
|
delete[] FmaxEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// yB: cos (AI) tu jest nie kompatybilne z czyms (hamulce)
|
|
||||||
// if (Controller!=Humandriver)
|
|
||||||
// if (Mechanik->LastReactionTime>0.5)
|
|
||||||
// {
|
|
||||||
// MoverParameters->BrakeCtrlPos=0;
|
|
||||||
// Mechanik->LastReactionTime=0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
Mechanik->UpdateSituation(dt1); // przebłyski świadomości AI
|
Mechanik->UpdateSituation(dt1); // przebłyski świadomości AI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
EU07.cpp
14
EU07.cpp
@@ -78,8 +78,8 @@ void screenshot_save_thread( char *img )
|
|||||||
png_image png;
|
png_image png;
|
||||||
memset(&png, 0, sizeof(png_image));
|
memset(&png, 0, sizeof(png_image));
|
||||||
png.version = PNG_IMAGE_VERSION;
|
png.version = PNG_IMAGE_VERSION;
|
||||||
png.width = Global::ScreenWidth;
|
png.width = Global::iWindowWidth;
|
||||||
png.height = Global::ScreenHeight;
|
png.height = Global::iWindowHeight;
|
||||||
png.format = PNG_FORMAT_RGB;
|
png.format = PNG_FORMAT_RGB;
|
||||||
|
|
||||||
char datetime[64];
|
char datetime[64];
|
||||||
@@ -95,7 +95,7 @@ void screenshot_save_thread( char *img )
|
|||||||
std::string filename = "screenshots/" + std::string(datetime) +
|
std::string filename = "screenshots/" + std::string(datetime) +
|
||||||
"_" + std::to_string(perf) + ".png";
|
"_" + std::to_string(perf) + ".png";
|
||||||
|
|
||||||
if (png_image_write_to_file(&png, filename.c_str(), 0, img, -Global::ScreenWidth * 3, nullptr) == 1)
|
if (png_image_write_to_file(&png, filename.c_str(), 0, img, -Global::iWindowWidth * 3, nullptr) == 1)
|
||||||
WriteLog("saved " + filename + ".");
|
WriteLog("saved " + filename + ".");
|
||||||
else
|
else
|
||||||
WriteLog("failed to save screenshot.");
|
WriteLog("failed to save screenshot.");
|
||||||
@@ -105,8 +105,8 @@ void screenshot_save_thread( char *img )
|
|||||||
|
|
||||||
void make_screenshot()
|
void make_screenshot()
|
||||||
{
|
{
|
||||||
char *img = new char[Global::ScreenWidth * Global::ScreenHeight * 3];
|
char *img = new char[Global::iWindowWidth * Global::iWindowHeight * 3];
|
||||||
glReadPixels(0, 0, Global::ScreenWidth, Global::ScreenHeight, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
|
glReadPixels(0, 0, Global::iWindowWidth, Global::iWindowHeight, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
|
||||||
|
|
||||||
std::thread t(screenshot_save_thread, img);
|
std::thread t(screenshot_save_thread, img);
|
||||||
t.detach();
|
t.detach();
|
||||||
@@ -117,8 +117,8 @@ void window_resize_callback(GLFWwindow *window, int w, int h)
|
|||||||
{
|
{
|
||||||
// NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
|
// NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
|
||||||
// TBD, TODO: merge them?
|
// TBD, TODO: merge them?
|
||||||
Global::ScreenWidth = Global::iWindowWidth = w;
|
Global::iWindowWidth = w;
|
||||||
Global::ScreenHeight = Global::iWindowHeight = h;
|
Global::iWindowHeight = h;
|
||||||
Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
|
Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ void TEvent::Load(cParser *parser, vector3 *org)
|
|||||||
parser->getTokens(1, false); // case sensitive
|
parser->getTokens(1, false); // case sensitive
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
// str = AnsiString(token.c_str());
|
// str = AnsiString(token.c_str());
|
||||||
Params[0].asText = new char[token.length() + 1];
|
Params[0].asText = new char[token.length() + 1]; // BUG: source of memory leak
|
||||||
strcpy(Params[0].asText, token.c_str());
|
strcpy(Params[0].asText, token.c_str());
|
||||||
if (token != "*") // czy ma zostać bez zmian?
|
if (token != "*") // czy ma zostać bez zmian?
|
||||||
iFlags |= update_memstring;
|
iFlags |= update_memstring;
|
||||||
|
|||||||
34
Float3d.h
34
Float3d.h
@@ -241,7 +241,7 @@ public:
|
|||||||
e[i + 2] = f; // zamiana Y i Z
|
e[i + 2] = f; // zamiana Y i Z
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
inline float4x4 &Rotation(double angle, float3 axis);
|
inline float4x4 &Rotation(float const angle, float3 const &axis);
|
||||||
inline bool IdentityIs()
|
inline bool IdentityIs()
|
||||||
{ // sprawdzenie jednostkowości
|
{ // sprawdzenie jednostkowości
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
@@ -270,34 +270,30 @@ inline glm::vec3 operator*( const float4x4 &m, const glm::vec3 &v ) { // mnożen
|
|||||||
v.x * m[ 0 ][ 2 ] + v.y * m[ 1 ][ 2 ] + v.z * m[ 2 ][ 2 ] + m[ 3 ][ 2 ] );
|
v.x * m[ 0 ][ 2 ] + v.y * m[ 1 ][ 2 ] + v.z * m[ 2 ][ 2 ] + m[ 3 ][ 2 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float4x4 &float4x4::Rotation(double angle, float3 axis)
|
inline float4x4 &float4x4::Rotation(float const Angle, float3 const &Axis)
|
||||||
{
|
{
|
||||||
double c = cos(angle);
|
auto const c = std::cos(Angle);
|
||||||
double s = sin(angle);
|
auto const s = std::sin(Angle);
|
||||||
// One minus c (short name for legibility of formulai)
|
// One minus c (short name for legibility of formulai)
|
||||||
double omc = (1 - c);
|
auto const omc = (1.f - c);
|
||||||
if (axis.Length() != 1.0f)
|
auto const axis = SafeNormalize(Axis);
|
||||||
axis = SafeNormalize(axis);
|
auto const xs = axis.x * s;
|
||||||
double x = axis.x;
|
auto const ys = axis.y * s;
|
||||||
double y = axis.y;
|
auto const zs = axis.z * s;
|
||||||
double z = axis.z;
|
auto const xyomc = axis.x * axis.y * omc;
|
||||||
double xs = x * s;
|
auto const xzomc = axis.x * axis.z * omc;
|
||||||
double ys = y * s;
|
auto const yzomc = axis.y * axis.z * omc;
|
||||||
double zs = z * s;
|
e[0] = axis.x * axis.x * omc + c;
|
||||||
double xyomc = x * y * omc;
|
|
||||||
double xzomc = x * z * omc;
|
|
||||||
double yzomc = y * z * omc;
|
|
||||||
e[0] = x * x * omc + c;
|
|
||||||
e[1] = xyomc + zs;
|
e[1] = xyomc + zs;
|
||||||
e[2] = xzomc - ys;
|
e[2] = xzomc - ys;
|
||||||
e[3] = 0;
|
e[3] = 0;
|
||||||
e[4] = xyomc - zs;
|
e[4] = xyomc - zs;
|
||||||
e[5] = y * y * omc + c;
|
e[5] = axis.y * axis.y * omc + c;
|
||||||
e[6] = yzomc + xs;
|
e[6] = yzomc + xs;
|
||||||
e[7] = 0;
|
e[7] = 0;
|
||||||
e[8] = xzomc + ys;
|
e[8] = xzomc + ys;
|
||||||
e[9] = yzomc - xs;
|
e[9] = yzomc - xs;
|
||||||
e[10] = z * z * omc + c;
|
e[10] = axis.z * axis.z * omc + c;
|
||||||
e[11] = 0;
|
e[11] = 0;
|
||||||
e[12] = 0;
|
e[12] = 0;
|
||||||
e[13] = 0;
|
e[13] = 0;
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ void TGauge::DecValue(double fNewDesired)
|
|||||||
void
|
void
|
||||||
TGauge::UpdateValue( double fNewDesired, PSound Fallbacksound ) {
|
TGauge::UpdateValue( double fNewDesired, PSound Fallbacksound ) {
|
||||||
|
|
||||||
auto const desiredtimes100 = static_cast<int>( 100.0 * fNewDesired );
|
auto const desiredtimes100 = static_cast<int>( std::round( 100.0 * fNewDesired ) );
|
||||||
if( static_cast<int>( std::round( 100.0 * ( fDesiredValue - fOffset ) / fScale ) ) == desiredtimes100 ) {
|
if( static_cast<int>( std::round( 100.0 * ( fDesiredValue - fOffset ) / fScale ) ) == desiredtimes100 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,14 +66,12 @@ cParser *Global::pParser = NULL;
|
|||||||
int Global::iSegmentsRendered = 90; // ilość segmentów do regulacji wydajności
|
int Global::iSegmentsRendered = 90; // ilość segmentów do regulacji wydajności
|
||||||
TCamera *Global::pCamera = NULL; // parametry kamery
|
TCamera *Global::pCamera = NULL; // parametry kamery
|
||||||
TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany bez trzęsienia
|
TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany bez trzęsienia
|
||||||
/*
|
|
||||||
std::string Global::asTranscript[5]; // napisy na ekranie (widoczne)
|
|
||||||
*/
|
|
||||||
TTranscripts Global::tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
TTranscripts Global::tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
||||||
float4 Global::UITextColor = float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
|
float4 Global::UITextColor = float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
|
||||||
|
|
||||||
// parametry scenerii
|
// parametry scenerii
|
||||||
vector3 Global::pCameraPosition;
|
vector3 Global::pCameraPosition;
|
||||||
|
vector3 Global::DebugCameraPosition;
|
||||||
double Global::pCameraRotation;
|
double Global::pCameraRotation;
|
||||||
double Global::pCameraRotationDeg;
|
double Global::pCameraRotationDeg;
|
||||||
std::vector<vector3> Global::FreeCameraInit;
|
std::vector<vector3> Global::FreeCameraInit;
|
||||||
@@ -84,11 +82,12 @@ GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f};
|
|||||||
double Global::fFogStart = 1700;
|
double Global::fFogStart = 1700;
|
||||||
double Global::fFogEnd = 2000;
|
double Global::fFogEnd = 2000;
|
||||||
float Global::Overcast { 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
float Global::Overcast { 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
||||||
|
float Global::BaseDrawRange { 2500.f };
|
||||||
opengl_light Global::DayLight;
|
opengl_light Global::DayLight;
|
||||||
int Global::DynamicLightCount { 3 };
|
int Global::DynamicLightCount { 3 };
|
||||||
bool Global::ScaleSpecularValues { true };
|
bool Global::ScaleSpecularValues { true };
|
||||||
bool Global::RenderShadows { false };
|
bool Global::RenderShadows { false };
|
||||||
Global::shadowtune_t Global::shadowtune = { 2048, 200.0f, 150.0f, 100.0f };
|
Global::shadowtune_t Global::shadowtune = { 2048, 250.f, 250.f, 500.f };
|
||||||
bool Global::bRollFix = true; // czy wykonać przeliczanie przechyłki
|
bool Global::bRollFix = true; // czy wykonać przeliczanie przechyłki
|
||||||
bool Global::bJoinEvents = false; // czy grupować eventy o tych samych nazwach
|
bool Global::bJoinEvents = false; // czy grupować eventy o tych samych nazwach
|
||||||
int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru
|
int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru
|
||||||
@@ -98,7 +97,7 @@ int Global::Keys[MaxKeys];
|
|||||||
bool Global::RealisticControlMode{ false };
|
bool Global::RealisticControlMode{ false };
|
||||||
int Global::iWindowWidth = 800;
|
int Global::iWindowWidth = 800;
|
||||||
int Global::iWindowHeight = 600;
|
int Global::iWindowHeight = 600;
|
||||||
float Global::fDistanceFactor = Global::ScreenHeight / 768.0; // baza do przeliczania odległości dla LoD
|
float Global::fDistanceFactor = Global::iWindowHeight / 768.0; // baza do przeliczania odległości dla LoD
|
||||||
int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
|
int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
|
||||||
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
|
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
|
||||||
bool Global::InputGamepad{ true };
|
bool Global::InputGamepad{ true };
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ class Global
|
|||||||
static int Keys[MaxKeys];
|
static int Keys[MaxKeys];
|
||||||
static bool RealisticControlMode; // controls ability to steer the vehicle from outside views
|
static bool RealisticControlMode; // controls ability to steer the vehicle from outside views
|
||||||
static Math3D::vector3 pCameraPosition; // pozycja kamery w świecie
|
static Math3D::vector3 pCameraPosition; // pozycja kamery w świecie
|
||||||
|
static Math3D::vector3 DebugCameraPosition; // pozycja kamery w świecie
|
||||||
static double
|
static double
|
||||||
pCameraRotation; // kierunek bezwzględny kamery w świecie: 0=północ, 90°=zachód (-azymut)
|
pCameraRotation; // kierunek bezwzględny kamery w świecie: 0=północ, 90°=zachód (-azymut)
|
||||||
static double pCameraRotationDeg; // w stopniach, dla animacji billboard
|
static double pCameraRotationDeg; // w stopniach, dla animacji billboard
|
||||||
@@ -223,6 +224,7 @@ class Global
|
|||||||
// static bool bTimeChange;
|
// static bool bTimeChange;
|
||||||
|
|
||||||
// TODO: put these things in the renderer
|
// TODO: put these things in the renderer
|
||||||
|
static float BaseDrawRange;
|
||||||
static opengl_light DayLight;
|
static opengl_light DayLight;
|
||||||
static int DynamicLightCount;
|
static int DynamicLightCount;
|
||||||
static bool ScaleSpecularValues;
|
static bool ScaleSpecularValues;
|
||||||
@@ -315,9 +317,6 @@ class Global
|
|||||||
// informacje podczas kalibracji
|
// informacje podczas kalibracji
|
||||||
static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
||||||
static bool bJoinEvents; // czy grupować eventy o tych samych nazwach
|
static bool bJoinEvents; // czy grupować eventy o tych samych nazwach
|
||||||
/*
|
|
||||||
static std::string asTranscript[5]; // napisy na ekranie (widoczne)
|
|
||||||
*/
|
|
||||||
static TTranscripts tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
static TTranscripts tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
|
||||||
static float4 UITextColor; // base color of UI text
|
static float4 UITextColor; // base color of UI text
|
||||||
static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47
|
static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47
|
||||||
|
|||||||
276
Ground.cpp
276
Ground.cpp
@@ -153,74 +153,30 @@ TGroundNode::TGroundNode( TGroundNodeType t ) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TGroundNode::InitNormals()
|
// obliczenie wektorów normalnych
|
||||||
{ // obliczenie wektorów normalnych
|
void TGroundNode::InitNormals() {
|
||||||
glm::dvec3 v1, v2, v3, v4, v5;
|
|
||||||
glm::vec3 n1, n2, n3, n4;
|
glm::dvec3 v1, v2;
|
||||||
|
glm::vec3 n1;
|
||||||
glm::vec2 t1;
|
glm::vec2 t1;
|
||||||
int i;
|
|
||||||
switch (iType)
|
|
||||||
{
|
|
||||||
case GL_TRIANGLE_STRIP:
|
|
||||||
v1 = Piece->vertices[0].position - Piece->vertices[1].position;
|
|
||||||
v2 = Piece->vertices[1].position - Piece->vertices[2].position;
|
|
||||||
n1 = glm::normalize(glm::cross(v1, v2));
|
|
||||||
if (Piece->vertices[0].normal == glm::vec3())
|
|
||||||
Piece->vertices[0].normal = n1;
|
|
||||||
v3 = Piece->vertices[2].position - Piece->vertices[3].position;
|
|
||||||
n2 = glm::normalize(glm::cross(v3, v2));
|
|
||||||
if (Piece->vertices[1].normal == glm::vec3())
|
|
||||||
Piece->vertices[1].normal = (n1 + n2) * 0.5f;
|
|
||||||
|
|
||||||
for ( i = 2; i < iNumVerts - 2; i += 2)
|
for( auto i = 0; i < iNumVerts; i += 3 ) {
|
||||||
{
|
|
||||||
v4 = Piece->vertices[i - 1].position - Piece->vertices[i].position;
|
|
||||||
v5 = Piece->vertices[i].position - Piece->vertices[i + 1].position;
|
|
||||||
n3 = glm::normalize(glm::cross(v3, v4));
|
|
||||||
n4 = glm::normalize(glm::cross(v5, v4));
|
|
||||||
if (Piece->vertices[i].normal == glm::vec3())
|
|
||||||
Piece->vertices[i].normal = (n1 + n2 + n3) / 3.0f;
|
|
||||||
if (Piece->vertices[i + 1].normal == glm::vec3())
|
|
||||||
Piece->vertices[i + 1].normal = (n2 + n3 + n4) / 3.0f;
|
|
||||||
n1 = n3;
|
|
||||||
n2 = n4;
|
|
||||||
v3 = v5;
|
|
||||||
}
|
|
||||||
if (Piece->vertices[i].normal == glm::vec3())
|
|
||||||
Piece->vertices[i].normal = (n1 + n2) / 2.0f;
|
|
||||||
if (i + 1 < iNumVerts)
|
|
||||||
{
|
|
||||||
if (Piece->vertices[i + 1].normal == glm::vec3())
|
|
||||||
Piece->vertices[i + 1].normal = n2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
WriteLog("odd number of vertices, normals may be wrong!");
|
|
||||||
|
|
||||||
break;
|
v1 = Piece->vertices[ i + 0 ].position - Piece->vertices[ i + 1 ].position;
|
||||||
case GL_TRIANGLE_FAN:
|
v2 = Piece->vertices[ i + 1 ].position - Piece->vertices[ i + 2 ].position;
|
||||||
|
n1 = glm::normalize( glm::cross( v1, v2 ) );
|
||||||
break;
|
if( Piece->vertices[ i + 0 ].normal == glm::vec3() )
|
||||||
case GL_TRIANGLES:
|
Piece->vertices[ i + 0 ].normal = ( n1 );
|
||||||
for (i = 0; i < iNumVerts; i += 3)
|
if( Piece->vertices[ i + 1 ].normal == glm::vec3() )
|
||||||
{
|
Piece->vertices[ i + 1 ].normal = ( n1 );
|
||||||
v1 = Piece->vertices[i + 0].position - Piece->vertices[i + 1].position;
|
if( Piece->vertices[ i + 2 ].normal == glm::vec3() )
|
||||||
v2 = Piece->vertices[i + 1].position - Piece->vertices[i + 2].position;
|
Piece->vertices[ i + 2 ].normal = ( n1 );
|
||||||
auto c = glm::cross(v1, v2);
|
t1 = glm::vec2(
|
||||||
n1 = glm::length(c) != 0 ? glm::normalize(c) : glm::vec3();
|
std::floor( Piece->vertices[ i + 0 ].texture.s ),
|
||||||
if( Piece->vertices[i + 0].normal == glm::vec3() )
|
std::floor( Piece->vertices[ i + 0 ].texture.t ) );
|
||||||
Piece->vertices[i + 0].normal = (n1);
|
Piece->vertices[ i + 1 ].texture -= t1;
|
||||||
if( Piece->vertices[i + 1].normal == glm::vec3() )
|
Piece->vertices[ i + 2 ].texture -= t1;
|
||||||
Piece->vertices[i + 1].normal = (n1);
|
Piece->vertices[ i + 0 ].texture -= t1;
|
||||||
if( Piece->vertices[i + 2].normal == glm::vec3() )
|
|
||||||
Piece->vertices[i + 2].normal = (n1);
|
|
||||||
t1 = glm::vec2(
|
|
||||||
std::floor( Piece->vertices[ i + 0 ].texture.s ),
|
|
||||||
std::floor( Piece->vertices[ i + 0 ].texture.t ) );
|
|
||||||
Piece->vertices[ i + 1 ].texture -= t1;
|
|
||||||
Piece->vertices[ i + 2 ].texture -= t1;
|
|
||||||
Piece->vertices[ i + 0 ].texture -= t1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,6 +661,42 @@ TGround::GetRect( double x, double z ) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// convert tp_terrain model to a series of triangle nodes
|
||||||
|
void
|
||||||
|
TGround::convert_terrain( TGroundNode const *Terrain ) {
|
||||||
|
|
||||||
|
TSubModel *submodel { nullptr };
|
||||||
|
for( auto cellindex = 1; cellindex < Terrain->iCount; ++cellindex ) {
|
||||||
|
// go through all submodels for individual terrain cells...
|
||||||
|
submodel = Terrain->nNode[ cellindex ].smTerrain;
|
||||||
|
convert_terrain( submodel );
|
||||||
|
// if there's more than one group of triangles in the cell they're held as children of the primary submodel
|
||||||
|
submodel = submodel->ChildGet();
|
||||||
|
while( submodel != nullptr ) {
|
||||||
|
convert_terrain( submodel );
|
||||||
|
submodel = submodel->NextGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TGround::convert_terrain( TSubModel const *Submodel ) {
|
||||||
|
|
||||||
|
auto groundnode = new TGroundNode( GL_TRIANGLES );
|
||||||
|
Submodel->convert( *groundnode );
|
||||||
|
|
||||||
|
if( groundnode->iNumVerts > 0 ) {
|
||||||
|
// jeśli nie jest pojazdem ostatni dodany dołączamy na końcu nowego
|
||||||
|
groundnode->nNext = nRootOfType[ groundnode->iType ];
|
||||||
|
// ustawienie nowego na początku listy
|
||||||
|
nRootOfType[ groundnode->iType ] = groundnode;
|
||||||
|
++iNumNodes;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete groundnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double fTrainSetVel = 0;
|
double fTrainSetVel = 0;
|
||||||
double fTrainSetDir = 0;
|
double fTrainSetDir = 0;
|
||||||
double fTrainSetDist = 0; // odległość składu od punktu 1 w stronę punktu 2
|
double fTrainSetDist = 0; // odległość składu od punktu 1 w stronę punktu 2
|
||||||
@@ -1220,61 +1212,123 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TP_MODEL:
|
case TP_MODEL: {
|
||||||
if (rmin < 0)
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
{
|
if( rmin < 0 ) {
|
||||||
tmp->iType = TP_TERRAIN;
|
tmp->iType = TP_TERRAIN;
|
||||||
tmp->fSquareMinRadius = 0; // to w ogóle potrzebne?
|
tmp->fSquareMinRadius = 0; // to w ogóle potrzebne?
|
||||||
}
|
}
|
||||||
parser->getTokens(3);
|
parser->getTokens( 3 );
|
||||||
*parser >> tmp->pCenter.x >> tmp->pCenter.y >> tmp->pCenter.z;
|
*parser >> tmp->pCenter.x >> tmp->pCenter.y >> tmp->pCenter.z;
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> tf1;
|
*parser >> tf1;
|
||||||
// OlO_EU&KAKISH-030103: obracanie punktow zaczepien w modelu
|
// OlO_EU&KAKISH-030103: obracanie punktow zaczepien w modelu
|
||||||
tmp->pCenter.RotateY(aRotate.y / 180.0 * M_PI);
|
tmp->pCenter.RotateY( aRotate.y / 180.0 * M_PI );
|
||||||
// McZapkie-260402: model tez ma wspolrzedne wzgledne
|
// McZapkie-260402: model tez ma wspolrzedne wzgledne
|
||||||
tmp->pCenter += pOrigin;
|
tmp->pCenter += pOrigin;
|
||||||
|
|
||||||
tmp->Model = new TAnimModel();
|
tmp->Model = new TAnimModel();
|
||||||
tmp->Model->RaAnglesSet(aRotate.x, tf1 + aRotate.y, aRotate.z); // dostosowanie do pochylania linii
|
tmp->Model->RaAnglesSet( aRotate.x, tf1 + aRotate.y, aRotate.z ); // dostosowanie do pochylania linii
|
||||||
if( tmp->Model->Load( parser, tmp->iType == TP_TERRAIN ) ) {
|
if( tmp->Model->Load( parser, tmp->iType == TP_TERRAIN ) ) {
|
||||||
// wczytanie modelu, tekstury i stanu świateł...
|
// wczytanie modelu, tekstury i stanu świateł...
|
||||||
tmp->iFlags = tmp->Model->Flags() | 0x200; // ustalenie, czy przezroczysty; flaga usuwania
|
tmp->iFlags = tmp->Model->Flags() | 0x200; // ustalenie, czy przezroczysty; flaga usuwania
|
||||||
}
|
}
|
||||||
else if (tmp->iType != TP_TERRAIN)
|
else if( tmp->iType != TP_TERRAIN ) { // model nie wczytał się - ignorowanie node
|
||||||
{ // model nie wczytał się - ignorowanie node
|
|
||||||
delete tmp;
|
delete tmp;
|
||||||
tmp = NULL; // nie może być tu return
|
tmp = NULL; // nie może być tu return
|
||||||
break; // nie może być tu return?
|
break; // nie może być tu return?
|
||||||
}
|
}
|
||||||
if (tmp->iType == TP_TERRAIN)
|
if( tmp->iType == TP_TERRAIN ) { // jeśli model jest terenem, trzeba utworzyć dodatkowe obiekty
|
||||||
{ // jeśli model jest terenem, trzeba utworzyć dodatkowe obiekty
|
|
||||||
// po wczytaniu model ma już utworzone DL albo VBO
|
// po wczytaniu model ma już utworzone DL albo VBO
|
||||||
Global::pTerrainCompact = tmp->Model; // istnieje co najmniej jeden obiekt terenu
|
Global::pTerrainCompact = tmp->Model; // istnieje co najmniej jeden obiekt terenu
|
||||||
tmp->pCenter = Math3D::vector3( 0.0, 0.0, 0.0 ); // enforce placement in the world center
|
tmp->pCenter = Math3D::vector3( 0.0, 0.0, 0.0 ); // enforce placement in the world center
|
||||||
tmp->iCount = Global::pTerrainCompact->TerrainCount() + 1; // zliczenie submodeli
|
tmp->iCount = Global::pTerrainCompact->TerrainCount() + 1; // zliczenie submodeli
|
||||||
tmp->nNode = new TGroundNode[tmp->iCount]; // sztuczne node dla kwadratów
|
tmp->nNode = new TGroundNode[ tmp->iCount ]; // sztuczne node dla kwadratów
|
||||||
tmp->nNode[0].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
tmp->nNode[ 0 ].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
||||||
tmp->nNode[0].Model = Global::pTerrainCompact;
|
tmp->nNode[ 0 ].Model = Global::pTerrainCompact;
|
||||||
tmp->nNode[0].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
tmp->nNode[ 0 ].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
||||||
for (int i = 1; i < tmp->iCount; ++i)
|
for( int i = 1; i < tmp->iCount; ++i ) { // a reszta to submodele
|
||||||
{ // a reszta to submodele
|
tmp->nNode[ i ].iType = TP_SUBMODEL;
|
||||||
tmp->nNode[i].iType = TP_SUBMODEL;
|
tmp->nNode[ i ].smTerrain = Global::pTerrainCompact->TerrainSquare( i - 1 );
|
||||||
tmp->nNode[i].smTerrain = Global::pTerrainCompact->TerrainSquare(i - 1);
|
tmp->nNode[ i ].iFlags = 0x10; // nieprzezroczyste; nie usuwany
|
||||||
tmp->nNode[i].iFlags = 0x10; // nieprzezroczyste; nie usuwany
|
tmp->nNode[ i ].bVisible = true;
|
||||||
tmp->nNode[i].bVisible = true;
|
tmp->nNode[ i ].pCenter = tmp->pCenter; // nie przesuwamy w inne miejsce
|
||||||
tmp->nNode[i].pCenter = tmp->pCenter; // nie przesuwamy w inne miejsce
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!tmp->asName.empty()) // jest pusta gdy "none"
|
else if( !tmp->asName.empty() ) // jest pusta gdy "none"
|
||||||
{ // dodanie do wyszukiwarki
|
{ // dodanie do wyszukiwarki
|
||||||
if( false == m_trackmap.Add( TP_MODEL, tmp->asName, tmp ) ) {
|
if( false == m_trackmap.Add( TP_MODEL, tmp->asName, tmp ) ) {
|
||||||
// przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna)
|
// przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna)
|
||||||
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// str=Parser->GetNextSymbol().LowerCase();
|
#else
|
||||||
|
if( rmin < 0 ) {
|
||||||
|
// legacy leftover: special case, terrain provided as 3d model
|
||||||
|
tmp->iType = TP_TERRAIN;
|
||||||
|
tmp->fSquareMinRadius = 0; // to w ogóle potrzebne?
|
||||||
|
// we ignore center and rotation for terrain; they should be set to 0 anyway
|
||||||
|
parser->getTokens( 4 );
|
||||||
|
|
||||||
|
tmp->iFlags = 0x200; // flaga usuwania
|
||||||
|
tmp->Model = new TAnimModel();
|
||||||
|
if( false == tmp->Model->Load( parser, true ) ) {
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmp->iFlags |= tmp->Model->Flags(); // ustalenie, czy przezroczysty
|
||||||
|
tmp->pCenter = Math3D::vector3(); // enforce placement in the world center
|
||||||
|
// jeśli model jest terenem, trzeba utworzyć dodatkowe obiekty
|
||||||
|
tmp->iCount = tmp->Model->TerrainCount() + 1; // zliczenie submodeli
|
||||||
|
Global::pTerrainCompact = tmp->Model;
|
||||||
|
tmp->nNode = new TGroundNode[ tmp->iCount ]; // sztuczne node dla kwadratów
|
||||||
|
tmp->nNode[ 0 ].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
||||||
|
tmp->nNode[ 0 ].Model = Global::pTerrainCompact;
|
||||||
|
tmp->nNode[ 0 ].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
||||||
|
for( auto i = 1; i < tmp->iCount; ++i ) { // a reszta to submodele
|
||||||
|
tmp->nNode[ i ].iType = TP_SUBMODEL;
|
||||||
|
tmp->nNode[ i ].smTerrain = Global::pTerrainCompact->TerrainSquare( i - 1 );
|
||||||
|
tmp->nNode[ i ].iFlags = 0x10; // nieprzezroczyste; nie usuwany
|
||||||
|
tmp->nNode[ i ].bVisible = true;
|
||||||
|
tmp->nNode[ i ].pCenter = tmp->pCenter; // nie przesuwamy w inne miejsce
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// regular 3d model
|
||||||
|
parser->getTokens( 3 );
|
||||||
|
*parser
|
||||||
|
>> tmp->pCenter.x
|
||||||
|
>> tmp->pCenter.y
|
||||||
|
>> tmp->pCenter.z;
|
||||||
|
parser->getTokens();
|
||||||
|
*parser >> tf1;
|
||||||
|
// OlO_EU&KAKISH-030103: obracanie punktow zaczepien w modelu
|
||||||
|
tmp->pCenter.RotateY( glm::radians( aRotate.y ) );
|
||||||
|
// McZapkie-260402: model tez ma wspolrzedne wzgledne
|
||||||
|
tmp->pCenter += pOrigin;
|
||||||
|
|
||||||
|
tmp->iFlags = 0x200; // flaga usuwania
|
||||||
|
tmp->Model = new TAnimModel();
|
||||||
|
tmp->Model->RaAnglesSet( aRotate.x, tf1 + aRotate.y, aRotate.z ); // dostosowanie do pochylania linii
|
||||||
|
if( false == tmp->Model->Load( parser, false ) ) {
|
||||||
|
// model nie wczytał się - ignorowanie node
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr; // nie może być tu return
|
||||||
|
break; // nie może być tu return?
|
||||||
|
}
|
||||||
|
tmp->iFlags |= tmp->Model->Flags(); // ustalenie, czy przezroczysty
|
||||||
|
if( false == tmp->asName.empty() ) { // jest pusta gdy "none"
|
||||||
|
// dodanie do wyszukiwarki
|
||||||
|
if( false == m_trackmap.Add( TP_MODEL, tmp->asName, tmp ) ) {
|
||||||
|
// przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna)
|
||||||
|
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// case TP_GEOMETRY :
|
// case TP_GEOMETRY :
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
case GL_TRIANGLE_STRIP:
|
case GL_TRIANGLE_STRIP:
|
||||||
@@ -1353,12 +1407,12 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
>> vertex.normal.z
|
>> vertex.normal.z
|
||||||
>> vertex.texture.s
|
>> vertex.texture.s
|
||||||
>> vertex.texture.t;
|
>> vertex.texture.t;
|
||||||
vertex.position = glm::rotateZ( vertex.position, aRotate.z / 180 * M_PI );
|
vertex.position = glm::rotateZ( vertex.position, glm::radians( aRotate.z ) );
|
||||||
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
vertex.position = glm::rotateX( vertex.position, glm::radians( aRotate.x ) );
|
||||||
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
vertex.position = glm::rotateY( vertex.position, glm::radians( aRotate.y ) );
|
||||||
vertex.normal = glm::rotateZ( vertex.normal, static_cast<float>( aRotate.z / 180 * M_PI ) );
|
vertex.normal = glm::rotateZ( vertex.normal, glm::radians<float>( aRotate.z ) );
|
||||||
vertex.normal = glm::rotateX( vertex.normal, static_cast<float>( aRotate.x / 180 * M_PI ) );
|
vertex.normal = glm::rotateX( vertex.normal, glm::radians<float>( aRotate.x ) );
|
||||||
vertex.normal = glm::rotateY( vertex.normal, static_cast<float>( aRotate.y / 180 * M_PI ) );
|
vertex.normal = glm::rotateY( vertex.normal, glm::radians<float>( aRotate.y ) );
|
||||||
vertex.position += glm::dvec3{ pOrigin };
|
vertex.position += glm::dvec3{ pOrigin };
|
||||||
if( true == clamps ) { vertex.texture.s = clamp( vertex.texture.s, 0.001f, 0.999f ); }
|
if( true == clamps ) { vertex.texture.s = clamp( vertex.texture.s, 0.001f, 0.999f ); }
|
||||||
if( true == clampt ) { vertex.texture.t = clamp( vertex.texture.t, 0.001f, 0.999f ); }
|
if( true == clampt ) { vertex.texture.t = clamp( vertex.texture.t, 0.001f, 0.999f ); }
|
||||||
@@ -1487,9 +1541,9 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
*parser
|
*parser
|
||||||
>> vertex.position.y
|
>> vertex.position.y
|
||||||
>> vertex.position.z;
|
>> vertex.position.z;
|
||||||
vertex.position = glm::rotateZ( vertex.position, aRotate.z / 180 * M_PI );
|
vertex.position = glm::rotateZ( vertex.position, glm::radians( aRotate.z ) );
|
||||||
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
vertex.position = glm::rotateX( vertex.position, glm::radians( aRotate.x ) );
|
||||||
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
vertex.position = glm::rotateY( vertex.position, glm::radians( aRotate.y ) );
|
||||||
|
|
||||||
vertex.position += glm::dvec3{ pOrigin };
|
vertex.position += glm::dvec3{ pOrigin };
|
||||||
// convert all data to gl_lines to allow data merge for matching nodes
|
// convert all data to gl_lines to allow data merge for matching nodes
|
||||||
@@ -1621,7 +1675,8 @@ void TGround::FirstInit()
|
|||||||
for (int type = 0; type < TP_LAST; ++type) {
|
for (int type = 0; type < TP_LAST; ++type) {
|
||||||
for (TGroundNode *Current = nRootOfType[type]; Current != nullptr; Current = Current->nNext) {
|
for (TGroundNode *Current = nRootOfType[type]; Current != nullptr; Current = Current->nNext) {
|
||||||
|
|
||||||
Current->InitNormals();
|
if( type == GL_TRIANGLES ) { Current->InitNormals(); }
|
||||||
|
|
||||||
if (Current->iType != TP_DYNAMIC)
|
if (Current->iType != TP_DYNAMIC)
|
||||||
{ // pojazdów w ogóle nie dotyczy dodawanie do mapy
|
{ // pojazdów w ogóle nie dotyczy dodawanie do mapy
|
||||||
if( ( type == TP_EVLAUNCH )
|
if( ( type == TP_EVLAUNCH )
|
||||||
@@ -1629,6 +1684,7 @@ void TGround::FirstInit()
|
|||||||
// dodanie do globalnego obiektu
|
// dodanie do globalnego obiektu
|
||||||
srGlobal.NodeAdd( Current );
|
srGlobal.NodeAdd( Current );
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
else if (type == TP_TERRAIN) {
|
else if (type == TP_TERRAIN) {
|
||||||
// specjalne przetwarzanie terenu wczytanego z pliku E3D
|
// specjalne przetwarzanie terenu wczytanego z pliku E3D
|
||||||
TGroundRect *gr;
|
TGroundRect *gr;
|
||||||
@@ -1641,6 +1697,7 @@ void TGround::FirstInit()
|
|||||||
gr->nTerrain = Current->nNode + j; // zapamiętanie
|
gr->nTerrain = Current->nNode + j; // zapamiętanie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
TSubRect *targetcell { nullptr };
|
TSubRect *targetcell { nullptr };
|
||||||
// test whether we can add the node to a ground cell, or a subcell
|
// test whether we can add the node to a ground cell, or a subcell
|
||||||
@@ -1744,6 +1801,15 @@ bool TGround::Init(std::string File)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifndef EU07_SCENERY_EDITOR
|
||||||
|
case TP_TERRAIN: {
|
||||||
|
// convert legacy terrain model to a series of triangle nodes, to take advantage of camera-centric render and geometry merging
|
||||||
|
// NOTE: this leaves us with a large model we don't use loaded and taking space. it'll sort of solve itself when the binary scenery file is in place
|
||||||
|
convert_terrain( LastNode );
|
||||||
|
SafeDelete( LastNode );
|
||||||
|
Global::pTerrainCompact = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2121,8 +2187,10 @@ bool TGround::Init(std::string File)
|
|||||||
|
|
||||||
if (!bInitDone)
|
if (!bInitDone)
|
||||||
FirstInit(); // jeśli nie było w scenerii
|
FirstInit(); // jeśli nie było w scenerii
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
if (Global::pTerrainCompact)
|
if (Global::pTerrainCompact)
|
||||||
TerrainWrite(); // Ra: teraz można zapisać teren w jednym pliku
|
TerrainWrite(); // Ra: teraz można zapisać teren w jednym pliku
|
||||||
|
#endif
|
||||||
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3494,18 +3562,6 @@ void
|
|||||||
TGround::Update_Lights() {
|
TGround::Update_Lights() {
|
||||||
|
|
||||||
m_lights.update();
|
m_lights.update();
|
||||||
// arrange the light array from closest to farthest from current position of the camera
|
|
||||||
auto const camera = Global::pCameraPosition;
|
|
||||||
std::sort(
|
|
||||||
m_lights.data.begin(),
|
|
||||||
m_lights.data.end(),
|
|
||||||
[&]( light_array::light_record const &Left, light_array::light_record const &Right ) {
|
|
||||||
// move lights which are off at the end...
|
|
||||||
if( Left.intensity == 0.0f ) { return false; }
|
|
||||||
if( Right.intensity == 0.0f ) { return true; }
|
|
||||||
// ...otherwise prefer closer and/or brigher light sources
|
|
||||||
return ((camera - Left.position).LengthSquared() * (1.0f - Left.intensity)) < ((camera - Right.position).LengthSquared() * (1.0f - Right.intensity));
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Winger 170204 - szukanie trakcji nad pantografami
|
// Winger 170204 - szukanie trakcji nad pantografami
|
||||||
|
|||||||
7
Ground.h
7
Ground.h
@@ -175,10 +175,6 @@ class TSubRect : /*public Resource,*/ public CMesh
|
|||||||
TTrack **tTracks = nullptr; // tory do renderowania pojazdów
|
TTrack **tTracks = nullptr; // tory do renderowania pojazdów
|
||||||
protected:
|
protected:
|
||||||
TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji
|
TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
TGroundNode *nRootMesh = nullptr; // obiekty renderujące wg tekstury (wtórne, lista po nNext2)
|
|
||||||
TGroundNode *nMeshed = nullptr; // lista obiektów dla których istnieją obiekty renderujące grupowo
|
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
TGroundNode *nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
|
TGroundNode *nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
|
||||||
TGroundNode *nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
|
TGroundNode *nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
|
||||||
@@ -333,6 +329,9 @@ class TGround
|
|||||||
void TrackJoin(TGroundNode *Current);
|
void TrackJoin(TGroundNode *Current);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// convert tp_terrain model to a series of triangle nodes
|
||||||
|
void convert_terrain( TGroundNode const *Terrain );
|
||||||
|
void convert_terrain( TSubModel const *Submodel );
|
||||||
void RaTriangleDivider(TGroundNode *node);
|
void RaTriangleDivider(TGroundNode *node);
|
||||||
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
|||||||
@@ -384,14 +384,14 @@ struct TBoilerType {
|
|||||||
};
|
};
|
||||||
/*rodzaj odbieraka pradu*/
|
/*rodzaj odbieraka pradu*/
|
||||||
struct TCurrentCollector {
|
struct TCurrentCollector {
|
||||||
long CollectorsNo{ 0 }; //musi być tu, bo inaczej się kopie
|
long CollectorsNo; //musi być tu, bo inaczej się kopie
|
||||||
double MinH{ 0.0 }; double MaxH{ 0.0 }; //zakres ruchu pantografu, nigdzie nie używany
|
double MinH; double MaxH; //zakres ruchu pantografu, nigdzie nie używany
|
||||||
double CSW{ 0.0 }; //szerokość części roboczej (styku) ślizgacza
|
double CSW; //szerokość części roboczej (styku) ślizgacza
|
||||||
double MinV{ 0.0 }; double MaxV{ 0.0 }; //minimalne i maksymalne akceptowane napięcie
|
double MinV; double MaxV; //minimalne i maksymalne akceptowane napięcie
|
||||||
double OVP{ 0.0 }; //czy jest przekaznik nadnapieciowy
|
double OVP; //czy jest przekaznik nadnapieciowy
|
||||||
double InsetV{ 0.0 }; //minimalne napięcie wymagane do załączenia
|
double InsetV; //minimalne napięcie wymagane do załączenia
|
||||||
double MinPress{ 0.0 }; //minimalne ciśnienie do załączenia WS
|
double MinPress; //minimalne ciśnienie do załączenia WS
|
||||||
double MaxPress{ 0.0 }; //maksymalne ciśnienie za reduktorem
|
double MaxPress; //maksymalne ciśnienie za reduktorem
|
||||||
//inline TCurrentCollector() {
|
//inline TCurrentCollector() {
|
||||||
// CollectorsNo = 0;
|
// CollectorsNo = 0;
|
||||||
// MinH, MaxH, CSW, MinV, MaxV = 0.0;
|
// MinH, MaxH, CSW, MinV, MaxV = 0.0;
|
||||||
@@ -624,14 +624,14 @@ public:
|
|||||||
bool Signalling = false; /*Czy jest zalaczona sygnalizacja hamowania ostatniego wagonu*/
|
bool Signalling = false; /*Czy jest zalaczona sygnalizacja hamowania ostatniego wagonu*/
|
||||||
bool DoorSignalling = false; /*Czy jest zalaczona sygnalizacja blokady drzwi*/
|
bool DoorSignalling = false; /*Czy jest zalaczona sygnalizacja blokady drzwi*/
|
||||||
bool Radio = true; /*Czy jest zalaczony radiotelefon*/
|
bool Radio = true; /*Czy jest zalaczony radiotelefon*/
|
||||||
double NominalBatteryVoltage = 0.0; /*Winger - baterie w elektrykach*/
|
float NominalBatteryVoltage = 0.f; /*Winger - baterie w elektrykach*/
|
||||||
TDimension Dim; /*wymiary*/
|
TDimension Dim; /*wymiary*/
|
||||||
double Cx = 0.0; /*wsp. op. aerodyn.*/
|
double Cx = 0.0; /*wsp. op. aerodyn.*/
|
||||||
double Floor = 0.96; //poziom podłogi dla ładunków
|
float Floor = 0.96f; //poziom podłogi dla ładunków
|
||||||
double WheelDiameter = 1.0; /*srednica kol napednych*/
|
float WheelDiameter = 1.f; /*srednica kol napednych*/
|
||||||
double WheelDiameterL = 0.9; //Ra: srednica kol tocznych przednich
|
float WheelDiameterL = 0.9f; //Ra: srednica kol tocznych przednich
|
||||||
double WheelDiameterT = 0.9; //Ra: srednica kol tocznych tylnych
|
float WheelDiameterT = 0.9f; //Ra: srednica kol tocznych tylnych
|
||||||
double TrackW = 1.435; /*nominalna szerokosc toru [m]*/
|
float TrackW = 1.435f; /*nominalna szerokosc toru [m]*/
|
||||||
double AxleInertialMoment = 0.0; /*moment bezwladnosci zestawu kolowego*/
|
double AxleInertialMoment = 0.0; /*moment bezwladnosci zestawu kolowego*/
|
||||||
std::string AxleArangement; /*uklad osi np. Bo'Bo' albo 1'C*/
|
std::string AxleArangement; /*uklad osi np. Bo'Bo' albo 1'C*/
|
||||||
int NPoweredAxles = 0; /*ilosc osi napednych liczona z powyzszego*/
|
int NPoweredAxles = 0; /*ilosc osi napednych liczona z powyzszego*/
|
||||||
|
|||||||
@@ -8178,7 +8178,7 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
else if (Command == "PantRear") /*Winger 160204, ABu 310105 i 030305*/
|
else if (Command == "PantRear") /*Winger 160204, ABu 310105 i 030305*/
|
||||||
{ // Ra: uwzględnić trzeba jeszcze zgodność sprzęgów
|
{ // Ra: uwzględnić trzeba jeszcze zgodność sprzęgów
|
||||||
if ((TrainType == dt_EZT))
|
if ((TrainType == dt_EZT))
|
||||||
{ /*'ezt'*/
|
{ //'ezt'
|
||||||
if ((CValue1 == 1))
|
if ((CValue1 == 1))
|
||||||
{
|
{
|
||||||
PantRearUp = true;
|
PantRearUp = true;
|
||||||
@@ -8191,9 +8191,9 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /*nie 'ezt'*/
|
{ //nie 'ezt'
|
||||||
if ((CValue1 == 1))
|
if ((CValue1 == 1))
|
||||||
/*if ostatni polaczony sprz. sterowania*/
|
//if ostatni polaczony sprz. sterowania
|
||||||
if ((TestFlag(Couplers[1].CouplingFlag, ctrain_controll) && (CValue2 == 1)) ||
|
if ((TestFlag(Couplers[1].CouplingFlag, ctrain_controll) && (CValue2 == 1)) ||
|
||||||
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ Copyright (C) 2007-2014 Maciej Cierniak
|
|||||||
|
|
||||||
bool DebugModeFlag = false;
|
bool DebugModeFlag = false;
|
||||||
bool FreeFlyModeFlag = false;
|
bool FreeFlyModeFlag = false;
|
||||||
|
bool DebugCameraFlag = false;
|
||||||
|
|
||||||
double Max0R(double x1, double x2)
|
double Max0R(double x1, double x2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
extern bool DebugModeFlag;
|
extern bool DebugModeFlag;
|
||||||
extern bool FreeFlyModeFlag;
|
extern bool FreeFlyModeFlag;
|
||||||
|
extern bool DebugCameraFlag;
|
||||||
|
|
||||||
/*funkcje matematyczne*/
|
/*funkcje matematyczne*/
|
||||||
double Max0R(double x1, double x2);
|
double Max0R(double x1, double x2);
|
||||||
|
|||||||
180
MdlMngr.cpp
180
MdlMngr.cpp
@@ -17,64 +17,45 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "MdlMngr.h"
|
#include "MdlMngr.h"
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Logs.h"
|
|
||||||
#include "McZapkie/mctools.h"
|
#include "McZapkie/mctools.h"
|
||||||
|
|
||||||
//#define SeekFiles std::string("*.t3d")
|
// wczytanie modelu do kontenerka
|
||||||
|
TModel3d *
|
||||||
|
TMdlContainer::LoadModel(std::string const &Name, bool const Dynamic) {
|
||||||
|
|
||||||
TModel3d * TMdlContainer::LoadModel(std::string const &NewName, bool dynamic)
|
Model = std::make_shared<TModel3d>();
|
||||||
{ // wczytanie modelu do kontenerka
|
if( true == Model->LoadFromFile( Name, Dynamic ) ) {
|
||||||
SafeDelete(Model);
|
m_name = Name;
|
||||||
Name = NewName;
|
return Model.get();
|
||||||
Model = new TModel3d();
|
}
|
||||||
if (!Model->LoadFromFile(Name, dynamic)) // np. "models\\pkp/head1-y.t3d"
|
else {
|
||||||
SafeDelete(Model);
|
m_name.clear();
|
||||||
return Model;
|
Model = nullptr;
|
||||||
};
|
return nullptr;
|
||||||
|
}
|
||||||
TMdlContainer *TModelsManager::Models;
|
};
|
||||||
int TModelsManager::Count;
|
|
||||||
int const MAX_MODELS = 1000;
|
TModelsManager::modelcontainer_sequence TModelsManager::m_models;
|
||||||
|
TModelsManager::stringmodelcontainerindex_map TModelsManager::m_modelsmap;
|
||||||
void TModelsManager::Init()
|
|
||||||
{
|
// wczytanie modelu do tablicy
|
||||||
Models = new TMdlContainer[MAX_MODELS];
|
TModel3d *
|
||||||
Count = 0;
|
TModelsManager::LoadModel(std::string const &Name, bool dynamic) {
|
||||||
}
|
|
||||||
/*
|
m_models.emplace_back();
|
||||||
TModelsManager::TModelsManager()
|
auto model = m_models.back().LoadModel( Name, dynamic );
|
||||||
{
|
if( model != nullptr ) {
|
||||||
// Models= NULL;
|
m_modelsmap.emplace( Name, m_models.size() - 1 );
|
||||||
Models= new TMdlContainer[MAX_MODELS];
|
return model;
|
||||||
Count= 0;
|
}
|
||||||
};
|
else {
|
||||||
|
m_models.pop_back();
|
||||||
TModelsManager::~TModelsManager()
|
return nullptr;
|
||||||
{
|
|
||||||
Free();
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
void TModelsManager::Free()
|
|
||||||
{
|
|
||||||
delete[] Models;
|
|
||||||
Models = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
TModel3d * TModelsManager::LoadModel(std::string const &Name, bool dynamic)
|
|
||||||
{ // wczytanie modelu do tablicy
|
|
||||||
TModel3d *mdl = NULL;
|
|
||||||
if (Count >= MAX_MODELS)
|
|
||||||
Error("FIXME: Too many models, program will now crash :)");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mdl = Models[Count].LoadModel(Name, dynamic);
|
|
||||||
if (mdl)
|
|
||||||
Count++; // jeśli błąd wczytania modelu, to go nie wliczamy
|
|
||||||
}
|
}
|
||||||
return mdl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TModel3d * TModelsManager::GetModel(std::string const &Name, bool dynamic)
|
TModel3d *
|
||||||
|
TModelsManager::GetModel(std::string const &Name, bool const Dynamic)
|
||||||
{ // model może być we wpisie "node...model" albo "node...dynamic", a także być dodatkowym w dynamic
|
{ // model może być we wpisie "node...model" albo "node...dynamic", a także być dodatkowym w dynamic
|
||||||
// (kabina, wnętrze, ładunek)
|
// (kabina, wnętrze, ładunek)
|
||||||
// dla "node...dynamic" mamy podaną ścieżkę w "\dynamic\" i musi być co najmniej 1 poziom, zwkle
|
// dla "node...dynamic" mamy podaną ścieżkę w "\dynamic\" i musi być co najmniej 1 poziom, zwkle
|
||||||
@@ -97,53 +78,10 @@ TModel3d * TModelsManager::GetModel(std::string const &Name, bool dynamic)
|
|||||||
// - niebo animowane, ścieżka brana ze wpisu, tekstury nieokreślone
|
// - niebo animowane, ścieżka brana ze wpisu, tekstury nieokreślone
|
||||||
// - wczytanie modelu animowanego - Init() - sprawdzić
|
// - wczytanie modelu animowanego - Init() - sprawdzić
|
||||||
std::string buf;
|
std::string buf;
|
||||||
std::string buftp = Global::asCurrentTexturePath; // zapamiętanie aktualnej ścieżki do tekstur,
|
std::string const buftp = Global::asCurrentTexturePath; // zapamiętanie aktualnej ścieżki do tekstur,
|
||||||
// bo będzie tyczmasowo zmieniana
|
|
||||||
/*
|
|
||||||
// Ra: niby tak jest lepiej, ale działa gorzej, więc przywrócone jest oryginalne
|
|
||||||
//nawet jeśli model będzie pobrany z tablicy, to trzeba ustalić ścieżkę dla tekstur
|
|
||||||
if (dynamic) //na razie tak, bo nie wiadomo, jaki może mieć wpływ na pozostałe modele
|
|
||||||
{//dla pojazdów podana jest zawsze pełna ścieżka do modelu
|
|
||||||
strcpy(buf,Name);
|
|
||||||
if (strchr(Name,'/')!=NULL)
|
|
||||||
{//pobieranie tekstur z katalogu, w którym jest model
|
|
||||||
Global::asCurrentTexturePath=Global::asCurrentTexturePath+AnsiString(Name);
|
|
||||||
Global::asCurrentTexturePath.Delete(Global::asCurrentTexturePath.Pos("/")+1,Global::asCurrentTexturePath.Length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{//dla modeli scenerii trzeba ustalić ścieżkę
|
|
||||||
if (strchr(Name,'\\')==NULL)
|
|
||||||
{//jeśli nie ma lewego ukośnika w ścieżce, a jest prawy, to zmienić ścieżkę dla tekstur na tę
|
|
||||||
z modelem
|
|
||||||
strcpy(buf,"models\\"); //Ra: było by lepiej katalog dodać w parserze
|
|
||||||
//strcpy(buf,"scenery\\"); //Ra: było by lepiej katalog dodać w parserze
|
|
||||||
strcat(buf,Name);
|
|
||||||
if (strchr(Name,'/')!=NULL)
|
|
||||||
{//jeszcze musi być prawy ukośnik
|
|
||||||
Global::asCurrentTexturePath=Global::asCurrentTexturePath+AnsiString(Name);
|
|
||||||
Global::asCurrentTexturePath.Delete(Global::asCurrentTexturePath.Pos("/")+1,Global::asCurrentTexturePath.Length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{//jeśli jest lewy ukośnik, to ścieżkę do tekstur zmienić tylko dla pojazdów
|
|
||||||
strcpy(buf,Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StrLower(buf);
|
|
||||||
for (int i=0;i<Count;i++)
|
|
||||||
{//bezsensowne przeszukanie tabeli na okoliczność wystąpienia modelu
|
|
||||||
if (strcmp(buf,Models[i].Name)==0)
|
|
||||||
{
|
|
||||||
Global::asCurrentTexturePath=buftp; //odtworzenie ścieżki do tekstur
|
|
||||||
return (Models[i].Model); //model znaleziony
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
if( Name.find('\\') == std::string::npos )
|
if( Name.find('\\') == std::string::npos )
|
||||||
{
|
{
|
||||||
buf = "models\\"; // Ra: było by lepiej katalog dodać w parserze
|
buf = "models\\" + Name; // Ra: było by lepiej katalog dodać w parserze
|
||||||
buf.append( Name );
|
|
||||||
if( Name.find( '/') != std::string::npos)
|
if( Name.find( '/') != std::string::npos)
|
||||||
{
|
{
|
||||||
Global::asCurrentTexturePath = Global::asCurrentTexturePath + Name;
|
Global::asCurrentTexturePath = Global::asCurrentTexturePath + Name;
|
||||||
@@ -154,43 +92,27 @@ TModel3d * TModelsManager::GetModel(std::string const &Name, bool dynamic)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf = Name;
|
buf = Name;
|
||||||
if (dynamic) // na razie tak, bo nie wiadomo, jaki może mieć wpływ na pozostałe modele
|
if( Dynamic ) {
|
||||||
if (Name.find( '/') != std::string::npos)
|
// na razie tak, bo nie wiadomo, jaki może mieć wpływ na pozostałe modele
|
||||||
{ // pobieranie tekstur z katalogu, w którym jest model
|
if( Name.find( '/' ) != std::string::npos ) { // pobieranie tekstur z katalogu, w którym jest model
|
||||||
Global::asCurrentTexturePath = Global::asCurrentTexturePath + Name;
|
Global::asCurrentTexturePath = Global::asCurrentTexturePath + Name;
|
||||||
Global::asCurrentTexturePath.erase(Global::asCurrentTexturePath.find("/") + 1,
|
Global::asCurrentTexturePath.erase(
|
||||||
Global::asCurrentTexturePath.length() - 1);
|
Global::asCurrentTexturePath.find( "/" ) + 1,
|
||||||
|
Global::asCurrentTexturePath.length() - 1 );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf = ToLower( buf );
|
buf = ToLower( buf );
|
||||||
for (int i = 0; i < Count; ++i)
|
|
||||||
{
|
auto const lookup = m_modelsmap.find( buf );
|
||||||
if ( buf == Models[i].Name )
|
if( lookup != m_modelsmap.end() ) {
|
||||||
{
|
Global::asCurrentTexturePath = buftp;
|
||||||
Global::asCurrentTexturePath = buftp;
|
return ( m_models[ lookup->second ].Model.get() );
|
||||||
return (Models[i].Model);
|
}
|
||||||
}
|
|
||||||
};
|
auto model = LoadModel(buf, Dynamic); // model nie znaleziony, to wczytać
|
||||||
TModel3d *tmpModel = LoadModel(buf, dynamic); // model nie znaleziony, to wczytać
|
|
||||||
Global::asCurrentTexturePath = buftp; // odtworzenie ścieżki do tekstur
|
Global::asCurrentTexturePath = buftp; // odtworzenie ścieżki do tekstur
|
||||||
return (tmpModel); // NULL jeśli błąd
|
return model; // NULL jeśli błąd
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
TModel3d TModelsManager::GetModel(char *Name, AnsiString asReplacableTexture)
|
|
||||||
{
|
|
||||||
GLuint ReplacableTextureID= 0;
|
|
||||||
TModel3d NewModel;
|
|
||||||
|
|
||||||
NewModel= *GetNextModel(Name);
|
|
||||||
|
|
||||||
if (asReplacableTexture!=AnsiString("none"))
|
|
||||||
ReplacableTextureID= TTexturesManager::GetTextureID(asReplacableTexture.c_str());
|
|
||||||
|
|
||||||
NewModel.ReplacableSkinID=ReplacableTextureID;
|
|
||||||
|
|
||||||
return NewModel;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
41
MdlMngr.h
41
MdlMngr.h
@@ -9,33 +9,28 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Model3d.h"
|
#include "Model3d.h"
|
||||||
#include "usefull.h"
|
|
||||||
|
|
||||||
class TMdlContainer
|
class TMdlContainer {
|
||||||
{
|
|
||||||
friend class TModelsManager;
|
friend class TModelsManager;
|
||||||
~TMdlContainer()
|
private:
|
||||||
{
|
TModel3d *LoadModel( std::string const &Name, bool const Dynamic );
|
||||||
delete Model;
|
std::shared_ptr<TModel3d> Model { nullptr };
|
||||||
};
|
std::string m_name;
|
||||||
TModel3d * LoadModel(std::string const &NewName, bool dynamic);
|
|
||||||
TModel3d *Model{ nullptr };
|
|
||||||
std::string Name;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TModelsManager
|
// klasa statyczna, nie ma obiektu
|
||||||
{ // klasa statyczna, nie ma obiektu
|
class TModelsManager {
|
||||||
private:
|
// types:
|
||||||
static TMdlContainer *Models;
|
typedef std::deque<TMdlContainer> modelcontainer_sequence;
|
||||||
static int Count;
|
typedef std::unordered_map<std::string, modelcontainer_sequence::size_type> stringmodelcontainerindex_map;
|
||||||
static TModel3d * LoadModel(std::string const &Name, bool dynamic);
|
// members:
|
||||||
|
static modelcontainer_sequence m_models;
|
||||||
public:
|
static stringmodelcontainerindex_map m_modelsmap;
|
||||||
// TModelsManager();
|
// methods:
|
||||||
// ~TModelsManager();
|
static TModel3d *LoadModel( std::string const &Name, bool const Dynamic );
|
||||||
static void Init();
|
public:
|
||||||
static void Free();
|
|
||||||
// McZapkie: dodalem sciezke, notabene Path!=Patch :)
|
// McZapkie: dodalem sciezke, notabene Path!=Patch :)
|
||||||
static TModel3d * GetModel(std::string const &Name, bool dynamic = false);
|
static TModel3d *GetModel( std::string const &Name, bool dynamic = false );
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
106
Model3d.cpp
106
Model3d.cpp
@@ -19,6 +19,7 @@ Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
|||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "mczapkie/mctools.h"
|
#include "mczapkie/mctools.h"
|
||||||
#include "Usefull.h"
|
#include "Usefull.h"
|
||||||
|
#include "ground.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
@@ -428,7 +429,9 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
std::vector<unsigned int> sg; sg.resize( facecount ); // maski przynależności trójkątów do powierzchni
|
std::vector<unsigned int> sg; sg.resize( facecount ); // maski przynależności trójkątów do powierzchni
|
||||||
std::vector<int> wsp; wsp.resize( iNumVerts );// z którego wierzchołka kopiować wektor normalny
|
std::vector<int> wsp; wsp.resize( iNumVerts );// z którego wierzchołka kopiować wektor normalny
|
||||||
int maska = 0;
|
int maska = 0;
|
||||||
|
int rawvertexcount = 0; // used to keep track of vertex indices in source file
|
||||||
for (int i = 0; i < iNumVerts; ++i) {
|
for (int i = 0; i < iNumVerts; ++i) {
|
||||||
|
++rawvertexcount;
|
||||||
// Ra: z konwersją na układ scenerii - będzie wydajniejsze wyświetlanie
|
// Ra: z konwersją na układ scenerii - będzie wydajniejsze wyświetlanie
|
||||||
wsp[i] = -1; // wektory normalne nie są policzone dla tego wierzchołka
|
wsp[i] = -1; // wektory normalne nie są policzone dla tego wierzchołka
|
||||||
if ((i % 3) == 0) {
|
if ((i % 3) == 0) {
|
||||||
@@ -465,7 +468,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
--facecount; // o jeden trójkąt mniej
|
--facecount; // o jeden trójkąt mniej
|
||||||
iNumVerts -= 3; // czyli o 3 wierzchołki
|
iNumVerts -= 3; // czyli o 3 wierzchołki
|
||||||
i -= 3; // wczytanie kolejnego w to miejsce
|
i -= 3; // wczytanie kolejnego w to miejsce
|
||||||
WriteLog("Bad model: degenerated triangle ignored in: \"" + pName + "\", vertices " + std::to_string(i) + "-" + std::to_string(i+2));
|
WriteLog("Bad model: degenerated triangle ignored in: \"" + pName + "\", vertices " + std::to_string(rawvertexcount-2) + "-" + std::to_string(rawvertexcount));
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
// jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać
|
// jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać
|
||||||
@@ -1035,7 +1038,7 @@ void TSubModel::RaAnimation(TAnimType a)
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void TSubModel::serialize_geometry( std::ostream &Output ) {
|
void TSubModel::serialize_geometry( std::ostream &Output ) const {
|
||||||
|
|
||||||
if( Child ) {
|
if( Child ) {
|
||||||
Child->serialize_geometry( Output );
|
Child->serialize_geometry( Output );
|
||||||
@@ -1074,6 +1077,65 @@ TSubModel::create_geometry( std::size_t &Dataoffset, geometrybank_handle const &
|
|||||||
Next->create_geometry( Dataoffset, Bank );
|
Next->create_geometry( Dataoffset, Bank );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// places contained geometry in provided ground node
|
||||||
|
void
|
||||||
|
TSubModel::convert( TGroundNode &Groundnode ) const {
|
||||||
|
|
||||||
|
Groundnode.asName = pName;
|
||||||
|
Groundnode.Ambient = f4Ambient;
|
||||||
|
Groundnode.Diffuse = f4Diffuse;
|
||||||
|
Groundnode.Specular = f4Specular;
|
||||||
|
Groundnode.TextureID = TextureID;
|
||||||
|
Groundnode.iFlags = (
|
||||||
|
( true == GfxRenderer.Texture( TextureID ).has_alpha ) ?
|
||||||
|
0x20 :
|
||||||
|
0x10 );
|
||||||
|
|
||||||
|
if( m_geometry == NULL ) { return; }
|
||||||
|
|
||||||
|
std::size_t vertexcount { 0 };
|
||||||
|
std::vector<TGroundVertex> importedvertices;
|
||||||
|
TGroundVertex vertex, vertex1, vertex2;
|
||||||
|
for( auto const &sourcevertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
|
vertex.position = sourcevertex.position;
|
||||||
|
vertex.normal = sourcevertex.normal;
|
||||||
|
vertex.texture = sourcevertex.texture;
|
||||||
|
if( vertexcount == 0 ) { vertex1 = vertex; }
|
||||||
|
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
||||||
|
else if( vertexcount >= 2 ) {
|
||||||
|
if( false == degenerate( vertex1.position, vertex2.position, vertex.position ) ) {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex2 );
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++vertexcount;
|
||||||
|
if( vertexcount > 2 ) { vertexcount = 0; } // start new triangle if needed
|
||||||
|
}
|
||||||
|
if( Groundnode.Piece == nullptr ) {
|
||||||
|
Groundnode.Piece = new piece_node();
|
||||||
|
}
|
||||||
|
Groundnode.iNumVerts = importedvertices.size();
|
||||||
|
if( Groundnode.iNumVerts > 0 ) {
|
||||||
|
|
||||||
|
Groundnode.Piece->vertices.swap( importedvertices );
|
||||||
|
|
||||||
|
for( auto const &vertex : Groundnode.Piece->vertices ) {
|
||||||
|
Groundnode.pCenter += vertex.position;
|
||||||
|
}
|
||||||
|
Groundnode.pCenter /= Groundnode.iNumVerts;
|
||||||
|
|
||||||
|
double r { 0.0 };
|
||||||
|
double tf;
|
||||||
|
for( auto const &vertex : Groundnode.Piece->vertices ) {
|
||||||
|
tf = glm::length2( vertex.position - glm::dvec3{ Groundnode.pCenter } );
|
||||||
|
if( tf > r )
|
||||||
|
r = tf;
|
||||||
|
}
|
||||||
|
Groundnode.fSquareRadius += r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: leftover from static distance factor adjustment.
|
// NOTE: leftover from static distance factor adjustment.
|
||||||
// TODO: get rid of it, once we have the dynamic adjustment code in place
|
// TODO: get rid of it, once we have the dynamic adjustment code in place
|
||||||
void TSubModel::AdjustDist()
|
void TSubModel::AdjustDist()
|
||||||
@@ -1665,16 +1727,22 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
pName = "";
|
pName = "";
|
||||||
if (iTexture > 0)
|
if (iTexture > 0)
|
||||||
{ // obsługa stałej tekstury
|
{ // obsługa stałej tekstury
|
||||||
pTexture = t->at(iTexture);
|
if( iTexture < t->size() ) {
|
||||||
if (pTexture.find_last_of("/\\") == std::string::npos)
|
pTexture = t->at( iTexture );
|
||||||
pTexture.insert(0, Global::asCurrentTexturePath);
|
if( pTexture.find_last_of( "/\\" ) == std::string::npos )
|
||||||
TextureID = GfxRenderer.Fetch_Texture(pTexture);
|
pTexture.insert( 0, Global::asCurrentTexturePath );
|
||||||
if( ( iFlags & 0x30 ) == 0 ) {
|
TextureID = GfxRenderer.Fetch_Texture( pTexture );
|
||||||
// texture-alpha based fallback if for some reason we don't have opacity flag set yet
|
if( ( iFlags & 0x30 ) == 0 ) {
|
||||||
iFlags |=
|
// texture-alpha based fallback if for some reason we don't have opacity flag set yet
|
||||||
( GfxRenderer.Texture( TextureID ).has_alpha ?
|
iFlags |=
|
||||||
0x20 :
|
( GfxRenderer.Texture( TextureID ).has_alpha ?
|
||||||
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
0x20 :
|
||||||
|
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Bad model: reference to non-existent texture index in sub-model" + ( pName.empty() ? "" : " \"" + pName + "\"" ) );
|
||||||
|
TextureID = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1853,17 +1921,3 @@ TSubModel *TModel3d::TerrainSquare(int n)
|
|||||||
r->UnFlagNext(); // blokowanie wyświetlania po Next głównej listy
|
r->UnFlagNext(); // blokowanie wyświetlania po Next głównej listy
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
void TModel3d::TerrainRenderVBO(int n)
|
|
||||||
{ // renderowanie terenu z VBO
|
|
||||||
::glPushMatrix();
|
|
||||||
::glTranslated( -Global::pCameraPosition.x, -Global::pCameraPosition.y, -Global::pCameraPosition.z );
|
|
||||||
TSubModel *r = Root;
|
|
||||||
while( r ) {
|
|
||||||
if( r->iVisible == n ) // tylko jeśli ma być widoczny w danej ramce (problem dla 0==false)
|
|
||||||
GfxRenderer.Render( r ); // sub kolejne (Next) się nie wyrenderują
|
|
||||||
r = r->NextGet();
|
|
||||||
}
|
|
||||||
::glPopMatrix();
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
@@ -50,6 +50,8 @@ enum TAnimType // rodzaj animacji
|
|||||||
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TGroundNode;
|
||||||
|
|
||||||
class TSubModel
|
class TSubModel
|
||||||
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||||
//m7todo: zrobić normalną serializację
|
//m7todo: zrobić normalną serializację
|
||||||
@@ -213,7 +215,9 @@ public:
|
|||||||
std::vector<std::string>&,
|
std::vector<std::string>&,
|
||||||
std::vector<std::string>&,
|
std::vector<std::string>&,
|
||||||
std::vector<float4x4>&);
|
std::vector<float4x4>&);
|
||||||
void serialize_geometry( std::ostream &Output );
|
void serialize_geometry( std::ostream &Output ) const;
|
||||||
|
// places contained geometry in provided ground node
|
||||||
|
void convert( TGroundNode &Groundnode ) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ private:
|
|||||||
std::chrono::nanoseconds const m_unusedresourcetimetolive;
|
std::chrono::nanoseconds const m_unusedresourcetimetolive;
|
||||||
typename Container_::size_type const m_unusedresourcesweepsize;
|
typename Container_::size_type const m_unusedresourcesweepsize;
|
||||||
std::string const m_resourcename;
|
std::string const m_resourcename;
|
||||||
typename Container_ &m_container;
|
Container_ &m_container;
|
||||||
typename Container_::size_type m_resourcesweepindex { 0 };
|
typename Container_::size_type m_resourcesweepindex { 0 };
|
||||||
std::chrono::steady_clock::time_point m_resourcetimestamp { std::chrono::steady_clock::now() };
|
std::chrono::steady_clock::time_point m_resourcetimestamp { std::chrono::steady_clock::now() };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -592,10 +592,7 @@ opengl_texture::create() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.swap( std::vector<char>() ); // TBD, TODO: keep the texture data if we start doing some gpu data cleaning down the road
|
data = std::vector<char>();
|
||||||
/*
|
|
||||||
data_state = resource_state::none;
|
|
||||||
*/
|
|
||||||
data_state = resource_state::none;
|
data_state = resource_state::none;
|
||||||
is_ready = true;
|
is_ready = true;
|
||||||
}
|
}
|
||||||
@@ -609,8 +606,6 @@ opengl_texture::release( bool const Backup ) {
|
|||||||
|
|
||||||
if( id == -1 ) { return; }
|
if( id == -1 ) { return; }
|
||||||
|
|
||||||
assert( is_ready );
|
|
||||||
|
|
||||||
if( true == Backup ) {
|
if( true == Backup ) {
|
||||||
// query texture details needed to perform the backup...
|
// query texture details needed to perform the backup...
|
||||||
::glBindTexture( GL_TEXTURE_2D, id );
|
::glBindTexture( GL_TEXTURE_2D, id );
|
||||||
@@ -914,7 +909,7 @@ texture_manager::info() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
"Textures: "
|
"; textures: "
|
||||||
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
|
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
+ std::to_string( readytexturecount )
|
+ std::to_string( readytexturecount )
|
||||||
+ " ("
|
+ " ("
|
||||||
|
|||||||
36
Train.cpp
36
Train.cpp
@@ -1368,10 +1368,6 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
Train->mvControlled->PantFrontSP = false;
|
Train->mvControlled->PantFrontSP = false;
|
||||||
if( Train->mvControlled->PantFront( true ) ) {
|
if( Train->mvControlled->PantFront( true ) ) {
|
||||||
if( Train->mvControlled->PantFrontStart != 1 ) {
|
if( Train->mvControlled->PantFrontStart != 1 ) {
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
// sound feedback
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
#endif
|
|
||||||
// visual feedback
|
// visual feedback
|
||||||
if( Train->ggPantFrontButton.SubModel )
|
if( Train->ggPantFrontButton.SubModel )
|
||||||
Train->ggPantFrontButton.UpdateValue( 1.0, Train->dsbSwitch );
|
Train->ggPantFrontButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
@@ -1404,10 +1400,6 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
Train->mvControlled->PantFrontSP = false;
|
Train->mvControlled->PantFrontSP = false;
|
||||||
if( false == Train->mvControlled->PantFront( false ) ) {
|
if( false == Train->mvControlled->PantFront( false ) ) {
|
||||||
if( Train->mvControlled->PantFrontStart != 0 ) {
|
if( Train->mvControlled->PantFrontStart != 0 ) {
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
// sound feedback
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
#endif
|
|
||||||
// visual feedback
|
// visual feedback
|
||||||
if( Train->ggPantFrontButton.SubModel )
|
if( Train->ggPantFrontButton.SubModel )
|
||||||
Train->ggPantFrontButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantFrontButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
@@ -1429,11 +1421,6 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
// impulse switches return automatically to neutral position
|
// impulse switches return automatically to neutral position
|
||||||
if( Train->mvOccupied->PantSwitchType == "impulse" ) {
|
if( Train->mvOccupied->PantSwitchType == "impulse" ) {
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
if( Train->ggPantFrontButton.GetValue() > 0.35 ) {
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( Train->ggPantFrontButton.SubModel )
|
if( Train->ggPantFrontButton.SubModel )
|
||||||
Train->ggPantFrontButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantFrontButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
@@ -1441,11 +1428,6 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
if( Train->ggPantSelectedButton.SubModel )
|
if( Train->ggPantSelectedButton.SubModel )
|
||||||
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
// also the switch off button, in cabs which have it
|
// also the switch off button, in cabs which have it
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
if( Train->ggPantFrontButtonOff.GetValue() > 0.35 ) {
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( Train->ggPantFrontButtonOff.SubModel )
|
if( Train->ggPantFrontButtonOff.SubModel )
|
||||||
Train->ggPantFrontButtonOff.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantFrontButtonOff.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
if( Train->ggPantSelectedDownButton.SubModel ) {
|
if( Train->ggPantSelectedDownButton.SubModel ) {
|
||||||
@@ -1466,10 +1448,6 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
Train->mvControlled->PantRearSP = false;
|
Train->mvControlled->PantRearSP = false;
|
||||||
if( Train->mvControlled->PantRear( true ) ) {
|
if( Train->mvControlled->PantRear( true ) ) {
|
||||||
if( Train->mvControlled->PantRearStart != 1 ) {
|
if( Train->mvControlled->PantRearStart != 1 ) {
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
// sound feedback
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
#endif
|
|
||||||
// visual feedback
|
// visual feedback
|
||||||
if( Train->ggPantRearButton.SubModel )
|
if( Train->ggPantRearButton.SubModel )
|
||||||
Train->ggPantRearButton.UpdateValue( 1.0, Train->dsbSwitch );
|
Train->ggPantRearButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
@@ -1502,10 +1480,6 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
Train->mvControlled->PantRearSP = false;
|
Train->mvControlled->PantRearSP = false;
|
||||||
if( false == Train->mvControlled->PantRear( false ) ) {
|
if( false == Train->mvControlled->PantRear( false ) ) {
|
||||||
if( Train->mvControlled->PantRearStart != 0 ) {
|
if( Train->mvControlled->PantRearStart != 0 ) {
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
// sound feedback
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
#endif
|
|
||||||
// visual feedback
|
// visual feedback
|
||||||
if( Train->ggPantRearButton.SubModel )
|
if( Train->ggPantRearButton.SubModel )
|
||||||
Train->ggPantRearButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantRearButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
@@ -1527,11 +1501,6 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
// impulse switches return automatically to neutral position
|
// impulse switches return automatically to neutral position
|
||||||
if( Train->mvOccupied->PantSwitchType == "impulse" ) {
|
if( Train->mvOccupied->PantSwitchType == "impulse" ) {
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
if( Train->ggPantRearButton.GetValue() > 0.35 ) {
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( Train->ggPantRearButton.SubModel )
|
if( Train->ggPantRearButton.SubModel )
|
||||||
Train->ggPantRearButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantRearButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
@@ -1539,11 +1508,6 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
if( Train->ggPantSelectedButton.SubModel )
|
if( Train->ggPantSelectedButton.SubModel )
|
||||||
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
// also the switch off button, in cabs which have it
|
// also the switch off button, in cabs which have it
|
||||||
#ifdef EU07_USE_OLD_CONTROLSOUNDS
|
|
||||||
if( Train->ggPantRearButtonOff.GetValue() > 0.35 ) {
|
|
||||||
Train->play_sound( Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( Train->ggPantRearButtonOff.SubModel )
|
if( Train->ggPantRearButtonOff.SubModel )
|
||||||
Train->ggPantRearButtonOff.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggPantRearButtonOff.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
if( Train->ggPantSelectedDownButton.SubModel ) {
|
if( Train->ggPantSelectedDownButton.SubModel ) {
|
||||||
|
|||||||
1
Train.h
1
Train.h
@@ -15,7 +15,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Gauge.h"
|
#include "Gauge.h"
|
||||||
#include "Spring.h"
|
#include "Spring.h"
|
||||||
#include "AdvSound.h"
|
#include "AdvSound.h"
|
||||||
#include "FadeSound.h"
|
|
||||||
#include "PyInt.h"
|
#include "PyInt.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
|
|||||||
128
World.cpp
128
World.cpp
@@ -32,8 +32,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "uilayer.h"
|
#include "uilayer.h"
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
|
|
||||||
//#define EU07_USE_DEBUG_SHADOWMAP
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
TDynamicObject *Controlled = NULL; // pojazd, który prowadzimy
|
TDynamicObject *Controlled = NULL; // pojazd, który prowadzimy
|
||||||
@@ -205,7 +203,6 @@ TWorld::~TWorld()
|
|||||||
TrainDelete();
|
TrainDelete();
|
||||||
// Ground.Free(); //Ra: usunięcie obiektów przed usunięciem dźwięków - sypie się
|
// Ground.Free(); //Ra: usunięcie obiektów przed usunięciem dźwięków - sypie się
|
||||||
TSoundsManager::Free();
|
TSoundsManager::Free();
|
||||||
TModelsManager::Free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWorld::TrainDelete(TDynamicObject *d)
|
void TWorld::TrainDelete(TDynamicObject *d)
|
||||||
@@ -290,22 +287,13 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
|||||||
"ShaXbee, Oli_EU, youBy, KURS90, Ra, hunter, szociu, Stele, Q, firleju and others\n" );
|
"ShaXbee, Oli_EU, youBy, KURS90, Ra, hunter, szociu, Stele, Q, firleju and others\n" );
|
||||||
|
|
||||||
UILayer.set_background( "logo" );
|
UILayer.set_background( "logo" );
|
||||||
/*
|
|
||||||
std::shared_ptr<ui_panel> initpanel = std::make_shared<ui_panel>(85, 600);
|
|
||||||
*/
|
|
||||||
TSoundsManager::Init( glfwGetWin32Window( window ) );
|
TSoundsManager::Init( glfwGetWin32Window( window ) );
|
||||||
WriteLog("Sound Init OK");
|
WriteLog("Sound Init OK");
|
||||||
TModelsManager::Init();
|
|
||||||
WriteLog("Models init OK");
|
|
||||||
/*
|
|
||||||
initpanel->text_lines.emplace_back( "Loading scenery / Wczytywanie scenerii:", float4( 0.0f, 0.0f, 0.0f, 1.0f ) );
|
|
||||||
initpanel->text_lines.emplace_back( Global::SceneryFile.substr(0, 40), float4( 0.0f, 0.0f, 0.0f, 1.0f ) );
|
|
||||||
UILayer.push_back( initpanel );
|
|
||||||
*/
|
|
||||||
glfwSetWindowTitle( window, ( Global::AppName + " (" + Global::SceneryFile + ")" ).c_str() ); // nazwa scenerii
|
glfwSetWindowTitle( window, ( Global::AppName + " (" + Global::SceneryFile + ")" ).c_str() ); // nazwa scenerii
|
||||||
UILayer.set_progress(0.01);
|
UILayer.set_progress(0.01);
|
||||||
UILayer.set_progress( "Loading scenery / Wczytywanie scenerii" );
|
UILayer.set_progress( "Loading scenery / Wczytywanie scenerii" );
|
||||||
|
|
||||||
GfxRenderer.Render();
|
GfxRenderer.Render();
|
||||||
|
|
||||||
WriteLog( "Ground init" );
|
WriteLog( "Ground init" );
|
||||||
@@ -317,13 +305,8 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
|||||||
|
|
||||||
Environment.init();
|
Environment.init();
|
||||||
Camera.Init(Global::FreeCameraInit[0], Global::FreeCameraInitAngle[0]);
|
Camera.Init(Global::FreeCameraInit[0], Global::FreeCameraInitAngle[0]);
|
||||||
/*
|
|
||||||
initpanel->text_lines.clear();
|
|
||||||
initpanel->text_lines.emplace_back( "Preparing train / Przygotowanie kabiny:", float4( 0.0f, 0.0f, 0.0f, 1.0f ) );
|
|
||||||
*/
|
|
||||||
UILayer.set_progress( "Preparing train / Przygotowanie kabiny" );
|
UILayer.set_progress( "Preparing train / Przygotowanie kabiny" );
|
||||||
GfxRenderer.Render();
|
|
||||||
|
|
||||||
WriteLog( "Player train init: " + Global::asHumanCtrlVehicle );
|
WriteLog( "Player train init: " + Global::asHumanCtrlVehicle );
|
||||||
|
|
||||||
TGroundNode *nPlayerTrain = NULL;
|
TGroundNode *nPlayerTrain = NULL;
|
||||||
@@ -491,9 +474,8 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
}
|
}
|
||||||
else // również przeskakiwanie
|
else // również przeskakiwanie
|
||||||
{ // Ra: to z tą kamerą (Camera.Pos i Global::pCameraPosition) jest trochę bez sensu
|
{ // Ra: to z tą kamerą (Camera.Pos i Global::pCameraPosition) jest trochę bez sensu
|
||||||
Global::SetCameraPosition(
|
Ground.Silence( Global::pCameraPosition ); // wyciszenie wszystkiego z poprzedniej pozycji
|
||||||
Global::FreeCameraInit[i]); // nowa pozycja dla generowania obiektów
|
Global::SetCameraPosition( Global::FreeCameraInit[i] ); // nowa pozycja dla generowania obiektów
|
||||||
Ground.Silence(Camera.Pos); // wyciszenie wszystkiego z poprzedniej pozycji
|
|
||||||
Camera.Init(Global::FreeCameraInit[i],
|
Camera.Init(Global::FreeCameraInit[i],
|
||||||
Global::FreeCameraInitAngle[i]); // przestawienie
|
Global::FreeCameraInitAngle[i]); // przestawienie
|
||||||
}
|
}
|
||||||
@@ -634,18 +616,18 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GLFW_KEY_F8: {
|
case GLFW_KEY_F8: {
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
if( Global::ctrlState
|
||||||
if( Global::iTextMode == cKey ) { ++Global::iScreenMode[ cKey - GLFW_KEY_F1 ]; }
|
&& Global::shiftState ) {
|
||||||
if( Global::iScreenMode[ cKey - GLFW_KEY_F1 ] > 1 ) {
|
DebugCameraFlag = !DebugCameraFlag; // taka opcjonalna funkcja, może się czasem przydać
|
||||||
Global::iScreenMode[ cKey - GLFW_KEY_F1 ] = 0;
|
}
|
||||||
|
else {
|
||||||
|
Global::iTextMode = cKey;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
Global::iTextMode = cKey;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GLFW_KEY_F9: {
|
case GLFW_KEY_F9: {
|
||||||
Global::iTextMode = cKey;
|
Global::iTextMode = cKey;
|
||||||
// wersja, typ wyświetlania, błędy OpenGL
|
// wersja
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GLFW_KEY_F10: {
|
case GLFW_KEY_F10: {
|
||||||
@@ -1058,17 +1040,17 @@ bool TWorld::Update()
|
|||||||
// 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
|
||||||
Ground.Update(dt / updatecount, updatecount); // tu zrobić tylko coklatkową aktualizację przesunięć
|
Ground.Update(dt / updatecount, updatecount); // tu zrobić tylko coklatkową aktualizację przesunięć
|
||||||
/*
|
|
||||||
if (DebugModeFlag)
|
// yB dodał przyspieszacz fizyki
|
||||||
if (Global::bActive) // nie przyspieszać, gdy jedzie w tle :)
|
if( (true == DebugModeFlag)
|
||||||
if( Console::Pressed( GLFW_KEY_ESCAPE ) ) {
|
&& (true == Global::bActive) // nie przyspieszać, gdy jedzie w tle :)
|
||||||
// yB dodał przyspieszacz fizyki
|
&& ( glfwGetKey( window, GLFW_KEY_PAUSE ) == GLFW_PRESS ) ) {
|
||||||
Ground.Update(dt, n);
|
|
||||||
Ground.Update(dt, n);
|
Ground.Update( dt, updatecount );
|
||||||
Ground.Update(dt, n);
|
Ground.Update( dt, updatecount );
|
||||||
Ground.Update(dt, n); // 5 razy
|
Ground.Update( dt, updatecount );
|
||||||
}
|
Ground.Update( dt, updatecount ); // 5 razy
|
||||||
*/
|
}
|
||||||
// secondary fixed step simulation time routines
|
// secondary fixed step simulation time routines
|
||||||
|
|
||||||
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
||||||
@@ -1083,8 +1065,9 @@ bool TWorld::Update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fixed step part of the camera update
|
// fixed step part of the camera update
|
||||||
if( (Train != nullptr)
|
if( ( Train != nullptr )
|
||||||
&& (Camera.Type == tp_Follow )) {
|
&& ( Camera.Type == tp_Follow )
|
||||||
|
&& ( false == DebugCameraFlag ) ) {
|
||||||
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
||||||
Train->UpdateMechPosition( m_secondaryupdaterate );
|
Train->UpdateMechPosition( m_secondaryupdaterate );
|
||||||
}
|
}
|
||||||
@@ -1121,11 +1104,16 @@ bool TWorld::Update()
|
|||||||
while( fTime50Hz >= 1.0 / 50.0 ) {
|
while( fTime50Hz >= 1.0 / 50.0 ) {
|
||||||
Console::Update(); // to i tak trzeba wywoływać
|
Console::Update(); // to i tak trzeba wywoływać
|
||||||
Update_UI();
|
Update_UI();
|
||||||
|
// decelerate camera
|
||||||
Camera.Velocity *= 0.65;
|
Camera.Velocity *= 0.65;
|
||||||
if( std::abs( Camera.Velocity.x ) < 0.01 ) { Camera.Velocity.x = 0.0; }
|
if( std::abs( Camera.Velocity.x ) < 0.01 ) { Camera.Velocity.x = 0.0; }
|
||||||
if( std::abs( Camera.Velocity.y ) < 0.01 ) { Camera.Velocity.y = 0.0; }
|
if( std::abs( Camera.Velocity.y ) < 0.01 ) { Camera.Velocity.y = 0.0; }
|
||||||
if( std::abs( Camera.Velocity.z ) < 0.01 ) { Camera.Velocity.z = 0.0; }
|
if( std::abs( Camera.Velocity.z ) < 0.01 ) { Camera.Velocity.z = 0.0; }
|
||||||
|
// decelerate debug camera too
|
||||||
|
DebugCamera.Velocity *= 0.65;
|
||||||
|
if( std::abs( DebugCamera.Velocity.x ) < 0.01 ) { DebugCamera.Velocity.x = 0.0; }
|
||||||
|
if( std::abs( DebugCamera.Velocity.y ) < 0.01 ) { DebugCamera.Velocity.y = 0.0; }
|
||||||
|
if( std::abs( DebugCamera.Velocity.z ) < 0.01 ) { DebugCamera.Velocity.z = 0.0; }
|
||||||
|
|
||||||
fTime50Hz -= 1.0 / 50.0;
|
fTime50Hz -= 1.0 / 50.0;
|
||||||
}
|
}
|
||||||
@@ -1144,25 +1132,25 @@ bool TWorld::Update()
|
|||||||
|
|
||||||
void
|
void
|
||||||
TWorld::Update_Camera( double const Deltatime ) {
|
TWorld::Update_Camera( double const Deltatime ) {
|
||||||
// Console::Update(); //tu jest zależne od FPS, co nie jest korzystne
|
|
||||||
|
|
||||||
if( false == Global::ControlPicking ) {
|
if( false == Global::ControlPicking ) {
|
||||||
if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) {
|
if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) {
|
||||||
Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe
|
Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe
|
||||||
// if (!FreeFlyModeFlag) //jeśli wewnątrz - patrzymy do tyłu
|
if( Controlled && LengthSquared3( Controlled->GetPosition() - Camera.Pos ) < ( 1500 * 1500 ) ) {
|
||||||
// Camera.LookAt=Train->pMechPosition-Normalize(Train->GetDirection())*10;
|
// gdy bliżej niż 1.5km
|
||||||
if( Controlled && LengthSquared3( Controlled->GetPosition() - Camera.Pos ) < ( 1500 * 1500 ) ) // gdy bliżej niż 1.5km
|
|
||||||
Camera.LookAt = Controlled->GetPosition();
|
Camera.LookAt = Controlled->GetPosition();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
TDynamicObject *d =
|
TDynamicObject *d =
|
||||||
Ground.DynamicNearest( Camera.Pos, 300 ); // szukaj w promieniu 300m
|
Ground.DynamicNearest( Camera.Pos, 300 ); // szukaj w promieniu 300m
|
||||||
if( !d )
|
if( !d )
|
||||||
d = Ground.DynamicNearest( Camera.Pos,
|
d = Ground.DynamicNearest( Camera.Pos, 1000 ); // dalej szukanie, jesli bliżej nie ma
|
||||||
1000 ); // dalej szukanie, jesli bliżej nie ma
|
if( d && pDynamicNearest ) {
|
||||||
if( d && pDynamicNearest ) // jeśli jakiś jest znaleziony wcześniej
|
// jeśli jakiś jest znaleziony wcześniej
|
||||||
if( 100.0 * LengthSquared3( d->GetPosition() - Camera.Pos ) >
|
if( 100.0 * LengthSquared3( d->GetPosition() - Camera.Pos ) > LengthSquared3( pDynamicNearest->GetPosition() - Camera.Pos ) ) {
|
||||||
LengthSquared3( pDynamicNearest->GetPosition() - Camera.Pos ) )
|
|
||||||
d = pDynamicNearest; // jeśli najbliższy nie jest 10 razy bliżej niż
|
d = pDynamicNearest; // jeśli najbliższy nie jest 10 razy bliżej niż
|
||||||
|
}
|
||||||
|
}
|
||||||
// poprzedni najbliższy, zostaje poprzedni
|
// poprzedni najbliższy, zostaje poprzedni
|
||||||
if( d )
|
if( d )
|
||||||
pDynamicNearest = d; // zmiana na nowy, jeśli coś znaleziony niepusty
|
pDynamicNearest = d; // zmiana na nowy, jeśli coś znaleziony niepusty
|
||||||
@@ -1172,7 +1160,7 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
if( FreeFlyModeFlag )
|
if( FreeFlyModeFlag )
|
||||||
Camera.RaLook(); // jednorazowe przestawienie kamery
|
Camera.RaLook(); // jednorazowe przestawienie kamery
|
||||||
}
|
}
|
||||||
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) { //||Console::Pressed(VK_F4))
|
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) {
|
||||||
FollowView( false ); // bez wyciszania dźwięków
|
FollowView( false ); // bez wyciszania dźwięków
|
||||||
}
|
}
|
||||||
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) == GLFW_PRESS ) {
|
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) == GLFW_PRESS ) {
|
||||||
@@ -1186,15 +1174,12 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera.Update(); // uwzględnienie ruchu wywołanego klawiszami
|
if( DebugCameraFlag ) { DebugCamera.Update(); }
|
||||||
/*
|
else { Camera.Update(); } // uwzględnienie ruchu wywołanego klawiszami
|
||||||
if( Camera.Type == tp_Follow ) {
|
|
||||||
if( Train ) { // jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
if( ( Train != nullptr )
|
||||||
Train->UpdateMechPosition( Deltatime /
|
&& ( Camera.Type == tp_Follow )
|
||||||
Global::fTimeSpeed ); // ograniczyć telepanie po przyspieszeniu
|
&& ( false == DebugCameraFlag ) ) {
|
||||||
*/
|
|
||||||
if( (Train != nullptr)
|
|
||||||
&& (Camera.Type == tp_Follow )) {
|
|
||||||
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
|
||||||
vector3 tempangle = Controlled->VectorFront() * ( Controlled->MoverParameters->ActiveCab == -1 ? -1 : 1 );
|
vector3 tempangle = Controlled->VectorFront() * ( Controlled->MoverParameters->ActiveCab == -1 ? -1 : 1 );
|
||||||
double modelrotate = atan2( -tempangle.x, tempangle.z );
|
double modelrotate = atan2( -tempangle.x, tempangle.z );
|
||||||
@@ -1256,6 +1241,9 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
else { // kamera nieruchoma
|
else { // kamera nieruchoma
|
||||||
Global::SetCameraRotation( Camera.Yaw - M_PI );
|
Global::SetCameraRotation( Camera.Yaw - M_PI );
|
||||||
}
|
}
|
||||||
|
// all done, update camera position to the new value
|
||||||
|
Global::pCameraPosition = Camera.Pos;
|
||||||
|
Global::DebugCameraPosition = DebugCamera.Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWorld::Update_Environment() {
|
void TWorld::Update_Environment() {
|
||||||
@@ -1609,8 +1597,9 @@ TWorld::Update_UI() {
|
|||||||
uitextline1 =
|
uitextline1 =
|
||||||
"FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 )
|
"FoV: " + to_string( Global::FieldOfView / Global::ZoomFactor, 1 )
|
||||||
+ ", Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
+ ", Draw range x " + to_string( Global::fDistanceFactor, 1 )
|
||||||
+ "; sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
// + "; sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
||||||
+ ", FPS: " + to_string( Timer::GetFPS(), 2 );
|
// + ", FPS: " + to_string( Timer::GetFPS(), 2 );
|
||||||
|
+ ", FPS: " + std::to_string( static_cast<int>(std::round(GfxRenderer.Framerate())) );
|
||||||
if( Global::iSlowMotion ) {
|
if( Global::iSlowMotion ) {
|
||||||
uitextline1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
|
uitextline1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
|
||||||
}
|
}
|
||||||
@@ -2229,10 +2218,12 @@ world_environment::update() {
|
|||||||
m_sun.update();
|
m_sun.update();
|
||||||
m_moon.update();
|
m_moon.update();
|
||||||
// ...determine source of key light and adjust global state accordingly...
|
// ...determine source of key light and adjust global state accordingly...
|
||||||
auto const sunlightlevel = m_sun.getIntensity();
|
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
|
||||||
|
float twilightfactor = clamp( -m_sun.getAngle(), 0.0f, 18.0f ) / 18.0f;
|
||||||
|
// NOTE: sun light receives extra padding to prevent moon from kicking in too soon
|
||||||
|
auto const sunlightlevel = m_sun.getIntensity() + 0.05f * ( 1.f - twilightfactor );
|
||||||
auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise
|
auto const moonlightlevel = m_moon.getIntensity() * 0.65f; // scaled down by arbitrary factor, it's pretty bright otherwise
|
||||||
float keylightintensity;
|
float keylightintensity;
|
||||||
float twilightfactor;
|
|
||||||
glm::vec3 keylightcolor;
|
glm::vec3 keylightcolor;
|
||||||
if( moonlightlevel > sunlightlevel ) {
|
if( moonlightlevel > sunlightlevel ) {
|
||||||
// rare situations when the moon is brighter than the sun, typically at night
|
// rare situations when the moon is brighter than the sun, typically at night
|
||||||
@@ -2250,8 +2241,7 @@ world_environment::update() {
|
|||||||
Global::DayLight.set_position( m_sun.getPosition() );
|
Global::DayLight.set_position( m_sun.getPosition() );
|
||||||
Global::DayLight.direction = -1.0f * m_sun.getDirection();
|
Global::DayLight.direction = -1.0f * m_sun.getDirection();
|
||||||
keylightintensity = sunlightlevel;
|
keylightintensity = sunlightlevel;
|
||||||
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
|
// include 'golden hour' effect in twilight lighting
|
||||||
twilightfactor = clamp( -Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
|
||||||
float const duskfactor = 1.0f - clamp( Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
float const duskfactor = 1.0f - clamp( Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
|
||||||
keylightcolor = interpolate(
|
keylightcolor = interpolate(
|
||||||
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
|
||||||
|
|||||||
1
World.h
1
World.h
@@ -118,6 +118,7 @@ private:
|
|||||||
void ResourceSweep();
|
void ResourceSweep();
|
||||||
|
|
||||||
TCamera Camera;
|
TCamera Camera;
|
||||||
|
TCamera DebugCamera;
|
||||||
TGround Ground;
|
TGround Ground;
|
||||||
world_environment Environment;
|
world_environment Environment;
|
||||||
TTrain *Train;
|
TTrain *Train;
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ cFrustum::calculate() {
|
|||||||
void
|
void
|
||||||
cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
|
cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
|
||||||
|
|
||||||
float const *proj = &Projection[ 0 ][ 0 ];
|
float const *proj = glm::value_ptr( Projection );
|
||||||
float const *modl = &Modelview[ 0 ][ 0 ];
|
float const *modl = glm::value_ptr( Modelview );
|
||||||
float clip[ 16 ];
|
float clip[ 16 ];
|
||||||
|
|
||||||
// multiply the matrices to retrieve clipping planes
|
// multiply the matrices to retrieve clipping planes
|
||||||
|
|||||||
10
frustum.h
10
frustum.h
@@ -12,6 +12,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "float3d.h"
|
#include "float3d.h"
|
||||||
#include "dumb3d.h"
|
#include "dumb3d.h"
|
||||||
|
|
||||||
|
std::vector<glm::vec4> const ndcfrustumshapepoints {
|
||||||
|
{ -1, -1, -1, 1 },{ 1, -1, -1, 1 },{ 1, 1, -1, 1 },{ -1, 1, -1, 1 }, // z-near
|
||||||
|
{ -1, -1, 1, 1 },{ 1, -1, 1, 1 },{ 1, 1, 1, 1 },{ -1, 1, 1, 1 } }; // z-far
|
||||||
|
|
||||||
|
std::vector<std::size_t> const frustumshapepoinstorder { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
|
||||||
|
|
||||||
// generic frustum class. used to determine if objects are inside current view area
|
// generic frustum class. used to determine if objects are inside current view area
|
||||||
|
|
||||||
class cFrustum {
|
class cFrustum {
|
||||||
@@ -62,7 +68,7 @@ public:
|
|||||||
bool
|
bool
|
||||||
cube_inside( float const X, float const Y, float const Z, float const Size ) const;
|
cube_inside( float const X, float const Y, float const Z, float const Size ) const;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
// types:
|
// types:
|
||||||
// planes of the frustum
|
// planes of the frustum
|
||||||
enum side { side_RIGHT = 0, side_LEFT = 1, side_BOTTOM = 2, side_TOP = 3, side_BACK = 4, side_FRONT = 5 };
|
enum side { side_RIGHT = 0, side_LEFT = 1, side_BOTTOM = 2, side_TOP = 3, side_BACK = 4, side_FRONT = 5 };
|
||||||
@@ -74,5 +80,5 @@ protected:
|
|||||||
normalize_plane( cFrustum::side const Side ); // normalizes a plane (A side) from the frustum
|
normalize_plane( cFrustum::side const Side ); // normalizes a plane (A side) from the frustum
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
float m_frustum[6][4]; // holds the A B C and D values (normal & distance) for each side of the frustum.
|
float m_frustum[6][4]; // holds the A B C and D values (normal & distance) for each side of the frustum.
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ light_array::update() {
|
|||||||
if( ( true == light.owner->MoverParameters->Battery ) || ( true == light.owner->MoverParameters->ConverterFlag ) ) {
|
if( ( true == light.owner->MoverParameters->Battery ) || ( true == light.owner->MoverParameters->ConverterFlag ) ) {
|
||||||
// with power on, the intensity depends on the state of activated switches
|
// with power on, the intensity depends on the state of activated switches
|
||||||
auto const &lightbits = light.owner->iLights[ light.index ];
|
auto const &lightbits = light.owner->iLights[ light.index ];
|
||||||
light.count = 0 +
|
light.count = 0
|
||||||
( ( lightbits & 1 ) ? 1 : 0 ) +
|
+ ( ( lightbits & TMoverParameters::light::headlight_left ) ? 1 : 0 )
|
||||||
( ( lightbits & 4 ) ? 1 : 0 ) +
|
+ ( ( lightbits & TMoverParameters::light::headlight_right ) ? 1 : 0 )
|
||||||
( ( lightbits & 16 ) ? 1 : 0 );
|
+ ( ( lightbits & TMoverParameters::light::headlight_upper ) ? 1 : 0 );
|
||||||
|
|
||||||
if( light.count > 0 ) {
|
if( light.count > 0 ) {
|
||||||
// TODO: intensity can be affected further by dim switch or other factors
|
// TODO: intensity can be affected further by dim switch or other factors
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ public:
|
|||||||
|
|
||||||
TDynamicObject const *owner; // the object in world which 'carries' the light
|
TDynamicObject const *owner; // the object in world which 'carries' the light
|
||||||
int index{ -1 }; // 0: front lights, 1: rear lights
|
int index{ -1 }; // 0: front lights, 1: rear lights
|
||||||
Math3D::vector3 position; // position of the light in 3d scene
|
glm::dvec3 position; // position of the light in 3d scene
|
||||||
glm::vec3 direction; // direction of the light in 3d scene
|
glm::vec3 direction; // direction of the light in 3d scene
|
||||||
float3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
|
glm::vec3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
|
||||||
float intensity{ 0.0f }; // (combined) intensity of the light(s)
|
float intensity{ 0.0f }; // (combined) intensity of the light(s)
|
||||||
int count{ 0 }; // number (or pattern) of active light(s)
|
int count{ 0 }; // number (or pattern) of active light(s)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,9 +63,6 @@
|
|||||||
<ClCompile Include="EvLaunch.cpp">
|
<ClCompile Include="EvLaunch.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="FadeSound.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Float3d.cpp">
|
<ClCompile Include="Float3d.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -120,9 +117,6 @@
|
|||||||
<ClCompile Include="Texture.cpp">
|
<ClCompile Include="Texture.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="TextureDDS.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Timer.cpp">
|
<ClCompile Include="Timer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -344,9 +338,6 @@
|
|||||||
<ClInclude Include="Names.h">
|
<ClInclude Include="Names.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="FadeSound.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Sound.h">
|
<ClInclude Include="Sound.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -377,9 +368,6 @@
|
|||||||
<ClInclude Include="Timer.h">
|
<ClInclude Include="Timer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TextureDDS.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ResourceManager.h">
|
<ClInclude Include="ResourceManager.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
8
moon.cpp
8
moon.cpp
@@ -36,9 +36,9 @@ void
|
|||||||
cMoon::update() {
|
cMoon::update() {
|
||||||
|
|
||||||
move();
|
move();
|
||||||
glm::vec3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
glm::vec3 position( 0.f, 0.f, -2000.f * Global::fDistanceFactor );
|
||||||
position = glm::rotateX( position, (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
position = glm::rotateX( position, glm::radians<float>( m_body.elevref ) );
|
||||||
position = glm::rotateY( position, (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
position = glm::rotateY( position, glm::radians<float>( -m_body.hrang ) );
|
||||||
|
|
||||||
m_position = position;
|
m_position = position;
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ cMoon::render() {
|
|||||||
glEnd();
|
glEnd();
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef( position.x, position.y, position.z );
|
glTranslatef( position.x, position.y, position.z );
|
||||||
gluSphere( moonsphere, /* (float)( Global::ScreenHeight / Global::FieldOfView ) * 0.5 * */ ( m_body.distance / 60.2666 ) * 9.037461, 12, 12 );
|
gluSphere( moonsphere, /* (float)( Global::iWindowHeight / Global::FieldOfView ) * 0.5 * */ ( m_body.distance / 60.2666 ) * 9.037461, 12, 12 );
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ mouse_input::poll() {
|
|||||||
|
|
||||||
auto updaterate { m_updaterate };
|
auto updaterate { m_updaterate };
|
||||||
if( m_varyingpollrate ) {
|
if( m_varyingpollrate ) {
|
||||||
updaterate /= std::max( 0.15, 2.0 * glm::length( m_cursorposition - m_commandstartcursor ) / std::max( 1, Global::ScreenHeight ) );
|
updaterate /= std::max( 0.15, 2.0 * glm::length( m_cursorposition - m_commandstartcursor ) / std::max( 1, Global::iWindowHeight ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_updateaccumulator < updaterate ) {
|
if( m_updateaccumulator < updaterate ) {
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ struct basic_vertex {
|
|||||||
glm::vec2 texture; // uv space
|
glm::vec2 texture; // uv space
|
||||||
|
|
||||||
basic_vertex() = default;
|
basic_vertex() = default;
|
||||||
basic_vertex( glm::vec3 const&Position, glm::vec3 const &Normal, glm::vec2 const &Texture ) :
|
basic_vertex( glm::vec3 const &Position, glm::vec3 const &Normal, glm::vec2 const &Texture ) :
|
||||||
position( Position ), normal( Normal ), texture( Texture )
|
position( Position ), normal( Normal ), texture( Texture )
|
||||||
{}
|
{}
|
||||||
void serialize( std::ostream& ) const;
|
void serialize( std::ostream& ) const;
|
||||||
void deserialize( std::istream& );
|
void deserialize( std::istream& );
|
||||||
|
|||||||
@@ -31,17 +31,23 @@ public:
|
|||||||
|
|
||||||
// methods:
|
// methods:
|
||||||
glm::mat4 const &
|
glm::mat4 const &
|
||||||
data() const { return m_stack.top(); }
|
data() const {
|
||||||
|
return m_stack.top(); }
|
||||||
void
|
void
|
||||||
push_matrix() { m_stack.emplace(m_stack.top()); }
|
push_matrix() {
|
||||||
|
m_stack.emplace( m_stack.top() ); }
|
||||||
void
|
void
|
||||||
pop_matrix() {
|
pop_matrix() {
|
||||||
m_stack.pop();
|
m_stack.pop();
|
||||||
if( m_stack.empty() ) { m_stack.emplace(1.0f); }
|
if( m_stack.empty() ) { m_stack.emplace( 1.f ); }
|
||||||
upload(); }
|
upload(); }
|
||||||
void
|
void
|
||||||
load_identity() {
|
load_identity() {
|
||||||
m_stack.top() = glm::mat4( 1.0f );
|
m_stack.top() = glm::mat4( 1.f );
|
||||||
|
upload(); }
|
||||||
|
void
|
||||||
|
load_matrix( glm::mat4 const &Matrix ) {
|
||||||
|
m_stack.top() = Matrix;
|
||||||
upload(); }
|
upload(); }
|
||||||
void
|
void
|
||||||
rotate( float const Angle, glm::vec3 const &Axis ) {
|
rotate( float const Angle, glm::vec3 const &Axis ) {
|
||||||
@@ -113,6 +119,11 @@ public:
|
|||||||
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
|
pop_matrix() { m_stacks[ m_mode ].pop_matrix(); }
|
||||||
void
|
void
|
||||||
load_identity() { m_stacks[ m_mode ].load_identity(); }
|
load_identity() { m_stacks[ m_mode ].load_identity(); }
|
||||||
|
void
|
||||||
|
load_matrix( glm::mat4 const &Matrix ) { m_stacks[ m_mode ].load_matrix( Matrix ); }
|
||||||
|
template <typename Type_>
|
||||||
|
void
|
||||||
|
load_matrix( Type_ const *Matrix ) { load_matrix( glm::make_mat4( Matrix ) ); }
|
||||||
template <typename Type_>
|
template <typename Type_>
|
||||||
void
|
void
|
||||||
rotate( Type_ const Angle, Type_ const X, Type_ const Y, Type_ const Z ) {
|
rotate( Type_ const Angle, Type_ const X, Type_ const Y, Type_ const Z ) {
|
||||||
@@ -184,6 +195,8 @@ extern opengl_matrices OpenGLMatrices;
|
|||||||
#define glPushMatrix OpenGLMatrices.push_matrix
|
#define glPushMatrix OpenGLMatrices.push_matrix
|
||||||
#define glPopMatrix OpenGLMatrices.pop_matrix
|
#define glPopMatrix OpenGLMatrices.pop_matrix
|
||||||
#define glLoadIdentity OpenGLMatrices.load_identity
|
#define glLoadIdentity OpenGLMatrices.load_identity
|
||||||
|
#define glLoadMatrixf OpenGLMatrices.load_matrix
|
||||||
|
#define glLoadMatrixd OpenGLMatrices.load_matrix
|
||||||
#define glRotated OpenGLMatrices.rotate
|
#define glRotated OpenGLMatrices.rotate
|
||||||
#define glRotatef OpenGLMatrices.rotate
|
#define glRotatef OpenGLMatrices.rotate
|
||||||
#define glTranslated OpenGLMatrices.translate
|
#define glTranslated OpenGLMatrices.translate
|
||||||
|
|||||||
36
parser.cpp
36
parser.cpp
@@ -72,6 +72,42 @@ cParser::~cParser()
|
|||||||
mComments.clear();
|
mComments.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
cParser&
|
||||||
|
cParser::operator>>( std::string &Right ) {
|
||||||
|
|
||||||
|
if( true == this->tokens.empty() ) { return *this; }
|
||||||
|
|
||||||
|
Right = this->tokens.front();
|
||||||
|
this->tokens.pop_front();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
cParser&
|
||||||
|
cParser::operator>>( bool &Right ) {
|
||||||
|
|
||||||
|
if( true == this->tokens.empty() ) { return *this; }
|
||||||
|
|
||||||
|
Right = ( ( this->tokens.front() == "true" )
|
||||||
|
|| ( this->tokens.front() == "yes" )
|
||||||
|
|| ( this->tokens.front() == "1" ) );
|
||||||
|
this->tokens.pop_front();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool
|
||||||
|
cParser::getToken<bool>( bool const ToLower, const char *Break ) {
|
||||||
|
|
||||||
|
auto const token = getToken<std::string>( true, Break );
|
||||||
|
return ( ( token == "true" )
|
||||||
|
|| ( token == "yes" )
|
||||||
|
|| ( token == "1" ) );
|
||||||
|
}
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
bool cParser::getTokens(unsigned int Count, bool ToLower, const char *Break)
|
bool cParser::getTokens(unsigned int Count, bool ToLower, const char *Break)
|
||||||
{
|
{
|
||||||
|
|||||||
91
parser.h
91
parser.h
@@ -35,12 +35,6 @@ class cParser //: public std::stringstream
|
|||||||
template <typename Type_>
|
template <typename Type_>
|
||||||
cParser &
|
cParser &
|
||||||
operator>>( Type_ &Right );
|
operator>>( Type_ &Right );
|
||||||
template <>
|
|
||||||
cParser &
|
|
||||||
operator>>( std::string &Right );
|
|
||||||
template <>
|
|
||||||
cParser &
|
|
||||||
operator>>( bool &Right );
|
|
||||||
template <typename Output_>
|
template <typename Output_>
|
||||||
Output_
|
Output_
|
||||||
getToken( bool const ToLower = true, const char *Break = "\n\r\t ;" ) {
|
getToken( bool const ToLower = true, const char *Break = "\n\r\t ;" ) {
|
||||||
@@ -48,41 +42,34 @@ class cParser //: public std::stringstream
|
|||||||
Output_ output;
|
Output_ output;
|
||||||
*this >> output;
|
*this >> output;
|
||||||
return output; };
|
return output; };
|
||||||
template <>
|
inline
|
||||||
bool
|
void
|
||||||
getToken<bool>( bool const ToLower, const char *Break ) {
|
ignoreToken() {
|
||||||
auto const token = getToken<std::string>( true, Break );
|
readToken(); };
|
||||||
return ( ( token == "true" )
|
inline
|
||||||
|| ( token == "yes" )
|
void
|
||||||
|| ( token == "1" ) ); }
|
ignoreTokens(int count) {
|
||||||
inline void ignoreToken()
|
for( int i = 0; i < count; ++i ) {
|
||||||
{
|
readToken(); } };
|
||||||
readToken();
|
inline
|
||||||
};
|
bool
|
||||||
inline void ignoreTokens(int count)
|
expectToken( std::string const &Value ) {
|
||||||
{
|
return readToken() == Value; };
|
||||||
for (int i = 0; i < count; i++)
|
bool
|
||||||
readToken();
|
eof() {
|
||||||
};
|
return mStream->eof(); };
|
||||||
inline bool expectToken(std::string const &value)
|
bool
|
||||||
{
|
ok() {
|
||||||
return readToken() == value;
|
return !mStream->fail(); };
|
||||||
};
|
bool
|
||||||
bool eof()
|
getTokens( unsigned int Count = 1, bool ToLower = true, char const *Break = "\n\r\t ;" );
|
||||||
{
|
|
||||||
return mStream->eof();
|
|
||||||
};
|
|
||||||
bool ok()
|
|
||||||
{
|
|
||||||
return !mStream->fail();
|
|
||||||
};
|
|
||||||
bool getTokens(unsigned int Count = 1, bool ToLower = true, char const *Break = "\n\r\t ;");
|
|
||||||
// returns next incoming token, if any, without removing it from the set
|
// returns next incoming token, if any, without removing it from the set
|
||||||
std::string peek() const {
|
std::string
|
||||||
return (
|
peek() const {
|
||||||
false == tokens.empty() ?
|
return (
|
||||||
tokens.front() :
|
false == tokens.empty() ?
|
||||||
"" ); }
|
tokens.front() :
|
||||||
|
"" ); }
|
||||||
// returns percentage of file processed so far
|
// returns percentage of file processed so far
|
||||||
int getProgress() const;
|
int getProgress() const;
|
||||||
int getFullProgress() const;
|
int getFullProgress() const;
|
||||||
@@ -129,26 +116,12 @@ cParser::operator>>( Type_ &Right ) {
|
|||||||
|
|
||||||
template<>
|
template<>
|
||||||
cParser&
|
cParser&
|
||||||
cParser::operator>>( std::string &Right ) {
|
cParser::operator>>( std::string &Right );
|
||||||
|
|
||||||
if( true == this->tokens.empty() ) { return *this; }
|
|
||||||
|
|
||||||
Right = this->tokens.front();
|
|
||||||
this->tokens.pop_front();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
cParser&
|
cParser&
|
||||||
cParser::operator>>( bool &Right ) {
|
cParser::operator>>( bool &Right );
|
||||||
|
|
||||||
if( true == this->tokens.empty() ) { return *this; }
|
template<>
|
||||||
|
bool
|
||||||
Right = ( ( this->tokens.front() == "true" )
|
cParser::getToken<bool>( bool const ToLower, const char *Break );
|
||||||
|| ( this->tokens.front() == "yes" )
|
|
||||||
|| ( this->tokens.front() == "1" ) );
|
|
||||||
this->tokens.pop_front();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|||||||
709
renderer.cpp
709
renderer.cpp
File diff suppressed because it is too large
Load Diff
141
renderer.h
141
renderer.h
@@ -18,15 +18,19 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "memcell.h"
|
#include "memcell.h"
|
||||||
|
|
||||||
|
#define EU07_USE_PICKING_FRAMEBUFFER
|
||||||
|
//#define EU07_USE_DEBUG_SHADOWMAP
|
||||||
|
//#define EU07_USE_DEBUG_CAMERA
|
||||||
|
|
||||||
struct opengl_light {
|
struct opengl_light {
|
||||||
|
|
||||||
GLuint id{ (GLuint)-1 };
|
GLuint id{ (GLuint)-1 };
|
||||||
glm::vec3 direction;
|
glm::vec3 direction;
|
||||||
glm::vec4
|
glm::vec4
|
||||||
position { 0.0f, 0.0f, 0.0f, 1.0f }, // 4th parameter specifies directional(0) or omni-directional(1) light source
|
position { 0.f, 0.f, 0.f, 1.f }, // 4th parameter specifies directional(0) or omni-directional(1) light source
|
||||||
ambient { 0.0f, 0.0f, 0.0f, 1.0f },
|
ambient { 0.f, 0.f, 0.f, 1.f },
|
||||||
diffuse { 1.0f, 1.0f, 1.0f, 1.0f },
|
diffuse { 1.f, 1.f, 1.f, 1.f },
|
||||||
specular { 1.0f, 1.0f, 1.0f, 1.0f };
|
specular { 1.f, 1.f, 1.f, 1.f };
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void apply_intensity( float const Factor = 1.0f ) {
|
void apply_intensity( float const Factor = 1.0f ) {
|
||||||
@@ -51,7 +55,7 @@ struct opengl_light {
|
|||||||
void apply_angle() {
|
void apply_angle() {
|
||||||
|
|
||||||
glLightfv( id, GL_POSITION, glm::value_ptr(position) );
|
glLightfv( id, GL_POSITION, glm::value_ptr(position) );
|
||||||
if( position.w == 1.0f ) {
|
if( position.w == 1.f ) {
|
||||||
glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr(direction) );
|
glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr(direction) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,10 +87,9 @@ public:
|
|||||||
// methods:
|
// methods:
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
update_frustum() { m_frustum.calculate(); }
|
update_frustum() { update_frustum( m_projection, m_modelview ); }
|
||||||
inline
|
|
||||||
void
|
void
|
||||||
update_frustum(glm::mat4 const &Projection, glm::mat4 const &Modelview) { m_frustum.calculate(Projection, Modelview); }
|
update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview );
|
||||||
bool
|
bool
|
||||||
visible( bounding_area const &Area ) const;
|
visible( bounding_area const &Area ) const;
|
||||||
bool
|
bool
|
||||||
@@ -97,11 +100,44 @@ public:
|
|||||||
inline
|
inline
|
||||||
glm::dvec3 &
|
glm::dvec3 &
|
||||||
position() { return m_position; }
|
position() { return m_position; }
|
||||||
|
inline
|
||||||
|
glm::mat4 const &
|
||||||
|
projection() const { return m_projection; }
|
||||||
|
inline
|
||||||
|
glm::mat4 &
|
||||||
|
projection() { return m_projection; }
|
||||||
|
inline
|
||||||
|
glm::mat4 const &
|
||||||
|
modelview() const { return m_modelview; }
|
||||||
|
inline
|
||||||
|
glm::mat4 &
|
||||||
|
modelview() { return m_modelview; }
|
||||||
|
inline
|
||||||
|
std::vector<glm::vec4> &
|
||||||
|
frustum_points() { return m_frustumpoints; }
|
||||||
|
// transforms provided set of clip space points to world space
|
||||||
|
template <class Iterator_>
|
||||||
|
void
|
||||||
|
transform_to_world( Iterator_ First, Iterator_ Last ) const {
|
||||||
|
std::for_each(
|
||||||
|
First, Last,
|
||||||
|
[this]( glm::vec4 &point ) {
|
||||||
|
// transform each point using the cached matrix...
|
||||||
|
point = this->m_inversetransformation * point;
|
||||||
|
// ...and scale by transformed w
|
||||||
|
point = glm::vec4{ glm::vec3{ point } / point.w, 1.f }; } ); }
|
||||||
|
// debug helper, draws shape of frustum in world space
|
||||||
|
void
|
||||||
|
draw( glm::vec3 const &Offset ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members:
|
// members:
|
||||||
cFrustum m_frustum;
|
cFrustum m_frustum;
|
||||||
|
std::vector<glm::vec4> m_frustumpoints; // visualization helper; corners of defined frustum, in world space
|
||||||
glm::dvec3 m_position;
|
glm::dvec3 m_position;
|
||||||
|
glm::mat4 m_projection;
|
||||||
|
glm::mat4 m_modelview;
|
||||||
|
glm::mat4 m_inversetransformation; // cached transformation to world space
|
||||||
};
|
};
|
||||||
|
|
||||||
// bare-bones render controller, in lack of anything better yet
|
// bare-bones render controller, in lack of anything better yet
|
||||||
@@ -119,6 +155,9 @@ public:
|
|||||||
// main draw call. returns false on error
|
// main draw call. returns false on error
|
||||||
bool
|
bool
|
||||||
Render();
|
Render();
|
||||||
|
inline
|
||||||
|
float
|
||||||
|
Framerate() { return m_framerate; }
|
||||||
// geometry methods
|
// geometry methods
|
||||||
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
|
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
|
||||||
// creates a new geometry bank. returns: handle to the bank or NULL
|
// creates a new geometry bank. returns: handle to the bank or NULL
|
||||||
@@ -159,7 +198,7 @@ public:
|
|||||||
TGroundNode const *
|
TGroundNode const *
|
||||||
Update_Pick_Node();
|
Update_Pick_Node();
|
||||||
// debug performance string
|
// debug performance string
|
||||||
std::string
|
std::string const &
|
||||||
Info() const;
|
Info() const;
|
||||||
|
|
||||||
// members
|
// members
|
||||||
@@ -179,10 +218,10 @@ private:
|
|||||||
typedef std::pair< double, TSubRect * > distancesubcell_pair;
|
typedef std::pair< double, TSubRect * > distancesubcell_pair;
|
||||||
|
|
||||||
struct renderpass_config {
|
struct renderpass_config {
|
||||||
|
|
||||||
opengl_camera camera;
|
opengl_camera camera;
|
||||||
rendermode draw_mode { rendermode::color };
|
rendermode draw_mode { rendermode::none };
|
||||||
float draw_range { 0.0f };
|
float draw_range { 0.0f };
|
||||||
std::vector<distancesubcell_pair> draw_queue; // list of subcells to be drawn in current render pass
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<opengl_light> opengllight_array;
|
typedef std::vector<opengl_light> opengllight_array;
|
||||||
@@ -193,24 +232,10 @@ private:
|
|||||||
// runs jobs needed to generate graphics for specified render pass
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
void
|
void
|
||||||
Render_pass( rendermode const Mode );
|
Render_pass( rendermode const Mode );
|
||||||
// configures projection matrix for the current render pass
|
|
||||||
void
|
void
|
||||||
setup_projection();
|
setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false );
|
||||||
void
|
void
|
||||||
setup_projection_world();
|
setup_matrices();
|
||||||
void
|
|
||||||
setup_projection_light_ortho();
|
|
||||||
void
|
|
||||||
setup_projection_light_perspective();
|
|
||||||
// configures camera for the current render pass
|
|
||||||
void
|
|
||||||
setup_camera();
|
|
||||||
void
|
|
||||||
setup_camera_world( glm::dmat4 &Viewmatrix );
|
|
||||||
void
|
|
||||||
setup_camera_light_ortho( glm::dmat4 &Viewmatrix );
|
|
||||||
void
|
|
||||||
setup_camera_light_perspective( glm::dmat4 &Viewmatrix );
|
|
||||||
void
|
void
|
||||||
setup_drawing( bool const Alpha = false );
|
setup_drawing( bool const Alpha = false );
|
||||||
void
|
void
|
||||||
@@ -218,7 +243,7 @@ private:
|
|||||||
void
|
void
|
||||||
setup_shadow_color( glm::vec4 const &Shadowcolor );
|
setup_shadow_color( glm::vec4 const &Shadowcolor );
|
||||||
void
|
void
|
||||||
toggle_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
switch_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
||||||
bool
|
bool
|
||||||
Render( world_environment *Environment );
|
Render( world_environment *Environment );
|
||||||
bool
|
bool
|
||||||
@@ -258,53 +283,67 @@ private:
|
|||||||
void
|
void
|
||||||
Render_Alpha( TSubModel *Submodel );
|
Render_Alpha( TSubModel *Submodel );
|
||||||
void
|
void
|
||||||
Update_Lights( light_array const &Lights );
|
Update_Lights( light_array &Lights );
|
||||||
glm::vec3
|
glm::vec3
|
||||||
pick_color( std::size_t const Index );
|
pick_color( std::size_t const Index );
|
||||||
std::size_t
|
std::size_t
|
||||||
pick_index( glm::ivec3 const &Color );
|
pick_index( glm::ivec3 const &Color );
|
||||||
|
|
||||||
// members
|
// members
|
||||||
|
GLFWwindow *m_window { nullptr };
|
||||||
geometrybank_manager m_geometry;
|
geometrybank_manager m_geometry;
|
||||||
texture_manager m_textures;
|
texture_manager m_textures;
|
||||||
opengllight_array m_lights;
|
opengllight_array m_lights;
|
||||||
GLFWwindow *m_window { nullptr };
|
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
|
||||||
GLuint m_pickframebuffer { 0 }; // TODO: refactor pick framebuffer stuff into an object
|
|
||||||
GLuint m_picktexture { 0 };
|
|
||||||
GLuint m_pickdepthbuffer { 0 };
|
|
||||||
int m_pickbuffersize { 1024 }; // size of (square) textures bound with the pick framebuffer
|
|
||||||
#endif
|
|
||||||
GLuint m_shadowframebuffer { 0 };
|
|
||||||
GLuint m_shadowtexture { 0 };
|
|
||||||
int m_shadowbuffersize { 4096 };
|
|
||||||
glm::mat4 m_shadowtexturematrix;
|
|
||||||
glm::vec4 m_shadowcolor{ 0.5f, 0.5f, 0.5f, 1.f };
|
|
||||||
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
|
||||||
int m_shadowtextureunit { GL_TEXTURE1 };
|
|
||||||
int m_helpertextureunit { GL_TEXTURE0 };
|
|
||||||
int m_diffusetextureunit { GL_TEXTURE2 };
|
|
||||||
|
|
||||||
geometry_handle m_billboardgeometry { 0, 0 };
|
geometry_handle m_billboardgeometry { NULL, NULL };
|
||||||
texture_handle m_glaretexture { -1 };
|
texture_handle m_glaretexture { -1 };
|
||||||
texture_handle m_suntexture { -1 };
|
texture_handle m_suntexture { -1 };
|
||||||
texture_handle m_moontexture { -1 };
|
texture_handle m_moontexture { -1 };
|
||||||
texture_handle m_reflectiontexture { -1 };
|
texture_handle m_reflectiontexture { -1 };
|
||||||
|
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
||||||
|
|
||||||
float m_drawtime { 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
|
bool m_framebuffersupport { false };
|
||||||
|
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
||||||
|
GLuint m_pickframebuffer { NULL }; // TODO: refactor pick framebuffer stuff into an object
|
||||||
|
GLuint m_picktexture { NULL };
|
||||||
|
GLuint m_pickdepthbuffer { NULL };
|
||||||
|
#endif
|
||||||
|
int m_shadowbuffersize { 4096 };
|
||||||
|
GLuint m_shadowframebuffer { NULL };
|
||||||
|
GLuint m_shadowtexture { NULL };
|
||||||
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
|
GLuint m_shadowdebugtexture{ NULL };
|
||||||
|
#endif
|
||||||
|
glm::mat4 m_shadowtexturematrix; // conversion from camera-centric world space to light-centric clip space
|
||||||
|
|
||||||
|
int m_shadowtextureunit { GL_TEXTURE1 };
|
||||||
|
int m_helpertextureunit { GL_TEXTURE0 };
|
||||||
|
int m_diffusetextureunit { GL_TEXTURE2 };
|
||||||
|
|
||||||
|
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;
|
||||||
|
float m_drawtimecolorpass { 1000.f / 30.f * 20.f };
|
||||||
|
float m_drawtimeshadowpass { 0.f };
|
||||||
double m_updateaccumulator { 0.0 };
|
double m_updateaccumulator { 0.0 };
|
||||||
std::string m_debuginfo;
|
std::string m_debuginfo;
|
||||||
|
|
||||||
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
float m_specularopaquescalefactor { 1.0f };
|
glm::vec4 m_shadowcolor { 0.5f, 0.5f, 0.5f, 1.f };
|
||||||
float m_speculartranslucentscalefactor { 1.0f };
|
float m_specularopaquescalefactor { 1.f };
|
||||||
|
float m_speculartranslucentscalefactor { 1.f };
|
||||||
|
bool m_renderspecular{ false }; // controls whether to include specular component in the calculations
|
||||||
|
|
||||||
bool m_framebuffersupport { false };
|
|
||||||
renderpass_config m_renderpass;
|
renderpass_config m_renderpass;
|
||||||
bool m_renderspecular { false }; // controls whether to include specular component in the calculations
|
std::vector<distancesubcell_pair> m_drawqueue; // list of subcells to be drawn in current render pass
|
||||||
|
|
||||||
std::vector<TGroundNode const *> m_picksceneryitems;
|
std::vector<TGroundNode const *> m_picksceneryitems;
|
||||||
std::vector<TSubModel const *> m_pickcontrolsitems;
|
std::vector<TSubModel const *> m_pickcontrolsitems;
|
||||||
TSubModel const *m_pickcontrolitem { nullptr };
|
TSubModel const *m_pickcontrolitem { nullptr };
|
||||||
TGroundNode const *m_picksceneryitem { nullptr };
|
TGroundNode const *m_picksceneryitem { nullptr };
|
||||||
|
#ifdef EU07_USE_DEBUG_CAMERA
|
||||||
|
renderpass_config m_worldcamera; // debug item
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern opengl_renderer GfxRenderer;
|
extern opengl_renderer GfxRenderer;
|
||||||
|
|||||||
19
sun.cpp
19
sun.cpp
@@ -33,9 +33,9 @@ void
|
|||||||
cSun::update() {
|
cSun::update() {
|
||||||
|
|
||||||
move();
|
move();
|
||||||
glm::vec3 position( 0.0f, 0.0f, -2000.0f * Global::fDistanceFactor );
|
glm::vec3 position( 0.f, 0.f, -2000.f * Global::fDistanceFactor );
|
||||||
position = glm::rotateX( position, (float)( m_body.elevref * ( M_PI / 180.0 ) ) );
|
position = glm::rotateX( position, glm::radians<float>( m_body.elevref ) );
|
||||||
position = glm::rotateY( position, (float)( -m_body.hrang * ( M_PI / 180.0 ) ) );
|
position = glm::rotateY( position, glm::radians<float>( -m_body.hrang ) );
|
||||||
|
|
||||||
m_position = position;
|
m_position = position;
|
||||||
}
|
}
|
||||||
@@ -251,21 +251,18 @@ void cSun::refract() {
|
|||||||
|
|
||||||
void cSun::irradiance() {
|
void cSun::irradiance() {
|
||||||
|
|
||||||
static double degrad = 57.295779513; // converts from radians to degrees
|
|
||||||
static double raddeg = 0.0174532925; // converts from degrees to radians
|
|
||||||
|
|
||||||
m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0;
|
m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0;
|
||||||
double sd = sin( raddeg * m_body.dayang ); // sine of the day angle
|
double sd = std::sin( glm::radians( m_body.dayang ) ); // sine of the day angle
|
||||||
double cd = cos( raddeg * m_body.dayang ); // cosine of the day angle or delination
|
double cd = std::cos( glm::radians( m_body.dayang ) ); // cosine of the day angle or delination
|
||||||
m_body.erv = 1.000110 + 0.034221*cd + 0.001280*sd;
|
m_body.erv = 1.000110 + 0.034221*cd + 0.001280*sd;
|
||||||
double d2 = 2.0 * m_body.dayang;
|
double d2 = 2.0 * m_body.dayang;
|
||||||
double c2 = cos( raddeg * d2 );
|
double c2 = std::cos( glm::radians( d2 ) );
|
||||||
double s2 = sin( raddeg * d2 );
|
double s2 = std::sin( glm::radians( d2 ) );
|
||||||
m_body.erv += 0.000719*c2 + 0.000077*s2;
|
m_body.erv += 0.000719*c2 + 0.000077*s2;
|
||||||
|
|
||||||
double solcon = 1367.0; // Solar constant, 1367 W/sq m
|
double solcon = 1367.0; // Solar constant, 1367 W/sq m
|
||||||
|
|
||||||
m_body.coszen = cos( raddeg * m_body.zenref );
|
m_body.coszen = std::cos( glm::radians( m_body.zenref ) );
|
||||||
if( m_body.coszen > 0.0 ) {
|
if( m_body.coszen > 0.0 ) {
|
||||||
m_body.etrn = solcon * m_body.erv;
|
m_body.etrn = solcon * m_body.erv;
|
||||||
m_body.etr = m_body.etrn * m_body.coszen;
|
m_body.etr = m_body.etrn * m_body.coszen;
|
||||||
|
|||||||
@@ -62,10 +62,10 @@ static std::unordered_map<std::string, std::string> m_cabcontrols = {
|
|||||||
{ "converteroff_sw:", "converter" },
|
{ "converteroff_sw:", "converter" },
|
||||||
{ "main_sw:", "line breaker" },
|
{ "main_sw:", "line breaker" },
|
||||||
{ "radio_sw:", "radio" },
|
{ "radio_sw:", "radio" },
|
||||||
{ "pantfront_sw:", "front pantograph" },
|
{ "pantfront_sw:", "pantograph A" },
|
||||||
{ "pantrear_sw:", "rear pantograph" },
|
{ "pantrear_sw:", "pantograph B" },
|
||||||
{ "pantfrontoff_sw:", "front pantograph" },
|
{ "pantfrontoff_sw:", "pantograph A" },
|
||||||
{ "pantrearoff_sw:", "rear pantograph" },
|
{ "pantrearoff_sw:", "pantograph B" },
|
||||||
{ "pantalloff_sw:", "all pantographs" },
|
{ "pantalloff_sw:", "all pantographs" },
|
||||||
{ "pantselected_sw:", "selected pantograph" },
|
{ "pantselected_sw:", "selected pantograph" },
|
||||||
{ "pantselectedoff_sw:", "selected pantograph" },
|
{ "pantselectedoff_sw:", "selected pantograph" },
|
||||||
|
|||||||
33
uilayer.cpp
33
uilayer.cpp
@@ -65,7 +65,7 @@ ui_layer::render() {
|
|||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho( 0, std::max( 1, Global::ScreenWidth ), std::max( 1, Global::ScreenHeight ), 0, -1, 1 );
|
glOrtho( 0, std::max( 1, Global::iWindowWidth ), std::max( 1, Global::iWindowHeight ), 0, -1, 1 );
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@@ -78,6 +78,7 @@ ui_layer::render() {
|
|||||||
|
|
||||||
// render code here
|
// render code here
|
||||||
render_background();
|
render_background();
|
||||||
|
render_texture();
|
||||||
render_progress();
|
render_progress();
|
||||||
render_panels();
|
render_panels();
|
||||||
render_tooltip();
|
render_tooltip();
|
||||||
@@ -106,11 +107,7 @@ ui_layer::set_background( std::string const &Filename ) {
|
|||||||
m_progressbottom = ( texture.width() != texture.height() );
|
m_progressbottom = ( texture.width() != texture.height() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void cGuiLayer::setNote( const std::string Note ) { mNote = Note; }
|
|
||||||
|
|
||||||
std::string cGuiLayer::getNote() { return mNote; }
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
ui_layer::render_progress() {
|
ui_layer::render_progress() {
|
||||||
|
|
||||||
@@ -235,6 +232,32 @@ ui_layer::render_background() {
|
|||||||
float4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
float4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ui_layer::render_texture() {
|
||||||
|
|
||||||
|
if( m_texture != NULL ) {
|
||||||
|
::glColor4f( 1.f, 1.f, 1.f, 1.f );
|
||||||
|
::glDisable( GL_BLEND );
|
||||||
|
|
||||||
|
GfxRenderer.Bind( NULL );
|
||||||
|
::glBindTexture( GL_TEXTURE_2D, m_texture );
|
||||||
|
|
||||||
|
auto const size = 512.f;
|
||||||
|
auto const offset = 64.f;
|
||||||
|
|
||||||
|
glBegin( GL_TRIANGLE_STRIP );
|
||||||
|
|
||||||
|
glMultiTexCoord2f( m_textureunit, 0.f, 1.f ); glVertex2f( offset, Global::iWindowHeight - offset - size );
|
||||||
|
glMultiTexCoord2f( m_textureunit, 0.f, 0.f ); glVertex2f( offset, Global::iWindowHeight - offset );
|
||||||
|
glMultiTexCoord2f( m_textureunit, 1.f, 1.f ); glVertex2f( offset + size, Global::iWindowHeight - offset - size );
|
||||||
|
glMultiTexCoord2f( m_textureunit, 1.f, 0.f ); glVertex2f( offset + size, Global::iWindowHeight - offset );
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
::glEnable( GL_BLEND );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ui_layer::print( std::string const &Text )
|
ui_layer::print( std::string const &Text )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ struct ui_panel {
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
std::vector<text_line> text_lines;
|
std::vector<text_line> text_lines;
|
||||||
float origin_x;
|
int origin_x;
|
||||||
float origin_y;
|
int origin_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ui_layer {
|
class ui_layer {
|
||||||
@@ -54,6 +54,8 @@ public:
|
|||||||
// sets the ui background texture, if any
|
// sets the ui background texture, if any
|
||||||
void
|
void
|
||||||
set_background( std::string const &Filename = "" );
|
set_background( std::string const &Filename = "" );
|
||||||
|
void
|
||||||
|
set_texture( GLuint Texture = NULL ) { m_texture = Texture; }
|
||||||
void
|
void
|
||||||
set_tooltip( std::string const &Tooltip ) { m_tooltip = Tooltip; }
|
set_tooltip( std::string const &Tooltip ) { m_tooltip = Tooltip; }
|
||||||
void
|
void
|
||||||
@@ -68,6 +70,8 @@ private:
|
|||||||
// draws background quad with specified earlier texture
|
// draws background quad with specified earlier texture
|
||||||
void
|
void
|
||||||
render_background();
|
render_background();
|
||||||
|
void
|
||||||
|
render_texture();
|
||||||
// draws a progress bar in defined earlier state
|
// draws a progress bar in defined earlier state
|
||||||
void
|
void
|
||||||
render_progress();
|
render_progress();
|
||||||
@@ -95,6 +99,7 @@ private:
|
|||||||
bool m_progressbottom { false }; // location of the progress bar
|
bool m_progressbottom { false }; // location of the progress bar
|
||||||
|
|
||||||
texture_handle m_background { NULL }; // path to texture used as the background. size depends on mAspect.
|
texture_handle m_background { NULL }; // path to texture used as the background. size depends on mAspect.
|
||||||
|
GLuint m_texture { NULL };
|
||||||
std::vector<std::shared_ptr<ui_panel> > m_panels;
|
std::vector<std::shared_ptr<ui_panel> > m_panels;
|
||||||
std::string m_tooltip;
|
std::string m_tooltip;
|
||||||
};
|
};
|
||||||
|
|||||||
17
usefull.h
17
usefull.h
@@ -77,7 +77,22 @@ bool
|
|||||||
degenerate( VecType_ const &Vertex1, VecType_ const &Vertex2, VecType_ const &Vertex3 ) {
|
degenerate( VecType_ const &Vertex1, VecType_ const &Vertex2, VecType_ const &Vertex3 ) {
|
||||||
|
|
||||||
// degenerate( A, B, C, minarea ) = ( ( B - A ).cross( C - A ) ).lengthSquared() < ( 4.0f * minarea * minarea );
|
// degenerate( A, B, C, minarea ) = ( ( B - A ).cross( C - A ) ).lengthSquared() < ( 4.0f * minarea * minarea );
|
||||||
return glm::length2( glm::cross( Vertex2 - Vertex1, Vertex3 - Vertex1 ) ) < std::numeric_limits<VecType_::value_type>::epsilon();
|
return ( glm::length2( glm::cross( Vertex2 - Vertex1, Vertex3 - Vertex1 ) ) == 0.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculates bounding box for provided set of points
|
||||||
|
template <class Iterator_, class VecType_>
|
||||||
|
void
|
||||||
|
bounding_box( VecType_ &Mincorner, VecType_ &Maxcorner, Iterator_ First, Iterator_ Last ) {
|
||||||
|
|
||||||
|
Mincorner = VecType_( typename std::numeric_limits<VecType_::value_type>::max() );
|
||||||
|
Maxcorner = VecType_( typename std::numeric_limits<VecType_::value_type>::lowest() );
|
||||||
|
|
||||||
|
std::for_each(
|
||||||
|
First, Last,
|
||||||
|
[&]( typename Iterator_::value_type &point ) {
|
||||||
|
Mincorner = glm::min( Mincorner, VecType_{ point } );
|
||||||
|
Maxcorner = glm::max( Maxcorner, VecType_{ point } ); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user