00001
00007 #include "ParticleSystem.h"
00008
00009 ParticleSystem::ParticleSystem() {
00010 m_age = 0.0f;
00011 m_timeLastUpdate = 0.0f;
00012 m_emissionResidue = 0.0f;
00013 m_direction = Vec3(0, 0, 0);
00014 die();
00015 }
00016
00017 ParticleSystem::~ParticleSystem() {
00018 }
00019
00020 bool ParticleSystem::update(float dTime, bool absoluteTime) {
00021 if (absoluteTime) {
00022 float time = dTime;
00023 dTime = dTime - m_timeLastUpdate;
00024 m_timeLastUpdate = time;
00025 }
00026
00027
00028 if (m_isMoving) {
00029 static float thetaHoriz = 0.0f;
00030 static float thetaVert = 180.0f;
00031
00032 thetaHoriz += 50.0f * dTime;
00033 thetaVert += 30.0f * dTime;
00034
00035 if (thetaHoriz > 350.0f)
00036 thetaHoriz = 0.0f;
00037
00038 if (thetaVert > 359.0f)
00039 thetaVert = 0.0f;
00040
00041 m_location.x = 30.0f*(float)cos(thetaHoriz*0.01745f);
00042 m_location.y = 50.0f+30.0f*(float)sin(thetaVert*0.1745f);
00043 m_location.z = 30.0f*(float)sin(thetaHoriz*0.01645f);
00044 }
00045 else {
00046
00047
00048
00049 }
00050
00051 m_particlesAlive = 0;
00052
00053 for (int i=0; i<MAX_PARTICLES; i++) {
00054 if (m_particles[i].m_age >= 0.0f)
00055 if (m_particles[i].update(dTime))
00056 m_particlesAlive++;
00057 }
00058
00059 float particlesNeeded = m_particlesPerSec*dTime + m_emissionResidue;
00060
00061 unsigned int particlesCreated = (unsigned int)particlesNeeded;
00062
00063 if (!m_isSuppressed) {
00064 m_emissionResidue = particlesNeeded - particlesCreated;
00065 }
00066 else {
00067 m_emissionResidue = particlesNeeded;
00068 particlesCreated = 0;
00069 }
00070
00071
00072 if (particlesCreated > 0) {
00073 for (i=0; i<MAX_PARTICLES; i++) {
00074 if (!particlesCreated)
00075 break;
00076
00077
00078 if (m_particles[i].m_age < 0.0f) {
00079 m_particles[i].m_age = 0.0f;
00080 m_particles[i].m_lifetime = m_life + RANDOM_NUM * m_lifeVar;
00081 Clamp(m_particles[i].m_lifetime, MIN_LIFETIME, MAX_LIFETIME);
00082
00083 m_particles[i].m_color.x = m_colorStart.x + RANDOM_NUM * m_colorVar.x;
00084 m_particles[i].m_color.y = m_colorStart.y + RANDOM_NUM * m_colorVar.y;
00085 m_particles[i].m_color.z = m_colorStart.z + RANDOM_NUM * m_colorVar.z;
00086 m_particles[i].m_color.w = 1.0f;
00087
00088 Clamp(m_particles[i].m_color.x, 0.0f, 1.0f);
00089 Clamp(m_particles[i].m_color.y, 0.0f, 1.0f);
00090 Clamp(m_particles[i].m_color.z, 0.0f, 1.0f);
00091
00092 m_particles[i].m_dColor.x = (m_colorEnd.x - m_particles[i].m_color.x)/m_particles[i].m_lifetime;
00093 m_particles[i].m_dColor.y = (m_colorEnd.y - m_particles[i].m_color.y)/m_particles[i].m_lifetime;
00094 m_particles[i].m_dColor.z = (m_colorEnd.z - m_particles[i].m_color.z)/m_particles[i].m_lifetime;
00095
00096 m_particles[i].m_alpha = m_alphaStart + RANDOM_NUM*m_alphaVar;
00097 Clamp(m_particles[i].m_alpha, MIN_ALPHA, MAX_ALPHA);
00098 m_particles[i].m_dAlpha = (m_alphaEnd - m_particles[i].m_alpha) / m_particles[i].m_lifetime;
00099
00100 m_particles[i].m_size = m_sizeStart + RANDOM_NUM*m_sizeVar;
00101 Clamp(m_particles[i].m_size, MIN_SIZE, MAX_SIZE);
00102 m_particles[i].m_dSize = (m_sizeEnd - m_particles[i].m_size) / m_particles[i].m_lifetime;
00103
00104 m_particles[i].m_gravity = m_gravityStart*9.82f + RANDOM_NUM*m_gravityVar*9.82f;
00105 Clamp(m_particles[i].m_gravity, MIN_GRAVITY*9.82f, MAX_GRAVITY*9.82f);
00106 m_particles[i].m_dGravity = (m_gravityEnd*9.82f - m_particles[i].m_gravity) / m_particles[i].m_lifetime;
00107
00108 Vec3 tmpVelocity = (m_location - m_prevLocation)/dTime;
00109
00110 m_particles[i].m_location = m_prevLocation + tmpVelocity*RANDOM_NUM*dTime;
00111
00112 m_particles[i].m_prevLocation = m_location;
00113
00114 float randomYaw = RANDOM_NUM*3.14159f*2.0f;
00115 float randomPitch = RANDOM_NUM*m_theta*3.14159f/180.0f;
00116
00117 m_particles[i].m_velocity.y = cosf(randomPitch);
00118 m_particles[i].m_velocity.x = sinf(randomPitch)*cosf(randomYaw);
00119 m_particles[i].m_velocity.z = sinf(randomPitch)*sinf(randomYaw);
00120
00121 float newSpeed = m_speed + RANDOM_NUM*m_speedVar;
00122 Clamp(newSpeed, MIN_SPEED, MAX_SPEED);
00123
00124 m_particles[i].m_velocity *= newSpeed;
00125
00126 m_particles[i].setParent(this);
00127
00128 particlesCreated--;
00129 }
00130 }
00131 }
00132
00133 m_prevLocation = m_location;
00134
00135 return true;
00136 }
00137
00138 void ParticleSystem::move(Vec3 location) {
00139 m_baseLocation = location;
00140 m_prevLocation = m_location;
00141 m_location = location;
00142 }
00143
00144 bool ParticleSystem::isMoving() {
00145 return m_isMoving;
00146 }
00147
00148 bool ParticleSystem::isColliding() {
00149 return m_isColliding;
00150 }
00151
00152 bool ParticleSystem::isAttractive() {
00153 return m_isAttractive;
00154 }
00155
00156 void ParticleSystem::getLocation(Vec3 &location) {
00157 location = m_location;
00158 }
00159
00160 unsigned int ParticleSystem::numParticles() {
00161 return m_particlesAlive;
00162 }
00163
00164 void ParticleSystem::setRenderer(void *renderer) {
00165 m_renderer = renderer;
00166 }
00167
00168 void ParticleSystem::loadPreset(unsigned int preset) {
00169 switch (preset) {
00170 case 0:
00171 m_colorStart.x = 1.0f;
00172 m_colorStart.y = 0.8f;
00173 m_colorStart.z = 0.5f;
00174
00175 m_colorVar.x = 0.0f;
00176 m_colorVar.y = 0.0f;
00177 m_colorVar.z = 0.0f;
00178
00179 m_colorEnd.x = 0.0f;
00180 m_colorEnd.y = 0.0f;
00181 m_colorEnd.z = 1.0f;
00182
00183 m_alphaStart = 0.5f;
00184 m_alphaVar = 0.0f;
00185 m_alphaEnd = 0.0f;
00186
00187 m_sizeStart = 4.0f;
00188 m_sizeVar = 0.0f;
00189 m_sizeEnd = 8.0f;
00190
00191 m_speed = 15.0f;
00192 m_speedVar = 0.0f;
00193
00194 m_theta = 180.0f;
00195
00196 m_life = 1.0f;
00197 m_lifeVar = 0.5f;
00198
00199 m_gravityStart = 0.0f;
00200 m_gravityVar = 0.0f;
00201 m_gravityEnd = 0.0f;
00202
00203 m_particlesPerSec = 80;
00204
00205 m_isMoving = FALSE;
00206 m_isAttractive = FALSE;
00207 m_isColliding = FALSE;
00208
00209
00210 break;
00211
00212 case 1:
00213 m_colorStart.x = 1.0f;
00214 m_colorStart.y = 1.0f;
00215 m_colorStart.z = 0.2f;
00216
00217 m_colorVar.x = 0.0f;
00218 m_colorVar.y = 0.0f;
00219 m_colorVar.z = 0.0f;
00220
00221 m_colorEnd.x = 1.0f;
00222 m_colorEnd.y = 0.0f;
00223 m_colorEnd.z = 0.0f;
00224
00225 m_alphaStart = 1.0f;
00226 m_alphaVar = 0.0f;
00227 m_alphaEnd = 0.0f;
00228
00229 m_sizeStart = 0.5f;
00230 m_sizeVar = 0.0f;
00231 m_sizeEnd = 10.0f;
00232
00233 m_speed = 0.0f;
00234 m_speedVar = 0.0f;
00235
00236 m_theta = 0.0f;
00237
00238 m_life = 2.0f;
00239 m_lifeVar = 0.0f;
00240
00241 m_gravityStart = 1.0f;
00242 m_gravityVar = 0.0f;
00243 m_gravityEnd = 1.0f;
00244
00245 m_particlesPerSec = 100;
00246
00247 m_isMoving = TRUE;
00248 m_isAttractive = FALSE;
00249 m_isColliding = TRUE;
00250
00251
00252 break;
00253
00254 case 2:
00255 m_colorStart.x = 1.0f;
00256 m_colorStart.y = 1.0f;
00257 m_colorStart.z = 1.0f;
00258
00259 m_colorVar.x = 0.0f;
00260 m_colorVar.y = 0.0f;
00261 m_colorVar.z = 0.0f;
00262
00263 m_colorEnd.x = 0.0f;
00264 m_colorEnd.y = 0.0f;
00265 m_colorEnd.z = 1.0f;
00266
00267 m_alphaStart = 1.0f;
00268 m_alphaVar = 0.0f;
00269 m_alphaEnd = 0.0f;
00270
00271 m_sizeStart = 4.0f;
00272 m_sizeVar = 0.0f;
00273 m_sizeEnd = 0.5f;
00274
00275 m_speed = 60.0f;
00276 m_speedVar = 10.0f;
00277
00278 m_theta = 35.0f;
00279
00280 m_life = 4.0f;
00281 m_lifeVar = 0.0f;
00282
00283 m_gravityStart = 0.0f;
00284 m_gravityVar = 0.0f;
00285 m_gravityEnd = 4.0f;
00286
00287 m_particlesPerSec = 150;
00288
00289 m_isMoving = FALSE;
00290 m_isAttractive = FALSE;
00291 m_isColliding = TRUE;
00292
00293
00294 break;
00295
00296 case 3:
00297 m_colorStart.x = 0.0f;
00298 m_colorStart.y = 1.0f;
00299 m_colorStart.z = 0.0f;
00300
00301 m_colorVar.x = 0.5f;
00302 m_colorVar.y = 0.5f;
00303 m_colorVar.z = 0.5f;
00304
00305 m_colorEnd.x = 1.0f;
00306 m_colorEnd.y = 1.0f;
00307 m_colorEnd.z = 1.0f;
00308
00309 m_alphaStart = 1.0f;
00310 m_alphaVar = 0.0f;
00311 m_alphaEnd = 1.0f;
00312
00313 m_sizeStart = 10.0f;
00314 m_sizeVar = 0.0f;
00315 m_sizeEnd = 5.0f;
00316
00317 m_speed = 50.0f;
00318 m_speedVar = 0.0f;
00319
00320 m_theta = 180.0f;
00321
00322 m_life = 4.0f;
00323 m_lifeVar = 0.0f;
00324
00325 m_gravityStart = 0.0f;
00326 m_gravityVar = 0.0f;
00327 m_gravityEnd = 0.0f;
00328
00329 m_particlesPerSec = 80;
00330
00331 m_isMoving = FALSE;
00332 m_isAttractive = TRUE;
00333 m_isColliding = FALSE;
00334
00335
00336 break;
00337
00338 case 4:
00339 m_colorStart.x = 1.0f;
00340 m_colorStart.y = 1.0f;
00341 m_colorStart.z = 1.0f;
00342
00343 m_colorVar.x = 0.1f;
00344 m_colorVar.y = 0.1f;
00345 m_colorVar.z = 0.1f;
00346
00347 m_colorEnd.x = 0.0f;
00348 m_colorEnd.y = 0.0f;
00349 m_colorEnd.z = 1.0f;
00350
00351 m_alphaStart = 0.7f;
00352 m_alphaVar = 0.0f;
00353 m_alphaEnd = 0.0f;
00354
00355 m_sizeStart = 2.0f;
00356 m_sizeVar = 0.1f;
00357 m_sizeEnd = 10.0f;
00358
00359 m_speed = 8.0f;
00360 m_speedVar = 0.0f;
00361
00362 m_theta = 180.0f;
00363
00364 m_life = 2.0f;
00365 m_lifeVar = 0.0f;
00366
00367 m_gravityStart = 0.0f;
00368 m_gravityVar = 0.0f;
00369 m_gravityEnd = 0.0f;
00370
00371 m_particlesPerSec = 45;
00372
00373 m_isMoving = FALSE;
00374 m_isAttractive = FALSE;
00375 m_isColliding = FALSE;
00376
00377
00378 break;
00379
00380 case 5:
00381 m_colorStart.x = 0.0f;
00382 m_colorStart.y = 0.0f;
00383 m_colorStart.z = 0.0f;
00384
00385 m_colorVar.x = 0.0f;
00386 m_colorVar.y = 0.0f;
00387 m_colorVar.z = 0.0f;
00388
00389 m_colorEnd.x = 0.5f;
00390 m_colorEnd.y = 0.5f;
00391 m_colorEnd.z = 0.5f;
00392
00393 m_alphaStart = 0.0f;
00394 m_alphaVar = 0.5f;
00395 m_alphaEnd = 0.0f;
00396
00397 m_sizeStart = 35.0f;
00398 m_sizeVar = 20.0f;
00399 m_sizeEnd = 5.0f;
00400
00401 m_speed = 5.0f;
00402 m_speedVar = 1.5f;
00403
00404 m_theta = 70.0f;
00405
00406 m_life = 2.0f;
00407 m_lifeVar = 0.0f;
00408
00409 m_gravityStart = -0.15f;
00410 m_gravityVar = -0.35f;
00411 m_gravityEnd = -0.75f;
00412
00413 m_particlesPerSec = 150;
00414
00415 m_isMoving = FALSE;
00416 m_isAttractive = FALSE;
00417 m_isColliding = FALSE;
00418
00419
00420 break;
00421
00422 case 6:
00423 m_colorStart.x = 1.00f;
00424 m_colorStart.y = 1.00f;
00425 m_colorStart.z = 0.30f;
00426
00427 m_colorVar.x = 0.00f;
00428 m_colorVar.y = 0.00f;
00429 m_colorVar.z = 0.00f;
00430
00431 m_colorEnd.x = 0.70f;
00432 m_colorEnd.y = 0.30f;
00433 m_colorEnd.z = 0.00f;
00434
00435 m_alphaStart = 0.96f;
00436 m_alphaVar = 1.00f;
00437 m_alphaEnd = 0.16f;
00438
00439 m_sizeStart = 2.74f;
00440 m_sizeVar = 2.00f;
00441 m_sizeEnd = 6.09f;
00442
00443 m_speed = 14.71f;
00444 m_speedVar = 50.00f;
00445
00446 m_theta = 30.12f;
00447
00448 m_life = 0.77f;
00449 m_lifeVar = 0.50f;
00450
00451 m_gravityStart = -0.69f;
00452 m_gravityVar = 1.00f;
00453 m_gravityEnd = -0.49f;
00454
00455 m_particlesPerSec = 441;
00456
00457 m_isMoving = 0;
00458 m_isAttractive = 0;
00459 m_isColliding = 0;
00460
00461
00462 break;
00463
00464 case 7:
00465 m_colorStart.x = 0.00f;
00466 m_colorStart.y = 0.00f;
00467 m_colorStart.z = 0.00f;
00468
00469 m_colorVar.x = 1.00f;
00470 m_colorVar.y = 1.00f;
00471 m_colorVar.z = 1.00f;
00472
00473 m_colorEnd.x = 0.00f;
00474 m_colorEnd.y = 0.00f;
00475 m_colorEnd.z = 0.00f;
00476
00477 m_alphaStart = 0.87f;
00478 m_alphaVar = 1.00f;
00479 m_alphaEnd = 0.89f;
00480
00481 m_sizeStart = 0.59f;
00482 m_sizeVar = 0.00f;
00483 m_sizeEnd = 9.35f;
00484
00485 m_speed = 188.73f;
00486 m_speedVar = 10.00f;
00487 m_theta = 54.71f;
00488
00489 m_life = 0.78f;
00490 m_lifeVar = 0.00f;
00491
00492 m_gravityStart = -0.20f;
00493 m_gravityVar = 0.00f;
00494 m_gravityEnd = -0.20f;
00495
00496 m_particlesPerSec = 676;
00497
00498 m_isMoving = 0;
00499 m_isAttractive = 0;
00500 m_isColliding = 0;
00501
00502
00503 break;
00504
00505 case PARTICLESYSTEM_SPAWN:
00506 m_colorStart.x = 0.50f;
00507 m_colorStart.y = 0.80f;
00508 m_colorStart.z = 0.50f;
00509
00510 m_colorVar.x = 0.10f;
00511 m_colorVar.y = 0.10f;
00512 m_colorVar.z = 0.10f;
00513
00514 m_colorEnd.x = 0.00f;
00515 m_colorEnd.y = 0.70f;
00516 m_colorEnd.z = 0.00f;
00517
00518 m_alphaStart = 0.9f;
00519 m_alphaVar = 0.00f;
00520 m_alphaEnd = 0.0f;
00521
00522 m_sizeStart = 4.50f;
00523 m_sizeVar = 0.50f;
00524 m_sizeEnd = 4.53f;
00525
00526 m_speed = 100.00f;
00527 m_speedVar = 5.00f;
00528
00529 m_theta = 10.00f;
00530
00531 m_life = 1.50f;
00532 m_lifeVar = 0.20f;
00533
00534 m_gravityStart = -0.29f;
00535 m_gravityVar = 0.00f;
00536 m_gravityEnd = 0.10f;
00537
00538 m_particlesPerSec = 59;
00539
00540 m_isMoving = true;
00541 m_isAttractive = false;
00542 m_isColliding = false;
00543
00544
00545 break;
00546
00547
00548 case PARTICLESYSTEM_SUN:
00549 m_colorStart.x = 1.00f;
00550 m_colorStart.y = 1.00f;
00551 m_colorStart.z = 0.30f;
00552
00553 m_colorVar.x = 0.00f;
00554 m_colorVar.y = 0.00f;
00555 m_colorVar.z = 0.00f;
00556
00557 m_colorEnd.x = 0.70f;
00558 m_colorEnd.y = 0.30f;
00559 m_colorEnd.z = 0.00f;
00560
00561 m_alphaStart = 0.96f;
00562 m_alphaVar = 1.00f;
00563 m_alphaEnd = 0.16f;
00564
00565 m_sizeStart = 7.0f;
00566 m_sizeVar = 0.1f;
00567 m_sizeEnd = 7.0f;
00568
00569 m_speed = 7.0f;
00570 m_speedVar = 0.0f;
00571
00572 m_theta = 180.0f;
00573
00574 m_life = 1.0f;
00575 m_lifeVar = 0.0f;
00576
00577 m_gravityStart = 0.0f;
00578 m_gravityVar = 0.0f;
00579 m_gravityEnd = 0.0f;
00580
00581 m_particlesPerSec = 25;
00582
00583 m_isMoving = false;
00584 m_isAttractive = false;
00585 m_isColliding = false;
00586
00587
00588 break;
00589
00590
00591
00592 default:
00593 m_colorStart.x = 1.0f;
00594 m_colorStart.y = 0.8f;
00595 m_colorStart.z = 0.5f;
00596
00597 m_colorVar.x = 0.0f;
00598 m_colorVar.y = 0.0f;
00599 m_colorVar.z = 0.0f;
00600
00601 m_colorEnd.x = 0.0f;
00602 m_colorEnd.y = 0.0f;
00603 m_colorEnd.z = 1.0f;
00604
00605 m_alphaStart = 0.5f;
00606 m_alphaVar = 0.0f;
00607 m_alphaEnd = 0.0f;
00608
00609 m_sizeStart = 4.0f;
00610 m_sizeVar = 0.0f;
00611 m_sizeEnd = 8.0f;
00612
00613 m_speed = 15.0f;
00614 m_speedVar = 0.0f;
00615
00616 m_theta = 180.0f;
00617
00618 m_life = 1.0f;
00619 m_lifeVar = 0.5f;
00620
00621 m_gravityStart = 0.0f;
00622 m_gravityVar = 0.0f;
00623 m_gravityEnd = 0.0f;
00624
00625 m_particlesPerSec = 80;
00626
00627 m_isMoving = FALSE;
00628 m_isAttractive = FALSE;
00629 m_isColliding = FALSE;
00630
00631
00632 break;
00633 }
00634 }