mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
build 181016. freespot color override, vehicle start jolt sound, switch trackbed generation fixes
This commit is contained in:
@@ -413,11 +413,9 @@ void TAnimContainer::EventAssign(basic_event *ev)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TAnimModel::TAnimModel( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {
|
||||
// TODO: wrap these in a tuple and move to underlying model
|
||||
for( int index = 0; index < iMaxNumLights; ++index ) {
|
||||
LightsOn[ index ] = LightsOff[ index ] = nullptr; // normalnie nie ma
|
||||
lsLights[ index ] = ls_Off; // a jeśli są, to wyłączone
|
||||
}
|
||||
|
||||
m_lightcolors.fill( glm::vec3{ -1.f } );
|
||||
m_lightopacities.fill( 1.f );
|
||||
}
|
||||
|
||||
TAnimModel::~TAnimModel()
|
||||
@@ -498,20 +496,44 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
||||
if (LightsOn[i] || LightsOff[i]) // Ra: zlikwidowałem wymóg istnienia obu
|
||||
iNumLights = i + 1;
|
||||
|
||||
if ( parser->getToken<std::string>() == "lights" )
|
||||
{
|
||||
int i = 0;
|
||||
std::string token = parser->getToken<std::string>();
|
||||
while( ( token != "" )
|
||||
&& ( token != "endmodel" ) ) {
|
||||
std::string token;
|
||||
do {
|
||||
token = parser->getToken<std::string>();
|
||||
|
||||
LightSet( i, std::stof( token ) ); // stan światła jest liczbą z ułamkiem
|
||||
++i;
|
||||
if( token == "lights" ) {
|
||||
auto i{ 0 };
|
||||
while( ( false == ( token = parser->getToken<std::string>() ).empty() )
|
||||
&& ( token != "lightcolors" )
|
||||
&& ( token != "endmodel" ) ) {
|
||||
|
||||
if( i < iNumLights ) {
|
||||
// stan światła jest liczbą z ułamkiem
|
||||
LightSet( i, std::stof( token ) );
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if( token == "lightcolors" ) {
|
||||
auto i{ 0 };
|
||||
while( ( false == ( token = parser->getToken<std::string>() ).empty() )
|
||||
&& ( token != "lights" )
|
||||
&& ( token != "endmodel" ) ) {
|
||||
|
||||
if( ( i < iNumLights )
|
||||
&& ( token != "-1" ) ) { // -1 leaves the default color intact
|
||||
auto const lightcolor { std::stoi( token, 0, 16 ) };
|
||||
m_lightcolors[i] = {
|
||||
( ( lightcolor >> 16 ) & 0xff ) / 255.f,
|
||||
( ( lightcolor >> 8 ) & 0xff ) / 255.f,
|
||||
( ( lightcolor ) & 0xff ) / 255.f };
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
} while( ( false == token.empty() )
|
||||
&& ( token != "endmodel" ) );
|
||||
|
||||
token = "";
|
||||
parser->getTokens(); *parser >> token;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -683,6 +705,10 @@ void TAnimModel::RaPrepare()
|
||||
if (LightsOff[i])
|
||||
LightsOff[i]->iVisible = !state;
|
||||
}
|
||||
// potentially modify freespot colors
|
||||
if( LightsOn[i] ) {
|
||||
LightsOn[i]->SetDiffuseOverride( m_lightcolors[i], true);
|
||||
}
|
||||
}
|
||||
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( this ); //żeby nie robić cudzych animacji
|
||||
TSubModel::pasText = &asText; // przekazanie tekstu do wyświetlacza (!!!! do przemyślenia)
|
||||
|
||||
16
AnimModel.h
16
AnimModel.h
@@ -179,19 +179,19 @@ private:
|
||||
// members
|
||||
TAnimContainer *pRoot { nullptr }; // pojemniki sterujące, tylko dla aniomowanych submodeli
|
||||
TModel3d *pModel { nullptr };
|
||||
// double fBlinkTimer { 0.0 };
|
||||
int iNumLights { 0 };
|
||||
TSubModel *LightsOn[ iMaxNumLights ]; // Ra: te wskaźniki powinny być w ramach TModel3d
|
||||
TSubModel *LightsOff[ iMaxNumLights ];
|
||||
glm::vec3 vAngle; // bazowe obroty egzemplarza względem osi
|
||||
material_data m_materialdata;
|
||||
|
||||
std::string asText; // tekst dla wyświetlacza znakowego
|
||||
TAnimAdvanced *pAdvanced { nullptr };
|
||||
// TODO: wrap into a light state struct
|
||||
float lsLights[ iMaxNumLights ];
|
||||
std::array<float, iMaxNumLights> m_lighttimers { 0.f };
|
||||
std::array<float, iMaxNumLights> m_lightopacities { 1.f };
|
||||
// TODO: wrap into a light state struct, remove fixed element count
|
||||
int iNumLights { 0 };
|
||||
std::array<TSubModel *, iMaxNumLights> LightsOn {}; // Ra: te wskaźniki powinny być w ramach TModel3d
|
||||
std::array<TSubModel *, iMaxNumLights> LightsOff {};
|
||||
std::array<float, iMaxNumLights> lsLights {}; // ls_Off
|
||||
std::array<glm::vec3, iMaxNumLights> m_lightcolors; // -1 in constructor
|
||||
std::array<float, iMaxNumLights> m_lighttimers {};
|
||||
std::array<float, iMaxNumLights> m_lightopacities; // {1} in constructor
|
||||
float fOnTime { 1.f / 2 };// { 60.f / 45.f / 2 };
|
||||
float fOffTime { 1.f / 2 };// { 60.f / 45.f / 2 }; // były stałymi, teraz mogą być zmienne dla każdego egzemplarza
|
||||
float fTransitionTime { fOnTime * 0.9f }; // time
|
||||
|
||||
23
DynObj.cpp
23
DynObj.cpp
@@ -3932,6 +3932,13 @@ void TDynamicObject::RenderSounds() {
|
||||
|
||||
if( Global.iPause != 0 ) { return; }
|
||||
|
||||
if( ( m_startjoltplayed )
|
||||
&& ( ( MoverParameters->AccSVBased < 0.01 )
|
||||
|| ( GetVelocity() < 0.01 ) ) ) {
|
||||
// if the vehicle comes to a stop set the movement jolt to play when it starts moving again
|
||||
m_startjoltplayed = false;
|
||||
}
|
||||
|
||||
double const dt{ Timer::GetDeltaRenderTime() };
|
||||
double volume{ 0.0 };
|
||||
double frequency{ 1.0 };
|
||||
@@ -4387,6 +4394,17 @@ void TDynamicObject::RenderSounds() {
|
||||
rscurve.stop();
|
||||
}
|
||||
|
||||
// movement start jolt
|
||||
if( false == m_startjoltplayed ) {
|
||||
auto const velocity { GetVelocity() };
|
||||
if( ( MoverParameters->AccSVBased > 0.2 )
|
||||
&& ( velocity > 2.5 )
|
||||
&& ( velocity < 15.0 ) ) {
|
||||
m_startjolt.play( sound_flags::exclusive );
|
||||
m_startjoltplayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// McZapkie! - to wazne - SoundFlag wystawiane jest przez moje moduly
|
||||
// gdy zachodza pewne wydarzenia komentowane dzwiekiem.
|
||||
if( TestFlag( MoverParameters->SoundFlag, sound::pneumatic ) ) {
|
||||
@@ -5799,6 +5817,11 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
couplersounds.dsbBufferClamp_loud = bufferclash;
|
||||
}
|
||||
}
|
||||
else if( token == "startjolt:" ) {
|
||||
// movement start jolt
|
||||
m_startjolt.deserialize( parser, sound_type::single );
|
||||
m_startjolt.owner( this );
|
||||
}
|
||||
|
||||
} while( token != "" );
|
||||
|
||||
|
||||
2
DynObj.h
2
DynObj.h
@@ -426,6 +426,8 @@ private:
|
||||
sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
||||
sound_source sSand { sound_placement::external };
|
||||
// moving part and other external sounds
|
||||
sound_source m_startjolt { sound_placement::general }; // movement start jolt, played once on initial acceleration at slow enough speed
|
||||
bool m_startjoltplayed { false };
|
||||
std::array<coupler_sounds, 2> m_couplersounds; // always front and rear
|
||||
std::vector<pantograph_sounds> m_pantographsounds; // typically 2 but can be less (or more?)
|
||||
std::vector<door_sounds> m_doorsounds; // can expect symmetrical arrangement, but don't count on it
|
||||
|
||||
@@ -1485,7 +1485,7 @@ lights_event::deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||
}
|
||||
while( lightidx < lightcountlimit ) {
|
||||
// HACK: mark unspecified lights with magic value
|
||||
m_lights[ lightidx++ ] = -2.f;
|
||||
m_lights[ lightidx++ ] = std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1498,11 +1498,11 @@ lights_event::run_() {
|
||||
if( targetmodel == nullptr ) { continue; }
|
||||
// event effect code
|
||||
for( auto lightidx = 0; lightidx < iMaxNumLights; ++lightidx ) {
|
||||
if( m_lights[ lightidx ] == -2.f ) {
|
||||
if( m_lights[ lightidx ] == std::numeric_limits<float>::quiet_NaN() ) {
|
||||
// processed all supplied values, bail out
|
||||
break;
|
||||
}
|
||||
if( m_lights[ lightidx ] >= 0.f ) {
|
||||
if( m_lights[ lightidx ] != -1.f ) {
|
||||
// -1 zostawia bez zmiany
|
||||
targetmodel->LightSet(
|
||||
lightidx,
|
||||
@@ -1518,7 +1518,7 @@ lights_event::export_as_text_( std::ostream &Output ) const {
|
||||
|
||||
auto lightidx{ 0 };
|
||||
while( ( lightidx < iMaxNumLights )
|
||||
&& ( m_lights[ lightidx ] > -2.0 ) ) {
|
||||
&& ( m_lights[ lightidx ] != std::numeric_limits<float>::quiet_NaN() ) ) {
|
||||
Output << m_lights[ lightidx ] << ' ';
|
||||
++lightidx;
|
||||
}
|
||||
|
||||
19
Model3d.cpp
19
Model3d.cpp
@@ -71,6 +71,25 @@ void TSubModel::Name(std::string const &Name)
|
||||
pName = Name;
|
||||
};
|
||||
|
||||
// sets rgb components of diffuse color override to specified value
|
||||
void
|
||||
TSubModel::SetDiffuseOverride( glm::vec3 const &Color, bool const Includechildren, bool const Includesiblings ) {
|
||||
|
||||
if( eType == TP_FREESPOTLIGHT ) {
|
||||
DiffuseOverride = Color;
|
||||
}
|
||||
if( true == Includesiblings ) {
|
||||
auto sibling { this };
|
||||
while( ( sibling = sibling->Next ) != nullptr ) {
|
||||
sibling->SetDiffuseOverride( Color, Includechildren, false ); // no need for all siblings to duplicate the work
|
||||
}
|
||||
}
|
||||
if( ( true == Includechildren )
|
||||
&& ( Child != nullptr ) ) {
|
||||
Child->SetDiffuseOverride( Color, Includechildren, true ); // node's children include child's siblings and children
|
||||
}
|
||||
}
|
||||
|
||||
// sets visibility level (alpha component) to specified value
|
||||
void
|
||||
TSubModel::SetVisibilityLevel( float const Level, bool const Includechildren, bool const Includesiblings ) {
|
||||
|
||||
@@ -104,6 +104,7 @@ private:
|
||||
f4Diffuse { 1.0f,1.0f,1.0f,1.0f },
|
||||
f4Specular { 0.0f,0.0f,0.0f,1.0f },
|
||||
f4Emision { 1.0f,1.0f,1.0f,1.0f };
|
||||
glm::vec3 DiffuseOverride { -1.f };
|
||||
normalization m_normalizenormals { normalization::none }; // indicates vectors need to be normalized due to scaling etc
|
||||
float fWireSize { 0.0f }; // nie używane, ale wczytywane
|
||||
float fSquareMaxDist { 10000.0f * 10000.0f };
|
||||
@@ -192,6 +193,8 @@ public:
|
||||
int Flags() const { return iFlags; };
|
||||
void UnFlagNext() { iFlags &= 0x00FFFFFF; };
|
||||
void ColorsSet( glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular );
|
||||
// sets rgb components of diffuse color override to specified value
|
||||
void SetDiffuseOverride( glm::vec3 const &Color, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
// sets visibility level (alpha component) to specified value
|
||||
void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
// sets light level (alpha component of illumination color) to specified value
|
||||
|
||||
29
Track.cpp
29
Track.cpp
@@ -3074,7 +3074,7 @@ path_table::InitTracks() {
|
||||
auto const trackname { track->name() };
|
||||
|
||||
switch (track->eType) {
|
||||
// TODO: re-enable
|
||||
|
||||
case tt_Table: {
|
||||
// obrotnicę też łączymy na starcie z innymi torami
|
||||
// szukamy modelu o tej samej nazwie
|
||||
@@ -3169,10 +3169,6 @@ path_table::InitTracks() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( Global.CreateSwitchTrackbeds ) {
|
||||
// when autogenerating trackbeds, try to restore trackbeds for tracks neighbouring double slips
|
||||
track->copy_adjacent_trackbed_material();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tt_Switch: {
|
||||
@@ -3180,10 +3176,6 @@ path_table::InitTracks() {
|
||||
track->AssignForcedEvents(
|
||||
simulation::Events.FindEvent( trackname + ":forced+" ),
|
||||
simulation::Events.FindEvent( trackname + ":forced-" ) );
|
||||
if( Global.CreateSwitchTrackbeds ) {
|
||||
// when autogenerating trackbeds, try to restore trackbeds for tracks neighbouring double slips
|
||||
track->copy_adjacent_trackbed_material();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -3199,6 +3191,25 @@ path_table::InitTracks() {
|
||||
}
|
||||
}
|
||||
|
||||
if( Global.CreateSwitchTrackbeds ) {
|
||||
// do this after all connections are established, otherwise missing switch connections
|
||||
// may prevent us from obtaining texture data for basic track from 'across' a switch
|
||||
for( auto *track : m_items ) {
|
||||
// try to assign missing trackbed materials for switches and tracks neighbouring switches
|
||||
switch( track->eType ) {
|
||||
|
||||
case tt_Normal:
|
||||
case tt_Switch: {
|
||||
track->copy_adjacent_trackbed_material();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
}
|
||||
|
||||
auto *isolated = TIsolated::Root();
|
||||
while( isolated ) {
|
||||
|
||||
|
||||
35
renderer.cpp
35
renderer.cpp
@@ -2579,6 +2579,11 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
auto const unitstate = m_unitstate;
|
||||
switch_units( m_unitstate.diffuse, false, false );
|
||||
|
||||
auto const *lightcolor {
|
||||
Submodel->DiffuseOverride.r < 0.f ? // -1 indicates no override
|
||||
glm::value_ptr( Submodel->f4Diffuse ) :
|
||||
glm::value_ptr( Submodel->DiffuseOverride ) };
|
||||
|
||||
// main draw call
|
||||
if( Global.Overcast > 1.f ) {
|
||||
// fake fog halo
|
||||
@@ -2587,11 +2592,12 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
2.f, 1.f,
|
||||
clamp<float>( Global.fFogEnd / 2000, 0.f, 1.f ) )
|
||||
* std::max( 1.f, Global.Overcast ) };
|
||||
|
||||
::glPointSize( pointsize * fogfactor );
|
||||
::glColor4f(
|
||||
Submodel->f4Diffuse[ 0 ],
|
||||
Submodel->f4Diffuse[ 1 ],
|
||||
Submodel->f4Diffuse[ 2 ],
|
||||
lightcolor[ 0 ],
|
||||
lightcolor[ 1 ],
|
||||
lightcolor[ 2 ],
|
||||
Submodel->fVisible * std::min( 1.f, lightlevel ) * 0.5f );
|
||||
::glDepthMask( GL_FALSE );
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
@@ -2599,9 +2605,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
}
|
||||
::glPointSize( pointsize );
|
||||
::glColor4f(
|
||||
Submodel->f4Diffuse[ 0 ],
|
||||
Submodel->f4Diffuse[ 1 ],
|
||||
Submodel->f4Diffuse[ 2 ],
|
||||
lightcolor[ 0 ],
|
||||
lightcolor[ 1 ],
|
||||
lightcolor[ 2 ],
|
||||
Submodel->fVisible * std::min( 1.f, lightlevel ) );
|
||||
m_geometry.draw( Submodel->m_geometry );
|
||||
|
||||
@@ -3507,7 +3513,6 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
::glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT );
|
||||
|
||||
Bind_Texture( m_glaretexture );
|
||||
::glColor4f( Submodel->f4Diffuse[ 0 ], Submodel->f4Diffuse[ 1 ], Submodel->f4Diffuse[ 2 ], Submodel->fVisible * glarelevel );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_FOG );
|
||||
::glDepthMask( GL_FALSE );
|
||||
@@ -3518,12 +3523,19 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
::glTranslatef( lightcenter.x, lightcenter.y, lightcenter.z ); // początek układu zostaje bez zmian
|
||||
::glRotated( std::atan2( lightcenter.x, lightcenter.z ) * 180.0 / M_PI, 0.0, 1.0, 0.0 ); // jedynie obracamy w pionie o kąt
|
||||
// disable shadows so they don't obstruct self-lit items
|
||||
/*
|
||||
setup_shadow_color( colors::white );
|
||||
*/
|
||||
auto const unitstate = m_unitstate;
|
||||
switch_units( unitstate.diffuse, false, false );
|
||||
|
||||
auto const *lightcolor {
|
||||
Submodel->DiffuseOverride.r < 0.f ? // -1 indicates no override
|
||||
glm::value_ptr( Submodel->f4Diffuse ) :
|
||||
glm::value_ptr( Submodel->DiffuseOverride ) };
|
||||
::glColor4f(
|
||||
lightcolor[ 0 ],
|
||||
lightcolor[ 1 ],
|
||||
lightcolor[ 2 ],
|
||||
Submodel->fVisible * glarelevel );
|
||||
|
||||
// main draw call
|
||||
m_geometry.draw( m_billboardgeometry );
|
||||
/*
|
||||
@@ -3535,9 +3547,6 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
// ...etc instead IF we had easy access to camera's forward and right vectors. TODO: check if Camera matrix is accessible
|
||||
*/
|
||||
// post-render cleanup
|
||||
/*
|
||||
setup_shadow_color( m_shadowcolor );
|
||||
*/
|
||||
switch_units( unitstate.diffuse, unitstate.shadows, unitstate.reflections );
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
13
scene.cpp
13
scene.cpp
@@ -1157,16 +1157,21 @@ basic_region::RadioStop( glm::dvec3 const &Location ) {
|
||||
}
|
||||
|
||||
std::vector<std::string> switchtrackbedtextures {
|
||||
"rkpd34r190-tpd1",
|
||||
"rkpd34r190-tpd2",
|
||||
"rkpd34r190-tpd-oil2",
|
||||
"rozkrz8r150-1pods-new",
|
||||
"rozkrz8r150-2pods-new",
|
||||
"rozkrz34r150-tpbps-new2",
|
||||
"rozkrz34r150-tpd1",
|
||||
"rkpd34r190-tpd1",
|
||||
"rkpd34r190-tpd2",
|
||||
"rkpd34r190-tpd-oil2",
|
||||
"rz-1200-185",
|
||||
"zwr41r500",
|
||||
"zwrot-tpd-oil1",
|
||||
"zwrot34r300pods-new" };
|
||||
"zwrot34r300pods",
|
||||
"zwrot34r300pods-new",
|
||||
"zwrot34r300pods-old",
|
||||
"zwrotl65r1200pods-new",
|
||||
"zwrotp65r1200pods-new" };
|
||||
|
||||
void
|
||||
basic_region::insert( shape_node Shape, scratch_data &Scratchpad, bool const Transform ) {
|
||||
|
||||
Reference in New Issue
Block a user