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