00001
00002
00003
00004
00005
00006
00007
00008 #include "particle.h"
00009 #include "matrix.h"
00010 #include "texture.h"
00011 #include "listnode.h"
00012 #include "collision.h"
00013 #include "general.h"
00014 #include "bsp.h"
00015 #include "locmath.h"
00016 #include "mmgr.h"
00017
00018 extern BSP_node* root;
00019 extern ParticleManager PManager;
00020 extern TEXTURE* texture;
00021 extern LinkedList<ListNode> LeafList;
00022 extern LinkedList<ListNode> PartitionList;
00023 extern ListNode* listnode;
00024
00025 int PARTICLE::Compare(const PARTICLE& Particle)
00026 {
00027 if (linkPosition < Particle.linkPosition)
00028 return smaller;
00029 if (linkPosition > Particle.linkPosition)
00030 return bigger;
00031 else
00032 return same;
00033 }
00034
00035
00036 void ParticleSystem::Render(int nodeid)
00037 {
00038
00039 }
00040
00041 void ParticleSystem::Update()
00042 {
00043
00044 }
00045
00046 void ParticleSystem::SetDefaults(PARTICLE* Particle)
00047 {
00048
00049 }
00050
00051 void ParticleSystem::SetShape(PARTICLE* Particle)
00052 {
00053
00054 }
00055
00056 int ParticleSystem::GetNumAlive()
00057 {
00058 int numParticles = 0;
00059 PARTICLE* tempParticle;
00060 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00061 {
00062 tempParticle = ParticleList.Get(loop);
00063 if (tempParticle->PartInfo.Alive)
00064 numParticles++;
00065 }
00066 return numParticles;
00067 }
00068
00069
00070 void ParticleSystem::SetupParticles()
00071 {
00072 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00073 {
00074 PARTICLE* newParticle = new PARTICLE;
00075 SetDefaults(newParticle);
00076 SetShape(newParticle);
00077 newParticle->linkPosition = loop;
00078 ParticleList.Insert(newParticle);
00079 }
00080 }
00081
00082 void ParticleSystem::Remove()
00083 {
00084 if (SysInfo.numParticles > 0)
00085 {
00086 ParticleList.Delete(1);
00087 --SysInfo.numParticles;
00088 }
00089 }
00090
00091 PARTICLE* ParticleSystem::Add()
00092 {
00093 PARTICLE* newParticle = new PARTICLE;
00094 SetDefaults(newParticle);
00095 SetShape(newParticle);
00096 newParticle->linkPosition = ++SysInfo.numParticles;
00097 ParticleList.Insert(newParticle);
00098 return newParticle;
00099 }
00100
00101 int ParticleSystem::Compare(const ParticleSystem& ParticleSys)
00102 {
00103 if (linkPosition < ParticleSys.linkPosition)
00104 return smaller;
00105 if (linkPosition > ParticleSys.linkPosition)
00106 return bigger;
00107 else
00108 return same;
00109 }
00110
00111
00112 void ParticleManager::Update()
00113 {
00114 int loop, innerloop;
00115 ParticleSystem* PartSys;
00116 PARTICLE* tempParticle;
00117 for (loop = 1; loop <= numSystems; loop++)
00118 {
00119 PartSys = SystemList.Get(loop);
00120
00121 if (!PartSys->GetNumAlive())
00122 {
00123 SystemList.Delete(PartSys->linkPosition);
00124 numSystems--;
00125 }
00126 else
00127 {
00128 PartSys->Update();
00129 for (innerloop = 1; innerloop < PartSys->SysInfo.numParticles; innerloop++)
00130 {
00131 tempParticle = PartSys->ParticleList.Get(innerloop);
00132 tempParticle->PartInfo.Leaf = FindCurrentLeaf(tempParticle->PartInfo.Pos, root);
00133 }
00134 }
00135 }
00136 }
00137
00138 void ParticleManager::Render(int nodeid)
00139 {
00140 for (int loop = 1; loop <= numSystems; loop++)
00141 {
00142 ParticleSystem* PartSys = SystemList.Get(loop);
00143 PartSys->Render(nodeid);
00144 }
00145 }
00146
00147 void ParticleManager::SetId(int Id, int newId)
00148 {
00149 for (int loop = 1; loop <= numSystems; loop++)
00150 {
00151 ParticleSystem* PartSys = SystemList.Get(loop);
00152 if (Id == PartSys->SysInfo.Id)
00153 PartSys->SysInfo.Id = newId;
00154 }
00155 }
00156
00157 void ParticleManager::SetTextureId(int Id, unsigned int TexID)
00158 {
00159 for (int loop = 1; loop <= numSystems; loop++)
00160 {
00161 ParticleSystem* PartSys = SystemList.Get(loop);
00162 if (Id == PartSys->SysInfo.Id)
00163 PartSys->SysInfo.TexID = TexID;
00164 }
00165 }
00166
00167 void ParticleManager::SetBlendMode(int Id, int BlendMode)
00168 {
00169 for (int loop = 1; loop <= numSystems; loop++)
00170 {
00171 ParticleSystem* PartSys = SystemList.Get(loop);
00172 if (Id == PartSys->SysInfo.Id)
00173 PartSys->SysInfo.BlendMode = BlendMode;
00174 }
00175 }
00176
00177 void ParticleManager::SetType(int Id, ParticleType Type)
00178 {
00179 for (int loop = 1; loop <= numSystems; loop++)
00180 {
00181 ParticleSystem* PartSys = SystemList.Get(loop);
00182 if (Id == PartSys->SysInfo.Id)
00183 PartSys->SysInfo.Type = Type;
00184 }
00185 }
00186
00187 void ParticleManager::SetVisibility(int Id, bool State)
00188 {
00189 for (int loop = 1; loop <= numSystems; loop++)
00190 {
00191 ParticleSystem* PartSys = SystemList.Get(loop);
00192 if (Id == PartSys->SysInfo.Id)
00193 PartSys->SysInfo.Visibility = State;
00194 }
00195 }
00196
00197 void ParticleManager::ToggleVisibility(int Id)
00198 {
00199 for (int loop = 1; loop <= numSystems; loop++)
00200 {
00201 ParticleSystem* PartSys = SystemList.Get(loop);
00202 if (Id == PartSys->SysInfo.Id)
00203 PartSys->SysInfo.Visibility = !PartSys->SysInfo.Visibility;
00204 }
00205 }
00206
00207 ParticleSystem* ParticleManager::Add(ParticleSystem* PartSys)
00208 {
00209 PartSys->SetupParticles();
00210 PartSys->linkPosition = ++numSystems;
00211 SystemList.Insert(PartSys);
00212 return PartSys;
00213 }
00214
00215 void ParticleManager::Remove(int Id)
00216 {
00217 for (int loop = 1; loop <= numSystems; loop++)
00218 {
00219 ParticleSystem* PartSys = SystemList.Get(loop);
00220 if (Id == PartSys->SysInfo.Id)
00221 {
00222 SystemList.Delete(PartSys->linkPosition);
00223 --numSystems;
00224 }
00225 }
00226 }
00227
00228 void ParticleManager::RemoveType(ParticleType Type)
00229 {
00230 for (int loop = 1; loop <= numSystems; loop++)
00231 {
00232 ParticleSystem* PartSys = SystemList.Get(loop);
00233 if (Type == PartSys->SysInfo.Type)
00234 {
00235 SystemList.Delete(PartSys->linkPosition);
00236 --numSystems;
00237 }
00238 }
00239 }
00240
00241
00242
00243
00244 void Spark::Update()
00245 {
00246 bool CollisionFlag;
00247 VECTOR VelocityVector, normal, pos, oldpos, temppos;
00248 PARTICLE* tempParticle;
00249
00250 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00251 {
00252
00253 tempParticle = ParticleList.Get(loop);
00254
00255 tempParticle->PartInfo.OldPos = tempParticle->PartInfo.Pos;
00256
00257 tempParticle->PartInfo.Velocity.x += 0.0;
00258 tempParticle->PartInfo.Velocity.y += -0.002;
00259 tempParticle->PartInfo.Velocity.z += 0.0;
00260
00261 if (tempParticle->PartInfo.Energy > 0.0)
00262 {
00263
00264 tempParticle->PartInfo.Color[3] = tempParticle->PartInfo.Energy;
00265
00266 tempParticle->PartInfo.Energy -= 0.002;
00267
00268 oldpos = tempParticle->PartInfo.Pos;
00269 pos = tempParticle->PartInfo.Pos + tempParticle->PartInfo.Velocity;
00270 temppos = pos;
00271
00272 CollisionFlag = CheckForParticleCollision(tempParticle, oldpos, &temppos, &normal);
00273
00274 if (CollisionFlag)
00275 {
00276 VECTOR vectn = normal * (normal.dot(tempParticle->PartInfo.Velocity));
00277 VECTOR vectt = tempParticle->PartInfo.Velocity - vectn;
00278 VECTOR vel = (vectt - vectn);
00279 tempParticle->PartInfo.Pos.x += vel.x;
00280 tempParticle->PartInfo.Pos.y += vel.y;
00281 tempParticle->PartInfo.Pos.z += vel.z;
00282
00283 tempParticle->PartInfo.Velocity.x = vel.x / 3.0;
00284 tempParticle->PartInfo.Velocity.y = vel.y / 3.0;
00285 tempParticle->PartInfo.Velocity.z = vel.z / 3.0;
00286
00287 tempParticle->PartInfo.Energy -= 0.2;
00288 }
00289 else
00290 {
00291 tempParticle->PartInfo.Pos.x += tempParticle->PartInfo.Velocity.x;
00292 tempParticle->PartInfo.Pos.y += tempParticle->PartInfo.Velocity.y;
00293 tempParticle->PartInfo.Pos.z += tempParticle->PartInfo.Velocity.z;
00294 }
00295 }
00296 else
00297 {
00298 tempParticle->PartInfo.Alive = false;
00299 }
00300 }
00301 }
00302
00303 void Spark::Render(int nodeid)
00304 {
00305 MATRIX mat;
00306 VECTOR up;
00307 VECTOR right;
00308 PARTICLE* tempParticle;
00309
00310 glGetFloatv(GL_MODELVIEW_MATRIX, mat.Element);
00311
00312 glEnable(GL_BLEND);
00313 glDepthMask(0);
00314 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00315 glDisable(GL_LIGHTING);
00316 glBindTexture(GL_TEXTURE_2D, SysInfo.TexID);
00317
00318 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00319 {
00320
00321 tempParticle = ParticleList.Get(loop);
00322
00323 if (tempParticle->PartInfo.Leaf == nodeid)
00324 {
00325
00326 if (tempParticle->PartInfo.Alive)
00327 {
00328
00329 right.x = mat.Element[0];
00330 right.y = mat.Element[4];
00331 right.z = mat.Element[8];
00332 right.Normalize();
00333 right.x *= tempParticle->PartInfo.SizeX / 2;
00334 right.y *= tempParticle->PartInfo.SizeX / 2;
00335 right.z *= tempParticle->PartInfo.SizeX / 2;
00336
00337 up.x = mat.Element[1];
00338 up.y = mat.Element[5];
00339 up.z = mat.Element[9];
00340 up.Normalize();
00341 up.x *= tempParticle->PartInfo.SizeY / 2;
00342 up.y *= tempParticle->PartInfo.SizeY / 2;
00343 up.z *= tempParticle->PartInfo.SizeY / 2;
00344
00345 glColor4f(tempParticle->PartInfo.Color[0],
00346 tempParticle->PartInfo.Color[1],
00347 tempParticle->PartInfo.Color[2],
00348 tempParticle->PartInfo.Color[3]);
00349
00350 glBegin(GL_QUADS);
00351 glTexCoord2f(0.0f, 0.0f);
00352 glVertex3f(tempParticle->PartInfo.Pos.x + (-right.x - up.x),
00353 tempParticle->PartInfo.Pos.y + (-right.y - up.y),
00354 tempParticle->PartInfo.Pos.z + (-right.z - up.z));
00355 glTexCoord2f(1.0f, 0.0f);
00356 glVertex3f(tempParticle->PartInfo.Pos.x + (right.x - up.x),
00357 tempParticle->PartInfo.Pos.y + (right.y - up.y),
00358 tempParticle->PartInfo.Pos.z + (right.z - up.z));
00359 glTexCoord2f(1.0f, 1.0f);
00360 glVertex3f(tempParticle->PartInfo.Pos.x + (right.x + up.x),
00361 tempParticle->PartInfo.Pos.y + (right.y + up.y),
00362 tempParticle->PartInfo.Pos.z + (right.z + up.z));
00363 glTexCoord2f(0.0f, 1.0f);
00364 glVertex3f(tempParticle->PartInfo.Pos.x + (up.x - right.x),
00365 tempParticle->PartInfo.Pos.y + (up.y - right.y),
00366 tempParticle->PartInfo.Pos.z + (up.z - right.z));
00367 glEnd();
00368 }
00369 }
00370 }
00371
00372 glEnable(GL_LIGHTING);
00373 glDepthMask(1);
00374 glDisable(GL_BLEND);
00375 }
00376
00377 void Spark::SetDefaults(PARTICLE* Particle)
00378 {
00379
00380 Particle->PartInfo.Alive = true;
00381 Particle->PartInfo.Pos = SysInfo.Pos;
00382 Particle->PartInfo.OldPos = SysInfo.Pos;
00383 Particle->PartInfo.OrigPos = SysInfo.Pos;
00384
00385 VECTOR Velocity = SysInfo.InitialVelocity;
00386 VECTOR vectn = SysInfo.Normal * (SysInfo.Normal.dot(Velocity));
00387 VECTOR vectt = Velocity - vectn;
00388 VECTOR vel = (vectt - vectn);
00389 Velocity.normalize();
00390
00391 float x;
00392 x = (float)rand()/(float)RAND_MAX;
00393 Particle->PartInfo.Velocity.x = Velocity.x + (x - 0.5);
00394 Particle->PartInfo.Velocity.x /= 2.0;
00395 x = (float)rand()/(float)RAND_MAX;
00396 Particle->PartInfo.Velocity.y = Velocity.y + (x - 0.5);
00397 Particle->PartInfo.Velocity.y /= 2.0;
00398 x = (float)rand()/(float)RAND_MAX;
00399 Particle->PartInfo.Velocity.z = Velocity.z + (x - 0.5);
00400 Particle->PartInfo.Velocity.z /= 2.0;
00401
00402 Particle->PartInfo.Color[0] = 1.0;
00403 Particle->PartInfo.Color[1] = 1.0;
00404 Particle->PartInfo.Color[2] = 1.0;
00405 Particle->PartInfo.Color[3] = 1.0;
00406
00407 x = (float)rand()/(float)RAND_MAX;
00408 Particle->PartInfo.Energy = x + 0.5;
00409 if (Particle->PartInfo.Energy > 1.0)
00410 Particle->PartInfo.Energy = 1.0;
00411
00412 Particle->PartInfo.SizeX = 0.8;
00413 Particle->PartInfo.SizeY = 0.8;
00414 }
00415
00416 void Spark::SetShape(PARTICLE* Particle)
00417 {
00418
00419 }
00420
00421
00422 void Roman::Update()
00423 {
00424 VECTOR normal, pos, oldpos, temppos;
00425 PARTICLE* tempParticle;
00426
00427 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00428 {
00429 tempParticle = ParticleList.Get(loop);
00430 tempParticle->PartInfo.OldPos = tempParticle->PartInfo.Pos;
00431 tempParticle->PartInfo.Velocity.x += 0.0;
00432 tempParticle->PartInfo.Velocity.y += -0.003;
00433 tempParticle->PartInfo.Velocity.z += 0.0;
00434 if (tempParticle->PartInfo.Energy > 0.0)
00435 {
00436 tempParticle->PartInfo.Color[3] = tempParticle->PartInfo.Energy;
00437 tempParticle->PartInfo.Energy -= 0.003;
00438 oldpos = tempParticle->PartInfo.Pos;
00439 pos = tempParticle->PartInfo.Pos + tempParticle->PartInfo.Velocity;
00440 temppos = pos;
00441 bool CollisionFlag = CheckForParticleCollision(tempParticle, oldpos, &temppos, &normal);
00442
00443 VECTOR VelocityVector;
00444
00445 if (CollisionFlag)
00446 {
00447 VECTOR vn = normal * (normal.dot(tempParticle->PartInfo.Velocity));
00448 VECTOR vt = tempParticle->PartInfo.Velocity - vn;
00449 VECTOR vel = (vt - vn);
00450 tempParticle->PartInfo.Pos.x += vel.x;
00451 tempParticle->PartInfo.Pos.y += vel.y;
00452 tempParticle->PartInfo.Pos.z += vel.z;
00453 tempParticle->PartInfo.Velocity.x = vel.x / 3.0;
00454 tempParticle->PartInfo.Velocity.y = vel.y / 3.0;
00455 tempParticle->PartInfo.Velocity.z = vel.z / 3.0;
00456 tempParticle->PartInfo.Energy -= 0.3;
00457 }
00458 else
00459 {
00460 tempParticle->PartInfo.Pos.x += tempParticle->PartInfo.Velocity.x;
00461 tempParticle->PartInfo.Pos.y += tempParticle->PartInfo.Velocity.y;
00462 tempParticle->PartInfo.Pos.z += tempParticle->PartInfo.Velocity.z;
00463 }
00464 }
00465 else
00466 {
00467 SetDefaults(tempParticle);
00468 }
00469
00470 tempParticle->PartInfo.Color[0] += 0.006;
00471 if (tempParticle->PartInfo.Color[0] > 1.0)
00472 tempParticle->PartInfo.Color[0] = 1.0;
00473 tempParticle->PartInfo.Color[1] += 0.006;
00474 if (tempParticle->PartInfo.Color[1] > 1.0)
00475 tempParticle->PartInfo.Color[1] = 1.0;
00476 tempParticle->PartInfo.Color[2] += 0.006;
00477 if (tempParticle->PartInfo.Color[2] > 1.0)
00478 tempParticle->PartInfo.Color[2] = 1.0;
00479 }
00480 }
00481
00482 void Roman::Render(int nodeid)
00483 {
00484 MATRIX mat;
00485 VECTOR up;
00486 VECTOR right;
00487 PARTICLE* tempParticle;
00488
00489 glGetFloatv(GL_MODELVIEW_MATRIX, mat.Element);
00490
00491 glEnable(GL_BLEND);
00492 glDepthMask(0);
00493 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00494 glDisable(GL_LIGHTING);
00495 glBindTexture(GL_TEXTURE_2D, SysInfo.TexID);
00496
00497 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00498 {
00499 tempParticle = ParticleList.Get(loop);
00500
00501 if (tempParticle->PartInfo.Leaf == nodeid)
00502 {
00503 if (tempParticle->PartInfo.Alive)
00504 {
00505 right.x = mat.Element[0];
00506 right.y = mat.Element[4];
00507 right.z = mat.Element[8];
00508 right.Normalize();
00509 right.x *= tempParticle->PartInfo.SizeX / 2;
00510 right.y *= tempParticle->PartInfo.SizeX / 2;
00511 right.z *= tempParticle->PartInfo.SizeX / 2;
00512
00513 up.x = mat.Element[1];
00514 up.y = mat.Element[5];
00515 up.z = mat.Element[9];
00516 up.Normalize();
00517 up.x *= tempParticle->PartInfo.SizeY / 2;
00518 up.y *= tempParticle->PartInfo.SizeY / 2;
00519 up.z *= tempParticle->PartInfo.SizeY / 2;
00520
00521 glColor4f(tempParticle->PartInfo.Color[0], tempParticle->PartInfo.Color[1], tempParticle->PartInfo.Color[2], tempParticle->PartInfo.Color[3]);
00522 glBegin(GL_QUADS);
00523 glTexCoord2f(0.0f, 0.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (-right.x - up.x), tempParticle->PartInfo.Pos.y + (-right.y - up.y), tempParticle->PartInfo.Pos.z + (-right.z - up.z));
00524 glTexCoord2f(1.0f, 0.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (right.x - up.x), tempParticle->PartInfo.Pos.y + (right.y - up.y), tempParticle->PartInfo.Pos.z + (right.z - up.z));
00525 glTexCoord2f(1.0f, 1.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (right.x + up.x), tempParticle->PartInfo.Pos.y + (right.y + up.y), tempParticle->PartInfo.Pos.z + (right.z + up.z));
00526 glTexCoord2f(0.0f, 1.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (up.x - right.x), tempParticle->PartInfo.Pos.y + (up.y - right.y), tempParticle->PartInfo.Pos.z + (up.z - right.z));
00527 glEnd();
00528 }
00529 }
00530 }
00531
00532 glEnable(GL_LIGHTING);
00533 glDepthMask(1);
00534 glDisable(GL_BLEND);
00535 }
00536
00537 void Roman::SetDefaults(PARTICLE* Particle)
00538 {
00539 Particle->PartInfo.Alive = true;
00540 Particle->PartInfo.Pos = SysInfo.Pos;
00541 Particle->PartInfo.OldPos = SysInfo.Pos;
00542 Particle->PartInfo.OrigPos = SysInfo.Pos;
00543
00544 VECTOR Velocity = SysInfo.Normal;
00545
00546 float x;
00547 x = (float)rand()/(float)RAND_MAX;
00548 Particle->PartInfo.Velocity.x = Velocity.x + (x - 0.5) / 5;
00549 Particle->PartInfo.Velocity.x /= 4.0;
00550 x = (float)rand()/(float)RAND_MAX;
00551 Particle->PartInfo.Velocity.y = Velocity.y + (x - 0.5);
00552 Particle->PartInfo.Velocity.y /= 4.0;
00553 x = (float)rand()/(float)RAND_MAX;
00554 Particle->PartInfo.Velocity.z = Velocity.z + (x - 0.5) / 5;
00555 Particle->PartInfo.Velocity.z /= 4.0;
00556
00557 Particle->PartInfo.Color[0] = SysInfo.Color[0];
00558 Particle->PartInfo.Color[1] = SysInfo.Color[1];
00559 Particle->PartInfo.Color[2] = SysInfo.Color[2];
00560 Particle->PartInfo.Color[3] = 1.0;
00561
00562 Particle->PartInfo.Energy = 1.0;
00563 Particle->PartInfo.SizeX = 3.0;
00564 Particle->PartInfo.SizeY = 3.0;
00565 }
00566
00567 void Roman::SetShape(PARTICLE* Particle)
00568 {
00569 }
00570
00571
00572 void Bouncy::Update()
00573 {
00574 bool CollisionFlag;
00575 VECTOR VelocityVector, normal, pos, oldpos, temppos;
00576 PARTICLE* tempParticle;
00577
00578 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00579 {
00580 tempParticle = ParticleList.Get(loop);
00581 tempParticle->PartInfo.OldPos = tempParticle->PartInfo.Pos;
00582 oldpos = tempParticle->PartInfo.Pos;
00583 pos = tempParticle->PartInfo.Pos + tempParticle->PartInfo.Velocity;
00584 temppos = pos;
00585 CollisionFlag = CheckForParticleCollision(tempParticle, oldpos, &temppos, &normal);
00586
00587 if (CollisionFlag)
00588 {
00589 VECTOR vn = normal * (normal.dot(tempParticle->PartInfo.Velocity));
00590 VECTOR vt = tempParticle->PartInfo.Velocity - vn;
00591 VECTOR vel = (vt - vn);
00592 tempParticle->PartInfo.Pos.x += vel.x;
00593 tempParticle->PartInfo.Pos.y += vel.y;
00594 tempParticle->PartInfo.Pos.z += vel.z;
00595 tempParticle->PartInfo.Velocity.x = vel.x;
00596 tempParticle->PartInfo.Velocity.y = vel.y;
00597 tempParticle->PartInfo.Velocity.z = vel.z;
00598 }
00599 else
00600 {
00601 tempParticle->PartInfo.Pos.x += tempParticle->PartInfo.Velocity.x;
00602 tempParticle->PartInfo.Pos.y += tempParticle->PartInfo.Velocity.y;
00603 tempParticle->PartInfo.Pos.z += tempParticle->PartInfo.Velocity.z;
00604 }
00605 }
00606 }
00607
00608 void Bouncy::Render(int nodeid)
00609 {
00610 MATRIX mat;
00611 VECTOR up;
00612 VECTOR right;
00613 PARTICLE* tempParticle;
00614
00615 glGetFloatv(GL_MODELVIEW_MATRIX, mat.Element);
00616
00617 glEnable(GL_BLEND);
00618 glDepthMask(0);
00619 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00620 glDisable(GL_LIGHTING);
00621 glBindTexture(GL_TEXTURE_2D, SysInfo.TexID);
00622
00623 for (int loop = 1; loop <= SysInfo.numParticles; loop++)
00624 {
00625 tempParticle = ParticleList.Get(loop);
00626
00627 if (tempParticle->PartInfo.Leaf == nodeid)
00628 {
00629 if (tempParticle->PartInfo.Alive)
00630 {
00631 right.x = mat.Element[0];
00632 right.y = mat.Element[4];
00633 right.z = mat.Element[8];
00634 right.Normalize();
00635 right.x *= tempParticle->PartInfo.SizeX / 2;
00636 right.y *= tempParticle->PartInfo.SizeX / 2;
00637 right.z *= tempParticle->PartInfo.SizeX / 2;
00638
00639 up.x = mat.Element[1];
00640 up.y = mat.Element[5];
00641 up.z = mat.Element[9];
00642 up.Normalize();
00643 up.x *= tempParticle->PartInfo.SizeY / 2;
00644 up.y *= tempParticle->PartInfo.SizeY / 2;
00645 up.z *= tempParticle->PartInfo.SizeY / 2;
00646
00647 glColor4f(0.0, 1.0, 0.0, 1.0);
00648 glBegin(GL_QUADS);
00649 glTexCoord2f(0.0f, 0.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (-right.x - up.x), tempParticle->PartInfo.Pos.y + (-right.y - up.y), tempParticle->PartInfo.Pos.z + (-right.z - up.z));
00650 glTexCoord2f(1.0f, 0.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (right.x - up.x), tempParticle->PartInfo.Pos.y + (right.y - up.y), tempParticle->PartInfo.Pos.z + (right.z - up.z));
00651 glTexCoord2f(1.0f, 1.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (right.x + up.x), tempParticle->PartInfo.Pos.y + (right.y + up.y), tempParticle->PartInfo.Pos.z + (right.z + up.z));
00652 glTexCoord2f(0.0f, 1.0f); glVertex3f(tempParticle->PartInfo.Pos.x + (up.x - right.x), tempParticle->PartInfo.Pos.y + (up.y - right.y), tempParticle->PartInfo.Pos.z + (up.z - right.z));
00653 glEnd();
00654 }
00655 }
00656 }
00657
00658 glEnable(GL_LIGHTING);
00659 glDepthMask(1);
00660 glDisable(GL_BLEND);
00661 }
00662
00663 void Bouncy::SetDefaults(PARTICLE* Particle)
00664 {
00665 Particle->PartInfo.Alive = true;
00666 Particle->PartInfo.Pos = SysInfo.Pos;
00667 Particle->PartInfo.OldPos = SysInfo.Pos;
00668 Particle->PartInfo.OrigPos = SysInfo.Pos;
00669
00670 VECTOR Velocity = SysInfo.Normal;
00671
00672 float x;
00673 x = (float)rand()/(float)RAND_MAX;
00674 Particle->PartInfo.Velocity.x = Velocity.x + (x - 0.5) / 5;
00675 Particle->PartInfo.Velocity.x /= 4.0;
00676 x = (float)rand()/(float)RAND_MAX;
00677 Particle->PartInfo.Velocity.y = Velocity.y + (x - 0.5);
00678 Particle->PartInfo.Velocity.y /= 4.0;
00679 x = (float)rand()/(float)RAND_MAX;
00680 Particle->PartInfo.Velocity.z = Velocity.z + (x - 0.5) / 5;
00681 Particle->PartInfo.Velocity.z /= 4.0;
00682
00683 Particle->PartInfo.Energy = 1.0;
00684 Particle->PartInfo.SizeX = 3.0;
00685 Particle->PartInfo.SizeY = 3.0;
00686 }
00687
00688 void Bouncy::SetShape(PARTICLE* Particle)
00689 {
00690 }
00691
00692 void RenderParticles(int nodeid)
00693 {
00694 PManager.Render(nodeid);
00695 }
00696
00697 void CreateSparks(VECTOR OldPos, VECTOR Pos, VECTOR Normal)
00698 {
00699 SystemInfo SI;
00700 ZeroMemory(&SI, sizeof(SI));
00701 SI.Visibility = true;
00702 SI.numParticles = rand()%6 + 2;
00703 SI.Type = spark;
00704 SI.TexID = texture[8].TexID;
00705 SI.Id = 1;
00706 SI.Pos = Pos;
00707 SI.Normal = Normal;
00708 SI.InitialVelocity = Pos - OldPos;
00709
00710 ParticleSystem* sparky = new Spark;
00711 sparky->SysInfo = SI;
00712 PManager.Add(sparky);
00713 }
00714
00715 void CreateRomanCandle(VECTOR Pos)
00716 {
00717
00718 SystemInfo SI;
00719 ZeroMemory(&SI, sizeof(SI));
00720 SI.Visibility = true;
00721 SI.numParticles = 80;
00722 SI.Type = roman;
00723 SI.TexID = texture[9].TexID;
00724 SI.Id = 2;
00725 SI.Pos = Pos;
00726 SI.Normal.Set(0.0, 1.0, 0.0);
00727
00728 SI.Color[0] = 1.0;
00729 SI.Color[1] = 0.0;
00730 SI.Color[2] = 0.0;
00731 SI.Color[3] = 1.0;
00732
00733 ParticleSystem* romancandle = new Roman;
00734 romancandle->SysInfo = SI;
00735 PManager.Add(romancandle);
00736 }
00737
00738 void CreateBouncy(VECTOR Pos)
00739 {
00740
00741 SystemInfo SI;
00742 ZeroMemory(&SI, sizeof(SI));
00743 SI.Visibility = true;
00744 SI.numParticles = 20;
00745 SI.Type = roman;
00746 SI.TexID = texture[9].TexID;
00747 SI.Id = 2;
00748 SI.Pos = Pos;
00749 SI.Normal.Set(0.0, 1.0, 0.0);
00750
00751 ParticleSystem* bouncy = new Bouncy;
00752 bouncy->SysInfo = SI;
00753 PManager.Add(bouncy);
00754 }
00755
00756
00757 bool CheckForParticleCollision(PARTICLE* Particle, VECTOR OldPos, VECTOR* Pos, VECTOR* Norm)
00758 {
00759 int CollisionPoly, ParticleLeaf;
00760 POLYGON Polygon;
00761 ListNode* tempnode;
00762 VECTOR CollisionPoint, p0, pN, a, b, c;
00763 bool CollisionFlag = false;
00764
00765 ParticleLeaf = FindCurrentLeaf(OldPos, root);
00766 tempnode = LeafList.Get(ParticleLeaf);
00767
00768
00769 for (CollisionPoly = 0; CollisionPoly < tempnode->node->numpolys; CollisionPoly++)
00770 {
00771 Polygon = tempnode->node->nodepolylist[CollisionPoly];
00772
00773 p0.x = Polygon.Vertex[0].x;
00774 p0.y = Polygon.Vertex[0].y;
00775 p0.z = Polygon.Vertex[0].z;
00776
00777 pN.x = Polygon.Vertex[0].nx;
00778 pN.y = Polygon.Vertex[0].ny;
00779 pN.z = Polygon.Vertex[0].nz;
00780
00781 if (ClassifyPoint(*Pos, p0, pN) == 1 || ClassifyPoint(*Pos, p0, pN) == 0)
00782 continue;
00783
00784 CollisionPoint = line_plane_collision(&OldPos, Pos, &Polygon);
00785
00786 a.x = Polygon.Vertex[0].x;
00787 a.y = Polygon.Vertex[0].y;
00788 a.z = Polygon.Vertex[0].z;
00789 b.x = Polygon.Vertex[1].x;
00790 b.y = Polygon.Vertex[1].y;
00791 b.z = Polygon.Vertex[1].z;
00792 c.x = Polygon.Vertex[2].x;
00793 c.y = Polygon.Vertex[2].y;
00794 c.z = Polygon.Vertex[2].z;
00795 if (CheckPointInTriangle(CollisionPoint, a, b, c))
00796 {
00797 CollisionFlag = true;
00798 VECTOR Normal = Polygon.GetNormal();
00799 Pos->x = CollisionPoint.x;
00800 Pos->y = CollisionPoint.y;
00801 Pos->z = CollisionPoint.z;
00802
00803 Normal.normalize();
00804 Norm->x = Normal.x;
00805 Norm->y = Normal.y;
00806 Norm->z = Normal.z;
00807 break;
00808 }
00809 }
00810 return CollisionFlag;
00811 }
00812