Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/rocket2/src/orxonox/controllers/NewHumanController.cc @ 7011

Last change on this file since 7011 was 6951, checked in by scheusso, 15 years ago

merged rocket branch into presentation3 and cleaned up some things (mostly debug output and intendation)

  • Property svn:eol-style set to native
File size: 23.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Michael Wirth
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "NewHumanController.h"
30
31#include <cmath>
32#include <OgreRay.h>
33#include <OgreSceneQuery.h>
34#include <OgreCamera.h>
35#include <OgreSceneManager.h>
36#include <bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
37
38#include "core/CoreIncludes.h"
39#include "core/ConsoleCommand.h"
40#include "worldentities/ControllableEntity.h"
41#include "worldentities/pawns/Pawn.h"
42#include "infos/PlayerInfo.h"
43#include "overlays/OrxonoxOverlay.h"
44#include "graphics/Camera.h"
45#include "sound/SoundManager.h"
46#include "tools/BulletConversions.h"
47#include "Scene.h"
48
49namespace orxonox
50{
51    SetConsoleCommand(NewHumanController, changeMode, false).keybindMode(KeybindMode::OnPress);
52    SetConsoleCommand(NewHumanController, accelerate, false).keybindMode(KeybindMode::OnPress);
53    SetConsoleCommand(NewHumanController, decelerate, false).keybindMode(KeybindMode::OnPress);
54    SetConsoleCommand(NewHumanController, unfire,      true).keybindMode(KeybindMode::OnRelease);
55
56    CreateUnloadableFactory(NewHumanController);
57
58    NewHumanController* NewHumanController::localController_s = 0;
59
60    NewHumanController::NewHumanController(BaseObject* creator)
61        : HumanController(creator)
62        , crossHairOverlay_(NULL)
63        , centerOverlay_(NULL)
64        , damageOverlayTop_(NULL)
65        , damageOverlayRight_(NULL)
66        , damageOverlayBottom_(NULL)
67        , damageOverlayLeft_(NULL)
68        , damageOverlayTT_(0)
69        , arrowsOverlay1_(NULL)
70        , arrowsOverlay2_(NULL)
71        , arrowsOverlay3_(NULL)
72        , arrowsOverlay4_(NULL)
73    {
74        RegisterObject(NewHumanController);
75
76        overlaySize_ = 0.08f;
77        arrowsSize_ = 0.4f;
78
79        damageOverlayTime_ = 0.6f;
80
81        controlMode_ = 0;
82        acceleration_ = 0;
83        accelerating_ = false;
84        firemode_ = -1;
85
86        showArrows_ = true;
87        showOverlays_ = false;
88        showDamageOverlay_ = true;
89
90        //currentPitch_ = 1;
91        //currentYaw_ = 1;
92
93        if (GameMode::showsGraphics())
94        {
95            crossHairOverlay_ = new OrxonoxOverlay(this);
96            crossHairOverlay_->setBackgroundMaterial("Orxonox/Crosshair3");
97            crossHairOverlay_->setSize(Vector2(overlaySize_, overlaySize_));
98            crossHairOverlay_->hide();
99            //crossHairOverlay_->setAspectCorrection(true); not working
100
101            centerOverlay_ = new OrxonoxOverlay(this);
102            centerOverlay_->setBackgroundMaterial("Orxonox/CenterOverlay");
103            centerOverlay_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
104            centerOverlay_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
105            centerOverlay_->hide();
106
107            if (showDamageOverlay_)
108            {
109                damageOverlayTop_ = new OrxonoxOverlay(this);
110                damageOverlayTop_->setBackgroundMaterial("Orxonox/DamageOverlayTop");
111                damageOverlayTop_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
112                damageOverlayTop_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
113                damageOverlayTop_->hide();
114
115                damageOverlayRight_ = new OrxonoxOverlay(this);
116                damageOverlayRight_->setBackgroundMaterial("Orxonox/DamageOverlayRight");
117                damageOverlayRight_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
118                damageOverlayRight_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
119                damageOverlayRight_->hide();
120
121                damageOverlayBottom_ = new OrxonoxOverlay(this);
122                damageOverlayBottom_->setBackgroundMaterial("Orxonox/DamageOverlayBottom");
123                damageOverlayBottom_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
124                damageOverlayBottom_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
125                damageOverlayBottom_->hide();
126
127                damageOverlayLeft_ = new OrxonoxOverlay(this);
128                damageOverlayLeft_->setBackgroundMaterial("Orxonox/DamageOverlayLeft");
129                damageOverlayLeft_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
130                damageOverlayLeft_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
131                damageOverlayLeft_->hide();
132            }
133
134            if (showArrows_)
135            {
136                arrowsOverlay1_ = new OrxonoxOverlay(this);
137                arrowsOverlay1_->setBackgroundMaterial("Orxonox/DirectionArrows1");
138                arrowsOverlay1_->setSize(Vector2(0.02727f, 0.36f * arrowsSize_));
139                arrowsOverlay1_->setPickPoint(Vector2(0.5f, 0.5f));
140                arrowsOverlay1_->setPosition(Vector2(0.5f, 0.5f));
141                arrowsOverlay1_->hide();
142
143                arrowsOverlay2_ = new OrxonoxOverlay(this);
144                arrowsOverlay2_->setBackgroundMaterial("Orxonox/DirectionArrows2");
145                arrowsOverlay2_->setSize(Vector2(0.02727f, 0.59f * arrowsSize_));
146                arrowsOverlay2_->setPickPoint(Vector2(0.5f, 0.5f));
147                arrowsOverlay2_->setPosition(Vector2(0.5f, 0.5f));
148                arrowsOverlay2_->hide();
149
150                arrowsOverlay3_ = new OrxonoxOverlay(this);
151                arrowsOverlay3_->setBackgroundMaterial("Orxonox/DirectionArrows3");
152                arrowsOverlay3_->setSize(Vector2(0.02727f, 0.77f * arrowsSize_));
153                arrowsOverlay3_->setPickPoint(Vector2(0.5f, 0.5f));
154                arrowsOverlay3_->setPosition(Vector2(0.5f, 0.5f));
155                arrowsOverlay3_->hide();
156
157                arrowsOverlay4_ = new OrxonoxOverlay(this);
158                arrowsOverlay4_->setBackgroundMaterial("Orxonox/DirectionArrows4");
159                arrowsOverlay4_->setSize(Vector2(0.02727f, arrowsSize_));
160                arrowsOverlay4_->setPickPoint(Vector2(0.5f, 0.5f));
161                arrowsOverlay4_->setPosition(Vector2(0.5f, 0.5f));
162                arrowsOverlay4_->hide();
163            }
164        }
165
166        // HACK: Define which objects are targetable when considering the creator of an orxonox::Model
167        this->targetMask_.exclude(ClassByString("BaseObject"));
168        this->targetMask_.include(ClassByString("WorldEntity"));
169        this->targetMask_.exclude(ClassByString("Projectile"));
170
171        NewHumanController::localController_s = this;
172
173        controlPaused_ = false;
174
175        //HumanController::localController_s->getControllableEntity()->getCamera()->setDrag(true);
176    }
177
178    NewHumanController::~NewHumanController()
179    {
180        if (this->isInitialized())
181        {
182            if (this->crossHairOverlay_)
183                this->crossHairOverlay_->destroy();
184            if (this->centerOverlay_)
185                this->centerOverlay_->destroy();
186
187            if (this->arrowsOverlay1_)
188                this->arrowsOverlay1_->destroy();
189            if (this->arrowsOverlay2_)
190                this->arrowsOverlay2_->destroy();
191            if (this->arrowsOverlay3_)
192                this->arrowsOverlay3_->destroy();
193            if (this->arrowsOverlay4_)
194                this->arrowsOverlay4_->destroy();
195            if (this->damageOverlayTop_)
196                this->damageOverlayTop_->destroy();
197            if (this->damageOverlayLeft_)
198                this->damageOverlayLeft_->destroy();
199            if (this->damageOverlayRight_)
200                this->damageOverlayRight_->destroy();
201            if (this->damageOverlayBottom_)
202                this->damageOverlayBottom_->destroy();
203        }
204    }
205
206    void NewHumanController::tick(float dt)
207    {
208        if (GameMode::showsGraphics())
209        {
210
211            if (this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
212            {
213                this->updateTarget();
214
215                if (!controlPaused_ )
216                {
217                    if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket"))))
218                        this->showOverlays();
219
220                    this->crossHairOverlay_->setPosition(Vector2(static_cast<float>(this->currentYaw_)/2*-1+.5f-overlaySize_/2, static_cast<float>(this->currentPitch_)/2*-1+.5f-overlaySize_/2));
221
222                    if (this->controlMode_ == 0 || (this->controlMode_ == 1 && this->firemode_ == 1))
223                    {
224                        if (this->showOverlays_ && this->showArrows_)
225                            alignArrows();
226                    }
227                    else
228                        hideArrows();
229
230                    if (this->showDamageOverlay_ && (this->damageOverlayTT_ > 0 || this->damageOverlayTR_ > 0 || this->damageOverlayTB_ > 0 || this->damageOverlayTL_ > 0))
231                    {
232                        this->damageOverlayTT_ -= dt;
233                        this->damageOverlayTR_ -= dt;
234                        this->damageOverlayTB_ -= dt;
235                        this->damageOverlayTL_ -= dt;
236                        if (this->damageOverlayTT_ <= 0)
237                            this->damageOverlayTop_->hide();
238                        if (this->damageOverlayTR_ <= 0)
239                            this->damageOverlayRight_->hide();
240                        if (this->damageOverlayTB_ <= 0)
241                            this->damageOverlayBottom_->hide();
242                        if (this->damageOverlayTL_ <= 0)
243                            this->damageOverlayLeft_->hide();
244                    }
245                }
246            }
247            else
248                this->hideOverlays();
249
250            if (this->acceleration_ > 0)
251            {
252                if (this->accelerating_)
253                    HumanController::moveFrontBack(Vector2(1, 0));
254                else
255                    HumanController::moveFrontBack(Vector2(this->acceleration_, 0));
256                this->accelerating_ = false;
257                //HumanController::moveFrontBack(Vector2(clamp(this->acceleration_ + this->currentAcceleration_, 0.0f, 1.0f), 0));
258            }
259        }
260
261        // Reset pitch and yaw rates
262        // TODO: Reactivate this to fix the game pad problem with 0 input
263        //this->currentPitch_ = 0;
264        //this->currentYaw_ = 0;
265
266        HumanController::tick(dt);
267    }
268
269    void NewHumanController::doFire(unsigned int firemode)
270    {
271        if (!this->controllableEntity_)
272            return;
273
274        this->firemode_ = firemode;
275
276        if (firemode == 1 && this->controlMode_ == 1)
277        {
278            //unlocked steering, steer on right mouse click
279            HumanController::yaw(Vector2(this->currentYaw_, 0));
280            HumanController::pitch(Vector2(this->currentPitch_, 0));
281        }
282        else
283            HumanController::localController_s->getControllableEntity()->fire(firemode);
284
285    }
286
287    void NewHumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
288    {
289        if (this->showDamageOverlay_ && !this->controlPaused_ && this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
290        {
291            Vector3 posA;
292            if (originator)
293                posA = originator->getWorldPosition();
294            else
295                posA = multi_cast<Vector3>(contactpoint.getPositionWorldOnA());
296            //Vector3 posB = multi_cast<Vector3>(contactpoint.getPositionWorldOnB());
297            //posA and posB are almost identical
298
299            Vector3 relativeHit = this->getControllableEntity()->getWorldOrientation().UnitInverse() * (this->getControllableEntity()->getWorldPosition() - posA);
300
301            //back is z positive
302            //x is left positive
303            //y is down positive
304            relativeHit.normalise();
305
306            float threshold = 0.3f;
307            if (relativeHit.x > threshold) // Left
308            {
309                this->damageOverlayLeft_->show();
310                this->damageOverlayTL_ = this->damageOverlayTime_;
311                //this->damageOverlayLeft_->setBackgroundAlpha(0.3);
312            }
313            if (relativeHit.x < -threshold) //Right
314            {
315                this->damageOverlayRight_->show();
316                this->damageOverlayTR_ = this->damageOverlayTime_;
317                //this->damageOverlayRight_->setBackgroundAlpha(0.3);
318            }
319            if (relativeHit.y > threshold) //Top
320            {
321                this->damageOverlayBottom_->show();
322                this->damageOverlayTB_ = this->damageOverlayTime_;
323                //this->damageOverlayTop_->setBackgroundAlpha(0.3);
324            }
325            if (relativeHit.y < -threshold) //Bottom
326            {
327                this->damageOverlayTop_->show();
328                this->damageOverlayTT_ = this->damageOverlayTime_;
329                //this->damageOverlayBottom_->setBackgroundAlpha(0.3);
330            }
331        }
332    }
333
334    void NewHumanController::unfire()
335    {
336        if (NewHumanController::localController_s)
337            NewHumanController::localController_s->doUnfire();
338    }
339
340    void NewHumanController::doUnfire()
341    {
342        this->firemode_ = -1;
343        hideArrows();
344    }
345
346    void NewHumanController::updateTarget()
347    {
348        Ogre::RaySceneQuery * rsq = HumanController::localController_s->getControllableEntity()->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
349
350        Ogre::Ray mouseRay = HumanController::localController_s->getControllableEntity()->getCamera()->getOgreCamera()->getCameraToViewportRay(static_cast<float>(this->currentYaw_)/2*-1+.5f, static_cast<float>(this->currentPitch_)/2*-1+.5f);
351
352        rsq->setRay(mouseRay);
353        rsq->setSortByDistance(true);
354
355        /*
356        Distance of objects:
357        ignore everything under 200 maybe even take 1000 as min distance to shoot at
358
359        shots are regularly traced and are entities!!!!!!!!! this is the biggest problem
360        they vanish only after a distance of 10'000
361        */
362
363
364        Ogre::RaySceneQueryResult& result = rsq->execute();
365        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
366        WorldEntity* myWe = static_cast<WorldEntity*>(this->getControllableEntity());
367
368        Ogre::RaySceneQueryResult::iterator itr;
369        for (itr = result.begin(); itr != result.end(); ++itr)
370        {
371//             CCOUT(0) << "testing object as target" << endl;
372            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" /*&& itr->distance > 500*/)
373            {
374                // Try to cast the user pointer
375                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(Ogre::any_cast<OrxonoxClass*>(itr->movable->getUserAny()));
376               
377                // make sure we don't shoot ourselves
378                if( wePtr==myWe )
379                    continue;
380               
381                if (wePtr)
382                {
383                    // go through all parents of object and look whether they are sightable or not
384                    bool isSightable = false;
385                    WorldEntity* parent = wePtr->getParent();
386                    while (parent)
387                    {
388                        if (this->targetMask_.isExcluded(parent->getIdentifier()) || parent==myWe)
389                        {
390                            parent = parent->getParent();
391                            continue;
392                        }
393                        else
394                        {
395                            isSightable = true;
396                            break;
397                        }
398                    }
399                    if (!isSightable)
400                        continue;
401                }
402
403                if (this->getControllableEntity() && this->getControllableEntity()->getTarget() != wePtr)
404                    this->getControllableEntity()->setTarget(wePtr);
405
406                if (pawn)
407                    pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance );
408
409                //itr->movable->getParentSceneNode()->showBoundingBox(true);
410                //return mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance; //or itr->movable->getParentSceneNode()->_getDerivedPosition()
411                return;
412            }
413        }
414
415        if (pawn)
416            pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * 1200 );
417
418        if( this->getControllableEntity() && this->getControllableEntity()->getTarget() != 0 )
419            this->getControllableEntity()->setTarget( 0 );
420
421        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getWorldOrientation() * Vector3::NEGATIVE_UNIT_Z * 2000);
422        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getCamera()->getOgreCamera()->getOrientation() * Vector3::NEGATIVE_UNIT_Z);
423    }
424
425    void NewHumanController::frontback(const Vector2& value)
426    {
427        this->accelerating_ = true;
428
429        //if (this->acceleration_ == 0)
430        HumanController::frontback(value);
431    }
432
433    void NewHumanController::yaw(const Vector2& value)
434    {
435        //SUPER(NewHumanController, yaw, value);
436        if (this->controlMode_ == 0 || (this->controllableEntity_ && this->controllableEntity_->isInMouseLook()))
437            HumanController::yaw(value);
438
439        this->currentYaw_ = value.x;
440    }
441
442    void NewHumanController::pitch(const Vector2& value)
443    {
444        //SUPER(NewHumanController, pitch, value);
445        if (this->controlMode_ == 0 || (this->controllableEntity_ && this->controllableEntity_->isInMouseLook()))
446            HumanController::pitch(value);
447
448        this->currentPitch_ = value.x;
449    }
450
451    void NewHumanController::changeMode()
452    {
453        if (NewHumanController::localController_s)
454        {
455            if (NewHumanController::localController_s->controlMode_ == 0)
456            {
457                NewHumanController::localController_s->controlMode_ = 1;
458                NewHumanController::localController_s->hideArrows();
459            }
460            else
461                NewHumanController::localController_s->controlMode_ = 0;
462        }
463    }
464
465    void NewHumanController::changedControllableEntity()
466    {
467        this->controlMode_ = 0;
468        this->currentYaw_ = 0;
469        this->currentPitch_ = 0;
470        if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket"))))
471        {
472            this->showOverlays_ = true;
473            if (!this->controlPaused_)
474            {
475                this->showOverlays();
476                this->alignArrows();
477            }
478        }
479        else
480        {
481            this->showOverlays_ = false;
482            this->hideOverlays();
483        }
484    }
485
486    void NewHumanController::accelerate()
487    {
488        if (NewHumanController::localController_s)
489            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ + 0.2f, 0.00f, 1.0f);
490    }
491
492    void NewHumanController::decelerate()
493    {
494        if (NewHumanController::localController_s)
495            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ - 0.1f, 0.0f, 1.0f);
496    }
497
498    void NewHumanController::doResumeControl()
499    {
500        this->controlPaused_ = false;
501        if (this->showOverlays_)
502            this->showOverlays();
503    }
504
505    void NewHumanController::doPauseControl()
506    {
507        this->controlPaused_ = true;
508        this->hideOverlays();
509    }
510
511    void NewHumanController::alignArrows()
512    {
513        if (showArrows_)
514        {
515            hideArrows();
516
517            float distance = sqrt(pow(static_cast<float>(this->currentYaw_)/2*-1,2) + pow(static_cast<float>(this->currentPitch_)/2*-1,2));
518
519            if (distance > 0.04f && distance <= 0.59f * arrowsSize_ / 2.0f )
520            {
521                this->arrowsOverlay1_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
522                this->arrowsOverlay1_->show();
523            }
524            else if (distance > 0.59f * arrowsSize_ / 2.0f && distance <= 0.77f * arrowsSize_ / 2.0f )
525            {
526                this->arrowsOverlay2_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
527                this->arrowsOverlay2_->show();
528            }
529            else if (distance > 0.77f * arrowsSize_ / 2.0f && distance <= arrowsSize_ / 2.0f)
530            {
531                this->arrowsOverlay3_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
532                this->arrowsOverlay3_->show();
533            }
534            else if (distance > arrowsSize_ / 2.0f)
535            {
536                this->arrowsOverlay4_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
537                this->arrowsOverlay4_->show();
538            }
539        }
540    }
541
542    void NewHumanController::showOverlays()
543    {
544        if (!GameMode::showsGraphics())
545            return;
546        this->crossHairOverlay_->show();
547        this->centerOverlay_->show();
548
549        if (showArrows_)
550        {
551            this->arrowsOverlay1_->show();
552            this->arrowsOverlay2_->show();
553            this->arrowsOverlay3_->show();
554            this->arrowsOverlay4_->show();
555        }
556    }
557
558    void NewHumanController::hideOverlays()
559    {
560        if (!GameMode::showsGraphics())
561            return;
562        this->crossHairOverlay_->hide();
563        this->centerOverlay_->hide();
564
565        if (showDamageOverlay_)
566        {
567            this->damageOverlayTop_->hide();
568            this->damageOverlayRight_->hide();
569            this->damageOverlayBottom_->hide();
570            this->damageOverlayLeft_->hide();
571        }
572
573        this->hideArrows();
574    }
575
576    void NewHumanController::hideArrows()
577    {
578        if(!GameMode::showsGraphics())
579            return;
580        if (showArrows_)
581        {
582            this->arrowsOverlay1_->hide();
583            this->arrowsOverlay2_->hide();
584            this->arrowsOverlay3_->hide();
585            this->arrowsOverlay4_->hide();
586        }
587    }
588       
589
590   
591
592
593}
Note: See TracBrowser for help on using the repository browser.