mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 01:59:19 +02:00
basic configurable rail profile implementation, track switch geometry creation tweaks
This commit is contained in:
39
Segment.cpp
39
Segment.cpp
@@ -374,12 +374,10 @@ Math3D::vector3 TSegment::FastGetPoint(double const t) const
|
||||
interpolate( Point1, Point2, t ) );
|
||||
}
|
||||
|
||||
bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Origin, const gfx::vertex_array &ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, float fOffsetX, glm::vec3 **p, bool bRender)
|
||||
bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Origin, const gfx::vertex_array &ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, std::pair<float, float> fOffsetX, glm::vec3 **p, bool bRender)
|
||||
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
// podany jest przekrój końcowy
|
||||
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli podany jest przekrój końcowy
|
||||
|
||||
if( fTsBuffer.empty() )
|
||||
return false; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
@@ -410,8 +408,12 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
|
||||
if( iEnd == 0 )
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double( iEnd ) / double( iSegCount );
|
||||
/*
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
*/
|
||||
m2 = static_cast<float>( i - iSkip ) / ( iEnd - iSkip );
|
||||
|
||||
jmm2 = 1.f - m2;
|
||||
|
||||
while( i < iEnd ) {
|
||||
|
||||
@@ -419,13 +421,17 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
/*
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
*/
|
||||
m2 = static_cast<float>( i - iSkip ) / ( iEnd - iSkip );
|
||||
|
||||
jmm2 = 1.f - m2; // nowa pozycja
|
||||
if( i == iEnd ) { // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= ( s - fEnd ); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fEnd;
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
m2 = 1.f;
|
||||
jmm2 = 0.f;
|
||||
}
|
||||
|
||||
while( tv1 < 0.0 ) {
|
||||
@@ -443,11 +449,11 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
|
||||
}
|
||||
parallel2 = glm::normalize( parallel2 );
|
||||
|
||||
// TODO: refactor the loop, there's no need to calculate starting points for each segment when we can copy the end points of the previous one
|
||||
if( trapez ) {
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
pt = parallel1 * ( jmm1 * ( ShapePoints[ j ].position.x - fOffsetX ) + m1 * ShapePoints[ j + iNumShapePoints ].position.x ) + pos1;
|
||||
pt = parallel1 * ( jmm1 * ( ShapePoints[ j ].position.x - fOffsetX.first ) + m1 * ( ShapePoints[ j + iNumShapePoints ].position.x - fOffsetX.second ) ) + pos1;
|
||||
pt.y += jmm1 * ShapePoints[ j ].position.y + m1 * ShapePoints[ j + iNumShapePoints ].position.y;
|
||||
// pt -= Origin;
|
||||
norm = ( jmm1 * ShapePoints[ j ].normal.x + m1 * ShapePoints[ j + iNumShapePoints ].normal.x ) * parallel1;
|
||||
norm.y += jmm1 * ShapePoints[ j ].normal.y + m1 * ShapePoints[ j + iNumShapePoints ].normal.y;
|
||||
if( bRender ) {
|
||||
@@ -465,11 +471,10 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].position.x - fOffsetX ) + m2 * ShapePoints[ j + iNumShapePoints ].position.x ) + pos2;
|
||||
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].position.x - fOffsetX.first ) + m2 * ( ShapePoints[ j + iNumShapePoints ].position.x - fOffsetX.second ) ) + pos2;
|
||||
pt.y += jmm2 * ShapePoints[ j ].position.y + m2 * ShapePoints[ j + iNumShapePoints ].position.y;
|
||||
// pt -= Origin;
|
||||
norm = ( jmm1 * ShapePoints[ j ].normal.x + m1 * ShapePoints[ j + iNumShapePoints ].normal.x ) * parallel2;
|
||||
norm.y += jmm1 * ShapePoints[ j ].normal.y + m1 * ShapePoints[ j + iNumShapePoints ].normal.y;
|
||||
norm = ( jmm2 * ShapePoints[ j ].normal.x + m2 * ShapePoints[ j + iNumShapePoints ].normal.x ) * parallel2;
|
||||
norm.y += jmm2 * ShapePoints[ j ].normal.y + m2 * ShapePoints[ j + iNumShapePoints ].normal.y;
|
||||
if( bRender ) {
|
||||
// skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||
Output.emplace_back(
|
||||
@@ -490,9 +495,8 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
|
||||
if( bRender ) {
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
//łuk z jednym profilem
|
||||
pt = parallel1 * ( ShapePoints[ j ].position.x - fOffsetX ) + pos1;
|
||||
pt = parallel1 * ( jmm1 * ( ShapePoints[ j ].position.x - fOffsetX.first ) + m1 * ( ShapePoints[ j ].position.x - fOffsetX.second ) ) + pos1;
|
||||
pt.y += ShapePoints[ j ].position.y;
|
||||
// pt -= Origin;
|
||||
norm = ShapePoints[ j ].normal.x * parallel1;
|
||||
norm.y += ShapePoints[ j ].normal.y;
|
||||
|
||||
@@ -501,9 +505,8 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
|
||||
glm::normalize( norm ),
|
||||
glm::vec2 { ShapePoints[ j ].texture.x / texturescale, tv1 } );
|
||||
|
||||
pt = parallel2 * ShapePoints[ j ].position.x + pos2;
|
||||
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].position.x - fOffsetX.first ) + m2 * ( ShapePoints[ j ].position.x - fOffsetX.second ) ) + pos2;
|
||||
pt.y += ShapePoints[ j ].position.y;
|
||||
// pt -= Origin;
|
||||
norm = ShapePoints[ j ].normal.x * parallel2;
|
||||
norm.y += ShapePoints[ j ].normal.y;
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
r2 = fRoll2; }
|
||||
|
||||
bool
|
||||
RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Origin, gfx::vertex_array const &ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, float fOffsetX = 0.f, glm::vec3 **p = nullptr, bool bRender = true);
|
||||
RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Origin, gfx::vertex_array const &ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, std::pair<float, float> fOffsetX = {0.f, 0.f}, glm::vec3 **p = nullptr, bool bRender = true );
|
||||
/*
|
||||
void
|
||||
Render();
|
||||
|
||||
370
Track.cpp
370
Track.cpp
@@ -25,6 +25,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Timer.h"
|
||||
#include "Logs.h"
|
||||
#include "renderer.h"
|
||||
#include "utilities.h"
|
||||
|
||||
// 101206 Ra: trapezoidalne drogi i tory
|
||||
// 110720 Ra: rozprucie zwrotnicy i odcinki izolowane
|
||||
@@ -42,6 +43,9 @@ const int iProsto3[4] = {1, -1, 2, 1}; // segmenty do jazdy prosto
|
||||
const int iEnds3[13] = {3, 0, 2, 1, 2, 0, -1, 1, 0, 2, 0, 3, 1}; // numer sąsiedniego toru na końcu segmentu "-1"
|
||||
TIsolated *TIsolated::pRoot = NULL;
|
||||
|
||||
TTrack::profiles_array TTrack::m_profiles;
|
||||
TTrack::profiles_map TTrack::m_profilesmap;
|
||||
|
||||
TSwitchExtension::TSwitchExtension(TTrack *owner, int const what)
|
||||
{ // na początku wszystko puste
|
||||
pNexts[0] = nullptr; // wskaźniki do kolejnych odcinków ruchu
|
||||
@@ -523,8 +527,10 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
|
||||
|
||||
if (iCategoryFlag & 1)
|
||||
{ // zero na główce szyny
|
||||
p1.y += 0.18;
|
||||
p2.y += 0.18;
|
||||
// TODO: delay these calculations unti rail profile and thus height is known
|
||||
auto const railheight { 0.18 };
|
||||
p1.y += railheight;
|
||||
p2.y += railheight;
|
||||
// na przechyłce doliczyć jeszcze pół przechyłki
|
||||
}
|
||||
|
||||
@@ -618,8 +624,10 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
|
||||
|
||||
if (iCategoryFlag & 1)
|
||||
{ // zero na główce szyny
|
||||
p1.y += 0.18;
|
||||
p2.y += 0.18;
|
||||
// TODO: delay these calculations unti rail profile and thus height is known
|
||||
auto const railheight { 0.18 };
|
||||
p1.y += railheight;
|
||||
p2.y += railheight;
|
||||
// na przechyłce doliczyć jeszcze pół przechyłki?
|
||||
}
|
||||
|
||||
@@ -680,8 +688,10 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
|
||||
|
||||
if (iCategoryFlag & 1)
|
||||
{ // zero na główce szyny
|
||||
p3.y += 0.18;
|
||||
p4.y += 0.18;
|
||||
// TODO: delay these calculations unti rail profile and thus height is known
|
||||
auto const railheight{ 0.18 };
|
||||
p3.y += railheight;
|
||||
p4.y += railheight;
|
||||
// na przechyłce doliczyć jeszcze pół przechyłki?
|
||||
}
|
||||
|
||||
@@ -877,8 +887,15 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
|
||||
SwitchExtension->m_material3 = GfxRenderer.Fetch_Material( trackbedtexture );
|
||||
}
|
||||
}
|
||||
else if( str == "railprofile" ) {
|
||||
// rail profile
|
||||
auto const railprofile { parser->getToken<std::string>() };
|
||||
if( iCategoryFlag == 1 ) {
|
||||
m_profile1 = fetch_track_rail_profile( railprofile );
|
||||
}
|
||||
}
|
||||
else
|
||||
ErrorLog("Unknown property: \"" + str + "\" in track \"" + m_name + "\"");
|
||||
ErrorLog("Bad track: unknown property: \"" + str + "\" defined for track \"" + m_name + "\"");
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str = token;
|
||||
@@ -1010,41 +1027,6 @@ bool TTrack::AddDynamicObject(TDynamicObject *Dynamic)
|
||||
};
|
||||
|
||||
const int numPts = 4;
|
||||
const int nnumPts = 12;
|
||||
|
||||
// szyna - vextor6(x,y,mapowanie tekstury,xn,yn,zn)
|
||||
// tę wersję opracował Tolein (bez pochylenia)
|
||||
// TODO: profile definitions in external files
|
||||
gfx::basic_vertex const szyna[ nnumPts ] = {
|
||||
{{ 0.111f, -0.180f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.00f, 0.f}},
|
||||
{{ 0.046f, -0.150f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.15f, 0.f}},
|
||||
{{ 0.044f, -0.050f, 0.f}, { 0.707f, -0.707f, 0.f}, {0.25f, 0.f}},
|
||||
{{ 0.073f, -0.038f, 0.f}, { 0.707f, -0.707f, 0.f}, {0.35f, 0.f}},
|
||||
{{ 0.072f, -0.010f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.40f, 0.f}},
|
||||
{{ 0.052f, -0.000f, 0.f}, { 0.000f, 1.000f, 0.f}, {0.45f, 0.f}},
|
||||
{{ 0.020f, -0.000f, 0.f}, { 0.000f, 1.000f, 0.f}, {0.55f, 0.f}},
|
||||
{{ 0.000f, -0.010f, 0.f}, {-0.707f, 0.707f, 0.f}, {0.60f, 0.f}},
|
||||
{{-0.001f, -0.038f, 0.f}, {-0.707f, -0.707f, 0.f}, {0.65f, 0.f}},
|
||||
{{ 0.028f, -0.050f, 0.f}, {-0.707f, -0.707f, 0.f}, {0.75f, 0.f}},
|
||||
{{ 0.026f, -0.150f, 0.f}, {-0.707f, 0.707f, 0.f}, {0.85f, 0.f}},
|
||||
{{-0.039f, -0.180f, 0.f}, {-1.000f, 0.000f, 0.f}, {1.00f, 0.f}} };
|
||||
|
||||
// iglica - vextor3(x,y,mapowanie tekstury)
|
||||
// 1 mm więcej, żeby nie nachodziły tekstury?
|
||||
// TODO: automatic generation from base profile TBD: reuse base profile?
|
||||
gfx::basic_vertex const iglica[ nnumPts ] = {
|
||||
{{ 0.010f, -0.180f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.00f, 0.f}},
|
||||
{{ 0.010f, -0.155f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.15f, 0.f}},
|
||||
{{ 0.010f, -0.070f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.25f, 0.f}},
|
||||
{{ 0.010f, -0.040f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.35f, 0.f}},
|
||||
{{ 0.010f, -0.010f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.40f, 0.f}},
|
||||
{{ 0.010f, -0.000f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.45f, 0.f}},
|
||||
{{ 0.000f, -0.000f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.55f, 0.f}},
|
||||
{{ 0.000f, -0.010f, 0.f}, {-1.000f, 0.000f, 0.f}, {0.60f, 0.f}},
|
||||
{{ 0.000f, -0.040f, 0.f}, {-1.000f, 0.000f, 0.f}, {0.65f, 0.f}},
|
||||
{{ 0.000f, -0.070f, 0.f}, {-1.000f, 0.000f, 0.f}, {0.75f, 0.f}},
|
||||
{{ 0.000f, -0.155f, 0.f}, {-0.707f, 0.707f, 0.f}, {0.85f, 0.f}},
|
||||
{{-0.040f, -0.180f, 0.f}, {-1.000f, 0.000f, 0.f}, {1.00f, 0.f}} };
|
||||
|
||||
bool TTrack::CheckDynamicObject(TDynamicObject *Dynamic)
|
||||
{ // sprawdzenie, czy pojazd jest przypisany do toru
|
||||
@@ -1167,6 +1149,7 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
}
|
||||
if (m_material1)
|
||||
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną
|
||||
auto const nnumPts { track_rail_profile( m_profile1.second ).size() / 2 };
|
||||
auto const texturelength { texture_length( m_material1 ) };
|
||||
gfx::vertex_array vertices;
|
||||
if( ( Bank != 0 ) && ( true == Geometry1.empty() ) ) {
|
||||
@@ -1193,34 +1176,39 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
create_track_blade_profile( rpts3, rpts4 );
|
||||
// TODO, TBD: change all track geometry to triangles, to allow packing data in less, larger buffers
|
||||
auto const bladelength { static_cast<int>( std::ceil( SwitchExtension->Segments[ 0 ]->RaSegCount() * 0.65 ) ) };
|
||||
auto const nnumPts { track_rail_profile( m_profile1.second ).size() / 2 };
|
||||
if (SwitchExtension->RightSwitch)
|
||||
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||
gfx::vertex_array vertices;
|
||||
if( m_material1 ) {
|
||||
auto const texturelength { texture_length( m_material1 ) };
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength );
|
||||
// left blade
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { SwitchExtension->fOffset2, SwitchExtension->fOffset2 / 2 } );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { SwitchExtension->fOffset2 / 2, 0.f } );
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength, 1.0, bladelength );
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength, SwitchExtension->fOffset2 );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength );
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
if( m_material2 ) {
|
||||
auto const texturelength { texture_length( m_material2 ) };
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength );
|
||||
// right blade
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { -fMaxOffset + SwitchExtension->fOffset1, ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2 } );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2, 0.f } );
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength, 1.0, bladelength );
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength );
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
@@ -1230,29 +1218,33 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
gfx::vertex_array vertices;
|
||||
if( m_material1 ) {
|
||||
auto const texturelength { texture_length( m_material1 ) };
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength ); // lewa szyna normalna cała
|
||||
// right blade
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { -SwitchExtension->fOffset2, -SwitchExtension->fOffset2 / 2 } );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { -SwitchExtension->fOffset2 / 2, 0.f } );
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength, 1.0, bladelength ); // prawa szyna za iglicą
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength, -SwitchExtension->fOffset2 );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength ); // lewa szyna normalna cała
|
||||
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
if( m_material2 ) {
|
||||
auto const texturelength { texture_length( m_material2 ) };
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength ); // prawa szyna normalnie cała
|
||||
// left blade
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { fMaxOffset - SwitchExtension->fOffset1, ( fMaxOffset - SwitchExtension->fOffset1 ) / 2 } );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { ( fMaxOffset - SwitchExtension->fOffset1 ) / 2, 0.f } );
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// fixed parts
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength, 1.0, bladelength ); // lewa szyna za iglicą
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength, fMaxOffset - SwitchExtension->fOffset1 );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength ); // prawa szyna normalnie cała
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
@@ -1393,22 +1385,22 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
if (SwitchExtension->iRoads == 4)
|
||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, {}, &b, render );
|
||||
if( true == render ) {
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
SwitchExtension->Segments[ 3 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 3 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, {}, &b, render );
|
||||
if( true == render ) {
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
SwitchExtension->Segments[ 4 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 4 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, {}, &b, render );
|
||||
if( true == render ) {
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
SwitchExtension->Segments[ 5 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 5 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, {}, &b, render );
|
||||
if( true == render ) {
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
@@ -1418,17 +1410,17 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
else {
|
||||
// punkt 3 pokrywa się z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, 0.0, &b, render ); // z P2 do P4
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, {}, &b, render ); // z P2 do P4
|
||||
if( true == render ) {
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, 0.0, &b, render ); // z P4 do P3=P1 (odwrócony)
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, {}, &b, render ); // z P4 do P3=P1 (odwrócony)
|
||||
if( true == render ) {
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
}
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, 0.0, &b, render ); // z P1 do P2
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, -3, texturelength, 1.0, 0, 0, {}, &b, render ); // z P1 do P2
|
||||
if( true == render ) {
|
||||
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
|
||||
vertices.clear();
|
||||
@@ -1790,24 +1782,31 @@ TTrack * TTrack::RaAnimate()
|
||||
&& ( ( false == Geometry1.empty() )
|
||||
|| ( false == Geometry2.empty() ) ) ) {
|
||||
// iglice liczone tylko dla zwrotnic
|
||||
gfx::vertex_array rpts1, rpts2;
|
||||
create_track_rail_profile( rpts1, rpts2 );
|
||||
gfx::vertex_array rpts3, rpts4;
|
||||
create_track_blade_profile( rpts3, rpts4 );
|
||||
gfx::vertex_array vertices;
|
||||
auto const bladelength { static_cast<int>( std::ceil( SwitchExtension->Segments[ 0 ]->RaSegCount() * 0.65 ) ) };
|
||||
auto const nnumPts { track_rail_profile( m_profile1.second ).size() / 2 };
|
||||
if (SwitchExtension->RightSwitch)
|
||||
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||
if( m_material1 ) {
|
||||
auto const texturelength { texture_length( m_material1 ) };
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength, SwitchExtension->fOffset2 );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { SwitchExtension->fOffset2, SwitchExtension->fOffset2 / 2 } );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { SwitchExtension->fOffset2 / 2, 0.f } );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 0 ] );
|
||||
vertices.clear();
|
||||
}
|
||||
if( m_material2 ) {
|
||||
auto const texturelength { texture_length( m_material2 ) };
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { -fMaxOffset + SwitchExtension->fOffset1, ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2 } );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2, 0.f } );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 0 ] );
|
||||
vertices.clear();
|
||||
}
|
||||
}
|
||||
@@ -1815,15 +1814,19 @@ TTrack * TTrack::RaAnimate()
|
||||
if( m_material1 ) {
|
||||
auto const texturelength { texture_length( m_material1 ) };
|
||||
// right blade
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength, -SwitchExtension->fOffset2 );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 2 ] );
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { -SwitchExtension->fOffset2, -SwitchExtension->fOffset2 / 2 } );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { -SwitchExtension->fOffset2 / 2, 0.f } );
|
||||
GfxRenderer.Replace( vertices, Geometry1[ 0 ] );
|
||||
vertices.clear();
|
||||
}
|
||||
if( m_material2 ) {
|
||||
auto const texturelength { texture_length( m_material2 ) };
|
||||
// left blade
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength, fMaxOffset - SwitchExtension->fOffset1 );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 2 ] );
|
||||
// composed from two parts: transition from blade to regular rail, and regular rail
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, -nnumPts, texturelength, 1.0, 0, bladelength / 2, { fMaxOffset - SwitchExtension->fOffset1, ( fMaxOffset - SwitchExtension->fOffset1 ) / 2 } );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, nnumPts, texturelength, 1.0, bladelength / 2, bladelength, { ( fMaxOffset - SwitchExtension->fOffset1 ) / 2, 0.f } );
|
||||
GfxRenderer.Replace( vertices, Geometry2[ 0 ] );
|
||||
vertices.clear();
|
||||
}
|
||||
}
|
||||
@@ -2171,6 +2174,107 @@ TTrack::export_as_text_( std::ostream &Output ) const {
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
// locates specified profile in the profile database, potentially loading it from a file
|
||||
// returns: pair <profile name, profile handle>
|
||||
std::pair<std::string, int>
|
||||
TTrack::fetch_track_rail_profile( std::string const &Profile ) {
|
||||
|
||||
auto const railprofilepath { std::string( szModelPath ) + "tory/railprofile_" };
|
||||
auto const railkeyprefix { std::string( "rail_" ) };
|
||||
|
||||
if( m_profiles.empty() ) {
|
||||
// ensure the default profile is always first in the database
|
||||
fetch_default_profiles();
|
||||
}
|
||||
// try to locate specified rail profile...
|
||||
auto const lookup { m_profilesmap.find( railkeyprefix + Profile ) };
|
||||
if( lookup != m_profilesmap.end() ) {
|
||||
// ...if it works, we're done...
|
||||
return { Profile, lookup->second };
|
||||
}
|
||||
// ... and if it fails try to add the profile to the database from a data file
|
||||
auto profilehandle { 0 }; // fallback link to default profile if loading it fails
|
||||
auto profiledata { deserialize_profile( railprofilepath + Profile ) };
|
||||
if( false == profiledata.empty() ) {
|
||||
// if we get the profile data add it to the database and calculate a link to it
|
||||
profilehandle = static_cast<int>( m_profiles.size() );
|
||||
m_profiles.emplace_back( profiledata );
|
||||
}
|
||||
m_profilesmap.emplace( railkeyprefix + Profile, profilehandle );
|
||||
return { Profile, profilehandle };
|
||||
}
|
||||
|
||||
void
|
||||
TTrack::fetch_default_profiles() {
|
||||
|
||||
if( false == m_profiles.empty() ) { return; }
|
||||
|
||||
auto const railprofilepath { std::string( szModelPath ) + "tory/railprofile_" };
|
||||
auto const railkeyprefix { std::string( "rail_" ) };
|
||||
|
||||
m_profiles.emplace_back( deserialize_profile( railprofilepath + "default" ) );
|
||||
if( m_profiles.back().empty() ) {
|
||||
// fallback to prevent utter start failure, supply legacy track profile
|
||||
m_profiles.back() = {
|
||||
// szyna - vextor6(x,y,mapowanie tekstury,xn,yn,zn)
|
||||
// tę wersję opracował Tolein (bez pochylenia)
|
||||
{{ 0.111f, -0.180f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.00f, 0.f}},
|
||||
{{ 0.046f, -0.150f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.15f, 0.f}},
|
||||
{{ 0.044f, -0.050f, 0.f}, { 0.707f, -0.707f, 0.f}, {0.25f, 0.f}},
|
||||
{{ 0.073f, -0.038f, 0.f}, { 0.707f, -0.707f, 0.f}, {0.35f, 0.f}},
|
||||
{{ 0.072f, -0.010f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.40f, 0.f}},
|
||||
{{ 0.052f, -0.000f, 0.f}, { 0.000f, 1.000f, 0.f}, {0.45f, 0.f}},
|
||||
{{ 0.020f, -0.000f, 0.f}, { 0.000f, 1.000f, 0.f}, {0.55f, 0.f}},
|
||||
{{ 0.000f, -0.010f, 0.f}, {-0.707f, 0.707f, 0.f}, {0.60f, 0.f}},
|
||||
{{-0.001f, -0.038f, 0.f}, {-0.707f, -0.707f, 0.f}, {0.65f, 0.f}},
|
||||
{{ 0.028f, -0.050f, 0.f}, {-0.707f, -0.707f, 0.f}, {0.75f, 0.f}},
|
||||
{{ 0.026f, -0.150f, 0.f}, {-0.707f, 0.707f, 0.f}, {0.85f, 0.f}},
|
||||
{{-0.039f, -0.180f, 0.f}, {-1.000f, 0.000f, 0.f}, {1.00f, 0.f}},
|
||||
// iglica - vextor3(x,y,mapowanie tekstury)
|
||||
// 1 mm więcej, żeby nie nachodziły tekstury?
|
||||
{{ 0.010f, -0.180f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.00f, 0.f}},
|
||||
{{ 0.010f, -0.155f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.15f, 0.f}},
|
||||
{{ 0.010f, -0.070f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.25f, 0.f}},
|
||||
{{ 0.010f, -0.040f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.35f, 0.f}},
|
||||
{{ 0.010f, -0.010f, 0.f}, { 1.000f, 0.000f, 0.f}, {0.40f, 0.f}},
|
||||
{{ 0.010f, -0.000f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.45f, 0.f}},
|
||||
{{ 0.000f, -0.000f, 0.f}, { 0.707f, 0.707f, 0.f}, {0.55f, 0.f}},
|
||||
{{ 0.000f, -0.010f, 0.f}, {-1.000f, 0.000f, 0.f}, {0.60f, 0.f}},
|
||||
{{ 0.000f, -0.040f, 0.f}, {-1.000f, 0.000f, 0.f}, {0.65f, 0.f}},
|
||||
{{ 0.000f, -0.070f, 0.f}, {-1.000f, 0.000f, 0.f}, {0.75f, 0.f}},
|
||||
{{ 0.000f, -0.155f, 0.f}, {-0.707f, 0.707f, 0.f}, {0.85f, 0.f}},
|
||||
{{-0.040f, -0.180f, 0.f}, {-1.000f, 0.000f, 0.f}, {1.00f, 0.f}} };
|
||||
}
|
||||
m_profilesmap.emplace( railkeyprefix + "default", 0 );
|
||||
}
|
||||
|
||||
gfx::vertex_array
|
||||
TTrack::deserialize_profile( std::string const &Profile ) {
|
||||
|
||||
gfx::vertex_array profiledata;
|
||||
|
||||
cParser input { Profile + ".txt", cParser::buffer_FILE };
|
||||
|
||||
while( input.getTokens( 5, true, "\n\r\t ;,{}" ) ) {
|
||||
gfx::basic_vertex vertex;
|
||||
input
|
||||
>> vertex.position.x
|
||||
>> vertex.position.y
|
||||
>> vertex.normal.x
|
||||
>> vertex.normal.y
|
||||
>> vertex.texture.s;
|
||||
profiledata.emplace_back( vertex );
|
||||
}
|
||||
|
||||
return profiledata;
|
||||
}
|
||||
|
||||
gfx::vertex_array const &
|
||||
TTrack::track_rail_profile( int const Profile ) {
|
||||
|
||||
return m_profiles[ Profile ];
|
||||
}
|
||||
|
||||
float
|
||||
TTrack::texture_length( material_handle const Material ) {
|
||||
|
||||
@@ -2319,66 +2423,70 @@ TTrack::create_track_rail_profile( gfx::vertex_array &Right, gfx::vertex_array &
|
||||
sin2 { std::sin( roll2 ) },
|
||||
cos2 { std::cos( roll2 ) };
|
||||
|
||||
auto const pointcount { iTrapezoid == 0 ? 12 : 24 };
|
||||
Right.resize( pointcount );
|
||||
Left.resize( pointcount );
|
||||
auto const &railprofile { track_rail_profile( m_profile1.second ) };
|
||||
// NOTE: rail profile defines both regular rail and switch blade profiles, so we halve total point count
|
||||
auto const pointcount { railprofile.size() / 2 };
|
||||
Right.resize( pointcount * ( iTrapezoid == 0 ? 1 : 2 ) );
|
||||
Left.resize( pointcount * ( iTrapezoid == 0 ? 1 : 2 ) );
|
||||
|
||||
for( int i = 0; i < 12; ++i ) {
|
||||
auto const *szyna { railprofile.data() };
|
||||
|
||||
for( int i = 0; i < pointcount; ++i ) {
|
||||
|
||||
Right[ i ] = {
|
||||
// position
|
||||
{( fHTW + szyna[ i ].position.x ) * cos1 + szyna[ i ].position.y * sin1,
|
||||
-( fHTW + szyna[ i ].position.x ) * sin1 + szyna[ i ].position.y * cos1,
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{ szyna[ i ].normal.x * cos1 + szyna[ i ].normal.y * sin1,
|
||||
-szyna[ i ].normal.x * sin1 + szyna[ i ].normal.y * cos1,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.x,
|
||||
szyna[ i ].texture.y } };
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{ szyna[ i ].normal.x * cos1 + szyna[ i ].normal.y * sin1,
|
||||
-szyna[ i ].normal.x * sin1 + szyna[ i ].normal.y * cos1,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.s,
|
||||
szyna[ i ].texture.t } };
|
||||
|
||||
Left[ 11 - i ] = {
|
||||
Left[ pointcount - 1 - i ] = {
|
||||
// position
|
||||
{(-fHTW - szyna[ i ].position.x ) * cos1 + szyna[ i ].position.y * sin1,
|
||||
-(-fHTW - szyna[ i ].position.x ) * sin1 + szyna[ i ].position.y * cos1,
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{-szyna[ i ].normal.x * cos1 + szyna[ i ].normal.y * sin1,
|
||||
szyna[ i ].normal.x * sin1 + szyna[ i ].normal.y * cos1,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.x,
|
||||
szyna[ i ].texture.y } };
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{-szyna[ i ].normal.x * cos1 + szyna[ i ].normal.y * sin1,
|
||||
szyna[ i ].normal.x * sin1 + szyna[ i ].normal.y * cos1,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.s,
|
||||
szyna[ i ].texture.t } };
|
||||
|
||||
if( iTrapezoid == 0 ) { continue; }
|
||||
// trapez albo przechyłki, to oddzielne punkty na końcu
|
||||
|
||||
Right[ 12 + i ] = {
|
||||
// trapez albo przechyłki, to oddzielne punkty na końcu
|
||||
Right[ pointcount + i ] = {
|
||||
// position
|
||||
{( fHTW + szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2,
|
||||
-( fHTW + szyna[ i ].position.x ) * sin2 + szyna[ i ].position.y * cos2,
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{ szyna[ i ].normal.x * cos2 + szyna[ i ].normal.y * sin2,
|
||||
-szyna[ i ].normal.x * sin2 + szyna[ i ].normal.y * cos2,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.x,
|
||||
szyna[ i ].texture.y } };
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{ szyna[ i ].normal.x * cos2 + szyna[ i ].normal.y * sin2,
|
||||
-szyna[ i ].normal.x * sin2 + szyna[ i ].normal.y * cos2,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.s,
|
||||
szyna[ i ].texture.t } };
|
||||
|
||||
Left[ 23 - i ] = {
|
||||
Left[ pointcount * 2 - 1 - i ] = {
|
||||
// position
|
||||
{(-fHTW - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2,
|
||||
-(-fHTW - szyna[ i ].position.x ) * sin2 + szyna[ i ].position.y * cos2,
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{-szyna[ i ].normal.x * cos2 + szyna[ i ].normal.y * sin2,
|
||||
szyna[ i ].normal.x * sin2 + szyna[ i ].normal.y * cos2,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.x,
|
||||
szyna[ i ].texture.y } };
|
||||
szyna[ i ].position.z},
|
||||
// normal
|
||||
{-szyna[ i ].normal.x * cos2 + szyna[ i ].normal.y * sin2,
|
||||
szyna[ i ].normal.x * sin2 + szyna[ i ].normal.y * cos2,
|
||||
szyna[ i ].normal.z },
|
||||
// texture
|
||||
{ szyna[ i ].texture.s,
|
||||
szyna[ i ].texture.t } };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2406,37 +2514,43 @@ TTrack::create_track_blade_profile( gfx::vertex_array &Right, gfx::vertex_array
|
||||
sin2 { std::sin( roll2 ) },
|
||||
cos2 { std::cos( roll2 ) };
|
||||
|
||||
auto const pointcount { 24 };
|
||||
Right.resize( pointcount );
|
||||
Left.resize( pointcount );
|
||||
auto const &railprofile { track_rail_profile( m_profile1.second ) };
|
||||
// NOTE: rail profile defines both regular rail and switch blade profiles, so we halve total point count
|
||||
auto const pointcount { railprofile.size() / 2 };
|
||||
|
||||
Right.resize( pointcount * 2 );
|
||||
Left.resize( pointcount * 2 );
|
||||
|
||||
auto const *szyna { railprofile.data() };
|
||||
auto const *iglica { szyna + pointcount };
|
||||
|
||||
glm::vec3 const flipxvalue { -1, 1, 1 };
|
||||
for( int i = 0; i < 12; ++i ) {
|
||||
for( int i = 0; i < pointcount; ++i ) {
|
||||
|
||||
Right[ i ] = {
|
||||
{+( fHTW + iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1,
|
||||
-( fHTW + iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1,
|
||||
0.f},
|
||||
{iglica[ i ].normal},
|
||||
{iglica[ i ].texture.x, 0.f} };
|
||||
Right[ i + 12 ] = {
|
||||
{iglica[ i ].texture.s, 0.f} };
|
||||
Right[ i + pointcount ] = {
|
||||
{+( fHTW2 + szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2,
|
||||
-( fHTW2 + szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2,
|
||||
-( fHTW2 + szyna[ i ].position.x ) * sin2 + szyna[ i ].position.y * cos2,
|
||||
0.f},
|
||||
{szyna[ i ].normal},
|
||||
{szyna[ i ].texture.x, 0.f} };
|
||||
Left[ 11 - i ] = {
|
||||
{szyna[ i ].texture.s, 0.f} };
|
||||
Left[ pointcount - 1 - i ] = {
|
||||
{ ( -fHTW - iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1,
|
||||
-( -fHTW - iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1,
|
||||
0.f},
|
||||
{iglica[ i ].normal * flipxvalue},
|
||||
{iglica[ i ].texture.x, 0.f} };
|
||||
Left[ 23 - i ] = {
|
||||
{iglica[ i ].texture.s, 0.f} };
|
||||
Left[ pointcount * 2 - 1 - i ] = {
|
||||
{ ( -fHTW2 - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2,
|
||||
-( -fHTW2 - szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2,
|
||||
-( -fHTW2 - szyna[ i ].position.x ) * sin2 + szyna[ i ].position.y * cos2,
|
||||
0.f},
|
||||
{szyna[ i ].normal * flipxvalue},
|
||||
{szyna[ i ].texture.x, 0.f} };
|
||||
{szyna[ i ].texture.s, 0.f} };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2520,7 +2634,7 @@ TTrack::create_track_bed_profile( gfx::vertex_array &Output, TTrack const *Previ
|
||||
Output.resize( pointcount );
|
||||
// potentially retrieve texture length override from the assigned material
|
||||
auto const texturelength { texture_length( copy_adjacent_trackbed_material() ) };
|
||||
auto const railheight { 0.18f };
|
||||
auto const railheight { std::abs( track_rail_profile( m_profile1.second ).front().position.y ) };
|
||||
if( texturelength == 4.f ) {
|
||||
// stare mapowanie z różną gęstością pikseli i oddzielnymi teksturami na każdy profil
|
||||
auto const normalx = std::cos( glm::radians( 75.f ) );
|
||||
@@ -3231,6 +3345,8 @@ path_table::InitTracks() {
|
||||
|
||||
isolated = isolated->Next();
|
||||
}
|
||||
|
||||
TTrack::fetch_default_profiles();
|
||||
}
|
||||
|
||||
// legacy method, sends list of occupied paths over network
|
||||
|
||||
15
Track.h
15
Track.h
@@ -170,6 +170,7 @@ private:
|
||||
// TODO: store material names as strings, for lossless serialization and export
|
||||
material_handle m_material1 = 0; // tekstura szyn albo nawierzchni
|
||||
material_handle m_material2 = 0; // tekstura automatycznej podsypki albo pobocza
|
||||
std::pair<std::string, int> m_profile1 {}; // profile of geometry chunks textured with texture 1
|
||||
using geometryhandle_sequence = std::vector<gfx::geometry_handle>;
|
||||
geometryhandle_sequence Geometry1; // geometry chunks textured with texture 1
|
||||
geometryhandle_sequence Geometry2; // geometry chunks textured with texture 2
|
||||
@@ -293,8 +294,13 @@ public:
|
||||
double VelocityGet();
|
||||
void ConnectionsLog();
|
||||
bool DoubleSlip() const;
|
||||
static void fetch_default_profiles();
|
||||
|
||||
private:
|
||||
// types
|
||||
using profiles_array = std::vector<gfx::vertex_array>;
|
||||
using profiles_map = std::unordered_map<std::string, int>;
|
||||
// methods
|
||||
// radius() subclass details, calculates node's bounding radius
|
||||
float radius_();
|
||||
// serialize() subclass details, sends content of the subclass to provided stream
|
||||
@@ -303,6 +309,12 @@ private:
|
||||
void deserialize_( std::istream &Input );
|
||||
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
|
||||
void export_as_text_( std::ostream &Output ) const;
|
||||
// locates specified profile in the profile database, potentially loading it from a file
|
||||
static std::pair<std::string, int> fetch_track_rail_profile( std::string const &Profile );
|
||||
// loads content of specified file and converts it into a vertex array
|
||||
static gfx::vertex_array deserialize_profile( std::string const &Profile );
|
||||
// provides direct access to vertex data of specified profile
|
||||
static gfx::vertex_array const & track_rail_profile( int const Profile );
|
||||
// returns texture length for specified material
|
||||
float texture_length( material_handle const Material );
|
||||
// creates profile for a part of current path
|
||||
@@ -312,6 +324,9 @@ private:
|
||||
void create_track_bed_profile( gfx::vertex_array &Output, TTrack const *Previous, TTrack const *Next );
|
||||
void create_road_profile( gfx::vertex_array &Output, bool const Forcetransition = false );
|
||||
void create_road_side_profile( gfx::vertex_array &Right, gfx::vertex_array &Left, gfx::vertex_array const &Road, bool const Forcetransition = false );
|
||||
// members
|
||||
static profiles_array m_profiles; // shared database of path element profiles
|
||||
static profiles_map m_profilesmap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user