mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 01:19:19 +02:00
Merge branch 'milek-dev' into gfx-work
This commit is contained in:
@@ -117,11 +117,6 @@ smoke_source::initialize() {
|
|||||||
// 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() ) ) ) );
|
||||||
/*
|
|
||||||
m_particlehead =
|
|
||||||
m_particletail =
|
|
||||||
std::begin( m_particles );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -134,6 +129,16 @@ smoke_source::bind( TDynamicObject const *Vehicle ) {
|
|||||||
owner_type::none );
|
owner_type::none );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
smoke_source::bind( TAnimModel const *Node ) {
|
||||||
|
|
||||||
|
m_owner.node = Node;
|
||||||
|
m_ownertype = (
|
||||||
|
m_owner.node != nullptr ?
|
||||||
|
owner_type::node :
|
||||||
|
owner_type::none );
|
||||||
|
}
|
||||||
|
|
||||||
// updates state of owned particles
|
// updates state of owned particles
|
||||||
void
|
void
|
||||||
smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
||||||
@@ -151,32 +156,6 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
|||||||
m_spawncount + ( m_spawnrate * Timedelta ),
|
m_spawncount + ( m_spawnrate * Timedelta ),
|
||||||
m_particles.capacity() ) );
|
m_particles.capacity() ) );
|
||||||
// update spawned particles
|
// update spawned particles
|
||||||
/*
|
|
||||||
while( m_particlehead != m_particletail ) {
|
|
||||||
|
|
||||||
auto &particle { *m_particlehead };
|
|
||||||
bool particleisalive;
|
|
||||||
|
|
||||||
while( ( false == ( particleisalive = update( particle, Timedelta ) ) )
|
|
||||||
&& ( m_spawncount >= 1.f ) ) {
|
|
||||||
// replace dead particle with a new one
|
|
||||||
m_spawncount -= 1.f;
|
|
||||||
initialize( particle );
|
|
||||||
}
|
|
||||||
if( false == particleisalive ) {
|
|
||||||
// we have a dead particle and no pending spawn requests, (try to) move the last particle here
|
|
||||||
do {
|
|
||||||
--m_particletail;
|
|
||||||
if( m_particlehead == m_particletail ) { break; }
|
|
||||||
particle = *m_particletail;
|
|
||||||
} while( false == ( particleisalive = update( particle, Timedelta ) ) );
|
|
||||||
}
|
|
||||||
if( true == particleisalive ) {
|
|
||||||
// ensure at the end of the pass the head iterator is placed after the last alive particle
|
|
||||||
++m_particlehead;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
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 ) {
|
||||||
|
|
||||||
auto &particle { *particleiterator };
|
auto &particle { *particleiterator };
|
||||||
@@ -205,18 +184,6 @@ 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 )
|
|
||||||
&& ( m_particlehead != std::end( m_particles ) ) ) {
|
|
||||||
|
|
||||||
m_spawncount -= 1.f;
|
|
||||||
auto &particle { *m_particlehead };
|
|
||||||
initialize( particle );
|
|
||||||
if( true == update( particle, Timedelta ) ) {
|
|
||||||
++m_particlehead;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
while( ( m_spawncount >= 1.f )
|
while( ( m_spawncount >= 1.f )
|
||||||
&& ( m_particles.size() < m_particles.capacity() ) ) {
|
&& ( m_particles.size() < m_particles.capacity() ) ) {
|
||||||
|
|
||||||
@@ -258,12 +225,6 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
|||||||
// discard pending spawn requests our container couldn't fit
|
// discard pending spawn requests our container couldn't fit
|
||||||
m_spawncount -= std::floor( m_spawncount );
|
m_spawncount -= std::floor( m_spawncount );
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// after the pass the head iterator is left last alive particle
|
|
||||||
m_particletail = m_particlehead;
|
|
||||||
m_particlehead = std::begin( m_particles );
|
|
||||||
*/
|
|
||||||
|
|
||||||
// determine bounding area from calculated bounding box
|
// determine bounding area from calculated bounding box
|
||||||
if( false == m_particles.empty() ) {
|
if( false == m_particles.empty() ) {
|
||||||
m_area.center = interpolate( boundingbox[ value_limit::min ], boundingbox[ value_limit::max ], 0.5 );
|
m_area.center = interpolate( boundingbox[ value_limit::min ], boundingbox[ value_limit::max ], 0.5 );
|
||||||
@@ -291,7 +252,8 @@ smoke_source::location() const {
|
|||||||
}
|
}
|
||||||
case owner_type::node: {
|
case owner_type::node: {
|
||||||
// TODO: take into account node rotation
|
// TODO: take into account node rotation
|
||||||
location = m_offset;
|
auto const rotation { glm::angleAxis( glm::radians( m_owner.node->Angles().y ), glm::vec3{ 0.f, 1.f, 0.f } ) };
|
||||||
|
location = rotation * glm::vec3{ m_offset };
|
||||||
location += m_owner.node->location();
|
location += m_owner.node->location();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -342,10 +304,12 @@ smoke_source::update( smoke_particle &Particle, bounding_box &Boundingbox, doubl
|
|||||||
|
|
||||||
// crude smoke dispersion simulation
|
// crude smoke dispersion simulation
|
||||||
// http://www.auburn.edu/academic/forestry_wildlife/fire/smoke_guide/smoke_dispersion.htm
|
// http://www.auburn.edu/academic/forestry_wildlife/fire/smoke_guide/smoke_dispersion.htm
|
||||||
Particle.velocity.y = std::max<float>( 0.25 * ( 1.f - Global.Overcast ), Particle.velocity.y - 0.25 * Global.Overcast * Timedelta );
|
Particle.velocity.y += ( 0.005 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 10 ) * Timedelta; // decelerate faster in cold weather
|
||||||
|
Particle.velocity.y -= ( 0.010 * Particle.velocity.y ) * Global.Overcast * Timedelta; // decelerate faster with high air humidity and/or precipitation
|
||||||
|
Particle.velocity.y = std::max<float>( 0.25 * ( 2.f - Global.Overcast ), Particle.velocity.y ); // put a cap on deceleration
|
||||||
|
|
||||||
Particle.position += Particle.velocity * static_cast<float>( Timedelta );
|
Particle.position += Particle.velocity * static_cast<float>( Timedelta );
|
||||||
Particle.position += 0.35f * simulation::Environment.wind() * static_cast<float>( Timedelta );
|
Particle.position += 0.1f * Particle.age * simulation::Environment.wind() * static_cast<float>( Timedelta );
|
||||||
// m_velocitymodifier.update( Particle.velocity, Timedelta );
|
// m_velocitymodifier.update( Particle.velocity, Timedelta );
|
||||||
|
|
||||||
Particle.age += Timedelta;
|
Particle.age += Timedelta;
|
||||||
@@ -389,6 +353,18 @@ particle_manager::insert( std::string const &Sourcetemplate, TDynamicObject cons
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
particle_manager::insert( std::string const &Sourcetemplate, TAnimModel const *Node, glm::dvec3 const Location ) {
|
||||||
|
|
||||||
|
if( false == insert( Sourcetemplate, Location ) ) { return false; }
|
||||||
|
|
||||||
|
// attach the source to specified node
|
||||||
|
auto &source { m_sources.back() };
|
||||||
|
source.bind( Node );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// updates state of all owned emitters
|
// updates state of all owned emitters
|
||||||
void
|
void
|
||||||
particle_manager::update() {
|
particle_manager::update() {
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ public:
|
|||||||
initialize();
|
initialize();
|
||||||
void
|
void
|
||||||
bind( TDynamicObject const *Vehicle );
|
bind( TDynamicObject const *Vehicle );
|
||||||
|
void
|
||||||
|
bind( TAnimModel const *Node );
|
||||||
// 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 );
|
||||||
@@ -171,6 +173,8 @@ public:
|
|||||||
insert( std::string const &Sourcetemplate, glm::dvec3 const Location );
|
insert( std::string const &Sourcetemplate, glm::dvec3 const Location );
|
||||||
bool
|
bool
|
||||||
insert( std::string const &Sourcetemplate, TDynamicObject const *Vehicle, glm::dvec3 const Location );
|
insert( std::string const &Sourcetemplate, TDynamicObject const *Vehicle, glm::dvec3 const Location );
|
||||||
|
bool
|
||||||
|
insert( std::string const &Sourcetemplate, TAnimModel const *Node, glm::dvec3 const Location );
|
||||||
// updates state of all owned emitters
|
// updates state of all owned emitters
|
||||||
void
|
void
|
||||||
update();
|
update();
|
||||||
|
|||||||
@@ -201,8 +201,12 @@ world_environment::update_wind() {
|
|||||||
m_wind.change_time -= timedelta;
|
m_wind.change_time -= timedelta;
|
||||||
if( m_wind.change_time < 0 ) {
|
if( m_wind.change_time < 0 ) {
|
||||||
m_wind.change_time = Random( 5, 30 );
|
m_wind.change_time = Random( 5, 30 );
|
||||||
m_wind.azimuth_change = Random( -5, 5 );
|
|
||||||
m_wind.velocity_change = Random( -1, 1 );
|
m_wind.velocity_change = Random( -1, 1 );
|
||||||
|
if( Random() < 0.2 ) {
|
||||||
|
// changes in wind direction should be less frequent than changes in wind speed
|
||||||
|
// TBD, TODO: configuration-driven direction change frequency
|
||||||
|
m_wind.azimuth_change = Random( -5, 5 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TBD, TODO: wind configuration
|
// TBD, TODO: wind configuration
|
||||||
m_wind.azimuth = clamp_circular( m_wind.azimuth + m_wind.azimuth_change * timedelta );
|
m_wind.azimuth = clamp_circular( m_wind.azimuth + m_wind.azimuth_change * timedelta );
|
||||||
|
|||||||
@@ -472,6 +472,15 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
|
|||||||
// model import can potentially fail
|
// model import can potentially fail
|
||||||
if( instance == nullptr ) { return; }
|
if( instance == nullptr ) { return; }
|
||||||
|
|
||||||
|
if( instance->Model() != nullptr ) {
|
||||||
|
for( auto const &smokesource : instance->Model()->smoke_sources() ) {
|
||||||
|
Particles.insert(
|
||||||
|
smokesource.first,
|
||||||
|
instance,
|
||||||
|
smokesource.second );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( false == simulation::Instances.insert( instance ) ) {
|
if( false == simulation::Instances.insert( instance ) ) {
|
||||||
ErrorLog( "Bad scenario: duplicate 3d model instance name \"" + instance->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: duplicate 3d model instance name \"" + instance->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user