build 181005. automatic switch trackbed generation

This commit is contained in:
tmj-fstate
2018-10-05 21:57:49 +02:00
parent 682514fe7b
commit 8b1a26632d
12 changed files with 879 additions and 784 deletions

View File

@@ -2689,7 +2689,7 @@ void TDynamicObject::LoadUpdate() {
}
else if( MoverParameters->LoadAmount == 0 ) {
// nie ma ładunku
MoverParameters->AssignLoad( "" );
// MoverParameters->AssignLoad( "" );
mdLoad = nullptr;
// erase bindings between lowpoly sections and potential load chunks placed inside them
update_load_sections();

View File

@@ -369,6 +369,11 @@ global_settings::ConfigParse(cParser &Parser) {
Parser >> splinefidelity;
SplineFidelity = clamp( splinefidelity, 1.f, 4.f );
}
else if( token == "createswitchtrackbeds" ) {
// podwójna jasność ambient
Parser.getTokens();
Parser >> CreateSwitchTrackbeds;
}
else if( token == "gfx.resource.sweep" ) {
Parser.getTokens();

View File

@@ -51,6 +51,7 @@ struct global_settings {
// settings
// filesystem
bool bLoadTraction{ true };
bool CreateSwitchTrackbeds { true };
std::string szTexturesTGA{ ".tga" }; // lista tekstur od TGA
std::string szTexturesDDS{ ".dds" }; // lista tekstur od DDS
std::string szDefaultExt{ szTexturesDDS };

View File

@@ -6640,15 +6640,14 @@ TMoverParameters::AssignLoad( std::string const &Name, float const Amount ) {
}
}
// can't mix load types, at least for the time being
if( ( LoadAmount > 0 ) && ( LoadType.name != Name ) ) { return false; }
if( Name.empty() ) {
// empty the vehicle
// empty the vehicle if requested
LoadType = load_attributes();
LoadAmount = 0.f;
return true;
}
// can't mix load types, at least for the time being
if( ( LoadAmount > 0 ) && ( LoadType.name != Name ) ) { return false; }
for( auto const &loadattributes : LoadAttributes ) {
if( Name == loadattributes.name ) {

View File

@@ -114,9 +114,6 @@ bool TSegment::Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, M
ErrorLog( "Bad track: zero length spline \"" + pOwner->name() + "\" (location: " + to_string( glm::dvec3{ Point1 } ) + ")" );
fLength = 0.01; // crude workaround TODO: fix this properly
/*
return false; // zerowe nie mogą być
*/
}
fStoop = std::atan2((Point2.y - Point1.y), fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
@@ -128,13 +125,12 @@ bool TSegment::Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, M
// NOTE: a workaround for too short switches (less than 3 segments) messing up animation/generation of blades
fStep = fLength / ( 3.0 * Global.SplineFidelity );
}
iSegCount = static_cast<int>( std::ceil( fLength / fStep ) ); // potrzebne do VBO
/*
// iSegCount = static_cast<int>( std::ceil( fLength / fStep ) ); // potrzebne do VBO
iSegCount = (
pOwner->eType == tt_Switch ?
6 * Global.SplineFidelity :
static_cast<int>( std::ceil( fLength / fStep ) ) ); // potrzebne do VBO
*/
fStep = fLength / iSegCount; // update step to equalize size of individual pieces
fTsBuffer.resize( iSegCount + 1 );
@@ -378,7 +374,7 @@ 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::basic_vertex *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, 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
@@ -459,7 +455,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
Output.emplace_back(
pt,
glm::normalize( norm ),
glm::vec2 { ( jmm1 * ShapePoints[ j ].texture.x + m1 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv1 } );
glm::vec2 { 1.f - ( jmm1 * ShapePoints[ j ].texture.x + m1 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv1 } );
}
if( p ) // jeśli jest wskaźnik do tablicy
if( *p )
@@ -479,7 +475,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
Output.emplace_back(
pt,
glm::normalize( norm ),
glm::vec2 { ( jmm2 * ShapePoints[ j ].texture.x + m2 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv2 } );
glm::vec2 { 1.f - ( jmm2 * ShapePoints[ j ].texture.x + m2 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv2 } );
}
if( p ) // jeśli jest wskaźnik do tablicy
if( *p )
@@ -503,7 +499,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
Output.emplace_back(
pt,
glm::normalize( norm ),
glm::vec2 { ShapePoints[ j ].texture.x / texturescale, tv1 } );
glm::vec2 { 1.f - ShapePoints[ j ].texture.x / texturescale, tv1 } );
pt = parallel2 * ShapePoints[ j ].position.x + pos2;
pt.y += ShapePoints[ j ].position.y;
@@ -514,7 +510,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
Output.emplace_back(
pt,
glm::normalize( norm ),
glm::vec2 { ShapePoints[ j ].texture.x / texturescale, tv2 } );
glm::vec2 { 1.f - ShapePoints[ j ].texture.x / texturescale, tv2 } );
}
}
}

View File

@@ -116,7 +116,7 @@ public:
r2 = fRoll2; }
bool
RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Origin, gfx::basic_vertex 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, float fOffsetX = 0.f, glm::vec3 **p = nullptr, bool bRender = true);
/*
void
Render();

1517
Track.cpp

File diff suppressed because it is too large Load Diff

14
Track.h
View File

@@ -93,6 +93,9 @@ class TSwitchExtension
*evMinus = nullptr; // zdarzenia sygnalizacji rozprucia
float fVelocity = -1.0; // maksymalne ograniczenie prędkości (ustawianej eventem)
Math3D::vector3 vTrans; // docelowa translacja przesuwnicy
material_handle m_material3 = 0; // texture of auto generated switch trackbed
gfx::geometry_handle m_geometry3; // geometry of auto generated switch trackbed
};
class TIsolated
@@ -134,7 +137,7 @@ private:
// members
int iAxles { 0 }; // ilość osi na odcinkach obsługiwanych przez obiekt
TIsolated *pNext { nullptr }; // odcinki izolowane są trzymane w postaci listy jednikierunkowej
TIsolated *pParent { nullptr }; // optional parent piece, collecting data from its children
TIsolated *pParent { nullptr }; // optional parent piece, receiving data from its children
static TIsolated *pRoot; // początek listy
};
@@ -222,6 +225,7 @@ public:
void ConnectPrevNext(TTrack *pNewPrev, int typ);
void ConnectNextPrev(TTrack *pNewNext, int typ);
void ConnectNextNext(TTrack *pNewNext, int typ);
material_handle copy_adjacent_trackbed_material( TTrack const *Exclude = nullptr );
inline double Length() const {
return Segment->GetLength(); };
inline std::shared_ptr<TSegment> CurrentSegment() const {
@@ -288,6 +292,7 @@ public:
void VelocitySet(float v);
double VelocityGet();
void ConnectionsLog();
bool DoubleSlip() const;
private:
// radius() subclass details, calculates node's bounding radius
@@ -300,6 +305,13 @@ private:
void export_as_text_( std::ostream &Output ) const;
// returns texture length for specified material
float texture_length( material_handle const Material );
// creates profile for a part of current path
void create_rail_profile( gfx::vertex_array &Right, gfx::vertex_array &Left );
void create_blade_profile( gfx::vertex_array &Right, gfx::vertex_array &Left );
void create_trackbed_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_sidewalk_profile( gfx::vertex_array &Right, gfx::vertex_array &Left, gfx::vertex_array const &Road, bool const Forcetransition = false );
void create_switch_trackbed( gfx::vertex_array &Output );
};

View File

@@ -2624,7 +2624,9 @@ void
opengl_renderer::Render( TTrack *Track ) {
if( ( Track->m_material1 == 0 )
&& ( Track->m_material2 == 0 ) ) {
&& ( Track->m_material2 == 0 )
&& ( ( Track->eType != tt_Switch )
|| ( Track->SwitchExtension->m_material3 == 0 ) ) ) {
return;
}
if( false == Track->m_visible ) {
@@ -2646,6 +2648,11 @@ opengl_renderer::Render( TTrack *Track ) {
Bind_Material( Track->m_material2 );
m_geometry.draw( std::begin( Track->Geometry2 ), std::end( Track->Geometry2 ) );
}
if( ( Track->eType == tt_Switch )
&& ( Track->SwitchExtension->m_material3 != 0 ) ) {
Bind_Material( Track->SwitchExtension->m_material3 );
m_geometry.draw( Track->SwitchExtension->m_geometry3 );
}
setup_environment_light();
break;
}
@@ -2666,6 +2673,11 @@ opengl_renderer::Render( TTrack *Track ) {
Bind_Material( Track->m_material2 );
m_geometry.draw( std::begin( Track->Geometry2 ), std::end( Track->Geometry2 ) );
}
if( ( Track->eType == tt_Switch )
&& ( Track->SwitchExtension->m_material3 != 0 ) ) {
Bind_Material( Track->SwitchExtension->m_material3 );
m_geometry.draw( Track->SwitchExtension->m_geometry3 );
}
break;
}
case rendermode::pickcontrols:
@@ -2692,6 +2704,7 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
}
}
// TODO: render auto generated trackbeds together with regular trackbeds in pass 1, and all rails in pass 2
// first pass, material 1
for( auto first { First }; first != Last; ++first ) {
@@ -2782,6 +2795,53 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
}
}
}
// third pass, material 3
for( auto first { First }; first != Last; ++first ) {
auto const track { *first };
if( track->eType != tt_Switch ) {
continue;
}
if( track->SwitchExtension->m_material3 == 0 ) {
continue;
}
if( false == track->m_visible ) {
continue;
}
switch( m_renderpass.draw_mode ) {
case rendermode::color:
case rendermode::reflections: {
if( track->eEnvironment != e_flat ) {
setup_environment_light( track->eEnvironment );
}
Bind_Material( track->SwitchExtension->m_material3 );
m_geometry.draw( track->SwitchExtension->m_geometry3 );
if( track->eEnvironment != e_flat ) {
// restore default lighting
setup_environment_light();
}
break;
}
case rendermode::shadows: {
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|| ( ( track->iCategoryFlag == 1 )
&& ( track->eType != tt_Normal ) ) ) {
// shadows are only calculated for high enough trackbeds
continue;
}
Bind_Material( track->SwitchExtension->m_material3 );
m_geometry.draw( track->SwitchExtension->m_geometry3 );
break;
}
case rendermode::pickscenery: // pick scenery mode uses piece-by-piece approach
case rendermode::pickcontrols:
default: {
break;
}
}
}
// post-render reset
switch( m_renderpass.draw_mode ) {
case rendermode::shadows: {
@@ -3058,7 +3118,7 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
::glLineWidth(
clamp(
0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f,
1.f, 1.5f ) );
1.f, 1.75f ) );
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
::glColor4fv(
glm::value_ptr(

View File

@@ -1156,9 +1156,28 @@ basic_region::RadioStop( glm::dvec3 const &Location ) {
}
}
std::vector<std::string> switchtrackbedtextures {
"rozkrz8r150-1pods-new",
"rozkrz8r150-2pods-new",
"rozkrz34r150-tpbps-new2",
"rozkrz34r150-tpd1",
"rkpd34r190-tpd1",
"rkpd34r190-tpd2",
"rkpd34r190-tpd-oil2" };
void
basic_region::insert( shape_node Shape, scratch_data &Scratchpad, bool const Transform ) {
if( Global.CreateSwitchTrackbeds ) {
auto const materialname{ GfxRenderer.Material( Shape.data().material ).name };
for( auto const &switchtrackbedtexture : switchtrackbedtextures ) {
if( materialname.find( switchtrackbedtexture ) != std::string::npos ) {
// geometry with blacklisted texture, part of old switch trackbed; ignore it
return;
}
}
}
// shape might need to be split into smaller pieces, so we create list of nodes instead of just single one
// using deque so we can do single pass iterating and addding generated pieces without invalidating anything
std::deque<shape_node> shapes { Shape };

View File

@@ -433,7 +433,16 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
|| ( nodedata.type == "triangle_strip" )
|| ( nodedata.type == "triangle_fan" ) ) {
if( false == Scratchpad.binary.terrain ) {
auto const skip {
// all shapes will be loaded from the binary version of the file
( true == Scratchpad.binary.terrain )
// crude way to detect fixed switch trackbed geometry
|| ( ( true == Global.CreateSwitchTrackbeds )
&& ( Input.Name().size() >= 15 )
&& ( Input.Name().substr( 0, 11 ) == "scenery/zwr" )
&& ( Input.Name().substr( Input.Name().size() - 4 ) == ".inc" ) ) };
if( false == skip ) {
simulation::Region->insert(
scene::shape_node().import(
@@ -442,7 +451,6 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
true );
}
else {
// all shapes were already loaded from the binary version of the file
skip_until( Input, "endtri" );
}
}

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 18
#define VERSION_MINOR 1001
#define VERSION_MINOR 1005
#define VERSION_REVISION 0