00001
00006 #include <iostream>
00007 #include <vector>
00008
00009 #ifdef __APPLE__
00010 #include <GraphicsLib/GraphicsLib.h>
00011 #include <GraphicsLib/ThreadTimer.h>
00012 #else
00013 #include "GraphicsLib.h"
00014 #include "ThreadTimer.h"
00015 #endif
00016
00017 #include <math.h>
00018 #include "ParticleSystems.h"
00019 #include "Debugger.h"
00020
00021 using namespace std;
00022 using namespace GraphicsLib;
00023 using namespace ParticleSystems;
00024
00028 Emitter *emit;
00029 DataStructure *dataParticle;
00030 ParticleSystem *particleSys;
00031
00036 ParticleSystemManager *manager;
00037
00039 int WIDTH = 1024;
00041 int HEIGHT = 800;
00042
00044 int FRAMESPERSEC = 25;
00045
00046
00047 Camera Cam;
00048
00049 int spinxface = 0 ;
00050 int spinyface = 0 ;
00051 int spinzface = 0 ;
00052 int origx,origy,origz,RotateXY,RotateXZ=0;
00053 int Rotate;
00054
00058 void MakeFloor()
00059 {
00060 const static GLfloat FSIZE=10.0;
00061 glPushMatrix();
00062 glDisable(GL_LIGHTING);
00063 glColor3f(0.2,0.2,0.2);
00064 glBegin(GL_QUADS);
00065 glVertex3d(-FSIZE,0,-FSIZE);
00066 glVertex3d(FSIZE,0,-FSIZE);
00067 glVertex3d(FSIZE,0,FSIZE);
00068 glVertex3d(-FSIZE,0,FSIZE);
00069 glEnd();
00070 glColor3f(0.6,0.6,0.6);
00071
00072 for(int x=-10; x<10; x++)
00073 {
00074 glBegin(GL_LINES);
00075 glVertex3d(x,0,FSIZE);
00076 glVertex3d(x,0,-FSIZE);
00077 glEnd();
00078 glBegin(GL_LINES);
00079 glVertex3d(FSIZE,0,x);
00080 glVertex3d(-FSIZE,0,x);
00081 glEnd();
00082 }
00083 glPopMatrix();
00084 glEnable(GL_LIGHTING);
00085 }
00086
00088 void display()
00089 {
00090
00091 int start = GetThreadTimeMS();
00092 #ifdef __TIMER__
00093 std::cout << "VectorDS: time start " << start << std::endl;
00094 #endif
00095
00096 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00097
00098
00099 glPushMatrix();
00100
00101 glRotated ( (GLdouble) spinxface, 1.0, 0.0, 0.0 ) ;
00102 glRotated ( (GLdouble) spinyface, 0.0, 1.0, 0.0 ) ;
00103 glRotated ( (GLdouble) spinzface, 0.0, 0.0, 1.0 ) ;
00104
00105
00106 DrawAxis(5);
00107
00108 #ifdef __PERFORMANCE__
00109 cout << "main: render" << endl;
00110 #endif
00111
00112 manager->render();
00113 #ifdef __PERFORMANCE__
00114 cout << "main: update" << endl;
00115 #endif
00116
00117
00118 manager->update();
00119 #ifdef __PERFORMANCE__
00120 cout << "main: update finished" << endl;
00121 #endif
00122
00123
00124 glPopMatrix();
00125
00126 glutSwapBuffers();
00127
00128 int end_time = GetThreadTimeMS();
00129
00130
00131 while(end_time < start+FRAMESPERSEC) {
00132 end_time = GetThreadTimeMS();
00133 }
00134 #ifdef __TIMER__
00135 std::cout << "VectorDS: time end " << end_time << std::endl;
00136 #endif
00137 }
00138
00139
00140
00141
00143 void update()
00144 {
00145 glutPostRedisplay();
00146 }
00147
00149 void initPSManager()
00150 {
00151 manager = new ParticleSystemManager();
00152 }
00153
00154
00155
00161 void multiCollision() {
00162
00163 Vector *constrain = new Vector(0.0,0.0,0.0);
00164
00165
00166 Vector *initVelocity2 = new Vector(0,0.05,0.1);
00167
00168
00169 Vector *initVelocity3 = new Vector(0.1,0.05,0.0);
00170
00171
00172 Colour *colour = new Colour(0.0,0.0,1.0,1.0);
00173 colour->set(0.0,0.0,1.0,1.0);
00174
00175
00176 Colour *flare = new Colour(0.0,0.0,0.0,0.00);
00177 flare->set(0.0,0.0,0.0,0.00);
00178
00179
00180 Vector *gravCon = new Vector(0,-0.005,0);
00181
00182
00183 Point3 emitPoint = new Point3(0,1,0);
00184
00185
00186 Point3 emitPoint2 = new Point3(-5,1,7);
00187
00188
00189 RandomForce *rf = new RandomForce(constrain, 0.01);
00190
00191
00192 GravityForce *f = new GravityForce(gravCon, 1, 0.9);
00193
00194
00195 StraightSolver *solver = new StraightSolver();
00196 solver->addForce(rf);
00197 solver->addForce(f);
00198
00199
00200 Emitter *emit2 = new PointEmitter(manager->getNextID(), solver, Emitter::STRIKE, (*initVelocity2),(*colour),0.1,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/smoke2.tga", emitPoint,0.05);
00201 emit2->flareColor = (*flare);
00202 emit2->particleLife = 100;
00203
00204
00205 Emitter *emit3 = new PointEmitter(manager->getNextID(), solver, Emitter::STRIKE, (*initVelocity3),(*colour),0.1,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/smoke2.tga", emitPoint2,0.05);
00206 emit3->flareColor = (*flare);
00207 emit3->particleLife = 100;
00208
00209
00210 DataStructure *data2 = new VectorDS();
00211 DataStructure *data3 = new VectorDS();
00212
00213
00214 Point3 *sPoint = new Point3(0,-4,8);
00215
00216 Real radius = 2.0;
00217 CollisionSphere *sphere = new CollisionSphere(sPoint, radius);
00218
00219
00220 data2->addCollisionObject(sphere);
00221 data3->addCollisionObject(sphere);
00222
00223
00224 data2->collision = true;
00225 data3->collision = true;
00226
00227 ParticleSystem *particleSys2 = new ParticleSystem(manager->getNextID(), emit2, data2, solver, 1000,1000);
00228
00229 manager->addSystem(particleSys2);
00230
00231 ParticleSystem *particleSys3 = new ParticleSystem(manager->getNextID(), emit3, data3, solver, 1000,1000);
00232
00233 manager->addSystem(particleSys3);
00234
00235 }
00236
00242 void fire() {
00243
00244 Vector *constrain = new Vector(0.1,0.1,0.1);
00245
00246 Vector *initVelocity = new Vector(0,0.5,0);
00247
00248 Colour *colour = new Colour(0.5,0.5,0.5,1.0);
00249 colour->set(0.75,0.5,0.25,1.0);
00250
00251 Colour *flare = new Colour(0.05,0.05,0.05,0.00);
00252 flare->set(0.05,0.05,0.05,0.00);
00253
00254 Vector *gravCon = new Vector(0,-0.1,0);
00255 Vector *x = new Vector(20,0,0);
00256 Vector *z = new Vector(0,0,20);
00257
00258 Point3 midPoint = new Point3(0,0,0);
00259 RandomForce *rf = new RandomForce(constrain, 1);
00260 GravityForce *f = new GravityForce(gravCon, 1, 0.5);
00261
00262 StraightSolver *solver = new StraightSolver();
00263 solver->addForce(rf);
00264
00265
00266
00267 emit = new PlanarEmitter(1, solver, Emitter::IMAGE,(*initVelocity),(*colour),0.5,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/Particle.tga",(*x), (*z));
00268 emit->flareColor = (*flare);
00269 emit->particleSizeFlare = 0.03;
00270 emit->particleLife = 30;
00271
00272 dataParticle = new VectorDS();
00273
00274 particleSys = new ParticleSystem(manager->getNextID(), emit, dataParticle, solver, 1000,5000);
00275
00276 manager->addSystem(particleSys);
00277 }
00278
00279 void smoke() {
00280 Vector *constrain = new Vector(0.1,0.1,0.1);
00281
00282 Vector *initVelocity = new Vector(0,0.5,0);
00283
00284 Colour *colour = new Colour(0.5,0.5,0.5,1.0);
00285 colour->set(0.5,0.5,0.5,0.3);
00286
00287 Colour *flare = new Colour(0.05,0.05,0.05,0.00);
00288 flare->set(0.0,0.0,0.0,0.00);
00289
00290 Vector *gravCon = new Vector(0,-0.1,0);
00291 Vector *x = new Vector(20,0,0);
00292 Vector *z = new Vector(0,0,20);
00293
00294 Point3 midPoint = new Point3(0,0,0);
00295
00296 RandomForce *rf = new RandomForce(constrain, 1);
00297 GravityForce *f = new GravityForce(gravCon, 1, 0.5);
00298
00299 StraightSolver *solver = new StraightSolver();
00300 solver->addForce(rf);
00301
00302
00303
00304 emit = new PlanarEmitter(1, solver, Emitter::IMAGE,(*initVelocity),(*colour),0.5,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/smoke2.tga",(*x), (*z));
00305 emit->flareColor = (*flare);
00306 emit->particleSizeFlare = 0.01;
00307 emit->particleLife = 20;
00308
00309 dataParticle = new VectorDS();
00310
00311
00312
00313 particleSys = new ParticleSystem(manager->getNextID(), emit, dataParticle, solver, 1000,2000);
00314
00315
00316 manager->addSystem(particleSys);
00317 }
00318
00322 void init() {
00323 initPSManager();
00324 }
00325
00327 void InitGL()
00328 {
00329 glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
00330
00331 glShadeModel(GL_SMOOTH);
00332
00333 glEnable(GL_LIGHT0);
00334
00335
00336 GLfloat AmbColour[]={0.2,0.2,0.2};
00337 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,AmbColour);
00338
00339 Point3 Eye(15.0f,15.0f,15.0f);
00340 Point3 Look(0.0f,0.0f,0.0f);
00341 Vector Up(0.0f,1.0f,0.0f);
00342
00343 Cam.set(Eye,Look,Up);
00344 Cam.setShape(45,640.0/480.0,0.5,150);
00345 glEnable(GL_LIGHTING);
00346 glEnable(GL_COLOR_MATERIAL);
00347 glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
00348 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
00349 glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
00350 glEnable(GL_NORMALIZE);
00351
00352 }
00353
00354
00358 void resetPMManager()
00359 {
00360 manager->reset();
00361 manager->restart();
00362 }
00363
00364
00365 void KeyPressed(unsigned char ch, int x, int y)
00366 {
00367 switch (ch)
00368 {
00369
00370 case 27 : exit(0); break;
00371 case 'p' : manager->pause(); break;
00372 case 'r' : resetPMManager(); break;
00373 case 's' : initPSManager(); smoke(); break;
00374 case 'f' : initPSManager(); fire(); break;
00375 case 'm' : initPSManager(); multiCollision(); break;
00376 case 't' : initPSManager(); smoke(); fire(); break;
00377
00378 }
00379
00380 glutPostRedisplay();
00381 }
00382
00383
00384
00388 void SpecialKeyPressed(int key, int x, int y)
00389 {
00390 switch (key)
00391 {
00392
00393 case GLUT_KEY_LEFT :
00394 Cam.slide(0.5,0.0,0.0);
00395 break;
00396 case GLUT_KEY_UP :
00397 Cam.slide(0.0,-0.5,0.0);
00398 break;
00399 case GLUT_KEY_RIGHT :
00400 Cam.slide(-0.5,0.0,0.0);
00401 break;
00402 case GLUT_KEY_DOWN :
00403 Cam.slide(0.0,0.5,0.0);
00404 break;
00405
00406 case GLUT_KEY_PAGE_UP :
00407 Cam.slide(0.0,0.0,0.5);
00408 break;
00409 case GLUT_KEY_PAGE_DOWN :
00410 Cam.slide(0.0,0.0,-0.5);
00411 break;
00412
00413
00414
00415 }
00416
00417 glutPostRedisplay();
00418 }
00419
00420
00424 void motion ( int x, int y )
00425 {
00426 if (Rotate) {
00427 spinyface = ( spinyface + (x - origx) ) % 360 ;
00428 spinxface = ( spinxface + (y - origy) ) % 360 ;
00429 origx = x;
00430 origy = y;
00431 glutPostRedisplay();
00432 }
00433 }
00434
00439 static void Button(int button, int down, int x, int y)
00440 {
00441 Rotate = 0;
00442 switch(button)
00443 {
00444 case GLUT_LEFT_BUTTON:
00445 if (down == GLUT_DOWN)
00446 {
00447 origx = x;
00448 origy = y;
00449 Rotate = 1;
00450 }
00451 else Rotate = 0;
00452 break;
00453 }
00454 }
00455
00459 void intro() {
00460 std::cout << "Welcome to Hannes Ricklefs ParticleSystem" << std::endl;
00461 std::cout << "There are 4 different demo scenes" << std::endl;
00462 std::cout << "1) Smoke can be viewed by pressing s" << std::endl;
00463 std::cout << "2) Fire can be viewed by pressing f" << std::endl;
00464 std::cout << "3) Fire and smoke together can be viewed by pressing t" << std::endl;
00465 std::cout << "4) Two ParticleSystems colliding with a CollisionSphere can be viewed by pressing m" << std::endl;
00466 std::cout << "To restart any of the demos press r" << std::endl;
00467 std::cout << "To pause any of the demos press p" << std::endl;
00468 std::cout << "To quit press esc" << std::endl;
00469 std::cout << "You can fly arround the scene by using your mouse or " << std::endl;
00470 std::cout << "by using the arrow keys";
00471 std::cout << "To zoom in and out use the page up and down keys" << std::endl;
00472 }
00473
00474
00478 int main(int argc, char **argv)
00479 {
00480 init();
00481
00482 srand(time(NULL));
00483
00484
00485 glutInit(&argc, argv);
00486 glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE |GLUT_ALPHA |GLUT_ACCUM);
00487 glutInitWindowSize(WIDTH, HEIGHT);
00488 glutCreateWindow("ParticleSystem :: Hannes Ricklefs");
00489
00490
00491 glutDisplayFunc(display);
00492
00493
00494 glutMouseFunc(Button);
00495 glutMotionFunc(motion);
00496 glutKeyboardFunc(KeyPressed);
00497 glutSpecialFunc(SpecialKeyPressed);
00498 glutIdleFunc(update);
00499 intro();
00500
00501 InitGL();
00502 glutMainLoop();
00503
00504 return 1;
00505 }
00506
00507
00508
00509
00510