source: GTP/trunk/App/Demos/Illum/Rain/src/RainFrameListener.cpp @ 2221

Revision 2221, 12.5 KB checked in by plemenos, 17 years ago (diff)
  • Property svn:executable set to *
Line 
1
2///////////////////////////////////////////////////////////////////////////
3//
4//              Realistic rain real-time simulation program
5//
6//              Pierre Rousseau
7//
8///////////////////////////////////////////////////////////////////////////
9//
10//              Main camera, and external events (mouse/keyboard) handling
11//
12///////////////////////////////////////////////////////////////////////////
13
14
15
16#include "RainCloseDropsParticles.h"
17#include "RainFrameListener.h"
18#include <OgreHardwarePixelBuffer.h>
19using namespace std;
20
21
22extern float startPos[3];
23
24// don't go below the ground with this
25extern RaySceneQuery* raySceneQuery;
26
27
28RainFrameListener::RainFrameListener(RenderWindow* win, Camera* cam, SceneNode* ViewNode, SceneNode* CameraNode, CloseDropsParticles *syst) : ExampleFrameListener(win, cam)
29{
30    mViewNode = ViewNode;
31    mCameraNode = CameraNode;
32    mRainSystem = syst;
33    timer = 0.0;
34    mWindow->setAutoUpdated(false);
35
36    Overlay * mRainOverlay = OverlayManager::getSingleton().getByName("RainOverlay");
37    mRainOverlay->show();
38
39    showDebugOverlay(false); // useless as we defined our own overlay
40}
41
42
43
44void RainFrameListener::updateStats(void)
45{
46    static String currFps = "FPS : ";
47    // update stats when necessary
48    try
49    {
50        OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("RainCurrFps");
51
52        const RenderTarget::FrameStats& stats = mWindow->getStatistics();
53
54        guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
55    }
56    catch(...)
57    {
58        // ignore
59    }
60}
61
62
63void RainFrameListener::displayMessage(String text)
64{
65    try
66    {
67        OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("RainCurrFps");
68        guiCurr->setCaption(text);
69    }
70    catch(...)
71    {
72        // ignore
73    }
74}
75
76
77bool RainFrameListener::frameStarted(const FrameEvent& evt)
78{
79    static bool usePrimaryPositionTexture = true;
80    static bool capture = false;
81    static bool stopDrop = false;
82    static int numScreenshot=0;
83    static bool firstFrame = true;
84        static bool showOverlay = true;
85    Real moveFactor;
86
87#ifdef SNOW
88
89    static float fallSpeed = 0.1;
90    static float windForce = 0.02;
91#else
92
93    static float fallSpeed = 0.7;
94    static float windForce = 0.0;
95#endif
96
97
98    if (firstFrame)
99    {
100        mRainSystem->definePosTextureAndBackup();
101        firstFrame = false;
102
103        // give initial values to the shader parameters
104        Vector3 camPos = mViewNode->getWorldPosition();
105        Vector3 viewPos( (camPos.x - PARTICLES_MIN_X) / float(PARTICLES_MAX_X - PARTICLES_MIN_X),
106                         (camPos.y - PARTICLES_MIN_Y) / float(PARTICLES_MAX_Y - PARTICLES_MIN_Y),
107                         (camPos.z - PARTICLES_MIN_Z) / float(PARTICLES_MAX_Z - PARTICLES_MIN_Z) );
108        Vector3 viewDir(0.0, 0.0, 1.0);
109        Vector3 fallVect(windForce, -fallSpeed, 0.0);
110        Vector3 boxMin(VIS_PARTICLE_BOX_MIN_X, VIS_PARTICLE_BOX_MIN_Y, VIS_PARTICLE_BOX_MIN_Z);
111        Vector3 boxMax(VIS_PARTICLE_BOX_MAX_X, VIS_PARTICLE_BOX_MAX_Y, VIS_PARTICLE_BOX_MAX_Z);
112        Vector3 lastMove( 0.0, 0.0, 0.0 );
113
114        Vector3 randomMove((rand() % 100 ) / 1000.0 - 0.05, (rand() % 100 ) / 1000.0 - 0.05, (rand() % 100 ) / 1000.0 - 0.05);
115
116        mRainSystem->updateShaderParameters(0.015, mRainSystem->mRainWidth, mRainSystem->mRainStreaksHeight, mRainSystem->getLightManagerPtr()->getLightCount(), viewPos, viewDir, fallVect, boxMin, boxMax, lastMove, randomMove, 1);
117
118                // the control overlay is for debugging purposes : uncomment if you wish to see a dynamic texture, such as the particle's position texture.
119        //mRainSystem->makeControlOverlay();
120    }
121    else
122    {
123        // set the active position texture
124        mRainSystem->showPositionBillboards();
125        mRainSystem->updatePositionTexture(usePrimaryPositionTexture);
126        mRainSystem->hidePositionBillboards();
127
128        usePrimaryPositionTexture = !usePrimaryPositionTexture;
129        //update random factor
130        mRainSystem->updateRandomMove(Vector3((rand() % 100 ) / 1000.0 - 0.05, (rand() % 100 ) / 1000.0 - 0.05, (rand() % 100 ) / 1000.0 - 0.05));
131    }
132
133
134
135
136
137    if (capture)
138    {
139        moveFactor = evt.timeSinceLastFrame * 10.0;
140
141        // set framerate to 30 fps
142        mRainSystem->updateTimeSinceLastFrame(1.0 / 30.0);
143    }
144    else
145    {
146        // tell the stat overlay to update
147        updateStats();
148
149        // update time since last frame
150        mRainSystem->updateTimeSinceLastFrame(evt.timeSinceLastFrame);
151
152        moveFactor = evt.timeSinceLastFrame * 80.0;
153    }
154
155    timer -= evt.timeSinceLastFrame;
156
157
158
159    mInputDevice->capture();
160
161    /////////////////////////////////////////////////
162    /////////////////////////////////////////////////
163    // translations
164    /////////////////////////////////////////////////
165    /////////////////////////////////////////////////
166
167    // save the previous position
168    Vector3 oldViewPos = mViewNode->getWorldPosition();
169
170    if (mInputDevice->isKeyDown(Ogre::KC_UP) || mInputDevice->isKeyDown(Ogre::KC_NUMPAD8))
171    {
172        mViewNode->translate(0.0, 0.0, -moveFactor, Ogre::Node::TS_LOCAL);
173    }
174
175    if (mInputDevice->isKeyDown(Ogre::KC_DOWN) || mInputDevice->isKeyDown(Ogre::KC_NUMPAD5))
176    {
177        mViewNode->translate(0.0, 0.0, moveFactor, Ogre::Node::TS_LOCAL);
178    }
179
180    // keep the feets on the ground
181    static Ray updateRay;
182    updateRay.setOrigin(mViewNode->getPosition());
183    updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
184    raySceneQuery->setRay(updateRay);
185    raySceneQuery->setQueryMask(0x80000000);
186    RaySceneQueryResult& qryResult = raySceneQuery->execute();
187    RaySceneQueryResult::iterator i = qryResult.begin();
188    if (i != qryResult.end() && i->worldFragment)
189    {
190        SceneQuery::WorldFragment* wf = i->worldFragment;
191        mViewNode->setPosition(mViewNode->getPosition().x, i->worldFragment->singleIntersection.y + HAUTEUR_OBSERVATEUR, mViewNode->getPosition().z);
192    }
193
194
195    // in case the user moved, update his position
196    Vector3 camPos = mViewNode->getWorldPosition();
197    mRainSystem->updateViewPos(camPos);
198
199
200    /////////////////////////////////////////////////
201    /////////////////////////////////////////////////
202    // rotations
203    /////////////////////////////////////////////////
204    /////////////////////////////////////////////////
205    Real rotX = -mInputDevice->getMouseRelativeX();
206    Real rotY = -mInputDevice->getMouseRelativeY();
207
208    Vector3 oldViewDir = mViewNode->getOrientation().zAxis();
209
210    mViewNode->yaw(Ogre::Radian(rotX * evt.timeSinceLastFrame / (capture ? 100.0 : 1.0)), Ogre::Node::TS_WORLD);
211    mCameraNode->pitch(-Ogre::Radian(rotY * evt.timeSinceLastFrame / (capture ? 100.0 : 1.0)), Ogre::Node::TS_LOCAL);
212
213    // get the orientation for the update shader
214    Vector3 newViewDir = mViewNode->getOrientation().zAxis();
215
216    Vector3 lastMove( (camPos.x - oldViewPos.x) / float(VIS_PARTICLE_BOX_MAX_X - VIS_PARTICLE_BOX_MIN_X) - (newViewDir.x - oldViewDir.x)/2.0,
217                      (camPos.y - oldViewPos.y) / float(VIS_PARTICLE_BOX_MAX_Y - VIS_PARTICLE_BOX_MIN_Y),
218                      (camPos.z - oldViewPos.z) / float(VIS_PARTICLE_BOX_MAX_Z - VIS_PARTICLE_BOX_MIN_Z) - (newViewDir.z - oldViewDir.z)/2.0 );
219    mRainSystem->updateLastMove(lastMove);
220
221    mRainSystem->updateViewDir(newViewDir);
222
223
224    /////////////////////////////////////////////////////////////////////////////////////
225    /////////////////////////////////////////////////////////////////////////////////////
226    //
227    //  react to user input (keyboard)
228    //
229    /////////////////////////////////////////////////////////////////////////////////////
230    /////////////////////////////////////////////////////////////////////////////////////
231
232
233// pause the system
234    if (mInputDevice->isKeyDown(KC_SPACE) && timer <= 0)
235    {
236        stopDrop = ! stopDrop;
237        if (stopDrop)
238            displayMessage("Pause");
239        else
240            displayMessage(" ");
241
242        timer = 0.5;
243
244        // update fall vector
245        mRainSystem->updateFallVector(Vector3(stopDrop?0.0:windForce, stopDrop?0.0:-fallSpeed, 0.0));
246    }
247
248
249
250    // modifying particle size
251
252    if (mInputDevice->isKeyDown(KC_ADD) && timer <= 0)
253    {
254        mRainSystem->mRainWidth += 0.05;
255        displayMessage("Radius : " + StringConverter::toString(mRainSystem->mRainWidth * 5.0f));
256        std::cout << "Radius : " << mRainSystem->mRainWidth * 5.0f << std::endl;
257#ifndef SNOW
258
259        if (mRainSystem->mRainWidth <= 0.901)
260        {
261            String nom_masque="masques/masque_" + StringConverter::toString(mRainSystem->mRainWidth * 5.0f) + "_.tga";
262            static_cast<MaterialPtr>(MaterialManager::getSingleton().getByName(RAIN_MATERIAL_NAME))->getTechnique (0)->getPass (0)->getTextureUnitState (2)->setTextureName(nom_masque);
263        }
264#endif
265        timer = 0.1;
266
267        // update the size
268        mRainSystem->updateRainBilboardSideLength(mRainSystem->mRainWidth);
269    }
270
271    if (mInputDevice->isKeyDown(KC_SUBTRACT) && timer <= 0)
272    {
273        if (mRainSystem->mRainWidth > 0.051)
274        {
275            mRainSystem->mRainWidth -= 0.05;
276            displayMessage("Radius : " + StringConverter::toString(mRainSystem->mRainWidth * 5.0f));
277            std::cout << "Radius : " << mRainSystem->mRainWidth * 5.0f << std::endl;
278#ifndef SNOW
279
280            if (mRainSystem->mRainWidth <= 0.9 && mRainSystem->mRainWidth >= 0.14)
281            {
282                String nom_masque="masques/masque_" + StringConverter::toString(mRainSystem->mRainWidth * 5.0f) + "_.tga";
283                static_cast<MaterialPtr>(MaterialManager::getSingleton().getByName(RAIN_MATERIAL_NAME))->getTechnique (0)->getPass (0)->getTextureUnitState (2)->setTextureName(nom_masque);
284            }
285#endif
286
287        }
288        timer = 0.1;
289
290        // update the size
291        mRainSystem->updateRainBilboardSideLength(mRainSystem->mRainWidth);
292    }
293
294
295
296    // press 'S' to accelerate, and 'Q' to slow down
297    if (mInputDevice->isKeyDown(KC_S))
298    {
299        displayMessage("Accelerating");
300        fallSpeed += 0.002;
301        std::cout << "fallSpeed : " << fallSpeed << std::endl;
302
303        // update fall vector
304        mRainSystem->updateFallVector(Vector3(stopDrop?0.0:windForce, stopDrop?0.0:-fallSpeed, 0.0));
305    }
306    if (mInputDevice->isKeyDown(KC_Q))
307    {
308        if (fallSpeed > 0.05)
309        {
310            displayMessage("Slowing");
311            fallSpeed -= 0.002;
312        }
313        std::cout << "fallSpeed : " << fallSpeed << std::endl;
314
315        // update fall vector
316        mRainSystem->updateFallVector(Vector3(stopDrop?0.0:windForce, stopDrop?0.0:-fallSpeed, 0.0));
317    }
318
319    // wind handling ('W' key)
320    if (mInputDevice->isKeyDown(KC_W))
321    {
322        if (mInputDevice->isKeyDown(KC_LSHIFT) || mInputDevice->isKeyDown(KC_RSHIFT))
323        {
324            displayMessage("Decreasing wind");
325            windForce -= 0.001;
326        }
327        else
328        {
329            displayMessage("Increasing wind");
330            windForce += 0.001;
331        }
332        std::cout << "wind : " << windForce << std::endl;
333
334        // update fall vector
335        mRainSystem->updateFallVector(Vector3(stopDrop?0.0:windForce, stopDrop?0.0:-fallSpeed, 0.0));
336    }
337
338
339    // erase text
340    if (mInputDevice->isKeyDown(KC_E))
341    {
342        displayMessage(" ");
343    }
344
345        // show / hide the calimero overlay
346    if (mInputDevice->isKeyDown(KC_O) && timer <= 0)
347    {
348        showOverlay = ! showOverlay;
349        if (showOverlay)
350                        OverlayManager::getSingleton().getByName("RainOverlay")->show();
351        else
352                        OverlayManager::getSingleton().getByName("RainOverlay")->hide();
353
354        timer = 0.5;
355    }
356
357
358    // we can capture a screenshot
359
360    mWindow->update();
361
362    if (mInputDevice->isKeyDown(KC_SYSRQ) && timer <= 0)
363    {
364        String tmp;
365
366        String padding = (numScreenshot<10) ? "000" : ( (numScreenshot<100) ? "00" : ((numScreenshot<1000) ? "0" : "" ) ) ;
367        tmp = "screenshot_" + padding;
368        tmp += StringConverter::toString(numScreenshot++) + ".jpg";
369        mWindow->writeContentsToFile(tmp);
370        timer = 0.5;
371    }
372
373    // on enregistre
374    if (mInputDevice->isKeyDown(Ogre::KC_C) && timer <= 0)
375    {
376        displayMessage(" ");
377        capture = !capture;
378        timer = 0.5;
379    }
380    if (capture)
381    {
382        String tmp;
383
384        String padding = (numScreenshot<10) ? "000" : ( (numScreenshot<100) ? "00" : ((numScreenshot<1000) ? "0" : "" ) ) ;
385        tmp = "Capture_" + padding;
386        tmp += StringConverter::toString(numScreenshot++) + ".jpg";
387
388        mWindow->writeContentsToFile(tmp);
389    }
390
391    // end of program
392
393    if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
394        return false;
395
396    return true;
397}
398
399
400
401
402bool RainFrameListener::frameEnded(const FrameEvent& evt)
403{
404    return ExampleFrameListener::frameEnded(evt);
405}
406
Note: See TracBrowser for help on using the repository browser.