aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ClientHamr/extantz/CDemo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ClientHamr/extantz/CDemo.cpp')
-rw-r--r--ClientHamr/extantz/CDemo.cpp555
1 files changed, 555 insertions, 0 deletions
diff --git a/ClientHamr/extantz/CDemo.cpp b/ClientHamr/extantz/CDemo.cpp
new file mode 100644
index 0000000..7f44a9c
--- /dev/null
+++ b/ClientHamr/extantz/CDemo.cpp
@@ -0,0 +1,555 @@
1// This is a Demo of the Irrlicht Engine (c) 2005-2009 by N.Gebhardt.
2// This file is not documented.
3
4#include <irrlicht.h>
5#include "extantz.h"
6#include "CDemo.h"
7
8
9CDemo::CDemo(GLData *gld, bool a)
10: additive(a),
11 device(gld->device),
12 currentScene(0),
13 quakeLevelMesh(0), quakeLevelNode(0), skyboxNode(0), model1(0), model2(0),
14 campFire(0), metaSelector(0), mapSelector(0), sceneStartTime(0),
15 timeForThisScene(0)
16{
17}
18
19
20CDemo::~CDemo()
21{
22 if (mapSelector)
23 mapSelector->drop();
24
25 if (metaSelector)
26 metaSelector->drop();
27}
28
29
30void CDemo::setup(GLData *gld)
31{
32 device = gld->device;
33 IrrlichtDevice *device = gld->device;
34 IVideoDriver *driver = gld->driver;
35 ISceneManager *smgr = gld->smgr;
36
37 if (device->getFileSystem()->existFile("irrlicht.dat"))
38 device->getFileSystem()->addFileArchive("irrlicht.dat");
39 else
40 device->getFileSystem()->addFileArchive("media/irrlicht.dat");
41 if (device->getFileSystem()->existFile("map-20kdm2.pk3"))
42 device->getFileSystem()->addFileArchive("map-20kdm2.pk3");
43 else
44 device->getFileSystem()->addFileArchive("media/map-20kdm2.pk3");
45
46 sceneStartTime = device->getTimer()->getTime();
47 timeForThisScene = 0;
48 loadSceneData();
49}
50
51
52void CDemo::preDraw(GLData *gld, u32 now)
53{
54 if (now - sceneStartTime > timeForThisScene && timeForThisScene!=-1)
55 switchToNextScene();
56
57 createParticleImpacts();
58}
59
60
61bool CDemo::OnEvent(const SEvent& event)
62{
63 if (!device)
64 return false;
65
66 if (((event.EventType == EET_KEY_INPUT_EVENT &&
67 event.KeyInput.Key == KEY_SPACE &&
68 event.KeyInput.PressedDown == false) ||
69 (event.EventType == EET_MOUSE_INPUT_EVENT &&
70 event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)) &&
71 currentScene == 3)
72 {
73 // shoot
74 shoot();
75 }
76 else
77 if (device->getSceneManager()->getActiveCamera())
78 {
79 device->getSceneManager()->getActiveCamera()->OnEvent(event);
80 return true;
81 }
82
83 return false;
84}
85
86
87void CDemo::switchToNextScene()
88{
89 currentScene++;
90 if (currentScene > 3)
91 currentScene = 1;
92
93 scene::ISceneManager* sm = device->getSceneManager();
94 scene::ISceneNodeAnimator* sa = 0;
95 scene::ICameraSceneNode* camera = 0;
96
97 camera = sm->getActiveCamera();
98 if (camera)
99 {
100 sm->setActiveCamera(0);
101 camera->remove();
102 camera = 0;
103 }
104
105 switch(currentScene)
106 {
107 case 1: // panorama camera
108 {
109 currentScene += 1;
110 core::array<core::vector3df> points;
111
112 points.push_back(core::vector3df(-931.473755f, 138.300003f, 987.279114f)); // -49873
113 points.push_back(core::vector3df(-847.902222f, 136.757553f, 915.792725f)); // -50559
114 points.push_back(core::vector3df(-748.680420f, 152.254501f, 826.418945f)); // -51964
115 points.push_back(core::vector3df(-708.428406f, 213.569580f, 784.466675f)); // -53251
116 points.push_back(core::vector3df(-686.217651f, 288.141174f, 762.965576f)); // -54015
117 points.push_back(core::vector3df(-679.685059f, 365.095612f, 756.551453f)); // -54733
118 points.push_back(core::vector3df(-671.317871f, 447.360107f, 749.394592f)); // -55588
119 points.push_back(core::vector3df(-669.468445f, 583.335632f, 747.711853f)); // -56178
120 points.push_back(core::vector3df(-667.611267f, 727.313232f, 746.018250f)); // -56757
121 points.push_back(core::vector3df(-665.853210f, 862.791931f, 744.436096f)); // -57859
122 points.push_back(core::vector3df(-642.649597f, 1026.047607f, 724.259827f)); // -59705
123 points.push_back(core::vector3df(-517.793884f, 838.396790f, 490.326050f)); // -60983
124 points.push_back(core::vector3df(-474.387299f, 715.691467f, 344.639984f)); // -61629
125 points.push_back(core::vector3df(-444.600250f, 601.155701f, 180.938095f)); // -62319
126 points.push_back(core::vector3df(-414.808899f, 479.691406f, 4.866660f)); // -63048
127 points.push_back(core::vector3df(-410.418945f, 429.642242f, -134.332687f)); // -63757
128 points.push_back(core::vector3df(-399.837585f, 411.498383f, -349.350983f)); // -64418
129 points.push_back(core::vector3df(-390.756653f, 403.970093f, -524.454407f)); // -65005
130 points.push_back(core::vector3df(-334.864227f, 350.065491f, -732.397400f)); // -65701
131 points.push_back(core::vector3df(-195.253387f, 349.577209f, -812.475891f)); // -66335
132 points.push_back(core::vector3df(16.255573f, 363.743134f, -833.800415f)); // -67170
133 points.push_back(core::vector3df(234.940964f, 352.957825f, -820.150696f)); // -67939
134 points.push_back(core::vector3df(436.797668f, 349.236450f, -816.914185f)); // -68596
135 points.push_back(core::vector3df(575.236206f, 356.244812f, -719.788513f)); // -69166
136 points.push_back(core::vector3df(594.131042f, 387.173828f, -609.675598f)); // -69744
137 points.push_back(core::vector3df(617.615234f, 412.002899f, -326.174072f)); // -70640
138 points.push_back(core::vector3df(606.456848f, 403.221954f, -104.179291f)); // -71390
139 points.push_back(core::vector3df(610.958252f, 407.037750f, 117.209778f)); // -72085
140 points.push_back(core::vector3df(597.956909f, 395.167877f, 345.942200f)); // -72817
141 points.push_back(core::vector3df(587.383118f, 391.444519f, 566.098633f)); // -73477
142 points.push_back(core::vector3df(559.572449f, 371.991333f, 777.689453f)); // -74124
143 points.push_back(core::vector3df(423.753204f, 329.990051f, 925.859741f)); // -74941
144 points.push_back(core::vector3df(247.520050f, 252.818954f, 935.311829f)); // -75651
145 points.push_back(core::vector3df(114.756012f, 199.799759f, 805.014160f));
146 points.push_back(core::vector3df(96.783348f, 181.639481f, 648.188110f));
147 points.push_back(core::vector3df(97.865623f, 138.905975f, 484.812561f));
148 points.push_back(core::vector3df(99.612457f, 102.463669f, 347.603210f));
149 points.push_back(core::vector3df(99.612457f, 102.463669f, 347.603210f));
150 points.push_back(core::vector3df(99.612457f, 102.463669f, 347.603210f));
151
152 timeForThisScene = (points.size()-3)* 1000;
153
154 camera = sm->addCameraSceneNode(0, points[0], core::vector3df(0 ,400,0));
155 //camera->setTarget(core::vector3df(0,400,0));
156
157 sa = sm->createFollowSplineAnimator(device->getTimer()->getTime(),
158 points);
159 camera->addAnimator(sa);
160 sa->drop();
161
162 model1->setVisible(false);
163 model2->setVisible(false);
164 campFire->setVisible(false);
165 }
166 break;
167
168 case 2: // down fly anim camera
169 camera = sm->addCameraSceneNode(0, core::vector3df(100,40,-80), core::vector3df(844,670,-885));
170 sa = sm->createFlyStraightAnimator(core::vector3df(94, 1002, 127),
171 core::vector3df(108, 15, -60), 10000, true);
172 camera->addAnimator(sa);
173 timeForThisScene = 9900;
174 model1->setVisible(true);
175 model2->setVisible(false);
176 campFire->setVisible(false);
177 sa->drop();
178 break;
179
180 case 3: // interactive, go around
181 {
182 model1->setVisible(true);
183 model2->setVisible(true);
184 campFire->setVisible(true);
185 timeForThisScene = -1;
186
187 SKeyMap keyMap[9];
188 keyMap[0].Action = EKA_MOVE_FORWARD;
189 keyMap[0].KeyCode = KEY_UP;
190 keyMap[1].Action = EKA_MOVE_FORWARD;
191 keyMap[1].KeyCode = KEY_KEY_W;
192
193 keyMap[2].Action = EKA_MOVE_BACKWARD;
194 keyMap[2].KeyCode = KEY_DOWN;
195 keyMap[3].Action = EKA_MOVE_BACKWARD;
196 keyMap[3].KeyCode = KEY_KEY_S;
197
198 keyMap[4].Action = EKA_STRAFE_LEFT;
199 keyMap[4].KeyCode = KEY_LEFT;
200 keyMap[5].Action = EKA_STRAFE_LEFT;
201 keyMap[5].KeyCode = KEY_KEY_A;
202
203 keyMap[6].Action = EKA_STRAFE_RIGHT;
204 keyMap[6].KeyCode = KEY_RIGHT;
205 keyMap[7].Action = EKA_STRAFE_RIGHT;
206 keyMap[7].KeyCode = KEY_KEY_D;
207
208 keyMap[8].Action = EKA_JUMP_UP;
209 keyMap[8].KeyCode = KEY_KEY_J;
210
211 camera = sm->addCameraSceneNodeFPS(0, 100.0f, .4f, -1, keyMap, 9, false, 3.f);
212 camera->setPosition(core::vector3df(108,140,-140));
213 camera->setFarValue(5000.0f);
214
215 scene::ISceneNodeAnimatorCollisionResponse* collider =
216 sm->createCollisionResponseAnimator(
217 metaSelector, camera, core::vector3df(25,50,25),
218 core::vector3df(0, quakeLevelMesh ? -10.f : 0.0f,0),
219 core::vector3df(0,45,0), 0.005f);
220
221 camera->addAnimator(collider);
222 collider->drop();
223 }
224 break;
225 }
226
227 sceneStartTime = device->getTimer()->getTime();
228}
229
230
231void CDemo::loadSceneData()
232{
233 // load quake level
234
235 video::IVideoDriver* driver = device->getVideoDriver();
236 scene::ISceneManager* sm = device->getSceneManager();
237
238 // Quake3 Shader controls Z-Writing
239 sm->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
240
241 quakeLevelMesh = (scene::IQ3LevelMesh*) sm->getMesh("maps/20kdm2.bsp");
242
243 if (quakeLevelMesh)
244 {
245 u32 i;
246
247 //move all quake level meshes (non-realtime)
248 core::matrix4 m;
249 m.setTranslation(core::vector3df(-1300,-70,-1249));
250
251 for ( i = 0; i != scene::quake3::E_Q3_MESH_SIZE; ++i )
252 sm->getMeshManipulator()->transform(quakeLevelMesh->getMesh(i), m);
253
254 quakeLevelNode = sm->addOctreeSceneNode(
255 quakeLevelMesh->getMesh( scene::quake3::E_Q3_MESH_GEOMETRY));
256 if (quakeLevelNode)
257 {
258 //quakeLevelNode->setPosition(core::vector3df(-1300,-70,-1249));
259 quakeLevelNode->setVisible(true);
260
261 // create map triangle selector
262 mapSelector = sm->createOctreeTriangleSelector(quakeLevelMesh->getMesh(0),
263 quakeLevelNode, 128);
264
265 // if not using shader and no gamma it's better to use more lighting, because
266 // quake3 level are usually dark
267 quakeLevelNode->setMaterialType ( video::EMT_LIGHTMAP_M4 );
268
269 // set additive blending if wanted
270 if (additive)
271 quakeLevelNode->setMaterialType(video::EMT_LIGHTMAP_ADD);
272 }
273
274 // the additional mesh can be quite huge and is unoptimized
275 scene::IMesh * additional_mesh = quakeLevelMesh->getMesh ( scene::quake3::E_Q3_MESH_ITEMS );
276
277 for ( i = 0; i!= additional_mesh->getMeshBufferCount (); ++i )
278 {
279 scene::IMeshBuffer *meshBuffer = additional_mesh->getMeshBuffer ( i );
280 const video::SMaterial &material = meshBuffer->getMaterial();
281
282 //! The ShaderIndex is stored in the material parameter
283 s32 shaderIndex = (s32) material.MaterialTypeParam2;
284
285 // the meshbuffer can be rendered without additional support, or it has no shader
286 const scene::quake3::IShader *shader = quakeLevelMesh->getShader ( shaderIndex );
287 if ( 0 == shader )
288 {
289 continue;
290 }
291 // Now add the MeshBuffer(s) with the current Shader to the Manager
292 sm->addQuake3SceneNode ( meshBuffer, shader );
293 }
294 }
295
296 // load sydney model and create 2 instances
297
298 scene::IAnimatedMesh* mesh = 0;
299 mesh = sm->getMesh("media/sydney.md2");
300 if (mesh)
301 {
302 model1 = sm->addAnimatedMeshSceneNode(mesh);
303 if (model1)
304 {
305 model1->setMaterialTexture(0, driver->getTexture("media/spheremap.jpg"));
306 model1->setPosition(core::vector3df(100,40,-80));
307 model1->setScale(core::vector3df(2,2,2));
308 model1->setMD2Animation(scene::EMAT_STAND);
309 model1->setMaterialFlag(video::EMF_LIGHTING, false);
310 model1->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
311 model1->setMaterialType(video::EMT_SPHERE_MAP);
312 model1->addShadowVolumeSceneNode();
313 }
314
315 model2 = sm->addAnimatedMeshSceneNode(mesh);
316 if (model2)
317 {
318 model2->setPosition(core::vector3df(180,15,-60));
319 model2->setScale(core::vector3df(2,2,2));
320 model2->setMD2Animation(scene::EMAT_RUN);
321 model2->setMaterialTexture(0, device->getVideoDriver()->getTexture("media/sydney.bmp"));
322 model2->setMaterialFlag(video::EMF_LIGHTING, true);
323 model2->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
324 model2->addShadowVolumeSceneNode();
325 }
326 }
327
328 scene::ISceneNodeAnimator* anim = 0;
329
330 // create sky box
331 driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
332 skyboxNode = sm->addSkyBoxSceneNode(
333 driver->getTexture("media/irrlicht2_up.jpg"),
334 driver->getTexture("media/irrlicht2_dn.jpg"),
335 driver->getTexture("media/irrlicht2_lf.jpg"),
336 driver->getTexture("media/irrlicht2_rt.jpg"),
337 driver->getTexture("media/irrlicht2_ft.jpg"),
338 driver->getTexture("media/irrlicht2_bk.jpg"));
339 driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
340
341 // create walk-between-portals animation
342
343 core::vector3df waypoint[2];
344 waypoint[0].set(-150,40,100);
345 waypoint[1].set(350,40,100);
346
347 if (model2)
348 {
349 anim = device->getSceneManager()->createFlyStraightAnimator(
350 waypoint[0], waypoint[1], 2000, true);
351 model2->addAnimator(anim);
352 anim->drop();
353 }
354
355 // create animation for portals;
356
357 core::array<video::ITexture*> textures;
358 for (s32 g=1; g<8; ++g)
359 {
360 core::stringc tmp("media/portal");
361 tmp += g;
362 tmp += ".bmp";
363 video::ITexture* t = driver->getTexture( tmp );
364 textures.push_back(t);
365 }
366
367 anim = sm->createTextureAnimator(textures, 100);
368
369 // create portals
370
371 scene::IBillboardSceneNode* bill = 0;
372
373 for (int r=0; r<2; ++r)
374 {
375 bill = sm->addBillboardSceneNode(0, core::dimension2d<f32>(100,100),
376 waypoint[r]+ core::vector3df(0,20,0));
377 bill->setMaterialFlag(video::EMF_LIGHTING, false);
378 bill->setMaterialTexture(0, driver->getTexture("media/portal1.bmp"));
379 bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
380 bill->addAnimator(anim);
381 }
382
383 anim->drop();
384
385 // create cirlce flying dynamic light with transparent billboard attached
386
387 scene::ILightSceneNode* light = 0;
388
389 light = sm->addLightSceneNode(0,
390 core::vector3df(0,0,0), video::SColorf(1.0f, 1.0f, 1.f, 1.0f), 500.f);
391
392 anim = sm->createFlyCircleAnimator(
393 core::vector3df(100,150,80), 80.0f, 0.0005f);
394
395 light->addAnimator(anim);
396 anim->drop();
397
398 bill = device->getSceneManager()->addBillboardSceneNode(
399 light, core::dimension2d<f32>(40,40));
400 bill->setMaterialFlag(video::EMF_LIGHTING, false);
401 bill->setMaterialTexture(0, driver->getTexture("media/particlewhite.bmp"));
402 bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
403
404 // create meta triangle selector with all triangles selectors in it.
405 metaSelector = sm->createMetaTriangleSelector();
406 metaSelector->addTriangleSelector(mapSelector);
407
408 // create camp fire
409
410 campFire = sm->addParticleSystemSceneNode(false);
411 campFire->setPosition(core::vector3df(100,120,600));
412 campFire->setScale(core::vector3df(2,2,2));
413
414 scene::IParticleEmitter* em = campFire->createBoxEmitter(
415 core::aabbox3d<f32>(-7,0,-7,7,1,7),
416 core::vector3df(0.0f,0.06f,0.0f),
417 80,100, video::SColor(1,255,255,255),video::SColor(1,255,255,255), 800,2000);
418
419 em->setMinStartSize(core::dimension2d<f32>(20.0f, 10.0f));
420 em->setMaxStartSize(core::dimension2d<f32>(20.0f, 10.0f));
421 campFire->setEmitter(em);
422 em->drop();
423
424 scene::IParticleAffector* paf = campFire->createFadeOutParticleAffector();
425 campFire->addAffector(paf);
426 paf->drop();
427
428 campFire->setMaterialFlag(video::EMF_LIGHTING, false);
429 campFire->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
430 campFire->setMaterialTexture(0, driver->getTexture("media/fireball.bmp"));
431 campFire->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
432}
433
434
435void CDemo::shoot()
436{
437 scene::ISceneManager* sm = device->getSceneManager();
438 scene::ICameraSceneNode* camera = sm->getActiveCamera();
439
440 if (!camera || !mapSelector)
441 return;
442
443 SParticleImpact imp;
444 imp.when = 0;
445
446 // get line of camera
447
448 core::vector3df start = camera->getPosition();
449 core::vector3df end = (camera->getTarget() - start);
450 end.normalize();
451 start += end*8.0f;
452 end = start + (end * camera->getFarValue());
453
454 core::triangle3df triangle;
455
456 core::line3d<f32> line(start, end);
457
458 // get intersection point with map
459 scene::ISceneNode* hitNode;
460 if (sm->getSceneCollisionManager()->getCollisionPoint(
461 line, mapSelector, end, triangle, hitNode))
462 {
463 // collides with wall
464 core::vector3df out = triangle.getNormal();
465 out.setLength(0.03f);
466
467 imp.when = 1;
468 imp.outVector = out;
469 imp.pos = end;
470 }
471 else
472 {
473 // doesnt collide with wall
474 core::vector3df start = camera->getPosition();
475 core::vector3df end = (camera->getTarget() - start);
476 end.normalize();
477 start += end*8.0f;
478 end = start + (end * camera->getFarValue());
479 }
480
481 // create fire ball
482 scene::ISceneNode* node = 0;
483 node = sm->addBillboardSceneNode(0,
484 core::dimension2d<f32>(25,25), start);
485
486 node->setMaterialFlag(video::EMF_LIGHTING, false);
487 node->setMaterialTexture(0, device->getVideoDriver()->getTexture("media/fireball.bmp"));
488 node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
489
490 f32 length = (f32)(end - start).getLength();
491 const f32 speed = 0.6f;
492 u32 time = (u32)(length / speed);
493
494 scene::ISceneNodeAnimator* anim = 0;
495
496 // set flight line
497
498 anim = sm->createFlyStraightAnimator(start, end, time);
499 node->addAnimator(anim);
500 anim->drop();
501
502 anim = sm->createDeleteAnimator(time);
503 node->addAnimator(anim);
504 anim->drop();
505
506 if (imp.when)
507 {
508 // create impact note
509 imp.when = device->getTimer()->getTime() + (time - 100);
510 Impacts.push_back(imp);
511 }
512}
513
514
515void CDemo::createParticleImpacts()
516{
517 u32 now = device->getTimer()->getTime();
518 scene::ISceneManager* sm = device->getSceneManager();
519
520 for (s32 i=0; i<(s32)Impacts.size(); ++i)
521 if (now > Impacts[i].when)
522 {
523 // create smoke particle system
524 scene::IParticleSystemSceneNode* pas = 0;
525
526 pas = sm->addParticleSystemSceneNode(false, 0, -1, Impacts[i].pos);
527
528 pas->setParticleSize(core::dimension2d<f32>(10.0f, 10.0f));
529
530 scene::IParticleEmitter* em = pas->createBoxEmitter(
531 core::aabbox3d<f32>(-5,-5,-5,5,5,5),
532 Impacts[i].outVector, 20,40, video::SColor(50,255,255,255),video::SColor(50,255,255,255),
533 1200,1600, 20);
534
535 pas->setEmitter(em);
536 em->drop();
537
538 scene::IParticleAffector* paf = campFire->createFadeOutParticleAffector();
539 pas->addAffector(paf);
540 paf->drop();
541
542 pas->setMaterialFlag(video::EMF_LIGHTING, false);
543 pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
544 pas->setMaterialTexture(0, device->getVideoDriver()->getTexture("media/smoke.bmp"));
545 pas->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
546
547 scene::ISceneNodeAnimator* anim = sm->createDeleteAnimator(2000);
548 pas->addAnimator(anim);
549 anim->drop();
550
551 // delete entry
552 Impacts.erase(i);
553 i--;
554 }
555}