- Timestamp:
- 08/16/14 00:40:54 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gfx/particle_engine.cc
r309 r312 47 47 "}\n"; 48 48 49 using namespace nv; 50 51 static void nv_particle_emmiter_point( const particle_emmiter_data*, particle* p, uint32 count ) 52 { 53 for ( uint32 i = 0; i < count; ++i ) 54 { 55 p[i].position = vec3(); 56 } 57 58 } 59 60 static void nv_particle_emmiter_box( const particle_emmiter_data* pe, particle* p, uint32 count ) 61 { 62 random& r = random::get(); 63 for ( uint32 i = 0; i < count; ++i ) 64 { 65 p[i].position = 66 r.frange( -pe->hextents[0], pe->hextents[0] ) * pe->cdir + 67 r.frange( 0.0f, pe->extents[1] ) * pe->dir + 68 r.frange( -pe->hextents[2], pe->hextents[2] ) * pe->odir; 69 } 70 } 71 72 static void nv_particle_emmiter_cylinder( const particle_emmiter_data* pe, particle* p, uint32 count ) 73 { 74 random& r = random::get(); 75 for ( uint32 i = 0; i < count; ++i ) 76 { 77 vec2 rellipse( r.disk_point( pe->precise ) * pe->extents[0] ); 78 p[i].position = 79 rellipse.x * pe->cdir + 80 r.frange( 0.0f, pe->extents[1] ) * pe->dir + 81 rellipse.y * pe->odir; 82 } 83 } 84 85 static void nv_particle_emmiter_sphere( const particle_emmiter_data* pe, particle* p, uint32 count ) 86 { 87 random& r = random::get(); 88 for ( uint32 i = 0; i < count; ++i ) 89 { 90 vec3 rsphere = r.sphere_point( pe->precise ) * pe->extents[0]; 91 p[i].position = 92 rsphere.x * pe->cdir + 93 rsphere.y * pe->dir + 94 rsphere.z * pe->odir; 95 } 96 } 97 98 static void nv_particle_emmiter_cylindroid( const particle_emmiter_data* pe, particle* p, uint32 count ) 99 { 100 random& r = random::get(); 101 for ( uint32 i = 0; i < count; ++i ) 102 { 103 vec2 rellipse = r.ellipse_point( vec2( pe->hextents[0], pe->hextents[2] ), pe->precise ); 104 p[i].position = 105 rellipse.x * pe->cdir + 106 r.frange( 0.0f, pe->extents[1] ) * pe->dir + 107 rellipse.y * pe->odir; 108 } 109 } 110 111 static void nv_particle_emmiter_ellipsoid( const particle_emmiter_data* pe, particle* p, uint32 count ) 112 { 113 random& r = random::get(); 114 for ( uint32 i = 0; i < count; ++i ) 115 { 116 vec3 rsphere = r.ellipsoid_point( pe->hextents, pe->precise ); 117 p[i].position = 118 rsphere.x * pe->cdir + 119 rsphere.y * pe->dir + 120 rsphere.z * pe->odir; 121 } 122 } 123 124 static void nv_particle_emmiter_hollow_cylinder( const particle_emmiter_data* pe, particle* p, uint32 count ) 125 { 126 random& r = random::get(); 127 for ( uint32 i = 0; i < count; ++i ) 128 { 129 vec2 rellipse = r.hollow_disk_point( 130 pe->ihextents[0], 131 pe->hextents[0], 132 pe->precise ); 133 p[i].position = 134 rellipse.x * pe->cdir + 135 r.frange( 0.0f, pe->extents[1] ) * pe->dir + 136 rellipse.y * pe->odir; 137 } 138 } 139 140 static void nv_particle_emmiter_hollow_sphere( const particle_emmiter_data* pe, particle* p, uint32 count ) 141 { 142 random& r = random::get(); 143 for ( uint32 i = 0; i < count; ++i ) 144 { 145 vec3 rellipse = r.hollow_sphere_point( pe->ihextents[0], pe->hextents[0], pe->precise ); 146 p[i].position = 147 rellipse.x * pe->cdir + 148 rellipse.y * pe->dir + 149 rellipse.z * pe->odir; 150 } 151 } 152 153 static void nv_particle_emmiter_hollow_cylindroid( const particle_emmiter_data* pe, particle* p, uint32 count ) 154 { 155 random& r = random::get(); 156 for ( uint32 i = 0; i < count; ++i ) 157 { 158 vec2 rellipse = r.hollow_ellipse_point( 159 vec2( pe->ihextents[0], pe->ihextents[2] ), 160 vec2( pe->hextents[0], pe->hextents[2] ), 161 pe->precise ); 162 p[i].position = 163 rellipse.x * pe->cdir + 164 r.frange( 0.0f, pe->extents[1] ) * pe->dir + 165 rellipse.y * pe->odir; 166 } 167 } 168 169 static void nv_particle_emmiter_hollow_ellipsoid( const particle_emmiter_data* pe, particle* p, uint32 count ) 170 { 171 random& r = random::get(); 172 for ( uint32 i = 0; i < count; ++i ) 173 { 174 vec3 rellipse = r.hollow_ellipsoid_point( pe->ihextents, pe->hextents, pe->precise ); 175 p[i].position = 176 rellipse.x * pe->cdir + 177 rellipse.y * pe->dir + 178 rellipse.z * pe->odir; 179 } 180 } 181 182 struct nvpe_linear_force_data 183 { 184 nv::vec3 force_vector; 185 bool average; 186 }; 187 188 static bool nv_particle_affector_linear_force_init( lua::table_guard* table, particle_affector_data* data ) 189 { 190 nvpe_linear_force_data* datap = ((nvpe_linear_force_data*)data->paramters); 191 datap->force_vector = table->get<vec3>("force_vector", vec3() ); 192 datap->average = table->get<bool>("average", false ); 193 return true; 194 } 195 196 static void nv_particle_affector_linear_force( const particle_affector_data* data, particle* p, float factor, uint32 count ) 197 { 198 nvpe_linear_force_data* datap = ((nvpe_linear_force_data*)data->paramters); 199 if ( datap->average ) 200 { 201 float norm_factor = glm::min( factor, 1.0f ); 202 for ( uint32 i = 0; i < count; ++i ) 203 p[i].velocity = datap->force_vector * norm_factor + p[i].velocity * ( 1.0f - norm_factor ); 204 } 205 else 206 { 207 vec3 scvector = datap->force_vector * factor; 208 for ( uint32 i = 0; i < count; ++i ) p[i].velocity += scvector; 209 } 210 } 211 212 struct nvpe_deflector_plane_data 213 { 214 nv::vec3 plane_point; 215 nv::vec3 plane_normal; 216 float bounce; 217 float distance; 218 }; 219 220 static bool nv_particle_affector_deflector_plane_init( lua::table_guard* table, particle_affector_data* data ) 221 { 222 nvpe_deflector_plane_data* datap = ((nvpe_deflector_plane_data*)data->paramters); 223 datap->plane_point = table->get<vec3>("plane_point", vec3() ); 224 datap->plane_normal = table->get<vec3>("plane_normal", vec3(0.0f,1.0f,0.0f) ); 225 datap->plane_normal = normalize_safe( datap->plane_normal, vec3(0.0f,1.0f,0.0f) ); 226 datap->bounce = table->get<float>("bounce", 0.0f ); 227 datap->distance = -glm::dot( datap->plane_normal, datap->plane_point ) / glm::sqrt(glm::dot( datap->plane_normal, datap->plane_normal ) ); 228 return true; 229 } 230 231 static void nv_particle_affector_deflector_plane( const particle_affector_data* data, particle* p, float factor, uint32 count ) 232 { 233 nvpe_deflector_plane_data* datap = ((nvpe_deflector_plane_data*)data->paramters); 234 for ( uint32 i = 0; i < count; ++i ) 235 { 236 particle& pt = p[i]; 237 vec3 direction = pt.velocity * factor; 238 if ( glm::dot( datap->plane_normal, pt.position + direction ) + datap->distance <= 0.0f ) 239 { 240 float val = glm::dot( datap->plane_normal, pt.position ) + datap->distance; 241 if ( val > 0.0f ) 242 { 243 vec3 part_dir = direction * ( -val / glm::dot( datap->plane_normal, direction ) ); 244 pt.position = pt.position + part_dir + ( part_dir - direction ) * datap->bounce; 245 pt.velocity = glm::reflect( pt.velocity, datap->plane_normal ) * datap->bounce; 246 } 247 } 248 } 249 } 250 251 struct nvpe_color_fader_data 252 { 253 nv::vec4 adjustment; 254 }; 255 256 static bool nv_particle_affector_color_fader_init( lua::table_guard* table, particle_affector_data* data ) 257 { 258 nvpe_color_fader_data* datap = ((nvpe_color_fader_data*)data->paramters); 259 datap->adjustment = table->get<vec4>("adjustment", vec4() ); 260 return true; 261 } 262 263 static void nv_particle_affector_color_fader( const particle_affector_data* data, particle* p, float factor, uint32 count ) 264 { 265 nvpe_color_fader_data* datap = ((nvpe_color_fader_data*)data->paramters); 266 vec4 adjustment = datap->adjustment * factor; 267 for ( uint32 i = 0; i < count; ++i ) 268 { 269 p[i].color = glm::clamp( p[i].color + adjustment, 0.0f, 1.0f ); 270 } 271 } 272 273 struct nvpe_scaler_data 274 { 275 nv::vec2 adjustment; 276 }; 277 278 static bool nv_particle_affector_scaler_init( lua::table_guard* table, particle_affector_data* data ) 279 { 280 nvpe_scaler_data* datap = ((nvpe_scaler_data*)data->paramters); 281 float rate = table->get<float>("rate", 0.0f ); 282 datap->adjustment = table->get<vec2>("adjustment", vec2(rate,rate) ); 283 return true; 284 } 285 286 static void nv_particle_affector_scaler( const particle_affector_data* data, particle* p, float factor, uint32 count ) 287 { 288 nvpe_scaler_data* datap = ((nvpe_scaler_data*)data->paramters); 289 vec2 adjustment = datap->adjustment * factor; 290 for ( uint32 i = 0; i < count; ++i ) 291 { 292 p[i].size = glm::max( p[i].size + adjustment, vec2() ); 293 } 294 } 295 49 296 void nv::particle_engine::load( lua::table_guard& table ) 50 297 { … … 60 307 auto& data = m_data.back(); 61 308 62 data.gravity = table.get<vec3>("gravity", vec3() );63 309 data.quota = table.get<uint32>("quota", 1024 ); 64 310 data.local = table.get<bool>("local_space", false ); 65 311 data.accurate_facing = table.get<bool>("accurate_facing", false ); 66 312 data.emmiter_count = 0; 313 data.affector_count = 0; 67 314 68 315 std::string orientation = table.get_string( "orientation", "point" ); … … 109 356 { 110 357 particle_emmiter_data& edata = data.emmiters[ data.emmiter_count ]; 111 112 if ( sub_type == "point" ) edata.type = particle_emmiter_type::POINT; 113 else if ( sub_type == "box" ) edata.type = particle_emmiter_type::BOX; 114 else if ( sub_type == "cylinder" ) edata.type = particle_emmiter_type::CYLINDER; 115 else if ( sub_type == "sphere" ) edata.type = particle_emmiter_type::SPHERE; 116 else if ( sub_type == "cylindroid" ) edata.type = particle_emmiter_type::CYLINDROID; 117 else if ( sub_type == "ellipsoid" ) edata.type = particle_emmiter_type::ELLIPSOID; 118 else if ( sub_type == "hollow_cylinder" ) edata.type = particle_emmiter_type::HOLLOW_CYLINDER; 119 else if ( sub_type == "hollow_sphere" ) edata.type = particle_emmiter_type::HOLLOW_SPHERE; 120 else if ( sub_type == "hollow_cylindroid" ) edata.type = particle_emmiter_type::HOLLOW_CYLINDROID; 121 else if ( sub_type == "hollow_ellipsoid" ) edata.type = particle_emmiter_type::HOLLOW_ELLIPSOID; 358 auto emmiter_iter = m_emmiters.find( sub_type ); 359 if ( emmiter_iter != m_emmiters.end() ) 360 { 361 edata.emmiter_func = emmiter_iter->second; 362 } 122 363 else 123 364 { 124 edata. type = particle_emmiter_type::POINT;365 edata.emmiter_func = nv_particle_emmiter_point; 125 366 NV_LOG( LOG_WARNING, "Unknown emmiter type in particle system! (" << sub_type << ")" ); 126 367 } … … 177 418 else if ( type == "affector" ) 178 419 { 179 420 if ( data.affector_count < MAX_PARTICLE_AFFECTORS ) 421 { 422 particle_affector_data& adata = data.affectors[ data.affector_count ]; 423 data.affector_count++; 424 auto affector_iter = m_affectors.find( sub_type ); 425 if ( affector_iter != m_affectors.end() ) 426 { 427 adata.process = affector_iter->second.process; 428 if ( !affector_iter->second.init( &element, &adata ) ) 429 { 430 data.affector_count--; 431 NV_LOG( LOG_WARNING, "Bad data passed to " << sub_type << " affector in particle system!" ); 432 } 433 } 434 else 435 { 436 data.affector_count--; 437 NV_LOG( LOG_WARNING, "Unknown affector type in particle system! (" << sub_type << ")" ); 438 } 439 } 440 else 441 { 442 NV_LOG( LOG_ERROR, "Too many affectors (" << MAX_PARTICLE_AFFECTORS << " is MAX)!" ); 443 } 180 444 } 181 445 else … … 193 457 m_program_local = m_device->create_program( nv_particle_engine_vertex_shader_local, nv_particle_engine_fragment_shader ); 194 458 m_program_world = m_device->create_program( nv_particle_engine_vertex_shader_world, nv_particle_engine_fragment_shader ); 459 460 register_standard_emmiters(); 461 register_standard_affectors(); 195 462 } 196 463 … … 324 591 vec3 z( 0.0f, 0.0f ,1.0f ); 325 592 326 mat3 rot_mat;327 vec3 right;328 mat3 irot_mat = glm::transpose( mat3( m_view_matrix ) );329 593 particle_orientation orientation = info->data->orientation; 330 594 vec3 common_up ( info->data->common_up ); 331 595 vec3 common_dir( info->data->common_dir ); 332 596 bool accurate_facing = info->data->accurate_facing; 333 597 mat3 rot_mat; 598 vec3 right; 599 vec3 pdir( 0.0f, 1.0f, 0.0f ); 334 600 335 601 for ( uint32 i = 0; i < info->count; ++i ) … … 346 612 right = glm::normalize( glm::cross( view_dir, vec3( 0, 1, 0 ) ) ); 347 613 rot_mat = mat3( right, glm::cross( right, -view_dir ), -view_dir ); 348 // rot_mat = irot_mat * glm::mat3_cast( glm::angleAxis( pdata.rotation, z ) );349 614 break; 350 615 case particle_orientation::ORIENTED : 351 right = glm::normalize( glm::cross( pdata.dir, view_dir ) ); 352 rot_mat = mat3( right, pdata.dir, glm::cross( pdata.dir, right ) ); 616 pdir = normalize_safe( pdata.velocity, pdir ); 617 right = glm::normalize( glm::cross( pdir, view_dir ) ); 618 rot_mat = mat3( right, pdir, glm::cross( pdir, right ) ); 353 619 break; 354 620 case particle_orientation::ORIENTED_COMMON : … … 357 623 break; 358 624 case particle_orientation::PERPENDICULAR : 359 right = glm::normalize( glm::cross( common_up, pdata.dir ) ); 625 pdir = normalize_safe( pdata.velocity, pdir ); 626 right = glm::normalize( glm::cross( common_up, pdir ) ); 360 627 rot_mat = mat3( right, common_up, glm::cross( common_up, right ) ); 361 628 break; … … 412 679 vec3 source; 413 680 mat3 orient; 414 if ( !info->data->local ) 681 bool local = info->data->local; 682 if ( !local ) 415 683 { 416 684 source = vec3( m_model_matrix[3] ); 417 685 orient = mat3( m_model_matrix ); 418 686 } 687 419 688 float fms = float(ms); 420 689 … … 431 700 { 432 701 particle& pinfo = info->particles[info->count]; 433 switch ( edata.type ) 434 { 435 case particle_emmiter_type::POINT: 436 pinfo.position = source; 437 break; 438 case particle_emmiter_type::BOX: 439 pinfo.position = source + orient * ( 440 r.frange( -edata.hextents[0], edata.hextents[0] ) * edata.cdir + 441 r.frange( 0.0f, edata.extents[1] ) * edata.dir + 442 r.frange( -edata.hextents[2], edata.hextents[2] ) * edata.odir 443 ); 444 break; 445 case particle_emmiter_type::CYLINDER: 446 { 447 vec2 rellipse = r.disk_point( edata.precise ); 448 pinfo.position = source + orient * ( 449 rellipse.x * edata.extents[0] * edata.cdir + 450 r.frange( 0.0f, edata.extents[1] ) * edata.dir + 451 rellipse.y * edata.extents[0] * edata.odir 452 ); 453 } 454 break; 455 case particle_emmiter_type::SPHERE: 456 { 457 vec3 rellipse = r.sphere_point( edata.precise ); 458 pinfo.position = source + orient * ( 459 rellipse.x * edata.extents[0] * edata.cdir + 460 rellipse.y * edata.extents[0] * edata.dir + 461 rellipse.z * edata.extents[0] * edata.odir 462 ); 463 } 464 break; 465 // TODO : this method is NOT uniform if width != height! 466 case particle_emmiter_type::CYLINDROID: 467 { 468 vec2 rellipse = r.ellipse_point( vec2( edata.hextents[0], edata.hextents[2] ), edata.precise ); 469 pinfo.position = source + orient * ( 470 rellipse.x * edata.cdir + 471 r.frange( 0.0f, edata.extents[1] ) * edata.dir + 472 rellipse.y * edata.odir 473 ); 474 } 475 break; 476 // TODO : this method is NOT uniform if all dimension are not equal! 477 case particle_emmiter_type::ELLIPSOID: 478 { 479 vec3 rsphere = r.ellipsoid_point( edata.hextents, edata.precise ); 480 pinfo.position = source + orient * ( 481 rsphere.x * edata.cdir + 482 rsphere.y * edata.dir + 483 rsphere.z * edata.odir 484 ); 485 } 486 break; 487 case particle_emmiter_type::HOLLOW_CYLINDER: 488 { 489 vec2 rellipse = r.hollow_disk_point( 490 edata.ihextents[0], 491 edata.hextents[0], 492 edata.precise ); 493 pinfo.position = source + orient * ( 494 rellipse.x * edata.cdir + 495 r.frange( 0.0f, edata.extents[1] ) * edata.dir + 496 rellipse.y * edata.odir 497 ); 498 } 499 break; 500 case particle_emmiter_type::HOLLOW_SPHERE: 501 { 502 vec3 rellipse = r.hollow_sphere_point( 503 edata.ihextents[0], 504 edata.hextents[0], 505 edata.precise ); 506 pinfo.position = source + orient * ( 507 rellipse.x * edata.cdir + 508 rellipse.y * edata.dir + 509 rellipse.z * edata.odir 510 ); 511 } 512 break; 513 case particle_emmiter_type::HOLLOW_CYLINDROID: 514 { 515 vec2 rellipse = r.hollow_ellipse_point( 516 vec2( edata.ihextents[0], edata.ihextents[2] ), 517 vec2( edata.hextents[0], edata.hextents[2] ), 518 edata.precise ); 519 pinfo.position = source + orient * ( 520 rellipse.x * edata.cdir + 521 r.frange( 0.0f, edata.extents[1] ) * edata.dir + 522 rellipse.y * edata.odir 523 ); 524 } 525 break; 526 // TODO : this method is NOT uniform if all dimension are not equal! 527 case particle_emmiter_type::HOLLOW_ELLIPSOID: 528 { 529 vec3 rellipse = r.hollow_ellipsoid_point( edata.ihextents, edata.hextents, edata.precise ); 530 pinfo.position = source + orient * ( 531 rellipse.x * edata.cdir + 532 rellipse.y * edata.dir + 533 rellipse.z * edata.odir 534 ); 535 } 536 break; 537 } 702 edata.emmiter_func( &(info->data->emmiters[i]), &pinfo, 1 ); 703 704 if ( !local ) pinfo.position = orient * pinfo.position + source; 538 705 pinfo.position += edata.position; 539 706 pinfo.color = edata.color_min == edata.color_max ? … … 542 709 edata.size_min : r.range( edata.size_min, edata.size_max ); 543 710 if ( edata.square ) pinfo.size.y = pinfo.size.x; 544 pinfo.velocity = edata.velocity_min == edata.velocity_max ?711 float velocity = edata.velocity_min == edata.velocity_max ? 545 712 edata.velocity_min : r.frange( edata.velocity_min, edata.velocity_max ); 546 713 pinfo.death = ms + ( edata.lifetime_min == edata.lifetime_max ? … … 548 715 //pinfo.rotation = r.frand( 360.0f ); 549 716 550 pinfo. dir= edata.dir;717 pinfo.velocity = edata.dir; 551 718 if ( edata.angle > 0.0f ) 552 719 { … … 555 722 float sin_theta = glm::sqrt(1.0f - cos_theta * cos_theta ); 556 723 float phi = r.frange( 0.0f, 2*glm::pi<float>() ); 557 pinfo. dir= orient *724 pinfo.velocity = orient * 558 725 ( edata.odir * ( glm::cos(phi) * sin_theta ) + 559 726 edata.cdir * ( glm::sin(phi)*sin_theta ) + 560 727 edata.dir * cos_theta ); 561 728 } 729 730 pinfo.velocity *= velocity; 562 731 563 732 info->count++; … … 569 738 } 570 739 571 void nv::particle_engine::update_particles( particle_system_info* system, uint32 ms ) 572 { 573 uint32 ticks = ms - system->last_update; 574 if ( ticks > 0 ) 575 for ( uint32 i = 0; i < system->count; ++i ) 576 { 577 particle& pdata = system->particles[i]; 578 vec3 velocity_vec = pdata.dir * pdata.velocity; 579 pdata.position += velocity_vec * ( 0.001f * ticks ); 580 velocity_vec += system->data->gravity * ( 0.001f * ticks ); 581 pdata.velocity = glm::length( velocity_vec ); 582 if ( pdata.velocity > 0.0f ) pdata.dir = glm::normalize( velocity_vec ); 583 if ( pdata.position.y < 0.0f ) 584 { 585 if ( pdata.velocity > 1.0f ) 586 { 587 pdata.position.y = -pdata.position.y; 588 pdata.velocity = 0.5f*pdata.velocity; 589 pdata.dir.y = -pdata.dir.y; 590 } 591 else 592 { 593 pdata.position.y = 0.0f; 594 pdata.velocity = 0.0f; 595 } 596 } 597 } 598 system->last_update = ms; 740 void nv::particle_engine::update_particles( particle_system_info* info, uint32 ms ) 741 { 742 uint32 ticks = ms - info->last_update; 743 if ( ticks == 0 ) return; 744 float factor = 0.001f * ticks; 745 746 uint32 acount = info->data->affector_count; 747 for ( uint32 i = 0; i < acount; ++i ) 748 { 749 const particle_affector_data* padata = &(info->data->affectors[i]); 750 padata->process( padata, info->particles, factor, info->count ); 751 } 752 753 754 for ( uint32 i = 0; i < info->count; ++i ) 755 { 756 particle& pdata = info->particles[i]; 757 pdata.position += pdata.velocity * factor; 758 } 759 info->last_update = ms; 599 760 } 600 761 … … 630 791 631 792 } 793 794 void nv::particle_engine::register_emmiter_type( const std::string& name, particle_emmiter_func func ) 795 { 796 m_emmiters[ name ] = func; 797 } 798 799 void nv::particle_engine::register_standard_emmiters() 800 { 801 register_emmiter_type( "point", nv_particle_emmiter_point ); 802 register_emmiter_type( "box", nv_particle_emmiter_box ); 803 register_emmiter_type( "cylinder", nv_particle_emmiter_cylinder ); 804 register_emmiter_type( "sphere", nv_particle_emmiter_sphere ); 805 register_emmiter_type( "cylindroid", nv_particle_emmiter_cylindroid ); 806 register_emmiter_type( "ellipsoid", nv_particle_emmiter_ellipsoid ); 807 register_emmiter_type( "hollow_cylinder", nv_particle_emmiter_hollow_cylinder ); 808 register_emmiter_type( "hollow_sphere", nv_particle_emmiter_hollow_sphere ); 809 register_emmiter_type( "hollow_cylindroid", nv_particle_emmiter_hollow_cylindroid ); 810 register_emmiter_type( "hollow_ellipsoid", nv_particle_emmiter_hollow_ellipsoid ); 811 } 812 813 void nv::particle_engine::register_affector_type( const std::string& name, particle_affector_init_func init, particle_affector_func process ) 814 { 815 m_affectors[ name ].init = init; 816 m_affectors[ name ].process = process; 817 } 818 819 void nv::particle_engine::register_standard_affectors() 820 { 821 register_affector_type( "linear_force", nv_particle_affector_linear_force_init, nv_particle_affector_linear_force ); 822 register_affector_type( "deflector_plane", nv_particle_affector_deflector_plane_init, nv_particle_affector_deflector_plane ); 823 register_affector_type( "color_fader", nv_particle_affector_color_fader_init, nv_particle_affector_color_fader ); 824 register_affector_type( "scaler", nv_particle_affector_scaler_init, nv_particle_affector_scaler ); 825 } 826
Note: See TracChangeset
for help on using the changeset viewer.