mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 09:19:18 +02:00
build 170708. cursor-based item picking, mouse support for cab controls, rudimentary render modes support in renderer
This commit is contained in:
@@ -447,7 +447,7 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
|
|||||||
m_materialdata.replacable_skins[1] =
|
m_materialdata.replacable_skins[1] =
|
||||||
GfxRenderer.GetTextureId( asReplacableTexture, "" );
|
GfxRenderer.GetTextureId( asReplacableTexture, "" );
|
||||||
if( ( m_materialdata.replacable_skins[ 1 ] != 0 )
|
if( ( m_materialdata.replacable_skins[ 1 ] != 0 )
|
||||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) ) {
|
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) ) {
|
||||||
// tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
// tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||||
m_materialdata.textures_alpha = 0x31310031;
|
m_materialdata.textures_alpha = 0x31310031;
|
||||||
}
|
}
|
||||||
@@ -470,7 +470,7 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
|||||||
if (ter) // jeśli teren
|
if (ter) // jeśli teren
|
||||||
{
|
{
|
||||||
if( name.substr( name.rfind( '.' ) ) == ".t3d" ) {
|
if( name.substr( name.rfind( '.' ) ) == ".t3d" ) {
|
||||||
name[ name.length() - 2 ] = 'e';
|
name[ name.length() - 3 ] = 'e';
|
||||||
}
|
}
|
||||||
Global::asTerrainModel = name;
|
Global::asTerrainModel = name;
|
||||||
WriteLog("Terrain model \"" + name + "\" will be created.");
|
WriteLog("Terrain model \"" + name + "\" will be created.");
|
||||||
|
|||||||
19
Camera.cpp
19
Camera.cpp
@@ -419,29 +419,18 @@ bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
|
|||||||
if( Type == tp_Follow ) {
|
if( Type == tp_Follow ) {
|
||||||
|
|
||||||
Matrix *= glm::lookAt(
|
Matrix *= glm::lookAt(
|
||||||
glm::dvec3( Pos.x, Pos.y, Pos.z ),
|
glm::dvec3{ Pos },
|
||||||
glm::dvec3( LookAt.x, LookAt.y, LookAt.z ),
|
glm::dvec3{ LookAt },
|
||||||
glm::dvec3( vUp.x, vUp.y, vUp.z ) );
|
glm::dvec3{ vUp } );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Matrix = glm::translate( Matrix, glm::dvec3( -Pos.x, -Pos.y, -Pos.z ) ); // nie zmienia kierunku patrzenia
|
Matrix = glm::translate( Matrix, glm::dvec3{ -Pos } ); // nie zmienia kierunku patrzenia
|
||||||
}
|
}
|
||||||
|
|
||||||
Global::SetCameraPosition( Pos ); // było +pOffset
|
Global::SetCameraPosition( Pos ); // było +pOffset
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCamera::SetCabMatrix(vector3 &p)
|
|
||||||
{ // ustawienie widoku z kamery bez przesunięcia robionego przez OpenGL - nie powinno tak trząść
|
|
||||||
|
|
||||||
glRotated(-Roll * 180.0 / M_PI, 0.0, 0.0, 1.0);
|
|
||||||
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 - p.x, Pos.y - p.y, Pos.z - p.z, LookAt.x - p.x, LookAt.y - p.y,
|
|
||||||
LookAt.z - p.z, vUp.x, vUp.y, vUp.z); // Ra: pOffset is zero
|
|
||||||
}
|
|
||||||
|
|
||||||
void TCamera::RaLook()
|
void TCamera::RaLook()
|
||||||
{ // zmiana kierunku patrzenia - przelicza Yaw
|
{ // zmiana kierunku patrzenia - przelicza Yaw
|
||||||
vector3 where = LookAt - Pos + vector3(0, 3, 0); // trochę w górę od szyn
|
vector3 where = LookAt - Pos + vector3(0, 3, 0); // trochę w górę od szyn
|
||||||
|
|||||||
1
Camera.h
1
Camera.h
@@ -59,7 +59,6 @@ class TCamera
|
|||||||
vector3 GetDirection();
|
vector3 GetDirection();
|
||||||
bool SetMatrix();
|
bool SetMatrix();
|
||||||
bool SetMatrix(glm::dmat4 &Matrix);
|
bool SetMatrix(glm::dmat4 &Matrix);
|
||||||
void SetCabMatrix( vector3 &p );
|
|
||||||
void RaLook();
|
void RaLook();
|
||||||
void Stop();
|
void Stop();
|
||||||
// bool GetMatrix(matrix4x4 &Matrix);
|
// bool GetMatrix(matrix4x4 &Matrix);
|
||||||
|
|||||||
45
EU07.cpp
45
EU07.cpp
@@ -66,6 +66,7 @@ namespace input {
|
|||||||
|
|
||||||
keyboard_input Keyboard;
|
keyboard_input Keyboard;
|
||||||
gamepad_input Gamepad;
|
gamepad_input Gamepad;
|
||||||
|
glm::dvec2 mouse_pos; // stores last mouse position in control picking mode
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,11 +123,22 @@ void window_resize_callback(GLFWwindow *window, int w, int h)
|
|||||||
|
|
||||||
void cursor_pos_callback(GLFWwindow *window, double x, double y)
|
void cursor_pos_callback(GLFWwindow *window, double x, double y)
|
||||||
{
|
{
|
||||||
input::Keyboard.mouse( x, y );
|
if( true == Global::ControlPicking ) {
|
||||||
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
|
glfwSetCursorPos( window, x, y );
|
||||||
World.OnMouseMove(x * 0.005, y * 0.01);
|
}
|
||||||
#endif
|
else {
|
||||||
glfwSetCursorPos(window, 0.0, 0.0);
|
input::Keyboard.mouse( x, y );
|
||||||
|
glfwSetCursorPos( window, 0, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ) {
|
||||||
|
|
||||||
|
if( ( button == GLFW_MOUSE_BUTTON_LEFT )
|
||||||
|
|| ( button == GLFW_MOUSE_BUTTON_RIGHT ) ) {
|
||||||
|
// we don't care about other mouse buttons at the moment
|
||||||
|
input::Keyboard.mouse( button, action );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods )
|
void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods )
|
||||||
@@ -136,6 +148,27 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
|
|||||||
Global::shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false;
|
Global::shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false;
|
||||||
Global::ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false;
|
Global::ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false;
|
||||||
|
|
||||||
|
if( ( key == GLFW_KEY_LEFT_ALT )
|
||||||
|
|| ( key == GLFW_KEY_RIGHT_ALT ) ) {
|
||||||
|
// if the alt key was pressed toggle control picking mode and set matching cursor behaviour
|
||||||
|
if( action == GLFW_RELEASE ) {
|
||||||
|
|
||||||
|
if( Global::ControlPicking ) {
|
||||||
|
// switch off
|
||||||
|
glfwGetCursorPos( window, &input::mouse_pos.x, &input::mouse_pos.y );
|
||||||
|
glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
|
||||||
|
glfwSetCursorPos( window, 0, 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// enter picking mode
|
||||||
|
glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );
|
||||||
|
glfwSetCursorPos( window, input::mouse_pos.x, input::mouse_pos.y );
|
||||||
|
}
|
||||||
|
// actually toggle the mode
|
||||||
|
Global::ControlPicking = !Global::ControlPicking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( ( key == GLFW_KEY_LEFT_SHIFT )
|
if( ( key == GLFW_KEY_LEFT_SHIFT )
|
||||||
|| ( key == GLFW_KEY_LEFT_CONTROL )
|
|| ( key == GLFW_KEY_LEFT_CONTROL )
|
||||||
|| ( key == GLFW_KEY_LEFT_ALT )
|
|| ( key == GLFW_KEY_LEFT_ALT )
|
||||||
@@ -340,6 +373,7 @@ int main(int argc, char *argv[])
|
|||||||
glfwSetCursorPos(window, 0.0, 0.0);
|
glfwSetCursorPos(window, 0.0, 0.0);
|
||||||
glfwSetFramebufferSizeCallback(window, window_resize_callback);
|
glfwSetFramebufferSizeCallback(window, window_resize_callback);
|
||||||
glfwSetCursorPosCallback(window, cursor_pos_callback);
|
glfwSetCursorPosCallback(window, cursor_pos_callback);
|
||||||
|
glfwSetMouseButtonCallback( window, mouse_button_callback );
|
||||||
glfwSetKeyCallback(window, key_callback);
|
glfwSetKeyCallback(window, key_callback);
|
||||||
glfwSetScrollCallback( window, scroll_callback );
|
glfwSetScrollCallback( window, scroll_callback );
|
||||||
glfwSetWindowFocusCallback(window, focus_callback);
|
glfwSetWindowFocusCallback(window, focus_callback);
|
||||||
@@ -417,6 +451,7 @@ int main(int argc, char *argv[])
|
|||||||
&& ( true == World.Update() )
|
&& ( true == World.Update() )
|
||||||
&& ( true == GfxRenderer.Render() ) ) {
|
&& ( true == GfxRenderer.Render() ) ) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
input::Keyboard.poll();
|
||||||
if( true == Global::InputGamepad ) {
|
if( true == Global::InputGamepad ) {
|
||||||
input::Gamepad.poll();
|
input::Gamepad.poll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ double Global::ABuDebug = 0;
|
|||||||
std::string Global::asSky = "1";
|
std::string Global::asSky = "1";
|
||||||
double Global::fLuminance = 1.0; // jasność światła do automatycznego zapalania
|
double Global::fLuminance = 1.0; // jasność światła do automatycznego zapalania
|
||||||
float Global::SunAngle = 0.0f;
|
float Global::SunAngle = 0.0f;
|
||||||
int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki
|
|
||||||
int Global::ScreenWidth = 1;
|
int Global::ScreenWidth = 1;
|
||||||
int Global::ScreenHeight = 1;
|
int Global::ScreenHeight = 1;
|
||||||
float Global::ZoomFactor = 1.0f;
|
float Global::ZoomFactor = 1.0f;
|
||||||
@@ -48,6 +47,7 @@ bool Global::shiftState;
|
|||||||
bool Global::ctrlState;
|
bool Global::ctrlState;
|
||||||
int Global::iCameraLast = -1;
|
int Global::iCameraLast = -1;
|
||||||
std::string Global::asVersion = "couldn't retrieve version string";
|
std::string Global::asVersion = "couldn't retrieve version string";
|
||||||
|
bool Global::ControlPicking = false; // indicates controls pick mode is enabled
|
||||||
int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego
|
int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego
|
||||||
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
|
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
|
||||||
double Global::fSunDeclination = 0.0; // deklinacja Słońca
|
double Global::fSunDeclination = 0.0; // deklinacja Słońca
|
||||||
|
|||||||
@@ -238,7 +238,6 @@ class Global
|
|||||||
static int iBallastFiltering; // domyślne rozmywanie tekstury podsypki
|
static int iBallastFiltering; // domyślne rozmywanie tekstury podsypki
|
||||||
static int iRailProFiltering; // domyślne rozmywanie tekstury szyn
|
static int iRailProFiltering; // domyślne rozmywanie tekstury szyn
|
||||||
static int iDynamicFiltering; // domyślne rozmywanie tekstur pojazdów
|
static int iDynamicFiltering; // domyślne rozmywanie tekstur pojazdów
|
||||||
static int iReCompile; // zwiększany, gdy trzeba odświeżyć siatki
|
|
||||||
static bool bUseVBO; // czy jest VBO w karcie graficznej
|
static bool bUseVBO; // czy jest VBO w karcie graficznej
|
||||||
static std::string LastGLError;
|
static std::string LastGLError;
|
||||||
static int iFeedbackMode; // tryb pracy informacji zwrotnej
|
static int iFeedbackMode; // tryb pracy informacji zwrotnej
|
||||||
@@ -257,6 +256,7 @@ class Global
|
|||||||
static int iCameraLast;
|
static int iCameraLast;
|
||||||
static std::string asVersion; // z opisem
|
static std::string asVersion; // z opisem
|
||||||
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
|
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
|
||||||
|
static bool ControlPicking; // indicates controls pick mode is enabled
|
||||||
static int iTextMode; // tryb pracy wyświetlacza tekstowego
|
static int iTextMode; // tryb pracy wyświetlacza tekstowego
|
||||||
static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego
|
static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego
|
||||||
static bool bDoubleAmbient; // podwójna jasność ambient
|
static bool bDoubleAmbient; // podwójna jasność ambient
|
||||||
|
|||||||
283
Ground.cpp
283
Ground.cpp
@@ -49,8 +49,14 @@ extern "C"
|
|||||||
bool bCondition; // McZapkie: do testowania warunku na event multiple
|
bool bCondition; // McZapkie: do testowania warunku na event multiple
|
||||||
std::string LogComment;
|
std::string LogComment;
|
||||||
|
|
||||||
// TODO: switch to the new unified code after we have in place merging of individual triangle nodes into material-based soups
|
// tests whether provided points form a degenerate triangle
|
||||||
#define EU07_USE_OLD_RENDERCODE
|
bool
|
||||||
|
degenerate( glm::dvec3 const &Vertex1, glm::dvec3 const &Vertex2, glm::dvec3 const &Vertex3 ) {
|
||||||
|
|
||||||
|
return ( ( Vertex1 == Vertex2 )
|
||||||
|
|| ( Vertex2 == Vertex3 )
|
||||||
|
|| ( Vertex3 == Vertex1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Obiekt renderujący siatkę jest sztucznie tworzonym obiektem pomocniczym,
|
// Obiekt renderujący siatkę jest sztucznie tworzonym obiektem pomocniczym,
|
||||||
@@ -692,6 +698,21 @@ TGroundNode * TGround::FindGroundNode(std::string asNameToFind, TGroundNodeType
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TGroundRect *
|
||||||
|
TGround::GetRect( double x, double z ) {
|
||||||
|
|
||||||
|
auto const column = GetColFromX( x ) / iNumSubRects;
|
||||||
|
auto const row = GetRowFromZ( z ) / iNumSubRects;
|
||||||
|
|
||||||
|
if( ( column >= 0 ) && ( column < iNumRects )
|
||||||
|
&& ( row >= 0 ) && ( row < iNumRects ) ) {
|
||||||
|
return &Rects[ column ][ row ];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
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
|
||||||
@@ -934,25 +955,25 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
>> tmp->hvTraction->pPoint1.x
|
>> tmp->hvTraction->pPoint1.x
|
||||||
>> tmp->hvTraction->pPoint1.y
|
>> tmp->hvTraction->pPoint1.y
|
||||||
>> tmp->hvTraction->pPoint1.z;
|
>> tmp->hvTraction->pPoint1.z;
|
||||||
tmp->hvTraction->pPoint1 += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
tmp->hvTraction->pPoint1 += glm::dvec3{ pOrigin };
|
||||||
parser->getTokens(3);
|
parser->getTokens(3);
|
||||||
*parser
|
*parser
|
||||||
>> tmp->hvTraction->pPoint2.x
|
>> tmp->hvTraction->pPoint2.x
|
||||||
>> tmp->hvTraction->pPoint2.y
|
>> tmp->hvTraction->pPoint2.y
|
||||||
>> tmp->hvTraction->pPoint2.z;
|
>> tmp->hvTraction->pPoint2.z;
|
||||||
tmp->hvTraction->pPoint2 += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
tmp->hvTraction->pPoint2 += glm::dvec3{ pOrigin };
|
||||||
parser->getTokens(3);
|
parser->getTokens(3);
|
||||||
*parser
|
*parser
|
||||||
>> tmp->hvTraction->pPoint3.x
|
>> tmp->hvTraction->pPoint3.x
|
||||||
>> tmp->hvTraction->pPoint3.y
|
>> tmp->hvTraction->pPoint3.y
|
||||||
>> tmp->hvTraction->pPoint3.z;
|
>> tmp->hvTraction->pPoint3.z;
|
||||||
tmp->hvTraction->pPoint3 += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
tmp->hvTraction->pPoint3 += glm::dvec3{ pOrigin };
|
||||||
parser->getTokens(3);
|
parser->getTokens(3);
|
||||||
*parser
|
*parser
|
||||||
>> tmp->hvTraction->pPoint4.x
|
>> tmp->hvTraction->pPoint4.x
|
||||||
>> tmp->hvTraction->pPoint4.y
|
>> tmp->hvTraction->pPoint4.y
|
||||||
>> tmp->hvTraction->pPoint4.z;
|
>> tmp->hvTraction->pPoint4.z;
|
||||||
tmp->hvTraction->pPoint4 += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
tmp->hvTraction->pPoint4 += glm::dvec3{ pOrigin };
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> tf1;
|
*parser >> tf1;
|
||||||
tmp->hvTraction->fHeightDifference =
|
tmp->hvTraction->fHeightDifference =
|
||||||
@@ -1238,6 +1259,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
{ // 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->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)
|
||||||
@@ -1245,7 +1267,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
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;
|
||||||
@@ -1264,27 +1286,24 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
// case TP_GEOMETRY :
|
// case TP_GEOMETRY :
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
case GL_TRIANGLE_STRIP:
|
case GL_TRIANGLE_STRIP:
|
||||||
case GL_TRIANGLE_FAN:
|
case GL_TRIANGLE_FAN: {
|
||||||
|
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
// McZapkie-050702: opcjonalne wczytywanie parametrow materialu (ambient,diffuse,specular)
|
// McZapkie-050702: opcjonalne wczytywanie parametrow materialu (ambient,diffuse,specular)
|
||||||
if (token.compare("material") == 0)
|
if( token.compare( "material" ) == 0 ) {
|
||||||
{
|
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
while (token.compare("endmaterial") != 0)
|
while( token.compare( "endmaterial" ) != 0 ) {
|
||||||
{
|
if( token.compare( "ambient:" ) == 0 ) {
|
||||||
if (token.compare("ambient:") == 0)
|
parser->getTokens( 3 );
|
||||||
{
|
|
||||||
parser->getTokens(3);
|
|
||||||
*parser
|
*parser
|
||||||
>> tmp->Ambient.r
|
>> tmp->Ambient.r
|
||||||
>> tmp->Ambient.g
|
>> tmp->Ambient.g
|
||||||
>> tmp->Ambient.b;
|
>> tmp->Ambient.b;
|
||||||
tmp->Ambient /= 255.0f;
|
tmp->Ambient /= 255.0f;
|
||||||
}
|
}
|
||||||
else if (token.compare("diffuse:") == 0)
|
else if( token.compare( "diffuse:" ) == 0 ) { // Ra: coś jest nie tak, bo w jednej linijce nie działa
|
||||||
{ // Ra: coś jest nie tak, bo w jednej linijce nie działa
|
|
||||||
parser->getTokens( 3 );
|
parser->getTokens( 3 );
|
||||||
*parser
|
*parser
|
||||||
>> tmp->Diffuse.r
|
>> tmp->Diffuse.r
|
||||||
@@ -1292,8 +1311,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
>> tmp->Diffuse.b;
|
>> tmp->Diffuse.b;
|
||||||
tmp->Diffuse /= 255.0f;
|
tmp->Diffuse /= 255.0f;
|
||||||
}
|
}
|
||||||
else if (token.compare("specular:") == 0)
|
else if( token.compare( "specular:" ) == 0 ) {
|
||||||
{
|
|
||||||
parser->getTokens( 3 );
|
parser->getTokens( 3 );
|
||||||
*parser
|
*parser
|
||||||
>> tmp->Specular.r
|
>> tmp->Specular.r
|
||||||
@@ -1302,18 +1320,25 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
tmp->Specular /= 255.0f;
|
tmp->Specular /= 255.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Error("Scene material failure!");
|
Error( "Scene material failure!" );
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (token.compare("endmaterial") == 0)
|
if( token.compare( "endmaterial" ) == 0 ) {
|
||||||
{
|
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
}
|
}
|
||||||
str = token;
|
str = token;
|
||||||
tmp->TextureID = GfxRenderer.GetTextureId( str, szTexturePath );
|
tmp->TextureID = GfxRenderer.GetTextureId( str, szTexturePath );
|
||||||
|
bool const clamps = (
|
||||||
|
tmp->TextureID ?
|
||||||
|
GfxRenderer.Texture( tmp->TextureID ).traits.find( 's' ) != std::string::npos :
|
||||||
|
false );
|
||||||
|
bool const clampt = (
|
||||||
|
tmp->TextureID ?
|
||||||
|
GfxRenderer.Texture( tmp->TextureID ).traits.find( 't' ) != std::string::npos :
|
||||||
|
false );
|
||||||
|
|
||||||
tmp->iFlags |= 200; // z usuwaniem
|
tmp->iFlags |= 200; // z usuwaniem
|
||||||
// remainder of legacy 'problend' system -- geometry assigned a texture with '@' in its name is treated as translucent, opaque otherwise
|
// remainder of legacy 'problend' system -- geometry assigned a texture with '@' in its name is treated as translucent, opaque otherwise
|
||||||
@@ -1322,49 +1347,76 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
&& ( true == GfxRenderer.Texture( tmp->TextureID ).has_alpha ) ) ?
|
&& ( true == GfxRenderer.Texture( tmp->TextureID ).has_alpha ) ) ?
|
||||||
0x20 :
|
0x20 :
|
||||||
0x10 );
|
0x10 );
|
||||||
{
|
|
||||||
TGroundVertex vertex, vertex1, vertex2;
|
TGroundVertex vertex, vertex1, vertex2;
|
||||||
std::size_t vertexcount { 0 };
|
std::size_t vertexcount{ 0 };
|
||||||
do {
|
do {
|
||||||
parser->getTokens( 8, false );
|
parser->getTokens( 8, false );
|
||||||
*parser
|
*parser
|
||||||
>> vertex.position.x
|
>> vertex.position.x
|
||||||
>> vertex.position.y
|
>> vertex.position.y
|
||||||
>> vertex.position.z
|
>> vertex.position.z
|
||||||
>> vertex.normal.x
|
>> vertex.normal.x
|
||||||
>> vertex.normal.y
|
>> vertex.normal.y
|
||||||
>> 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, aRotate.z / 180 * M_PI );
|
||||||
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
||||||
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
||||||
vertex.normal = glm::rotateZ( vertex.normal, static_cast<float>( aRotate.z / 180 * M_PI ) );
|
vertex.normal = glm::rotateZ( vertex.normal, static_cast<float>( aRotate.z / 180 * M_PI ) );
|
||||||
vertex.normal = glm::rotateX( vertex.normal, static_cast<float>( aRotate.x / 180 * M_PI ) );
|
vertex.normal = glm::rotateX( vertex.normal, static_cast<float>( aRotate.x / 180 * M_PI ) );
|
||||||
vertex.normal = glm::rotateY( vertex.normal, static_cast<float>( aRotate.y / 180 * M_PI ) );
|
vertex.normal = glm::rotateY( vertex.normal, static_cast<float>( aRotate.y / 180 * M_PI ) );
|
||||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
vertex.position += glm::dvec3{ pOrigin };
|
||||||
// convert all data to gl_triangles to allow data merge for matching nodes
|
if( true == clamps ) { vertex.texture.s = clamp( vertex.texture.s, 0.001f, 0.999f ); }
|
||||||
switch( tmp->iType ) {
|
if( true == clampt ) { vertex.texture.t = clamp( vertex.texture.t, 0.001f, 0.999f ); }
|
||||||
case GL_TRIANGLES: {
|
// convert all data to gl_triangles to allow data merge for matching nodes
|
||||||
importedvertices.emplace_back( vertex );
|
switch( tmp->iType ) {
|
||||||
break;
|
case GL_TRIANGLES: {
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog(
|
||||||
|
"Bad geometry: degenerate triangle encountered"
|
||||||
|
+ ( tmp->asName != "" ? " in node \"" + tmp->asName + "\"" : "" )
|
||||||
|
+ " (vertices: " + to_string( vertex1.position ) + " + " + to_string( vertex2.position ) + " + " + to_string( vertex.position ) + ")" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case GL_TRIANGLE_FAN: {
|
++vertexcount;
|
||||||
if( vertexcount == 0 ) { vertex1 = vertex; }
|
if( vertexcount > 2 ) { vertexcount = 0; } // start new triangle if needed
|
||||||
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
break;
|
||||||
else if( vertexcount >= 2 ) {
|
}
|
||||||
|
case GL_TRIANGLE_FAN: {
|
||||||
|
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( vertex1 );
|
||||||
importedvertices.emplace_back( vertex2 );
|
importedvertices.emplace_back( vertex2 );
|
||||||
importedvertices.emplace_back( vertex );
|
importedvertices.emplace_back( vertex );
|
||||||
vertex2 = vertex;
|
vertex2 = vertex;
|
||||||
}
|
}
|
||||||
++vertexcount;
|
else {
|
||||||
break;
|
ErrorLog(
|
||||||
|
"Bad geometry: degenerate triangle encountered"
|
||||||
|
+ ( tmp->asName != "" ? " in node \"" + tmp->asName + "\"" : "" )
|
||||||
|
+ " (vertices: " + to_string( vertex1.position ) + " + " + to_string( vertex2.position ) + " + " + to_string( vertex.position ) + ")" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case GL_TRIANGLE_STRIP: {
|
++vertexcount;
|
||||||
if( vertexcount == 0 ) { vertex1 = vertex; }
|
break;
|
||||||
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
}
|
||||||
else if( vertexcount >= 2 ) {
|
case GL_TRIANGLE_STRIP: {
|
||||||
|
if( vertexcount == 0 ) { vertex1 = vertex; }
|
||||||
|
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
||||||
|
else if( vertexcount >= 2 ) {
|
||||||
|
if( false == degenerate( vertex1.position, vertex2.position, vertex.position ) ) {
|
||||||
// swap order every other triangle, to maintain consistent winding
|
// swap order every other triangle, to maintain consistent winding
|
||||||
if( vertexcount % 2 == 0 ) {
|
if( vertexcount % 2 == 0 ) {
|
||||||
importedvertices.emplace_back( vertex1 );
|
importedvertices.emplace_back( vertex1 );
|
||||||
@@ -1379,40 +1431,47 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
vertex1 = vertex2;
|
vertex1 = vertex2;
|
||||||
vertex2 = vertex;
|
vertex2 = vertex;
|
||||||
}
|
}
|
||||||
++vertexcount;
|
else {
|
||||||
break;
|
ErrorLog(
|
||||||
|
"Bad geometry: degenerate triangle encountered"
|
||||||
|
+ ( tmp->asName != "" ? " in node \"" + tmp->asName + "\"" : "" )
|
||||||
|
+ " (vertices: " + to_string( vertex1.position ) + " + " + to_string( vertex2.position ) + " + " + to_string( vertex.position ) + ")" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default: { break; }
|
++vertexcount;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parser->getTokens();
|
default: { break; }
|
||||||
*parser >> token;
|
|
||||||
|
|
||||||
} while (token.compare("endtri") != 0);
|
|
||||||
|
|
||||||
tmp->iType = GL_TRIANGLES;
|
|
||||||
tmp->Piece = new piece_node();
|
|
||||||
tmp->iNumVerts = importedvertices.size();
|
|
||||||
|
|
||||||
if( tmp->iNumVerts > 0 ) {
|
|
||||||
|
|
||||||
tmp->Piece->vertices.swap( importedvertices );
|
|
||||||
|
|
||||||
for( auto const &vertex : tmp->Piece->vertices ) {
|
|
||||||
tmp->pCenter += vertex.position;
|
|
||||||
}
|
|
||||||
tmp->pCenter /= tmp->iNumVerts;
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
for( auto const &vertex : tmp->Piece->vertices ) {
|
|
||||||
tf = SquareMagnitude( vertex.position - tmp->pCenter );
|
|
||||||
if( tf > r )
|
|
||||||
r = tf;
|
|
||||||
}
|
|
||||||
tmp->fSquareRadius += r;
|
|
||||||
RaTriangleDivider( tmp ); // Ra: dzielenie trójkątów jest teraz całkiem wydajne
|
|
||||||
}
|
}
|
||||||
|
parser->getTokens();
|
||||||
|
*parser >> token;
|
||||||
|
|
||||||
|
} while( token.compare( "endtri" ) != 0 );
|
||||||
|
|
||||||
|
tmp->iType = GL_TRIANGLES;
|
||||||
|
tmp->Piece = new piece_node();
|
||||||
|
tmp->iNumVerts = importedvertices.size();
|
||||||
|
|
||||||
|
if( tmp->iNumVerts > 0 ) {
|
||||||
|
|
||||||
|
tmp->Piece->vertices.swap( importedvertices );
|
||||||
|
|
||||||
|
for( auto const &vertex : tmp->Piece->vertices ) {
|
||||||
|
tmp->pCenter += vertex.position;
|
||||||
|
}
|
||||||
|
tmp->pCenter /= tmp->iNumVerts;
|
||||||
|
|
||||||
|
r = 0;
|
||||||
|
for( auto const &vertex : tmp->Piece->vertices ) {
|
||||||
|
tf = glm::length2( vertex.position - glm::dvec3{ tmp->pCenter } );
|
||||||
|
if( tf > r )
|
||||||
|
r = tf;
|
||||||
|
}
|
||||||
|
tmp->fSquareRadius += r;
|
||||||
|
RaTriangleDivider( tmp ); // Ra: dzielenie trójkątów jest teraz całkiem wydajne
|
||||||
} // koniec wczytywania trójkątów
|
} // koniec wczytywania trójkątów
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GL_LINES:
|
case GL_LINES:
|
||||||
case GL_LINE_STRIP:
|
case GL_LINE_STRIP:
|
||||||
case GL_LINE_LOOP: {
|
case GL_LINE_LOOP: {
|
||||||
@@ -1440,7 +1499,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
vertex.position = glm::rotateX( vertex.position, aRotate.x / 180 * M_PI );
|
||||||
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
vertex.position = glm::rotateY( vertex.position, aRotate.y / 180 * M_PI );
|
||||||
|
|
||||||
vertex.position += glm::dvec3( pOrigin.x, pOrigin.y, pOrigin.z );
|
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
|
||||||
switch( tmp->iType ) {
|
switch( tmp->iType ) {
|
||||||
case GL_LINES: {
|
case GL_LINES: {
|
||||||
@@ -1578,11 +1637,11 @@ void TGround::FirstInit()
|
|||||||
// dodanie do globalnego obiektu
|
// dodanie do globalnego obiektu
|
||||||
srGlobal.NodeAdd( Current );
|
srGlobal.NodeAdd( Current );
|
||||||
}
|
}
|
||||||
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;
|
||||||
for (int j = 1; j < Current->iCount; ++j)
|
for (int j = 1; j < Current->iCount; ++j) {
|
||||||
{ // od 1 do końca są zestawy trójkątów
|
// od 1 do końca są zestawy trójkątów
|
||||||
std::string xxxzzz = Current->nNode[j].smTerrain->pName; // pobranie nazwy
|
std::string xxxzzz = Current->nNode[j].smTerrain->pName; // pobranie nazwy
|
||||||
gr = GetRect(
|
gr = GetRect(
|
||||||
( std::stoi( xxxzzz.substr( 0, 3 )) - 500 ) * 1000,
|
( std::stoi( xxxzzz.substr( 0, 3 )) - 500 ) * 1000,
|
||||||
@@ -1590,16 +1649,30 @@ void TGround::FirstInit()
|
|||||||
gr->nTerrain = Current->nNode + j; // zapamiętanie
|
gr->nTerrain = Current->nNode + j; // zapamiętanie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( ( Current->iType != GL_TRIANGLES )
|
|
||||||
|| ( Current->iFlags & 0x20 )
|
|
||||||
|| ( Current->fSquareMinRadius != 0.0 )
|
|
||||||
|| ( Current->fSquareRadius <= 90000.0 ) ) {
|
|
||||||
// add to sub-rectangle
|
|
||||||
GetSubRect( Current->pCenter.x, Current->pCenter.z )->NodeAdd( Current );
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
// dodajemy do kwadratu kilometrowego
|
TSubRect *targetcell { nullptr };
|
||||||
GetRect( Current->pCenter.x, Current->pCenter.z )->NodeAdd( Current );
|
// test whether we can add the node to a ground cell, or a subcell
|
||||||
|
if( ( Current->iType != GL_TRIANGLES )
|
||||||
|
|| ( Current->iFlags & 0x20 )
|
||||||
|
|| ( Current->fSquareMinRadius != 0.0 )
|
||||||
|
|| ( Current->fSquareRadius <= 90000.0 ) ) {
|
||||||
|
// add to sub-rectangle
|
||||||
|
targetcell = GetSubRect( Current->pCenter.x, Current->pCenter.z );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// dodajemy do kwadratu kilometrowego
|
||||||
|
targetcell = GetRect( Current->pCenter.x, Current->pCenter.z );
|
||||||
|
}
|
||||||
|
if( targetcell != nullptr ) {
|
||||||
|
targetcell->NodeAdd( Current );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Scenery node" + (
|
||||||
|
Current->asName == "" ?
|
||||||
|
"" :
|
||||||
|
" \"" + Current->asName + "\"" )
|
||||||
|
+ " placed in location outside of map bounds (location: " + to_string( glm::dvec3{ Current->pCenter } ) + ")" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2900,7 +2973,7 @@ TTraction * TGround::TractionNearestFind(glm::dvec3 &p, int dir, TGroundNode *n)
|
|||||||
if (nCurrent->hvTraction->fResistance[k] >=
|
if (nCurrent->hvTraction->fResistance[k] >=
|
||||||
0.0) //żeby się nie propagowały jakieś ujemne
|
0.0) //żeby się nie propagowały jakieś ujemne
|
||||||
{ // znaleziony kandydat do połączenia
|
{ // znaleziony kandydat do połączenia
|
||||||
d = SquareMagnitude( p - nCurrent->pCenter ); // kwadrat odległości środków
|
d = glm::length2( p - glm::dvec3{ nCurrent->pCenter } ); // kwadrat odległości środków
|
||||||
if (dist > d)
|
if (dist > d)
|
||||||
{ // zapamiętanie nowego najbliższego
|
{ // zapamiętanie nowego najbliższego
|
||||||
dist = d; // nowy rekord odległości
|
dist = d; // nowy rekord odległości
|
||||||
@@ -3568,10 +3641,10 @@ bool TGround::GetTraction(TDynamicObject *model)
|
|||||||
vParam =
|
vParam =
|
||||||
node->hvTraction
|
node->hvTraction
|
||||||
->vParametric; // współczynniki równania parametrycznego
|
->vParametric; // współczynniki równania parametrycznego
|
||||||
fRaParam = -DotProduct(pant0, vFront);
|
fRaParam = -glm::dot(pant0, vFront);
|
||||||
auto const paramfrontdot = DotProduct( vParam, vFront );
|
auto const paramfrontdot = glm::dot( vParam, vFront );
|
||||||
fRaParam =
|
fRaParam =
|
||||||
-( DotProduct( node->hvTraction->pPoint1, vFront ) + fRaParam )
|
-( glm::dot( node->hvTraction->pPoint1, vFront ) + fRaParam )
|
||||||
/ ( paramfrontdot != 0.0 ? paramfrontdot : 0.001 ); // div0 trap
|
/ ( paramfrontdot != 0.0 ? paramfrontdot : 0.001 ); // div0 trap
|
||||||
if ((fRaParam >= -0.001) ? (fRaParam <= 1.001) : false)
|
if ((fRaParam >= -0.001) ? (fRaParam <= 1.001) : false)
|
||||||
{ // jeśli tylko jest w przedziale, wyznaczyć odległość wzdłuż
|
{ // jeśli tylko jest w przedziale, wyznaczyć odległość wzdłuż
|
||||||
|
|||||||
30
Ground.h
30
Ground.h
@@ -313,27 +313,21 @@ class TGround
|
|||||||
TGroundNode * DynamicFind(std::string const &Name);
|
TGroundNode * DynamicFind(std::string const &Name);
|
||||||
void DynamicList(bool all = false);
|
void DynamicList(bool all = false);
|
||||||
TGroundNode * FindGroundNode(std::string asNameToFind, TGroundNodeType iNodeType);
|
TGroundNode * FindGroundNode(std::string asNameToFind, TGroundNodeType iNodeType);
|
||||||
TGroundRect * GetRect(double x, double z)
|
TGroundRect * GetRect( double x, double z );
|
||||||
{
|
|
||||||
return &Rects[GetColFromX(x) / iNumSubRects][GetRowFromZ(z) / iNumSubRects];
|
|
||||||
};
|
|
||||||
TSubRect * GetSubRect( int iCol, int iRow );
|
TSubRect * GetSubRect( int iCol, int iRow );
|
||||||
TSubRect * GetSubRect(double x, double z)
|
inline
|
||||||
{
|
TSubRect * GetSubRect(double x, double z) {
|
||||||
return GetSubRect(GetColFromX(x), GetRowFromZ(z));
|
return GetSubRect(GetColFromX(x), GetRowFromZ(z)); };
|
||||||
};
|
|
||||||
TSubRect * FastGetSubRect( int iCol, int iRow );
|
TSubRect * FastGetSubRect( int iCol, int iRow );
|
||||||
|
inline
|
||||||
TSubRect * FastGetSubRect( double x, double z ) {
|
TSubRect * FastGetSubRect( double x, double z ) {
|
||||||
return FastGetSubRect( GetColFromX( x ), GetRowFromZ( z ) );
|
return FastGetSubRect( GetColFromX( x ), GetRowFromZ( z ) ); };
|
||||||
};
|
inline
|
||||||
int GetRowFromZ(double z)
|
int GetRowFromZ(double z) {
|
||||||
{
|
return (int)(z / fSubRectSize + fHalfTotalNumSubRects); };
|
||||||
return (int)(z / fSubRectSize + fHalfTotalNumSubRects);
|
inline
|
||||||
};
|
int GetColFromX(double x) {
|
||||||
int GetColFromX(double x)
|
return (int)(x / fSubRectSize + fHalfTotalNumSubRects); };
|
||||||
{
|
|
||||||
return (int)(x / fSubRectSize + fHalfTotalNumSubRects);
|
|
||||||
};
|
|
||||||
TEvent * FindEvent(const std::string &asEventName);
|
TEvent * FindEvent(const std::string &asEventName);
|
||||||
TEvent * FindEventScan(const std::string &asEventName);
|
TEvent * FindEventScan(const std::string &asEventName);
|
||||||
void TrackJoin(TGroundNode *Current);
|
void TrackJoin(TGroundNode *Current);
|
||||||
|
|||||||
@@ -814,9 +814,11 @@ void TMoverParameters::UpdateBatteryVoltage(double dt)
|
|||||||
sn3 = 0.0,
|
sn3 = 0.0,
|
||||||
sn4 = 0.0,
|
sn4 = 0.0,
|
||||||
sn5 = 0.0; // Ra: zrobić z tego amperomierz NN
|
sn5 = 0.0; // Ra: zrobić z tego amperomierz NN
|
||||||
if ((BatteryVoltage > 0) && (EngineType != DieselEngine) && (EngineType != WheelsDriven) &&
|
if( ( BatteryVoltage > 0 )
|
||||||
(NominalBatteryVoltage > 0))
|
&& ( EngineType != DieselEngine )
|
||||||
{
|
&& ( EngineType != WheelsDriven )
|
||||||
|
&& ( NominalBatteryVoltage > 0 ) ) {
|
||||||
|
|
||||||
if ((NominalBatteryVoltage / BatteryVoltage < 1.22) && Battery)
|
if ((NominalBatteryVoltage / BatteryVoltage < 1.22) && Battery)
|
||||||
{ // 110V
|
{ // 110V
|
||||||
if (!ConverterFlag)
|
if (!ConverterFlag)
|
||||||
@@ -884,10 +886,10 @@ void TMoverParameters::UpdateBatteryVoltage(double dt)
|
|||||||
if (BatteryVoltage < 0.01)
|
if (BatteryVoltage < 0.01)
|
||||||
BatteryVoltage = 0.01;
|
BatteryVoltage = 0.01;
|
||||||
}
|
}
|
||||||
else if (NominalBatteryVoltage == 0)
|
else {
|
||||||
BatteryVoltage = 0;
|
// TODO: check and implement proper way to handle this for diesel engines
|
||||||
else
|
BatteryVoltage = NominalBatteryVoltage;
|
||||||
BatteryVoltage = 90;
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Ukrotnienie EN57:
|
/* Ukrotnienie EN57:
|
||||||
|
|||||||
@@ -121,11 +121,16 @@ std::string to_string(double _Val, int precision);
|
|||||||
std::string to_string(double _Val, int precision, int width);
|
std::string to_string(double _Val, int precision, int width);
|
||||||
std::string to_hex_str( int const _Val, int const width = 4 );
|
std::string to_hex_str( int const _Val, int const width = 4 );
|
||||||
|
|
||||||
inline std::string to_string(bool _Val)
|
inline std::string to_string(bool _Val) {
|
||||||
{
|
|
||||||
return _Val == true ? "true" : "false";
|
return _Val == true ? "true" : "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Type_, glm::precision Precision_ = glm::defaultp>
|
||||||
|
std::string to_string( glm::tvec3<Type_, Precision_> const &Value ) {
|
||||||
|
return to_string( Value.x, 2 ) + ", " + to_string( Value.y, 2 ) + ", " + to_string( Value.z, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
int stol_def(const std::string & str, const int & DefaultValue);
|
int stol_def(const std::string & str, const int & DefaultValue);
|
||||||
|
|
||||||
std::string ToLower(std::string const &text);
|
std::string ToLower(std::string const &text);
|
||||||
|
|||||||
12
Model3d.cpp
12
Model3d.cpp
@@ -381,11 +381,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|
||||||
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|
||||||
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
|
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
|
||||||
ErrorLog(
|
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: " + to_string( scale ) + ")" );
|
||||||
"Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: "
|
|
||||||
+ to_string( scale.x, 2 ) + ", "
|
|
||||||
+ to_string( scale.y, 2 ) + ", "
|
|
||||||
+ to_string( scale.z, 2 ) + ")" );
|
|
||||||
m_normalizenormals = (
|
m_normalizenormals = (
|
||||||
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
|
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
|
||||||
rescale :
|
rescale :
|
||||||
@@ -1719,11 +1715,7 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|
||||||
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|
||||||
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
|
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
|
||||||
ErrorLog(
|
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: " + to_string( scale ) + ")" );
|
||||||
"Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: "
|
|
||||||
+ to_string( scale.x, 2 ) + ", "
|
|
||||||
+ to_string( scale.y, 2 ) + ", "
|
|
||||||
+ to_string( scale.z, 2 ) + ")" );
|
|
||||||
m_normalizenormals = (
|
m_normalizenormals = (
|
||||||
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
|
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
|
||||||
rescale :
|
rescale :
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
// 101206 Ra: trapezoidalne drogi
|
// 101206 Ra: trapezoidalne drogi
|
||||||
// 110806 Ra: odwrócone mapowanie wzdłuż - Point1 == 1.0
|
// 110806 Ra: odwrócone mapowanie wzdłuż - Point1 == 1.0
|
||||||
std::string Where(vector3 p)
|
|
||||||
{ // zamiana współrzędnych na tekst, używana w błędach
|
|
||||||
return std::to_string(p.x) + " " + std::to_string(p.y) + " " + std::to_string(p.z);
|
|
||||||
};
|
|
||||||
|
|
||||||
TSegment::TSegment(TTrack *owner) :
|
TSegment::TSegment(TTrack *owner) :
|
||||||
pOwner( owner )
|
pOwner( owner )
|
||||||
@@ -112,7 +108,7 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
|
|||||||
fStep = fNewStep;
|
fStep = fNewStep;
|
||||||
if (fLength <= 0)
|
if (fLength <= 0)
|
||||||
{
|
{
|
||||||
ErrorLog( "Bad geometry (zero length) for spline \"" + pOwner->NameGet() + "\" at " + Where( Point1 ) );
|
ErrorLog( "Bad geometry: zero length spline \"" + pOwner->NameGet() + "\" (location: " + to_string( glm::dvec3{ Point1 } ) + ")" );
|
||||||
// MessageBox(0,"Length<=0","TSegment::Init",MB_OK);
|
// MessageBox(0,"Length<=0","TSegment::Init",MB_OK);
|
||||||
fLength = 0.01; // crude workaround TODO: fix this properly
|
fLength = 0.01; // crude workaround TODO: fix this properly
|
||||||
/*
|
/*
|
||||||
@@ -215,7 +211,7 @@ double TSegment::GetTFromS(double s)
|
|||||||
// Newton's method failed. If this happens, increase iterations or
|
// Newton's method failed. If this happens, increase iterations or
|
||||||
// tolerance or integration accuracy.
|
// tolerance or integration accuracy.
|
||||||
// return -1; //Ra: tu nigdy nie dojdzie
|
// return -1; //Ra: tu nigdy nie dojdzie
|
||||||
ErrorLog( "Bad geometry (shape estimation failed) for spline \"" + pOwner->NameGet() + "\" at " + Where( Point1 ) );
|
ErrorLog( "Bad geometry: shape estimation failed for spline \"" + pOwner->NameGet() + "\" (location: " + to_string( glm::dvec3{ Point1 } ) + ")" );
|
||||||
// MessageBox(0,"Too many iterations","GetTFromS",MB_OK);
|
// MessageBox(0,"Too many iterations","GetTFromS",MB_OK);
|
||||||
return fTime;
|
return fTime;
|
||||||
};
|
};
|
||||||
|
|||||||
10
Track.cpp
10
Track.cpp
@@ -307,10 +307,12 @@ TTrack * TTrack::NullCreate(int dir)
|
|||||||
tmp2->pCenter = tmp->pCenter; // ten sam środek jest
|
tmp2->pCenter = tmp->pCenter; // ten sam środek jest
|
||||||
// Ra: to poniżej to porażka, ale na razie się nie da inaczej
|
// Ra: to poniżej to porażka, ale na razie się nie da inaczej
|
||||||
TSubRect *r = Global::pGround->GetSubRect(tmp->pCenter.x, tmp->pCenter.z);
|
TSubRect *r = Global::pGround->GetSubRect(tmp->pCenter.x, tmp->pCenter.z);
|
||||||
r->NodeAdd(tmp); // dodanie toru do segmentu
|
if( r != nullptr ) {
|
||||||
if (tmp2)
|
r->NodeAdd( tmp ); // dodanie toru do segmentu
|
||||||
r->NodeAdd(tmp2); // drugiego też
|
if( tmp2 )
|
||||||
r->Sort(); //żeby wyświetlał tabor z dodanego toru
|
r->NodeAdd( tmp2 ); // drugiego też
|
||||||
|
r->Sort(); //żeby wyświetlał tabor z dodanego toru
|
||||||
|
}
|
||||||
return trk;
|
return trk;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
408
Train.cpp
408
Train.cpp
@@ -22,6 +22,27 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
control_mapper::insert( TGauge const &Gauge, std::string const &Label ) {
|
||||||
|
|
||||||
|
auto const submodel = Gauge.SubModel;
|
||||||
|
if( submodel != nullptr ) {
|
||||||
|
m_controlnames.emplace( submodel, Label );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
control_mapper::find( TSubModel const *Control ) const {
|
||||||
|
|
||||||
|
auto const lookup = m_controlnames.find( Control );
|
||||||
|
if( lookup != m_controlnames.end() ) {
|
||||||
|
return lookup->second;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TCab::TCab()
|
TCab::TCab()
|
||||||
{
|
{
|
||||||
CabPos1.x = -1.0;
|
CabPos1.x = -1.0;
|
||||||
@@ -5943,13 +5964,16 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
// TODO: rework it into something more elegant, when redoing the whole consist/unit/cab etc arrangement
|
// TODO: rework it into something more elegant, when redoing the whole consist/unit/cab etc arrangement
|
||||||
if( ( mvControlled->Battery )
|
if( ( mvControlled->Battery )
|
||||||
|| ( mvControlled->ConverterFlag ) ) {
|
|| ( mvControlled->ConverterFlag ) ) {
|
||||||
if( ( false == mvControlled->PantFrontUp )
|
if( ggPantAllDownButton.GetValue() == 0.0 ) {
|
||||||
&& ( ggPantFrontButton.GetValue() >= 1.0 ) ) {
|
// the 'lower all' button overrides state of switches, while active itself
|
||||||
mvControlled->PantFront( true );
|
if( ( false == mvControlled->PantFrontUp )
|
||||||
}
|
&& ( ggPantFrontButton.GetValue() >= 1.0 ) ) {
|
||||||
if( ( false == mvControlled->PantRearUp )
|
mvControlled->PantFront( true );
|
||||||
&& ( ggPantRearButton.GetValue() >= 1.0 ) ) {
|
}
|
||||||
mvControlled->PantRear( true );
|
if( ( false == mvControlled->PantRearUp )
|
||||||
|
&& ( ggPantRearButton.GetValue() >= 1.0 ) ) {
|
||||||
|
mvControlled->PantRear( true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -6309,6 +6333,7 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
|||||||
|
|
||||||
bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
||||||
{
|
{
|
||||||
|
m_controlmapper.clear();
|
||||||
pyScreens.reset(this);
|
pyScreens.reset(this);
|
||||||
pyScreens.setLookupPath(DynamicObject->asBaseDir);
|
pyScreens.setLookupPath(DynamicObject->asBaseDir);
|
||||||
bool parse = false;
|
bool parse = false;
|
||||||
@@ -7195,309 +7220,78 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
|||||||
// otherwise
|
// otherwise
|
||||||
// NOTE: this is temporary work-around for compiler else-if limit
|
// NOTE: this is temporary work-around for compiler else-if limit
|
||||||
// TODO: refactor the cabin controls into some sensible structure
|
// TODO: refactor the cabin controls into some sensible structure
|
||||||
bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex)
|
bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex) {
|
||||||
{
|
|
||||||
|
|
||||||
TGauge *gg; // roboczy wskaźnik na obiekt animujący gałkę
|
TGauge *gg { nullptr }; // roboczy wskaźnik na obiekt animujący gałkę
|
||||||
|
std::unordered_map<std::string, TGauge &> gauges = {
|
||||||
/* sanity check
|
{ "mainctrl:", ggMainCtrl },
|
||||||
if( !DynamicObject->mdKabina ) {
|
{ "scndctrl:", ggScndCtrl },
|
||||||
WriteLog( "Cab not initialised!" );
|
{ "dirkey:" , ggDirKey },
|
||||||
return false;
|
{ "brakectrl:", ggBrakeCtrl },
|
||||||
}
|
{ "localbrake:", ggLocalBrake },
|
||||||
*/
|
{ "manualbrake:", ggManualBrake },
|
||||||
// SEKCJA REGULATOROW
|
{ "brakeprofile_sw:", ggBrakeProfileCtrl },
|
||||||
if (Label == "mainctrl:")
|
{ "brakeprofileg_sw:", ggBrakeProfileG },
|
||||||
{
|
{ "brakeprofiler_sw:", ggBrakeProfileR },
|
||||||
// nastawnik
|
{ "maxcurrent_sw:", ggMaxCurrentCtrl },
|
||||||
ggMainCtrl.Load(Parser, DynamicObject->mdKabina);
|
{ "main_off_bt:", ggMainOffButton },
|
||||||
}
|
{ "main_on_bt:", ggMainOnButton },
|
||||||
else if (Label == "mainctrlact:")
|
{ "security_reset_bt:", ggSecurityResetButton },
|
||||||
{
|
{ "releaser_bt:", ggReleaserButton },
|
||||||
// zabek pozycji aktualnej
|
{ "sand_bt:", ggSandButton },
|
||||||
ggMainCtrlAct.Load(Parser, DynamicObject->mdKabina);
|
{ "antislip_bt:", ggAntiSlipButton },
|
||||||
}
|
{ "horn_bt:", ggHornButton },
|
||||||
else if (Label == "scndctrl:")
|
{ "hornlow_bt:", ggHornLowButton },
|
||||||
{
|
{ "hornhigh_bt:", ggHornHighButton },
|
||||||
// bocznik
|
{ "fuse_bt:", ggFuseButton },
|
||||||
ggScndCtrl.Load(Parser, DynamicObject->mdKabina);
|
{ "converterfuse_bt:", ggConverterFuseButton },
|
||||||
}
|
{ "stlinoff_bt:", ggStLinOffButton },
|
||||||
else if (Label == "dirkey:")
|
{ "door_left_sw:", ggDoorLeftButton },
|
||||||
{
|
{ "door_right_sw:", ggDoorRightButton },
|
||||||
// klucz kierunku
|
{ "departure_signal_bt:", ggDepartureSignalButton },
|
||||||
ggDirKey.Load(Parser, DynamicObject->mdKabina);
|
{ "upperlight_sw:", ggUpperLightButton },
|
||||||
}
|
{ "leftlight_sw:", ggLeftLightButton },
|
||||||
else if (Label == "brakectrl:")
|
{ "rightlight_sw:", ggRightLightButton },
|
||||||
{
|
{ "dimheadlights_sw:", ggDimHeadlightsButton },
|
||||||
// hamulec zasadniczy
|
{ "leftend_sw:", ggLeftEndLightButton },
|
||||||
ggBrakeCtrl.Load(Parser, DynamicObject->mdKabina);
|
{ "rightend_sw:", ggRightEndLightButton },
|
||||||
}
|
{ "lights_sw:", ggLightsButton },
|
||||||
else if (Label == "localbrake:")
|
{ "rearupperlight_sw:", ggRearUpperLightButton },
|
||||||
{
|
{ "rearleftlight_sw:", ggRearLeftLightButton },
|
||||||
// hamulec pomocniczy
|
{ "rearrightlight_sw:", ggRearRightLightButton },
|
||||||
ggLocalBrake.Load(Parser, DynamicObject->mdKabina);
|
{ "rearleftend_sw:", ggRearLeftEndLightButton },
|
||||||
}
|
{ "rearrightend_sw:", ggRearRightEndLightButton },
|
||||||
else if (Label == "manualbrake:")
|
{ "compressor_sw:", ggCompressorButton },
|
||||||
{
|
{ "compressorlocal_sw:", ggCompressorLocalButton },
|
||||||
// hamulec reczny
|
{ "converter_sw:", ggConverterButton },
|
||||||
ggManualBrake.Load(Parser, DynamicObject->mdKabina);
|
{ "converterlocal_sw:", ggConverterLocalButton },
|
||||||
}
|
{ "converteroff_sw:", ggConverterOffButton },
|
||||||
// sekcja przelacznikow obrotowych
|
{ "main_sw:", ggMainButton },
|
||||||
else if (Label == "brakeprofile_sw:")
|
{ "radio_sw:", ggRadioButton },
|
||||||
{
|
{ "pantfront_sw:", ggPantFrontButton },
|
||||||
// przelacznik tow/osob/posp
|
{ "pantrear_sw:", ggPantRearButton },
|
||||||
ggBrakeProfileCtrl.Load(Parser, DynamicObject->mdKabina);
|
{ "pantfrontoff_sw:", ggPantFrontButtonOff },
|
||||||
}
|
{ "pantrearoff_sw:", ggPantRearButtonOff },
|
||||||
else if (Label == "brakeprofileg_sw:")
|
{ "pantalloff_sw:", ggPantAllDownButton },
|
||||||
{
|
{ "pantselected_sw:", ggPantSelectedButton },
|
||||||
// przelacznik tow/osob
|
{ "pantselectedoff_sw:", ggPantSelectedDownButton },
|
||||||
ggBrakeProfileG.Load(Parser, DynamicObject->mdKabina);
|
{ "trainheating_sw:", ggTrainHeatingButton },
|
||||||
}
|
{ "signalling_sw:", ggSignallingButton },
|
||||||
else if (Label == "brakeprofiler_sw:")
|
{ "door_signalling_sw:", ggDoorSignallingButton },
|
||||||
{
|
{ "nextcurrent_sw:", ggNextCurrentButton },
|
||||||
// przelacznik osob/posp
|
{ "cablight_sw:", ggCabLightButton },
|
||||||
ggBrakeProfileR.Load(Parser, DynamicObject->mdKabina);
|
{ "cablightdim_sw:", ggCabLightDimButton },
|
||||||
}
|
{ "battery_sw:", ggBatteryButton }
|
||||||
else if (Label == "maxcurrent_sw:")
|
};
|
||||||
{
|
auto lookup = gauges.find( Label );
|
||||||
// przelacznik rozruchu
|
if( lookup != gauges.end() ) {
|
||||||
ggMaxCurrentCtrl.Load(Parser, DynamicObject->mdKabina);
|
lookup->second.Load( Parser, DynamicObject->mdKabina );
|
||||||
}
|
m_controlmapper.insert( lookup->second, lookup->first );
|
||||||
// SEKCJA przyciskow sprezynujacych
|
|
||||||
else if (Label == "main_off_bt:")
|
|
||||||
{
|
|
||||||
// przycisk wylaczajacy (w EU07 wyl szybki czerwony)
|
|
||||||
ggMainOffButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "main_on_bt:")
|
|
||||||
{
|
|
||||||
// przycisk wlaczajacy (w EU07 wyl szybki zielony)
|
|
||||||
ggMainOnButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "security_reset_bt:")
|
|
||||||
{
|
|
||||||
// przycisk zbijajacy SHP/czuwak
|
|
||||||
ggSecurityResetButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "releaser_bt:")
|
|
||||||
{
|
|
||||||
// przycisk odluzniacza
|
|
||||||
ggReleaserButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "sand_bt:")
|
|
||||||
{
|
|
||||||
// przycisk piasecznicy
|
|
||||||
ggSandButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "antislip_bt:")
|
|
||||||
{
|
|
||||||
// przycisk antyposlizgowy
|
|
||||||
ggAntiSlipButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "horn_bt:")
|
|
||||||
{
|
|
||||||
// dzwignia syreny
|
|
||||||
ggHornButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "hornlow_bt:" ) {
|
|
||||||
// dzwignia syreny
|
|
||||||
ggHornLowButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if( Label == "hornhigh_bt:" ) {
|
|
||||||
// dzwignia syreny
|
|
||||||
ggHornHighButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if( Label == "fuse_bt:" )
|
|
||||||
{
|
|
||||||
// bezp. nadmiarowy
|
|
||||||
ggFuseButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "converterfuse_bt:")
|
|
||||||
{
|
|
||||||
// hunter-261211:
|
|
||||||
// odblokowanie przekaznika nadm. przetw. i ogrz.
|
|
||||||
ggConverterFuseButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "stlinoff_bt:")
|
|
||||||
{
|
|
||||||
// st. liniowe
|
|
||||||
ggStLinOffButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "door_left_sw:")
|
|
||||||
{
|
|
||||||
// drzwi lewe
|
|
||||||
ggDoorLeftButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "door_right_sw:")
|
|
||||||
{
|
|
||||||
// drzwi prawe
|
|
||||||
ggDoorRightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "departure_signal_bt:")
|
|
||||||
{
|
|
||||||
// sygnal odjazdu
|
|
||||||
ggDepartureSignalButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "upperlight_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggUpperLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "leftlight_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggLeftLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "rightlight_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggRightLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "dimheadlights_sw:" ) {
|
|
||||||
// swiatlo
|
|
||||||
ggDimHeadlightsButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if( Label == "leftend_sw:" )
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggLeftEndLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "rightend_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggRightEndLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "lights_sw:")
|
|
||||||
{
|
|
||||||
// swiatla wszystkie
|
|
||||||
ggLightsButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
//---------------------
|
|
||||||
// hunter-230112: przelaczniki swiatel tylnich
|
|
||||||
else if (Label == "rearupperlight_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggRearUpperLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "rearleftlight_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggRearLeftLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "rearrightlight_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggRearRightLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "rearleftend_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggRearLeftEndLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "rearrightend_sw:")
|
|
||||||
{
|
|
||||||
// swiatlo
|
|
||||||
ggRearRightEndLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
//------------------
|
|
||||||
else if (Label == "compressor_sw:")
|
|
||||||
{
|
|
||||||
// sprezarka
|
|
||||||
ggCompressorButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "compressorlocal_sw:" ) {
|
|
||||||
// sprezarka
|
|
||||||
ggCompressorLocalButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if (Label == "converter_sw:")
|
|
||||||
{
|
|
||||||
// przetwornica
|
|
||||||
ggConverterButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "converterlocal_sw:" ) {
|
|
||||||
// przetwornica
|
|
||||||
ggConverterLocalButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if (Label == "converteroff_sw:")
|
|
||||||
{
|
|
||||||
// przetwornica wyl
|
|
||||||
ggConverterOffButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "main_sw:")
|
|
||||||
{
|
|
||||||
// wyl szybki (ezt)
|
|
||||||
ggMainButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "radio_sw:")
|
|
||||||
{
|
|
||||||
// radio
|
|
||||||
ggRadioButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "pantfront_sw:")
|
|
||||||
{
|
|
||||||
// patyk przedni
|
|
||||||
ggPantFrontButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "pantrear_sw:")
|
|
||||||
{
|
|
||||||
// patyk tylny
|
|
||||||
ggPantRearButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "pantfrontoff_sw:" )
|
|
||||||
{
|
|
||||||
// patyk przedni w dol
|
|
||||||
ggPantFrontButtonOff.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "pantrearoff_sw:" ) {
|
|
||||||
// rear pant down
|
|
||||||
ggPantRearButtonOff.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if( Label == "pantalloff_sw:" ) {
|
|
||||||
// both pantographs down
|
|
||||||
ggPantAllDownButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "pantselected_sw:" ) {
|
|
||||||
// operate selected pantograph(s)
|
|
||||||
ggPantSelectedButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if( Label == "pantselectedoff_sw:" ) {
|
|
||||||
// operate selected pantograph(s)
|
|
||||||
ggPantSelectedDownButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
|
||||||
else if (Label == "trainheating_sw:") {
|
|
||||||
// grzanie skladu
|
|
||||||
ggTrainHeatingButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "signalling_sw:")
|
|
||||||
{
|
|
||||||
// Sygnalizacja hamowania
|
|
||||||
ggSignallingButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "door_signalling_sw:")
|
|
||||||
{
|
|
||||||
// Sygnalizacja blokady drzwi
|
|
||||||
ggDoorSignallingButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "nextcurrent_sw:")
|
|
||||||
{
|
|
||||||
// prąd drugiego członu
|
|
||||||
ggNextCurrentButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "cablight_sw:")
|
|
||||||
{
|
|
||||||
// hunter-091012: swiatlo w kabinie
|
|
||||||
ggCabLightButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if (Label == "cablightdim_sw:")
|
|
||||||
{
|
|
||||||
// hunter-091012: przyciemnienie swiatla w kabinie
|
|
||||||
ggCabLightDimButton.Load(Parser, DynamicObject->mdKabina);
|
|
||||||
}
|
|
||||||
else if( Label == "battery_sw:" ) {
|
|
||||||
|
|
||||||
ggBatteryButton.Load( Parser, DynamicObject->mdKabina );
|
|
||||||
}
|
}
|
||||||
// ABu 090305: uniwersalne przyciski lub inne rzeczy
|
// ABu 090305: uniwersalne przyciski lub inne rzeczy
|
||||||
|
else if( Label == "mainctrlact:" ) {
|
||||||
|
ggMainCtrlAct.Load( Parser, DynamicObject->mdKabina, DynamicObject->mdModel );
|
||||||
|
}
|
||||||
else if (Label == "universal1:")
|
else if (Label == "universal1:")
|
||||||
{
|
{
|
||||||
ggUniversal1Button.Load(Parser, DynamicObject->mdKabina, DynamicObject->mdModel);
|
ggUniversal1Button.Load(Parser, DynamicObject->mdKabina, DynamicObject->mdModel);
|
||||||
|
|||||||
18
Train.h
18
Train.h
@@ -57,6 +57,18 @@ class TCab
|
|||||||
void Update();
|
void Update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class control_mapper {
|
||||||
|
typedef std::unordered_map< TSubModel const *, std::string> submodelstring_map;
|
||||||
|
submodelstring_map m_controlnames;
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
clear() { m_controlnames.clear(); }
|
||||||
|
void
|
||||||
|
insert( TGauge const &Gauge, std::string const &Label );
|
||||||
|
std::string
|
||||||
|
find( TSubModel const *Control ) const;
|
||||||
|
};
|
||||||
|
|
||||||
class TTrain
|
class TTrain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -72,6 +84,7 @@ class TTrain
|
|||||||
|
|
||||||
inline vector3 GetDirection() { return DynamicObject->VectorFront(); };
|
inline vector3 GetDirection() { return DynamicObject->VectorFront(); };
|
||||||
inline vector3 GetUp() { return DynamicObject->VectorUp(); };
|
inline vector3 GetUp() { return DynamicObject->VectorUp(); };
|
||||||
|
inline std::string GetLabel( TSubModel const *Control ) const { return m_controlmapper.find( Control ); }
|
||||||
void UpdateMechPosition(double dt);
|
void UpdateMechPosition(double dt);
|
||||||
vector3 GetWorldMechPosition();
|
vector3 GetWorldMechPosition();
|
||||||
bool Update( double const Deltatime );
|
bool Update( double const Deltatime );
|
||||||
@@ -84,7 +97,7 @@ class TTrain
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
typedef void( *command_handler )( TTrain *Train, command_data const &Command );
|
typedef void( *command_handler )( TTrain *Train, command_data const &Command );
|
||||||
typedef std::unordered_map<user_command, command_handler> commandhandler_map;
|
typedef std::unordered_map<user_command, command_handler> commandhandler_map;
|
||||||
// clears state of all cabin controls
|
// clears state of all cabin controls
|
||||||
void clear_cab_controls();
|
void clear_cab_controls();
|
||||||
@@ -184,8 +197,9 @@ class TTrain
|
|||||||
TMoverParameters *mvSecond; // drugi człon (ET40, ET41, ET42, ukrotnienia)
|
TMoverParameters *mvSecond; // drugi człon (ET40, ET41, ET42, ukrotnienia)
|
||||||
TMoverParameters *mvThird; // trzeci człon (SN61)
|
TMoverParameters *mvThird; // trzeci człon (SN61)
|
||||||
// helper variable, to prevent immediate switch between closing and opening line breaker circuit
|
// helper variable, to prevent immediate switch between closing and opening line breaker circuit
|
||||||
int m_linebreakerstate{ 0 }; // -1: freshly open, 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it)
|
int m_linebreakerstate { 0 }; // -1: freshly open, 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it)
|
||||||
static const commandhandler_map m_commandhandlers;
|
static const commandhandler_map m_commandhandlers;
|
||||||
|
control_mapper m_controlmapper;
|
||||||
|
|
||||||
public: // reszta może by?publiczna
|
public: // reszta może by?publiczna
|
||||||
|
|
||||||
|
|||||||
170
World.cpp
170
World.cpp
@@ -180,6 +180,20 @@ simulation_time::julian_day() const {
|
|||||||
return JD;
|
return JD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace locale {
|
||||||
|
|
||||||
|
std::string
|
||||||
|
control( std::string const &Label ) {
|
||||||
|
|
||||||
|
auto const lookup = m_controls.find( Label );
|
||||||
|
return (
|
||||||
|
lookup != m_controls.end() ?
|
||||||
|
lookup->second :
|
||||||
|
"" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TWorld::TWorld()
|
TWorld::TWorld()
|
||||||
{
|
{
|
||||||
// randomize();
|
// randomize();
|
||||||
@@ -1135,43 +1149,44 @@ 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
|
// Console::Update(); //tu jest zależne od FPS, co nie jest korzystne
|
||||||
|
|
||||||
if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) {
|
if( false == Global::ControlPicking ) {
|
||||||
Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe
|
if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT ) == GLFW_PRESS ) {
|
||||||
// if (!FreeFlyModeFlag) //jeśli wewnątrz - patrzymy do tyłu
|
Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe
|
||||||
// Camera.LookAt=Train->pMechPosition-Normalize(Train->GetDirection())*10;
|
// if (!FreeFlyModeFlag) //jeśli wewnątrz - patrzymy do tyłu
|
||||||
if( Controlled ? LengthSquared3( Controlled->GetPosition() - Camera.Pos ) < 2250000 :
|
// Camera.LookAt=Train->pMechPosition-Normalize(Train->GetDirection())*10;
|
||||||
false ) // 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 ) // jeśli jakiś jest znaleziony wcześniej
|
if( d && pDynamicNearest ) // 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
|
||||||
if( pDynamicNearest )
|
if( pDynamicNearest )
|
||||||
Camera.LookAt = pDynamicNearest->GetPosition();
|
Camera.LookAt = pDynamicNearest->GetPosition();
|
||||||
|
}
|
||||||
|
if( FreeFlyModeFlag )
|
||||||
|
Camera.RaLook(); // jednorazowe przestawienie kamery
|
||||||
|
}
|
||||||
|
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) { //||Console::Pressed(VK_F4))
|
||||||
|
FollowView( false ); // bez wyciszania dźwięków
|
||||||
|
}
|
||||||
|
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) == GLFW_PRESS ) {
|
||||||
|
// middle mouse button controls zoom.
|
||||||
|
Global::ZoomFactor = std::min( 4.5f, Global::ZoomFactor + 15.0f * static_cast<float>( Deltatime ) );
|
||||||
|
}
|
||||||
|
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) != GLFW_PRESS ) {
|
||||||
|
// reset zoom level if the button is no longer held down.
|
||||||
|
// NOTE: yes, this is terrible way to go about it. it'll do for now.
|
||||||
|
Global::ZoomFactor = std::max( 1.0f, Global::ZoomFactor - 15.0f * static_cast<float>( Deltatime ) );
|
||||||
}
|
}
|
||||||
if( FreeFlyModeFlag )
|
|
||||||
Camera.RaLook(); // jednorazowe przestawienie kamery
|
|
||||||
}
|
|
||||||
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_RIGHT ) == GLFW_PRESS ) { //||Console::Pressed(VK_F4))
|
|
||||||
FollowView( false ); // bez wyciszania dźwięków
|
|
||||||
}
|
|
||||||
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) == GLFW_PRESS ) {
|
|
||||||
// middle mouse button controls zoom.
|
|
||||||
Global::ZoomFactor = std::min( 4.5f, Global::ZoomFactor + 15.0f * static_cast<float>( Deltatime ) );
|
|
||||||
}
|
|
||||||
else if( glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_MIDDLE ) != GLFW_PRESS ) {
|
|
||||||
// reset zoom level if the button is no longer held down.
|
|
||||||
// NOTE: yes, this is terrible way to go about it. it'll do for now.
|
|
||||||
Global::ZoomFactor = std::max( 1.0f, Global::ZoomFactor - 15.0f * static_cast<float>( Deltatime ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera.Update(); // uwzględnienie ruchu wywołanego klawiszami
|
Camera.Update(); // uwzględnienie ruchu wywołanego klawiszami
|
||||||
@@ -1258,74 +1273,28 @@ void TWorld::ResourceSweep()
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
|
|
||||||
void
|
|
||||||
TWorld::Render_Cab() {
|
|
||||||
|
|
||||||
if( Train == nullptr ) {
|
|
||||||
|
|
||||||
TSubModel::iInstance = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TDynamicObject *dynamic = Train->Dynamic();
|
|
||||||
TSubModel::iInstance = reinterpret_cast<std::size_t>( dynamic );
|
|
||||||
|
|
||||||
if( ( true == FreeFlyModeFlag )
|
|
||||||
|| ( false == dynamic->bDisplayCab )
|
|
||||||
|| ( dynamic->mdKabina == dynamic->mdModel ) ) {
|
|
||||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
glPushMatrix();
|
|
||||||
vector3 pos = dynamic->GetPosition(); // wszpółrzędne pojazdu z kabiną
|
|
||||||
// glTranslatef(pos.x,pos.y,pos.z); //przesunięcie o wektor (tak było i trzęsło)
|
|
||||||
// aby pozbyć się choć trochę trzęsienia, trzeba by nie przeliczać kabiny do punktu
|
|
||||||
// zerowego scenerii
|
|
||||||
glLoadIdentity(); // zacząć od macierzy jedynkowej
|
|
||||||
Camera.SetCabMatrix( pos ); // widok z kamery po przesunięciu
|
|
||||||
glMultMatrixd( dynamic->mMatrix.getArray() ); // ta macierz nie ma przesunięcia
|
|
||||||
*/
|
|
||||||
::glPushMatrix();
|
|
||||||
auto const originoffset = dynamic->GetPosition() - Global::pCameraPosition;
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
|
||||||
::glMultMatrixd( dynamic->mMatrix.getArray() );
|
|
||||||
|
|
||||||
if( dynamic->mdKabina ) // bo mogła zniknąć przy przechodzeniu do innego pojazdu
|
|
||||||
{
|
|
||||||
// setup
|
|
||||||
if( dynamic->fShade > 0.0f ) {
|
|
||||||
// change light level based on light level of the occupied track
|
|
||||||
Global::DayLight.apply_intensity( dynamic->fShade );
|
|
||||||
}
|
|
||||||
if( dynamic->InteriorLightLevel > 0.0f ) {
|
|
||||||
// crude way to light the cabin, until we have something more complete in place
|
|
||||||
auto const cablight = dynamic->InteriorLight * dynamic->InteriorLightLevel;
|
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
|
|
||||||
}
|
|
||||||
// render
|
|
||||||
GfxRenderer.Render( dynamic->mdKabina, dynamic->Material(), 0.0 );
|
|
||||||
GfxRenderer.Render_Alpha( dynamic->mdKabina, dynamic->Material(), 0.0 );
|
|
||||||
// post-render restore
|
|
||||||
if( dynamic->fShade > 0.0f ) {
|
|
||||||
// change light level based on light level of the occupied track
|
|
||||||
Global::DayLight.apply_intensity();
|
|
||||||
}
|
|
||||||
if( dynamic->InteriorLightLevel > 0.0f ) {
|
|
||||||
// reset the overall ambient
|
|
||||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TWorld::Update_UI() {
|
TWorld::Update_UI() {
|
||||||
|
|
||||||
UITable->text_lines.clear();
|
UITable->text_lines.clear();
|
||||||
std::string uitextline1, uitextline2, uitextline3, uitextline4;
|
std::string uitextline1, uitextline2, uitextline3, uitextline4;
|
||||||
|
UILayer.set_tooltip( "" );
|
||||||
|
|
||||||
|
if( ( Train != nullptr ) && ( false == FreeFlyModeFlag ) ) {
|
||||||
|
if( false == DebugModeFlag ) {
|
||||||
|
// in regular mode show control functions, for defined controls
|
||||||
|
UILayer.set_tooltip( locale::control( Train->GetLabel( GfxRenderer.Pick_Control() ) ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// in debug mode show names of submodels, to help with cab setup and/or debugging
|
||||||
|
auto const cabcontrol = GfxRenderer.Pick_Control();
|
||||||
|
UILayer.set_tooltip( ( cabcontrol ? cabcontrol->pName : "" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( ( true == Global::ControlPicking ) && ( true == FreeFlyModeFlag ) && ( true == DebugModeFlag ) ) {
|
||||||
|
auto const scenerynode = GfxRenderer.Pick_Node();
|
||||||
|
UILayer.set_tooltip( ( scenerynode ? scenerynode->asName : "" ) );
|
||||||
|
}
|
||||||
|
|
||||||
switch( Global::iTextMode ) {
|
switch( Global::iTextMode ) {
|
||||||
|
|
||||||
@@ -2338,9 +2307,6 @@ world_environment::update() {
|
|||||||
Global::FogColor[ 0 ] = skydomecolour.x;
|
Global::FogColor[ 0 ] = skydomecolour.x;
|
||||||
Global::FogColor[ 1 ] = skydomecolour.y;
|
Global::FogColor[ 1 ] = skydomecolour.y;
|
||||||
Global::FogColor[ 2 ] = skydomecolour.z;
|
Global::FogColor[ 2 ] = skydomecolour.z;
|
||||||
::glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły
|
|
||||||
|
|
||||||
::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 1.0f ); // kolor nieba
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
71
World.h
71
World.h
@@ -60,6 +60,74 @@ extern simulation_time Time;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace locale {
|
||||||
|
|
||||||
|
std::string
|
||||||
|
control( std::string const &Label );
|
||||||
|
|
||||||
|
static std::unordered_map<std::string, std::string> m_controls = {
|
||||||
|
{ "mainctrl:", "master controller" },
|
||||||
|
{ "scndctrl:", "second controller" },
|
||||||
|
{ "dirkey:" , "reverser" },
|
||||||
|
{ "brakectrl:", "train brake" },
|
||||||
|
{ "localbrake:", "independent brake" },
|
||||||
|
{ "manualbrake:", "manual brake" },
|
||||||
|
{ "brakeprofile_sw:", "brake acting speed" },
|
||||||
|
{ "brakeprofileg_sw:", "brake acting speed: cargo" },
|
||||||
|
{ "brakeprofiler_sw:", "brake acting speed: rapid" },
|
||||||
|
{ "maxcurrent_sw:", "motor overload relay threshold" },
|
||||||
|
{ "main_off_bt:", "line breaker" },
|
||||||
|
{ "main_on_bt:", "line breaker" },
|
||||||
|
{ "security_reset_bt:", "alerter" },
|
||||||
|
{ "releaser_bt:", "independent brake releaser" },
|
||||||
|
{ "sand_bt:", "sandbox" },
|
||||||
|
{ "antislip_bt:", "wheelspin brake" },
|
||||||
|
{ "horn_bt:", "horn" },
|
||||||
|
{ "hornlow_bt:", "low tone horn" },
|
||||||
|
{ "hornhigh_bt:", "high tone horn" },
|
||||||
|
{ "fuse_bt:", "motor overload relay reset" },
|
||||||
|
{ "converterfuse_bt:", "converter overload relay reset" },
|
||||||
|
{ "stlinoff_bt:", "motor connectors" },
|
||||||
|
{ "door_left_sw:", "left door" },
|
||||||
|
{ "door_right_sw:", "right door" },
|
||||||
|
{ "departure_signal_bt:", "departure signal" },
|
||||||
|
{ "upperlight_sw:", "upper headlight" },
|
||||||
|
{ "leftlight_sw:", "left headlight" },
|
||||||
|
{ "rightlight_sw:", "right headlight" },
|
||||||
|
{ "dimheadlights_sw:", "headlights dimmer" },
|
||||||
|
{ "leftend_sw:", "left marker light" },
|
||||||
|
{ "rightend_sw:", "right marker light" },
|
||||||
|
{ "lights_sw:", "light pattern" },
|
||||||
|
{ "rearupperlight_sw:", "rear upper headlight" },
|
||||||
|
{ "rearleftlight_sw:", "rear left headlight" },
|
||||||
|
{ "rearrightlight_sw:", "rear right headlight" },
|
||||||
|
{ "rearleftend_sw:", "rear left marker light" },
|
||||||
|
{ "rearrightend_sw:", "rear right marker light" },
|
||||||
|
{ "compressor_sw:", "compressor" },
|
||||||
|
{ "compressorlocal_sw:", "local compressor" },
|
||||||
|
{ "converter_sw:", "converter" },
|
||||||
|
{ "converterlocal_sw:", "local converter" },
|
||||||
|
{ "converteroff_sw:", "converter" },
|
||||||
|
{ "main_sw:", "line breaker" },
|
||||||
|
{ "radio_sw:", "radio" },
|
||||||
|
{ "pantfront_sw:", "front pantograph" },
|
||||||
|
{ "pantrear_sw:", "rear pantograph" },
|
||||||
|
{ "pantfrontoff_sw:", "front pantograph" },
|
||||||
|
{ "pantrearoff_sw:", "rear pantograph" },
|
||||||
|
{ "pantalloff_sw:", "all pantographs" },
|
||||||
|
{ "pantselected_sw:", "selected pantograph" },
|
||||||
|
{ "pantselectedoff_sw:", "selected pantograph" },
|
||||||
|
{ "trainheating_sw:", "heating" },
|
||||||
|
{ "signalling_sw:", "braking indicator" },
|
||||||
|
{ "door_signalling_sw:", "door locking" },
|
||||||
|
{ "nextcurrent_sw:", "current indicator source" },
|
||||||
|
{ "cablight_sw:", "interior light" },
|
||||||
|
{ "cablightdim_sw:", "interior light dimmer" },
|
||||||
|
{ "battery_sw:", "battery" }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// wrapper for environment elements -- sky, sun, stars, clouds etc
|
// wrapper for environment elements -- sky, sun, stars, clouds etc
|
||||||
class world_environment {
|
class world_environment {
|
||||||
|
|
||||||
@@ -106,6 +174,8 @@ TWorld();
|
|||||||
void OnCommandGet(DaneRozkaz *pRozkaz);
|
void OnCommandGet(DaneRozkaz *pRozkaz);
|
||||||
bool Update();
|
bool Update();
|
||||||
void TrainDelete(TDynamicObject *d = NULL);
|
void TrainDelete(TDynamicObject *d = NULL);
|
||||||
|
TTrain const *
|
||||||
|
train() const { return Train; }
|
||||||
// switches between static and dynamic daylight calculation
|
// switches between static and dynamic daylight calculation
|
||||||
void ToggleDaylight();
|
void ToggleDaylight();
|
||||||
|
|
||||||
@@ -114,7 +184,6 @@ private:
|
|||||||
void Update_Camera( const double Deltatime );
|
void Update_Camera( const double Deltatime );
|
||||||
void Update_UI();
|
void Update_UI();
|
||||||
void ResourceSweep();
|
void ResourceSweep();
|
||||||
void Render_Cab();
|
|
||||||
|
|
||||||
TCamera Camera;
|
TCamera Camera;
|
||||||
TGround Ground;
|
TGround Ground;
|
||||||
|
|||||||
@@ -120,10 +120,11 @@ const int k_Univ4 = 69;
|
|||||||
const int k_EndSign = 70;
|
const int k_EndSign = 70;
|
||||||
const int k_Active = 71;
|
const int k_Active = 71;
|
||||||
*/
|
*/
|
||||||
batterytoggle
|
batterytoggle,
|
||||||
/*
|
/*
|
||||||
const int k_WalkMode = 73;
|
const int k_WalkMode = 73;
|
||||||
*/
|
*/
|
||||||
|
none = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class command_target {
|
enum class command_target {
|
||||||
|
|||||||
16
dumb3d.h
16
dumb3d.h
@@ -64,18 +64,16 @@ class vector3
|
|||||||
public:
|
public:
|
||||||
vector3(void) :
|
vector3(void) :
|
||||||
x(0.0), y(0.0), z(0.0)
|
x(0.0), y(0.0), z(0.0)
|
||||||
{
|
{}
|
||||||
}
|
vector3( scalar_t X, scalar_t Y, scalar_t Z ) :
|
||||||
vector3(scalar_t a, scalar_t b, scalar_t c)
|
x( X ), y( Y ), z( Z )
|
||||||
{
|
{}
|
||||||
x = a;
|
|
||||||
y = b;
|
|
||||||
z = c;
|
|
||||||
}
|
|
||||||
vector3( glm::dvec3 const &Vector ) :
|
vector3( glm::dvec3 const &Vector ) :
|
||||||
x( Vector.x ), y( Vector.y ), z( Vector.z )
|
x( Vector.x ), y( Vector.y ), z( Vector.z )
|
||||||
{}
|
{}
|
||||||
|
template <glm::precision Precision_>
|
||||||
|
operator glm::tvec3<double, Precision_>() const {
|
||||||
|
return glm::tvec3<double, Precision_>{ x, y, z }; }
|
||||||
// The int parameter is the number of elements to copy from initArray (3 or 4)
|
// The int parameter is the number of elements to copy from initArray (3 or 4)
|
||||||
// explicit vector3(scalar_t* initArray, int arraySize = 3)
|
// explicit vector3(scalar_t* initArray, int arraySize = 3)
|
||||||
// { for (int i = 0;i<arraySize;++i) e[i] = initArray[i]; }
|
// { for (int i = 0;i<arraySize;++i) e[i] = initArray[i]; }
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "keyboardinput.h"
|
#include "keyboardinput.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
#include "globals.h"
|
||||||
|
#include "timer.h"
|
||||||
|
//#include "world.h"
|
||||||
|
#include "train.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
|
extern TWorld World;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
keyboard_input::recall_bindings() {
|
keyboard_input::recall_bindings() {
|
||||||
@@ -168,6 +175,78 @@ keyboard_input::mouse( double Mousex, double Mousey ) {
|
|||||||
0 );
|
0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
keyboard_input::mouse( int const Button, int const Action ) {
|
||||||
|
|
||||||
|
if( false == Global::ControlPicking ) { return; }
|
||||||
|
if( true == FreeFlyModeFlag ) {
|
||||||
|
// for now we're only interested in cab controls
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user_command &mousecommand = (
|
||||||
|
Button == GLFW_MOUSE_BUTTON_LEFT ?
|
||||||
|
m_mousecommandleft :
|
||||||
|
m_mousecommandright
|
||||||
|
);
|
||||||
|
|
||||||
|
if( Action == GLFW_RELEASE ) {
|
||||||
|
if( mousecommand != user_command::none ) {
|
||||||
|
// NOTE: basic keyboard controls don't have any parameters
|
||||||
|
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||||
|
// TODO: pass correct entity id once the missing systems are in place
|
||||||
|
m_relay.post( mousecommand, 0, 0, Action, 0 );
|
||||||
|
mousecommand = user_command::none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// if not release then it's press
|
||||||
|
auto train = World.train();
|
||||||
|
if( train != nullptr ) {
|
||||||
|
auto lookup = m_mousecommands.find( train->GetLabel( GfxRenderer.Update_Pick_Control() ) );
|
||||||
|
if( lookup != m_mousecommands.end() ) {
|
||||||
|
mousecommand = (
|
||||||
|
Button == GLFW_MOUSE_BUTTON_LEFT ?
|
||||||
|
lookup->second.left :
|
||||||
|
lookup->second.right
|
||||||
|
);
|
||||||
|
if( mousecommand != user_command::none ) {
|
||||||
|
// NOTE: basic keyboard controls don't have any parameters
|
||||||
|
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||||
|
// TODO: pass correct entity id once the missing systems are in place
|
||||||
|
m_relay.post( mousecommand, 0, 0, Action, 0 );
|
||||||
|
m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
keyboard_input::poll() {
|
||||||
|
|
||||||
|
m_updateaccumulator += Timer::GetDeltaRenderTime();
|
||||||
|
|
||||||
|
if( m_updateaccumulator < 0.2 ) {
|
||||||
|
// too early for any work
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_updateaccumulator -= 0.2;
|
||||||
|
|
||||||
|
if( m_mousecommandleft != user_command::none ) {
|
||||||
|
// NOTE: basic keyboard controls don't have any parameters
|
||||||
|
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||||
|
// TODO: pass correct entity id once the missing systems are in place
|
||||||
|
m_relay.post( m_mousecommandleft, 0, 0, GLFW_REPEAT, 0 );
|
||||||
|
}
|
||||||
|
if( m_mousecommandright != user_command::none ) {
|
||||||
|
// NOTE: basic keyboard controls don't have any parameters
|
||||||
|
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||||
|
// TODO: pass correct entity id once the missing systems are in place
|
||||||
|
m_relay.post( m_mousecommandright, 0, 0, GLFW_REPEAT, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
keyboard_input::default_bindings() {
|
keyboard_input::default_bindings() {
|
||||||
|
|
||||||
@@ -366,6 +445,183 @@ const int k_WalkMode = 73;
|
|||||||
};
|
};
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
|
m_mousecommands = {
|
||||||
|
{ "mainctrl:", {
|
||||||
|
user_command::mastercontrollerincrease,
|
||||||
|
user_command::mastercontrollerdecrease } },
|
||||||
|
{ "scndctrl:", {
|
||||||
|
user_command::secondcontrollerincrease,
|
||||||
|
user_command::secondcontrollerdecrease } },
|
||||||
|
{ "dirkey:", {
|
||||||
|
user_command::reverserincrease,
|
||||||
|
user_command::reverserdecrease } },
|
||||||
|
{ "brakectrl:", {
|
||||||
|
user_command::trainbrakedecrease,
|
||||||
|
user_command::trainbrakeincrease } },
|
||||||
|
{ "localbrake:", {
|
||||||
|
user_command::independentbrakedecrease,
|
||||||
|
user_command::independentbrakeincrease } },
|
||||||
|
{ "manualbrake:", {
|
||||||
|
user_command::none,
|
||||||
|
user_command::none } },
|
||||||
|
{ "brakeprofile_sw:", {
|
||||||
|
user_command::brakeactingspeedincrease,
|
||||||
|
user_command::brakeactingspeeddecrease } },
|
||||||
|
{ "brakeprofileg_sw:", {
|
||||||
|
user_command::brakeactingspeeddecrease,
|
||||||
|
user_command::none } },
|
||||||
|
{ "brakeprofiler_sw:", {
|
||||||
|
user_command::brakeactingspeedincrease,
|
||||||
|
user_command::none } },
|
||||||
|
{ "maxcurrent_sw:", {
|
||||||
|
user_command::motoroverloadrelaythresholdtoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "main_off_bt:", {
|
||||||
|
user_command::linebreakertoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "main_on_bt:",{
|
||||||
|
user_command::linebreakertoggle,
|
||||||
|
user_command::none } }, // TODO: dedicated on and off line breaker commands
|
||||||
|
{ "security_reset_bt:", {
|
||||||
|
user_command::alerteracknowledge,
|
||||||
|
user_command::none } },
|
||||||
|
{ "releaser_bt:", {
|
||||||
|
user_command::independentbrakebailoff,
|
||||||
|
user_command::none } },
|
||||||
|
{ "sand_bt:", {
|
||||||
|
user_command::sandboxactivate,
|
||||||
|
user_command::none } },
|
||||||
|
{ "antislip_bt:", {
|
||||||
|
user_command::wheelspinbrakeactivate,
|
||||||
|
user_command::none } },
|
||||||
|
{ "horn_bt:", {
|
||||||
|
user_command::hornhighactivate,
|
||||||
|
user_command::hornlowactivate } },
|
||||||
|
{ "hornlow_bt:", {
|
||||||
|
user_command::hornlowactivate,
|
||||||
|
user_command::none } },
|
||||||
|
{ "hornhigh_bt:", {
|
||||||
|
user_command::hornhighactivate,
|
||||||
|
user_command::none } },
|
||||||
|
{ "fuse_bt:", {
|
||||||
|
user_command::motoroverloadrelayreset,
|
||||||
|
user_command::none } },
|
||||||
|
{ "converterfuse_bt:", {
|
||||||
|
user_command::converteroverloadrelayreset,
|
||||||
|
user_command::none } },
|
||||||
|
{ "stlinoff_bt:", {
|
||||||
|
user_command::motorconnectorsopen,
|
||||||
|
user_command::none } },
|
||||||
|
{ "door_left_sw:", {
|
||||||
|
user_command::doortoggleleft,
|
||||||
|
user_command::none } },
|
||||||
|
{ "door_right_sw:", {
|
||||||
|
user_command::doortoggleright,
|
||||||
|
user_command::none } },
|
||||||
|
{ "departure_signal_bt:", {
|
||||||
|
user_command::departureannounce,
|
||||||
|
user_command::none } },
|
||||||
|
{ "upperlight_sw:", {
|
||||||
|
user_command::headlighttoggleupper,
|
||||||
|
user_command::none } },
|
||||||
|
{ "leftlight_sw:", {
|
||||||
|
user_command::headlighttoggleleft,
|
||||||
|
user_command::none } },
|
||||||
|
{ "rightlight_sw:", {
|
||||||
|
user_command::headlighttoggleright,
|
||||||
|
user_command::none } },
|
||||||
|
{ "dimheadlights_sw:", {
|
||||||
|
user_command::headlightsdimtoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "leftend_sw:", {
|
||||||
|
user_command::redmarkertoggleleft,
|
||||||
|
user_command::none } },
|
||||||
|
{ "rightend_sw:", {
|
||||||
|
user_command::redmarkertoggleright,
|
||||||
|
user_command::none } },
|
||||||
|
{ "lights_sw:", {
|
||||||
|
user_command::none,
|
||||||
|
user_command::none } }, // TODO: implement commands for lights controller
|
||||||
|
{ "rearupperlight_sw:", {
|
||||||
|
user_command::headlighttogglerearupper,
|
||||||
|
user_command::none } },
|
||||||
|
{ "rearleftlight_sw:", {
|
||||||
|
user_command::headlighttogglerearleft,
|
||||||
|
user_command::none } },
|
||||||
|
{ "rearrightlight_sw:", {
|
||||||
|
user_command::headlighttogglerearright,
|
||||||
|
user_command::none } },
|
||||||
|
{ "rearleftend_sw:", {
|
||||||
|
user_command::redmarkertogglerearleft,
|
||||||
|
user_command::none } },
|
||||||
|
{ "rearrightend_sw:", {
|
||||||
|
user_command::redmarkertogglerearright,
|
||||||
|
user_command::none } },
|
||||||
|
{ "compressor_sw:", {
|
||||||
|
user_command::compressortoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "compressorlocal_sw:", {
|
||||||
|
user_command::compressortogglelocal,
|
||||||
|
user_command::none } },
|
||||||
|
{ "converter_sw:", {
|
||||||
|
user_command::convertertoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "converterlocal_sw:", {
|
||||||
|
user_command::convertertogglelocal,
|
||||||
|
user_command::none } },
|
||||||
|
{ "converteroff_sw:", {
|
||||||
|
user_command::convertertoggle,
|
||||||
|
user_command::none } }, // TODO: dedicated converter shutdown command
|
||||||
|
{ "main_sw:", {
|
||||||
|
user_command::linebreakertoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "radio_sw:", {
|
||||||
|
user_command::radiotoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "pantfront_sw:", {
|
||||||
|
user_command::pantographtogglefront,
|
||||||
|
user_command::none } },
|
||||||
|
{ "pantrear_sw:", {
|
||||||
|
user_command::pantographtogglerear,
|
||||||
|
user_command::none } },
|
||||||
|
{ "pantfrontoff_sw:", {
|
||||||
|
user_command::pantographtogglefront,
|
||||||
|
user_command::none } }, // TODO: dedicated lower pantograph commands
|
||||||
|
{ "pantrearoff_sw:", {
|
||||||
|
user_command::pantographtogglerear,
|
||||||
|
user_command::none } }, // TODO: dedicated lower pantograph commands
|
||||||
|
{ "pantalloff_sw:", {
|
||||||
|
user_command::pantographlowerall,
|
||||||
|
user_command::none } },
|
||||||
|
{ "pantselected_sw:", {
|
||||||
|
user_command::none,
|
||||||
|
user_command::none } }, // TODO: selected pantograph(s) operation command
|
||||||
|
{ "pantselectedoff_sw:", {
|
||||||
|
user_command::none,
|
||||||
|
user_command::none } }, // TODO: lower selected pantograp(s) command
|
||||||
|
{ "trainheating_sw:", {
|
||||||
|
user_command::heatingtoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "signalling_sw:", {
|
||||||
|
user_command::mubrakingindicatortoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "door_signalling_sw:", {
|
||||||
|
user_command::doorlocktoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "nextcurrent_sw:", {
|
||||||
|
user_command::mucurrentindicatorothersourceactivate,
|
||||||
|
user_command::none } },
|
||||||
|
{ "cablight_sw:", {
|
||||||
|
user_command::interiorlighttoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "cablightdim_sw:", {
|
||||||
|
user_command::interiorlightdimtoggle,
|
||||||
|
user_command::none } },
|
||||||
|
{ "battery_sw:", {
|
||||||
|
user_command::batterytoggle,
|
||||||
|
user_command::none } }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ public:
|
|||||||
key( int const Key, int const Action );
|
key( int const Key, int const Action );
|
||||||
void
|
void
|
||||||
mouse( double const Mousex, double const Mousey );
|
mouse( double const Mousex, double const Mousey );
|
||||||
|
void
|
||||||
|
mouse( int const Button, int const Action );
|
||||||
|
void
|
||||||
|
poll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
@@ -45,6 +49,18 @@ private:
|
|||||||
typedef std::vector<command_setup> commandsetup_sequence;
|
typedef std::vector<command_setup> commandsetup_sequence;
|
||||||
typedef std::unordered_map<int, user_command> usercommand_map;
|
typedef std::unordered_map<int, user_command> usercommand_map;
|
||||||
|
|
||||||
|
struct mouse_commands {
|
||||||
|
|
||||||
|
user_command left;
|
||||||
|
user_command right;
|
||||||
|
|
||||||
|
mouse_commands( user_command const Left, user_command const Right ):
|
||||||
|
left(Left), right(Right)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::unordered_map<std::string, mouse_commands> controlcommands_map;
|
||||||
|
|
||||||
struct bindings_cache {
|
struct bindings_cache {
|
||||||
|
|
||||||
int forward{ -1 };
|
int forward{ -1 };
|
||||||
@@ -66,9 +82,13 @@ private:
|
|||||||
// members
|
// members
|
||||||
commandsetup_sequence m_commands;
|
commandsetup_sequence m_commands;
|
||||||
usercommand_map m_bindings;
|
usercommand_map m_bindings;
|
||||||
|
controlcommands_map m_mousecommands;
|
||||||
|
user_command m_mousecommandleft { user_command::none }; // last if any command issued with mouse
|
||||||
|
user_command m_mousecommandright { user_command::none };
|
||||||
command_relay m_relay;
|
command_relay m_relay;
|
||||||
bool m_shift{ false };
|
bool m_shift{ false };
|
||||||
bool m_ctrl{ false };
|
bool m_ctrl{ false };
|
||||||
|
double m_updateaccumulator { 0.0 };
|
||||||
bindings_cache m_bindingscache;
|
bindings_cache m_bindingscache;
|
||||||
std::array<char, GLFW_KEY_LAST + 1> m_keys;
|
std::array<char, GLFW_KEY_LAST + 1> m_keys;
|
||||||
};
|
};
|
||||||
|
|||||||
1299
renderer.cpp
1299
renderer.cpp
File diff suppressed because it is too large
Load Diff
94
renderer.h
94
renderer.h
@@ -134,15 +134,6 @@ public:
|
|||||||
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
Render_Alpha( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
||||||
bool
|
bool
|
||||||
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance );
|
||||||
// maintenance jobs
|
|
||||||
void
|
|
||||||
Update( double const Deltatime );
|
|
||||||
// debug performance string
|
|
||||||
std::string const &
|
|
||||||
Info() const;
|
|
||||||
// light methods
|
|
||||||
void
|
|
||||||
Disable_Lights();
|
|
||||||
// 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
|
||||||
@@ -167,6 +158,24 @@ public:
|
|||||||
Bind( texture_handle const Texture );
|
Bind( texture_handle const Texture );
|
||||||
opengl_texture const &
|
opengl_texture const &
|
||||||
Texture( texture_handle const Texture );
|
Texture( texture_handle const Texture );
|
||||||
|
// light methods
|
||||||
|
void
|
||||||
|
Disable_Lights();
|
||||||
|
// utility methods
|
||||||
|
TSubModel const *
|
||||||
|
Pick_Control() const { return m_pickcontrolitem; }
|
||||||
|
TGroundNode const *
|
||||||
|
Pick_Node() const { return m_picksceneryitem; }
|
||||||
|
// maintenance jobs
|
||||||
|
void
|
||||||
|
Update( double const Deltatime );
|
||||||
|
TSubModel const *
|
||||||
|
Update_Pick_Control();
|
||||||
|
TGroundNode const *
|
||||||
|
Update_Pick_Node();
|
||||||
|
// debug performance string
|
||||||
|
std::string const &
|
||||||
|
Info() const;
|
||||||
|
|
||||||
// members
|
// members
|
||||||
GLenum static const sunlight{ GL_LIGHT0 };
|
GLenum static const sunlight{ GL_LIGHT0 };
|
||||||
@@ -175,16 +184,37 @@ public:
|
|||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
enum class rendermode {
|
enum class rendermode {
|
||||||
color
|
color,
|
||||||
|
shadows,
|
||||||
|
pickcontrols,
|
||||||
|
pickscenery
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::pair< double, TSubRect * > distancesubcell_pair;
|
||||||
|
|
||||||
|
struct renderpass_config {
|
||||||
|
opengl_camera camera;
|
||||||
|
rendermode draw_mode { rendermode::color };
|
||||||
|
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;
|
||||||
|
|
||||||
typedef std::pair< double, TSubRect * > distancesubcell_pair;
|
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
bool
|
bool
|
||||||
Init_caps();
|
Init_caps();
|
||||||
|
// runs jobs needed to generate graphics for specified render pass
|
||||||
|
void
|
||||||
|
Render_pass( rendermode const Mode );
|
||||||
|
// configures projection matrix for the current render pass
|
||||||
|
void
|
||||||
|
Render_projection();
|
||||||
|
// configures camera for the current render pass
|
||||||
|
void
|
||||||
|
Render_camera();
|
||||||
|
void
|
||||||
|
Render_setup( bool const Alpha = false );
|
||||||
bool
|
bool
|
||||||
Render( world_environment *Environment );
|
Render( world_environment *Environment );
|
||||||
bool
|
bool
|
||||||
@@ -197,6 +227,8 @@ private:
|
|||||||
Render( TGroundNode *Node );
|
Render( TGroundNode *Node );
|
||||||
void
|
void
|
||||||
Render( TTrack *Track );
|
Render( TTrack *Track );
|
||||||
|
bool
|
||||||
|
Render_cab( TDynamicObject *Dynamic );
|
||||||
void
|
void
|
||||||
Render( TMemCell *Memcell );
|
Render( TMemCell *Memcell );
|
||||||
bool
|
bool
|
||||||
@@ -209,29 +241,43 @@ private:
|
|||||||
Render_Alpha( TSubModel *Submodel );
|
Render_Alpha( TSubModel *Submodel );
|
||||||
void
|
void
|
||||||
Update_Lights( light_array const &Lights );
|
Update_Lights( light_array const &Lights );
|
||||||
|
glm::vec3
|
||||||
|
pick_color( std::size_t const Index );
|
||||||
|
std::size_t
|
||||||
|
pick_index( glm::ivec3 const &Color );
|
||||||
// members
|
// members
|
||||||
opengllight_array m_lights;
|
|
||||||
geometrybank_manager m_geometry;
|
geometrybank_manager m_geometry;
|
||||||
texture_manager m_textures;
|
texture_manager m_textures;
|
||||||
opengl_camera m_camera;
|
opengllight_array m_lights;
|
||||||
rendermode renderpass { rendermode::color };
|
|
||||||
float m_drawrange { 2500.0f }; // current drawing range
|
|
||||||
float m_drawtime { 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
|
|
||||||
double m_updateaccumulator { 0.0 };
|
|
||||||
std::string m_debuginfo;
|
|
||||||
GLFWwindow *m_window { nullptr };
|
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 };
|
||||||
|
#endif
|
||||||
|
GLUquadricObj *m_quadric { nullptr }; // helper object for drawing debug mode scene elements
|
||||||
|
|
||||||
|
geometry_handle m_billboardgeometry { 0, 0 };
|
||||||
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 };
|
||||||
geometry_handle m_billboardgeometry { 0, 0 };
|
|
||||||
GLUquadricObj *m_quadric; // 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
|
||||||
std::vector<distancesubcell_pair> m_drawqueue; // list of subcells to be drawn in current render pass
|
double m_updateaccumulator { 0.0 };
|
||||||
|
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 };
|
||||||
bool m_renderspecular{ false }; // controls whether to include specular component in the calculations
|
|
||||||
float m_specularopaquescalefactor { 1.0f };
|
float m_specularopaquescalefactor { 1.0f };
|
||||||
float m_speculartranslucentscalefactor { 1.0f };
|
float m_speculartranslucentscalefactor { 1.0f };
|
||||||
|
|
||||||
|
bool m_framebuffersupport { false };
|
||||||
|
rendermode m_texenvmode { rendermode::color }; // last configured texture environment
|
||||||
|
renderpass_config m_renderpass;
|
||||||
|
bool m_renderspecular { false }; // controls whether to include specular component in the calculations
|
||||||
|
std::vector<TGroundNode const *> m_picksceneryitems;
|
||||||
|
std::vector<TSubModel const *> m_pickcontrolsitems;
|
||||||
|
TSubModel const *m_pickcontrolitem { nullptr };
|
||||||
|
TGroundNode const *m_picksceneryitem { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
extern opengl_renderer GfxRenderer;
|
extern opengl_renderer GfxRenderer;
|
||||||
|
|||||||
45
uilayer.cpp
45
uilayer.cpp
@@ -25,9 +25,10 @@ ui_layer::~ui_layer() {
|
|||||||
bool
|
bool
|
||||||
ui_layer::init( GLFWwindow *Window ) {
|
ui_layer::init( GLFWwindow *Window ) {
|
||||||
|
|
||||||
|
m_window = Window;
|
||||||
HFONT font; // Windows Font ID
|
HFONT font; // Windows Font ID
|
||||||
m_fontbase = ::glGenLists(96); // storage for 96 characters
|
m_fontbase = ::glGenLists(96); // storage for 96 characters
|
||||||
HDC hDC = ::GetDC( glfwGetWin32Window( Window ) );
|
HDC hDC = ::GetDC( glfwGetWin32Window( m_window ) );
|
||||||
font = ::CreateFont( -MulDiv( 10, ::GetDeviceCaps( hDC, LOGPIXELSY ), 72 ), // height of font
|
font = ::CreateFont( -MulDiv( 10, ::GetDeviceCaps( hDC, LOGPIXELSY ), 72 ), // height of font
|
||||||
0, // width of font
|
0, // width of font
|
||||||
0, // angle of escapement
|
0, // angle of escapement
|
||||||
@@ -79,6 +80,7 @@ ui_layer::render() {
|
|||||||
render_background();
|
render_background();
|
||||||
render_progress();
|
render_progress();
|
||||||
render_panels();
|
render_panels();
|
||||||
|
render_tooltip();
|
||||||
|
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
}
|
}
|
||||||
@@ -94,12 +96,14 @@ void
|
|||||||
ui_layer::set_background( std::string const &Filename ) {
|
ui_layer::set_background( std::string const &Filename ) {
|
||||||
|
|
||||||
if( false == Filename.empty() ) {
|
if( false == Filename.empty() ) {
|
||||||
|
|
||||||
m_background = GfxRenderer.GetTextureId( Filename, szTexturePath );
|
m_background = GfxRenderer.GetTextureId( Filename, szTexturePath );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
m_background = NULL;
|
||||||
m_background = 0;
|
}
|
||||||
|
if( m_background != NULL ) {
|
||||||
|
auto const &texture = GfxRenderer.Texture( m_background );
|
||||||
|
m_progressbottom = ( texture.width() != texture.height() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -115,17 +119,27 @@ ui_layer::render_progress() {
|
|||||||
glPushAttrib( GL_ENABLE_BIT );
|
glPushAttrib( GL_ENABLE_BIT );
|
||||||
glDisable( GL_TEXTURE_2D );
|
glDisable( GL_TEXTURE_2D );
|
||||||
|
|
||||||
quad( float4( 75.0f, 640.0f, 75.0f + 320.0f, 640.0f + 16.0f ), float4(0.0f, 0.0f, 0.0f, 0.25f) );
|
glm::vec2 origin, size;
|
||||||
|
if( m_progressbottom == true ) {
|
||||||
|
origin = glm::vec2{ 0.0f, 768.0f - 20.0f };
|
||||||
|
size = glm::vec2{ 1024.0f, 20.0f };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
origin = glm::vec2{ 75.0f, 640.0f };
|
||||||
|
size = glm::vec2{ 320.0f, 16.0f };
|
||||||
|
}
|
||||||
|
|
||||||
|
quad( float4( origin.x, origin.y, origin.x + size.x, origin.y + size.y ), float4(0.0f, 0.0f, 0.0f, 0.25f) );
|
||||||
// secondary bar
|
// secondary bar
|
||||||
if( m_subtaskprogress ) {
|
if( m_subtaskprogress ) {
|
||||||
quad(
|
quad(
|
||||||
float4( 75.0f, 640.0f, 75.0f + 320.0f * m_subtaskprogress, 640.0f + 16.0f),
|
float4( origin.x, origin.y, origin.x + size.x * m_subtaskprogress, origin.y + size.y),
|
||||||
float4( 8.0f/255.0f, 160.0f/255.0f, 8.0f/255.0f, 0.35f ) );
|
float4( 8.0f/255.0f, 160.0f/255.0f, 8.0f/255.0f, 0.35f ) );
|
||||||
}
|
}
|
||||||
// primary bar
|
// primary bar
|
||||||
if( m_progress ) {
|
if( m_progress ) {
|
||||||
quad(
|
quad(
|
||||||
float4( 75.0f, 640.0f, 75.0f + 320.0f * m_progress, 640.0f + 16.0f ),
|
float4( origin.x, origin.y, origin.x + size.x * m_progress, origin.y + size.y ),
|
||||||
float4( 8.0f / 255.0f, 160.0f / 255.0f, 8.0f / 255.0f, 1.0f ) );
|
float4( 8.0f / 255.0f, 160.0f / 255.0f, 8.0f / 255.0f, 1.0f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +174,23 @@ ui_layer::render_panels() {
|
|||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ui_layer::render_tooltip() {
|
||||||
|
|
||||||
|
if( m_tooltip.empty() ) { return; }
|
||||||
|
|
||||||
|
glm::dvec2 mousepos;
|
||||||
|
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||||
|
|
||||||
|
glPushAttrib( GL_ENABLE_BIT );
|
||||||
|
glDisable( GL_TEXTURE_2D );
|
||||||
|
::glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||||
|
::glRasterPos2f( mousepos.x + 20.0f, mousepos.y + 25.0f );
|
||||||
|
print( m_tooltip );
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ui_layer::render_background() {
|
ui_layer::render_background() {
|
||||||
|
|
||||||
|
|||||||
19
uilayer.h
19
uilayer.h
@@ -50,6 +50,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_tooltip( std::string const &Tooltip ) { m_tooltip = Tooltip; }
|
||||||
void
|
void
|
||||||
clear_texts() { m_panels.clear(); }
|
clear_texts() { m_panels.clear(); }
|
||||||
void
|
void
|
||||||
@@ -67,6 +69,8 @@ private:
|
|||||||
render_progress();
|
render_progress();
|
||||||
void
|
void
|
||||||
render_panels();
|
render_panels();
|
||||||
|
void
|
||||||
|
render_tooltip();
|
||||||
// prints specified text, using display lists font
|
// prints specified text, using display lists font
|
||||||
void
|
void
|
||||||
print( std::string const &Text );
|
print( std::string const &Text );
|
||||||
@@ -76,11 +80,18 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
GLuint m_fontbase{ (GLuint)-1 }; // numer DL dla znaków w napisach
|
GLFWwindow *m_window { nullptr };
|
||||||
float m_progress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
GLuint m_fontbase { (GLuint)-1 }; // numer DL dla znaków w napisach
|
||||||
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
|
||||||
texture_handle m_background; // path to texture used as the background. size depends on mAspect.
|
// progress bar config. TODO: put these together into an object
|
||||||
|
float m_progress { 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||||
|
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||||
|
std::string m_progresstext; // label placed over 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.
|
||||||
std::vector<std::shared_ptr<ui_panel> > m_panels;
|
std::vector<std::shared_ptr<ui_panel> > m_panels;
|
||||||
|
std::string m_tooltip;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ui_layer UILayer;
|
extern ui_layer UILayer;
|
||||||
|
|||||||
Reference in New Issue
Block a user