mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 14:49:19 +02:00
heating power source fix, particle color support
This commit is contained in:
2
DynObj.h
2
DynObj.h
@@ -619,7 +619,7 @@ private:
|
|||||||
Axle1.GetTranslation() :
|
Axle1.GetTranslation() :
|
||||||
Axle0.GetTranslation(); };
|
Axle0.GetTranslation(); };
|
||||||
// zwraca tor z aktywną osią
|
// zwraca tor z aktywną osią
|
||||||
inline TTrack * RaTrackGet() const {
|
inline TTrack const * RaTrackGet() const {
|
||||||
return iAxleFirst ?
|
return iAxleFirst ?
|
||||||
Axle1.GetTrack() :
|
Axle1.GetTrack() :
|
||||||
Axle0.GetTrack(); };
|
Axle0.GetTrack(); };
|
||||||
|
|||||||
@@ -1410,7 +1410,13 @@ void TMoverParameters::PowerCouplersCheck( double const Deltatime ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TPowerSource::Main: {
|
case TPowerSource::Main: {
|
||||||
localvoltage = ( true == Mains ? Voltage : 0.0 );
|
// HACK: main circuit can be fed through couplers, so we explicitly check pantograph supply here
|
||||||
|
localvoltage = (
|
||||||
|
true == Mains ?
|
||||||
|
std::max(
|
||||||
|
PantFrontVolt,
|
||||||
|
PantRearVolt ) :
|
||||||
|
0.0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ smoke_source::particle_emitter::deserialize( cParser &Input ) {
|
|||||||
|
|
||||||
if( Input.getToken<std::string>() != "{" ) { return; }
|
if( Input.getToken<std::string>() != "{" ) { return; }
|
||||||
|
|
||||||
std::unordered_map<std::string, float &> const variablemap{
|
std::unordered_map<std::string, float &> const variablemap {
|
||||||
{ "min_inclination:", inclination[ value_limit::min ] },
|
{ "min_inclination:", inclination[ value_limit::min ] },
|
||||||
{ "max_inclination:", inclination[ value_limit::max ] },
|
{ "max_inclination:", inclination[ value_limit::max ] },
|
||||||
{ "min_velocity:", velocity[ value_limit::min ] },
|
{ "min_velocity:", velocity[ value_limit::min ] },
|
||||||
@@ -35,10 +35,22 @@ smoke_source::particle_emitter::deserialize( cParser &Input ) {
|
|||||||
while( ( false == ( ( key = Input.getToken<std::string>( true, "\n\r\t ,;[]" ) ).empty() ) )
|
while( ( false == ( ( key = Input.getToken<std::string>( true, "\n\r\t ,;[]" ) ).empty() ) )
|
||||||
&& ( key != "}" ) ) {
|
&& ( key != "}" ) ) {
|
||||||
|
|
||||||
auto const lookup { variablemap.find( key ) };
|
if( key == "color:" ) {
|
||||||
if( lookup == variablemap.end() ) { continue; }
|
// special case, vec3 attribute type
|
||||||
|
// TODO: variable table, if amount of vector attributes increases
|
||||||
lookup->second = Input.getToken<float>( true, "\n\r\t ,;[]" );
|
color = Input.getToken<glm::vec3>( true, "\n\r\t ,;[]" );
|
||||||
|
color =
|
||||||
|
glm::clamp(
|
||||||
|
color / 255.f,
|
||||||
|
glm::vec3{ 0.f }, glm::vec3{ 1.f } );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// float type attributes
|
||||||
|
auto const lookup { variablemap.find( key ) };
|
||||||
|
if( lookup != variablemap.end() ) {
|
||||||
|
lookup->second = Input.getToken<float>( true, "\n\r\t ,;[]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,14 +121,14 @@ smoke_source::deserialize_mapping( cParser &Input ) {
|
|||||||
void
|
void
|
||||||
smoke_source::initialize() {
|
smoke_source::initialize() {
|
||||||
|
|
||||||
m_particles.reserve(
|
m_max_particles =
|
||||||
// put a cap on number of particles in a single source. TBD, TODO: make it part of he source configuration?
|
// put a cap on number of particles in a single source. TBD, TODO: make it part of he source configuration?
|
||||||
std::min(
|
std::min(
|
||||||
static_cast<int>( 500 * Global.SmokeFidelity ),
|
static_cast<int>( 500 * Global.SmokeFidelity ),
|
||||||
// NOTE: given nature of the smoke we're presuming opacity decreases over time and the particle is killed when it reaches 0
|
// NOTE: given nature of the smoke we're presuming opacity decreases over time and the particle is killed when it reaches 0
|
||||||
// this gives us estimate of longest potential lifespan of single particle, and how many particles total can there be at any given time
|
// this gives us estimate of longest potential lifespan of single particle, and how many particles total can there be at any given time
|
||||||
// TBD, TODO: explicit lifespan variable as part of the source configuration?
|
// TBD, TODO: explicit lifespan variable as part of the source configuration?
|
||||||
static_cast<int>( m_spawnrate / std::abs( m_opacitymodifier.value_change() ) ) ) );
|
static_cast<int>( m_spawnrate / std::abs( m_opacitymodifier.value_change() ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -154,7 +166,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
|||||||
0.f :
|
0.f :
|
||||||
std::min<float>(
|
std::min<float>(
|
||||||
m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
|
m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
|
||||||
m_particles.capacity() ) );
|
m_max_particles ) );
|
||||||
// update spawned particles
|
// update spawned particles
|
||||||
for( auto particleiterator { std::begin( m_particles ) }; particleiterator != std::end( m_particles ); ++particleiterator ) {
|
for( auto particleiterator { std::begin( m_particles ) }; particleiterator != std::end( m_particles ); ++particleiterator ) {
|
||||||
|
|
||||||
@@ -185,7 +197,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
|||||||
}
|
}
|
||||||
// spawn pending particles in remaining container slots
|
// spawn pending particles in remaining container slots
|
||||||
while( ( m_spawncount >= 1.f )
|
while( ( m_spawncount >= 1.f )
|
||||||
&& ( m_particles.size() < m_particles.capacity() ) ) {
|
&& ( m_particles.size() < m_max_particles ) ) {
|
||||||
|
|
||||||
m_spawncount -= 1.f;
|
m_spawncount -= 1.f;
|
||||||
// work with a temporary copy in case initial update renders the particle dead
|
// work with a temporary copy in case initial update renders the particle dead
|
||||||
|
|||||||
13
particles.h
13
particles.h
@@ -93,6 +93,9 @@ public:
|
|||||||
// updates state of owned particles
|
// updates state of owned particles
|
||||||
void
|
void
|
||||||
update( double const Timedelta, bool const Onlydespawn );
|
update( double const Timedelta, bool const Onlydespawn );
|
||||||
|
glm::vec3 const &
|
||||||
|
color() const {
|
||||||
|
return m_emitter.color; }
|
||||||
glm::dvec3
|
glm::dvec3
|
||||||
location() const;
|
location() const;
|
||||||
// provides access to bounding area data
|
// provides access to bounding area data
|
||||||
@@ -116,6 +119,7 @@ private:
|
|||||||
float velocity[ 2 ] { 1.f, 1.f };
|
float velocity[ 2 ] { 1.f, 1.f };
|
||||||
float size[ 2 ] { 1.f, 1.f };
|
float size[ 2 ] { 1.f, 1.f };
|
||||||
float opacity[ 2 ] { 1.f, 1.f };
|
float opacity[ 2 ] { 1.f, 1.f };
|
||||||
|
glm::vec3 color { 16.f / 255.f };
|
||||||
|
|
||||||
void deserialize( cParser &Input );
|
void deserialize( cParser &Input );
|
||||||
void initialize( smoke_particle &Particle );
|
void initialize( smoke_particle &Particle );
|
||||||
@@ -145,19 +149,14 @@ private:
|
|||||||
particle_emitter m_emitter;
|
particle_emitter m_emitter;
|
||||||
// bool m_inheritvelocity { false }; // whether spawned particle should receive velocity of its owner
|
// bool m_inheritvelocity { false }; // whether spawned particle should receive velocity of its owner
|
||||||
// TODO: replace modifiers with configurable interpolator item allowing keyframe-based changes over time
|
// TODO: replace modifiers with configurable interpolator item allowing keyframe-based changes over time
|
||||||
// fixedstep_modifier<glm::vec3> m_velocitymodifier; // particle velocity
|
|
||||||
fixedstep_modifier<float> m_sizemodifier; // particle billboard size
|
fixedstep_modifier<float> m_sizemodifier; // particle billboard size
|
||||||
// fixedstep_modifier<glm::vec4> m_colormodifier; // particle billboard color and opacity
|
// fixedstep_modifier<glm::vec3> m_colormodifier; // particle billboard color and opacity
|
||||||
fixedstep_modifier<float> m_opacitymodifier;
|
fixedstep_modifier<float> m_opacitymodifier;
|
||||||
// texture_handle m_texture { -1 }; // texture assigned to particle billboards
|
// texture_handle m_texture { -1 }; // texture assigned to particle billboards
|
||||||
// current state
|
// current state
|
||||||
float m_spawncount { 0.f }; // number of particles to spawn during next update
|
float m_spawncount { 0.f }; // number of particles to spawn during next update
|
||||||
particle_sequence m_particles; // collection of spawned particles
|
particle_sequence m_particles; // collection of spawned particles
|
||||||
/*
|
std::size_t m_max_particles; // maximum number of particles existing
|
||||||
smoke_sequence::iterator // helpers, iterators marking currently used part of the particle container
|
|
||||||
m_particlehead,
|
|
||||||
m_particletail;
|
|
||||||
*/
|
|
||||||
scene::bounding_area m_area; // bounding sphere of owned particles
|
scene::bounding_area m_area; // bounding sphere of owned particles
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
16
renderer.cpp
16
renderer.cpp
@@ -142,6 +142,12 @@ opengl_particles::update( opengl_camera const &Camera ) {
|
|||||||
particle_vertex vertex;
|
particle_vertex vertex;
|
||||||
for( auto const &source : sources ) {
|
for( auto const &source : sources ) {
|
||||||
|
|
||||||
|
auto const particlecolor {
|
||||||
|
glm::clamp(
|
||||||
|
source.second.color()
|
||||||
|
* ( glm::vec3 { Global.DayLight.ambient } + 0.35f * glm::vec3{ Global.DayLight.diffuse } )
|
||||||
|
* 255.f,
|
||||||
|
glm::vec3{ 0.f }, glm::vec3{ 255.f } ) };
|
||||||
auto const &particles { source.second.sequence() };
|
auto const &particles { source.second.sequence() };
|
||||||
// TODO: put sanity cap on the overall amount of particles that can be drawn
|
// TODO: put sanity cap on the overall amount of particles that can be drawn
|
||||||
auto const sizestep { 256.0 * billboard_vertices.size() };
|
auto const sizestep { 256.0 * billboard_vertices.size() };
|
||||||
@@ -149,9 +155,9 @@ opengl_particles::update( opengl_camera const &Camera ) {
|
|||||||
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
|
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
|
||||||
for( auto const &particle : particles ) {
|
for( auto const &particle : particles ) {
|
||||||
// TODO: particle color support
|
// TODO: particle color support
|
||||||
vertex.color[ 0 ] =
|
vertex.color[ 0 ] = static_cast<std::uint_fast8_t>( particlecolor.r );
|
||||||
vertex.color[ 1 ] =
|
vertex.color[ 1 ] = static_cast<std::uint_fast8_t>( particlecolor.g );
|
||||||
vertex.color[ 2 ] = static_cast<std::uint8_t>( Global.fLuminance * 32 );
|
vertex.color[ 2 ] = static_cast<std::uint_fast8_t>( particlecolor.b );
|
||||||
vertex.color[ 3 ] = clamp<std::uint8_t>( particle.opacity * 255, 0, 255 );
|
vertex.color[ 3 ] = clamp<std::uint8_t>( particle.opacity * 255, 0, 255 );
|
||||||
|
|
||||||
auto const offset { glm::vec3{ particle.position - Camera.position() } };
|
auto const offset { glm::vec3{ particle.position - Camera.position() } };
|
||||||
@@ -3157,6 +3163,10 @@ opengl_renderer::Render_particles() {
|
|||||||
|
|
||||||
Bind_Texture( m_smoketexture );
|
Bind_Texture( m_smoketexture );
|
||||||
m_particlerenderer.render( m_diffusetextureunit );
|
m_particlerenderer.render( m_diffusetextureunit );
|
||||||
|
if( Global.bUseVBO ) {
|
||||||
|
// shouldn't be strictly necessary but, eh
|
||||||
|
gfx::opengl_vbogeometrybank::reset();
|
||||||
|
}
|
||||||
|
|
||||||
::glDepthMask( GL_TRUE );
|
::glDepthMask( GL_TRUE );
|
||||||
::glEnable( GL_LIGHTING );
|
::glEnable( GL_LIGHTING );
|
||||||
|
|||||||
Reference in New Issue
Block a user