Changeset 307


Ignore:
Timestamp:
08/12/14 11:46:15 (11 years ago)
Author:
epyon
Message:
  • particle_system - duration (duration_min/duration_max) added to emmiter options
  • particle_system - repeat_delay (repeat_delay_min/repeat_delay_max) added to emmiter options
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/gfx/particle_engine.hh

    r306 r307  
    6363                vec3   odir;
    6464                vec3   cdir;
     65                uint32 duration_min;
     66                uint32 duration_max;
     67                uint32 repeat_min;
     68                uint32 repeat_max;
    6569                float  rate;
    6670        };
     71
    6772        struct particle_emmiter_info
    6873        {
     74                bool   active;
     75                uint32 next_toggle;
    6976                uint32 last_create;
    7077        };
     
    120127                void create_particles( particle_system_info* info, uint32 ms );
    121128                void update_particles( particle_system_info* info, uint32 ms );
     129                void update_emmiters( particle_system_info* info, uint32 ms );
    122130
    123131                device*                        m_device;
  • trunk/src/gfx/particle_engine.cc

    r306 r307  
    104104                                edata.lifetime_min = uint32( element.get<float>("lifetime_min", lifetime ) * 1000.f );
    105105                                edata.lifetime_max = uint32( element.get<float>("lifetime_max", lifetime ) * 1000.f );
     106                                float duration     = element.get<float>("duration", 0.0f );
     107                                edata.duration_min = uint32( element.get<float>("duration_min", duration ) * 1000.f );
     108                                edata.duration_max = uint32( element.get<float>("duration_max", duration ) * 1000.f );
     109                                float repeat       = element.get<float>("repeat_delay", 0.0f );
     110                                edata.repeat_min   = uint32( element.get<float>("repeat_delay_min", repeat ) * 1000.f );
     111                                edata.repeat_max   = uint32( element.get<float>("repeat_delay_max", repeat ) * 1000.f );
     112
    106113                                edata.rate         = element.get<float>("rate", 1.0f );
    107114                                edata.dir          = glm::normalize( element.get<vec3>("direction", vec3(0,1,0) ) );
     
    153160        for ( uint32 i = 0; i < ecount; ++i )
    154161        {
     162                info->emmiters[i].active      = true;
    155163                info->emmiters[i].last_create = 0;
     164                info->emmiters[i].next_toggle = random::get().urange( data->emmiters[i].duration_min, data->emmiters[i].duration_max );
    156165        }
    157166
     
    208217                m_inv_view_dir = glm::normalize(-s.get_camera().get_direction());
    209218
     219                update_emmiters( info, ms );
    210220                destroy_particles( info, ms );
    211221                create_particles( info, ms );
     
    348358                const auto& edata = info->data->emmiters[i];
    349359                auto& einfo = info->emmiters[i];
    350 
    351                 uint32 period = glm::max<uint32>( uint32(1000.f / edata.rate), 1 );
    352                 while ( ms - einfo.last_create > period )
    353                 {
    354                         if ( info->count < info->data->quota-1 )
    355                         {
    356                                 particle& pinfo = info->particles[info->count];
    357                                 pinfo.position = source;
    358                                 pinfo.color    = edata.color_min == edata.color_max ?
    359                                         edata.color_min : r.range( edata.color_min, edata.color_max );
    360                                 pinfo.size     = edata.size_min == edata.size_max ?
    361                                         edata.size_min : r.range( edata.size_min, edata.size_max );
    362                                 if ( edata.square ) pinfo.size.y = pinfo.size.x;
    363                                 pinfo.velocity  = edata.velocity_min == edata.velocity_max ?
    364                                         edata.velocity_min : r.frange( edata.velocity_min, edata.velocity_max );
    365                                 pinfo.death     = ms + ( edata.lifetime_min == edata.lifetime_max ?
    366                                         edata.lifetime_min : r.urange( edata.lifetime_min, edata.lifetime_max ) );
    367                                 //pinfo.rotation = r.frand( 360.0f );
    368 
    369                                 pinfo.dir = edata.dir;
    370                                 if ( edata.angle > 0.0f )
     360                if ( einfo.active )
     361                {
     362                        uint32 period = glm::max<uint32>( uint32(1000.f / edata.rate), 1 );
     363                        while ( ms - einfo.last_create > period )
     364                        {
     365                                if ( info->count < info->data->quota-1 )
    371366                                {
    372                                         float emission_angle = glm::radians( edata.angle );
    373                                         float cos_theta = r.frange( cos( emission_angle ), 1.0f );
    374                                         float sin_theta = glm::sqrt(1.0f - cos_theta * cos_theta );
    375                                         float phi       = r.frange( 0.0f, 2*glm::pi<float>() );
    376                                         pinfo.dir = orient *
    377                                                 ( edata.odir * ( glm::cos(phi) * sin_theta ) +
    378                                                 edata.cdir * ( glm::sin(phi)*sin_theta ) +
    379                                                 edata.dir  * cos_theta );
     367                                        particle& pinfo = info->particles[info->count];
     368                                        pinfo.position = source;
     369                                        pinfo.color    = edata.color_min == edata.color_max ?
     370                                                edata.color_min : r.range( edata.color_min, edata.color_max );
     371                                        pinfo.size     = edata.size_min == edata.size_max ?
     372                                                edata.size_min : r.range( edata.size_min, edata.size_max );
     373                                        if ( edata.square ) pinfo.size.y = pinfo.size.x;
     374                                        pinfo.velocity  = edata.velocity_min == edata.velocity_max ?
     375                                                edata.velocity_min : r.frange( edata.velocity_min, edata.velocity_max );
     376                                        pinfo.death     = ms + ( edata.lifetime_min == edata.lifetime_max ?
     377                                                edata.lifetime_min : r.urange( edata.lifetime_min, edata.lifetime_max ) );
     378                                        //pinfo.rotation = r.frand( 360.0f );
     379
     380                                        pinfo.dir = edata.dir;
     381                                        if ( edata.angle > 0.0f )
     382                                        {
     383                                                float emission_angle = glm::radians( edata.angle );
     384                                                float cos_theta = r.frange( cos( emission_angle ), 1.0f );
     385                                                float sin_theta = glm::sqrt(1.0f - cos_theta * cos_theta );
     386                                                float phi       = r.frange( 0.0f, 2*glm::pi<float>() );
     387                                                pinfo.dir = orient *
     388                                                        ( edata.odir * ( glm::cos(phi) * sin_theta ) +
     389                                                        edata.cdir * ( glm::sin(phi)*sin_theta ) +
     390                                                        edata.dir  * cos_theta );
     391                                        }
     392
     393                                        info->count++;
    380394                                }
    381 
    382                                 info->count++;
    383                         }
    384                         einfo.last_create += period;
     395                                einfo.last_create += period;
     396                        }
    385397                }
    386398        }
     
    416428                system->last_update = ms;
    417429}
     430
     431void nv::particle_engine::update_emmiters( particle_system_info* info, uint32 ms )
     432{
     433        uint32 ecount = info->data->emmiter_count;
     434        if ( ecount == 0 ) return;
     435        random& r = random::get();
     436
     437        for ( uint32 i = 0; i < ecount; ++i )
     438        {
     439                const auto& edata = info->data->emmiters[i];
     440                auto& einfo = info->emmiters[i];
     441
     442                if ( einfo.next_toggle != 0 && ms >= einfo.next_toggle )
     443                {
     444                        if ( einfo.active )
     445                        {
     446                                einfo.active = false;
     447                                if ( edata.repeat_min > 0 )
     448                                        einfo.next_toggle += r.urange( edata.repeat_min, edata.repeat_max );
     449                                else
     450                                        einfo.next_toggle = 0;
     451                        }
     452                        else
     453                        {
     454                                einfo.active = true;
     455                                einfo.last_create = einfo.next_toggle;
     456                                einfo.next_toggle += r.urange( edata.duration_min, edata.duration_max );
     457                        }
     458                }
     459        }
     460
     461}
Note: See TracChangeset for help on using the changeset viewer.