Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/orxonox/controllers/NewHumanController.cc @ 6310

Last change on this file since 6310 was 6310, checked in by wirthmi, 14 years ago

Added damage overlays

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