Changeset 309 for trunk/src/gfx/particle_engine.cc
- Timestamp:
- 08/12/14 20:37:39 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gfx/particle_engine.cc
r307 r309 5 5 #include <nv/lua/lua_glm.hh> 6 6 #include <nv/logging.hh> 7 #include <cmath> 7 8 8 9 static const char *nv_particle_engine_vertex_shader_world = … … 61 62 data.gravity = table.get<vec3>("gravity", vec3() ); 62 63 data.quota = table.get<uint32>("quota", 1024 ); 63 data.local = table.get<bool>("local ", false );64 data.local = table.get<bool>("local_space", false ); 64 65 data.accurate_facing = table.get<bool>("accurate_facing", false ); 65 66 data.emmiter_count = 0; … … 73 74 else 74 75 { 75 NV_LOG( LOG_ERROR, "Unknown orientation type! (" << orientation << " is MAX)!" );76 NV_LOG( LOG_ERROR, "Unknown orientation type! (" << orientation << ")!" ); 76 77 data.orientation = particle_orientation::POINT; 77 78 } 79 80 std::string origin = table.get_string( "origin", "center" ); 81 if ( origin == "center" ) { data.origin = particle_origin::CENTER; } 82 else if ( origin == "top_left" ) { data.origin = particle_origin::TOP_LEFT; } 83 else if ( origin == "top_center" ) { data.origin = particle_origin::TOP_CENTER; } 84 else if ( origin == "top_right" ) { data.origin = particle_origin::TOP_RIGHT; } 85 else if ( origin == "center_left" ) { data.origin = particle_origin::CENTER_LEFT; } 86 else if ( origin == "center_right" ) { data.origin = particle_origin::CENTER_RIGHT; } 87 else if ( origin == "bottom_left" ) { data.origin = particle_origin::BOTTOM_LEFT; } 88 else if ( origin == "bottom_center" ) { data.origin = particle_origin::BOTTOM_CENTER; } 89 else if ( origin == "bottom_right" ) { data.origin = particle_origin::BOTTOM_RIGHT; } 90 else 91 { 92 NV_LOG( LOG_ERROR, "Unknown particle origin! (" << origin << ")!" ); 93 data.origin = particle_origin::CENTER; 94 } 95 78 96 data.common_up = glm::normalize( table.get<vec3>("common_up", vec3(1,0,0) ) ); 79 97 data.common_dir = glm::normalize( table.get<vec3>("common_dir", vec3(0,1,0) ) ); 80 98 99 vec2 def_size = table.get<vec2>("size", vec2(0.1,0.1) ); 81 100 uint32 elements = table.get_size(); 82 101 for ( uint32 i = 0; i < elements; ++i ) 83 102 { 84 103 lua::table_guard element( table, i+1 ); 85 std::string type = element.get_string("type");86 std::string etype = element.get_string("etype");104 std::string type = element.get_string("type"); 105 std::string sub_type = element.get_string("sub_type"); 87 106 if ( type == "emmiter" ) 88 107 { … … 90 109 { 91 110 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; 122 else 123 { 124 edata.type = particle_emmiter_type::POINT; 125 NV_LOG( LOG_WARNING, "Unknown emmiter type in particle system! (" << sub_type << ")" ); 126 } 127 128 edata.position = element.get<vec3>("position", vec3() ); 129 edata.extents = element.get<vec3>("extents", vec3(1,1,1) ); 130 edata.extents[0] = element.get<float>("width", edata.extents[0] ); 131 edata.extents[1] = element.get<float>("depth", edata.extents[1] ); 132 edata.extents[2] = element.get<float>("height", edata.extents[2] ); 133 edata.extents[0] = element.get<float>("radius", edata.extents[0] ); 134 edata.iextents = element.get<vec3>("inner_extents", vec3() ); 135 edata.iextents[0] = element.get<float>("inner_width", edata.iextents[0] ); 136 edata.iextents[1] = element.get<float>("inner_depth", edata.iextents[1] ); 137 edata.iextents[2] = element.get<float>("inner_height", edata.iextents[2] ); 138 edata.iextents[0] = element.get<float>("inner_radius", edata.iextents[0] ); 139 edata.hextents = 0.5f * edata.extents; 140 edata.ihextents = 0.5f * edata.iextents; 141 edata.precise = element.get<bool>("precise", false ); 142 edata.square = element.get<bool>("square", true ); 92 143 vec4 color = element.get<vec4>("color", vec4(1,1,1,1) ); 93 144 edata.color_min = element.get<vec4>("color_min", color ); 94 145 edata.color_max = element.get<vec4>("color_max", color ); 95 vec2 size = element.get<vec2>("size", vec2(0.1,0.1));146 vec2 size = element.get<vec2>("size", def_size ); 96 147 edata.size_min = element.get<vec2>("size_min", size ); 97 148 edata.size_max = element.get<vec2>("size_max", size ); 98 edata.square = element.get<bool>("square", true );99 149 edata.angle = element.get<float>("angle", 0.0f ); 100 150 float velocity = element.get<float>("velocity", 0.0f ); … … 249 299 void nv::particle_engine::generate_data( particle_system_info* info ) 250 300 { 251 const vec3 x( 0.5f, 0.0f, 0.0f ); 252 const vec3 y( 0.0f, 0.5f, 0.0f ); 253 const vec3 z( 0.0f, 0.0f ,1.0f ); 254 255 const vec3 sm[4] = { 256 vec3( -x-y ), 257 vec3( x-y ), 258 vec3( -x+y ), 259 vec3( x+y ) 301 vec2 lb = vec2( -0.5f, -0.5f ); 302 vec2 rt = vec2( 0.5f, 0.5f ); 303 304 switch ( info->data->origin ) 305 { 306 case particle_origin::CENTER : break; 307 case particle_origin::TOP_LEFT : lb = vec2(0.f,-1.f); rt = vec2(1.f,0.f); break; 308 case particle_origin::TOP_CENTER : lb.y = -1.f; rt.y = 0.f; break; break; 309 case particle_origin::TOP_RIGHT : lb = vec2(-1.f,-1.f); rt = vec2(); break; 310 case particle_origin::CENTER_LEFT : lb.x = 0.f; rt.x = 1.f; break; 311 case particle_origin::CENTER_RIGHT : lb.x = -1.f; rt.x = 0.f; break; 312 case particle_origin::BOTTOM_LEFT : lb = vec2(); rt = vec2(1.f,1.f); break; 313 case particle_origin::BOTTOM_CENTER : lb.y = 0.f; rt.y = 1.f; break; 314 case particle_origin::BOTTOM_RIGHT : lb = vec2(-1.f,0.f); rt = vec2(.0f,1.f); break; 315 } 316 317 const vec3 sm[4] = 318 { 319 vec3( lb.x, lb.y, 0.0f ), 320 vec3( rt.x, lb.y, 0.0f ), 321 vec3( lb.x, rt.y, 0.0f ), 322 vec3( rt.x, rt.y, 0.0f ), 260 323 }; 324 vec3 z( 0.0f, 0.0f ,1.0f ); 261 325 262 326 mat3 rot_mat; … … 353 417 orient = mat3( m_model_matrix ); 354 418 } 419 float fms = float(ms); 355 420 356 421 for ( uint32 i = 0; i < ecount; ++i ) … … 360 425 if ( einfo.active ) 361 426 { 362 uint32 period = glm::max<uint32>( uint32(1000.f / edata.rate), 1 );363 while ( ms - einfo.last_create > period )427 float period = 1000.f / edata.rate; 428 while ( fms - einfo.last_create > period ) 364 429 { 365 430 if ( info->count < info->data->quota-1 ) 366 431 { 367 432 particle& pinfo = info->particles[info->count]; 368 pinfo.position = source; 369 pinfo.color = edata.color_min == edata.color_max ? 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 } 538 pinfo.position += edata.position; 539 pinfo.color = edata.color_min == edata.color_max ? 370 540 edata.color_min : r.range( edata.color_min, edata.color_max ); 371 pinfo.size = edata.size_min == edata.size_max ?541 pinfo.size = edata.size_min == edata.size_max ? 372 542 edata.size_min : r.range( edata.size_min, edata.size_max ); 373 543 if ( edata.square ) pinfo.size.y = pinfo.size.x; … … 453 623 { 454 624 einfo.active = true; 455 einfo.last_create = einfo.next_toggle;625 einfo.last_create = float( einfo.next_toggle ); 456 626 einfo.next_toggle += r.urange( edata.duration_min, edata.duration_max ); 457 627 }
Note: See TracChangeset
for help on using the changeset viewer.