Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Fixed bug: overlays hide when ingame menu is brought up

  • Property svn:eol-style set to native
File size: 18.1 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
47namespace orxonox
48{
49    SetConsoleCommand(NewHumanController, changeMode,          false).keybindMode(KeybindMode::OnPress);
50    SetConsoleCommand(NewHumanController, accelerate,          false).keybindMode(KeybindMode::OnPress);
51    SetConsoleCommand(NewHumanController, decelerate,          false).keybindMode(KeybindMode::OnPress);
52    SetConsoleCommand(NewHumanController, unfire,              true).keybindMode(KeybindMode::OnRelease);
53
54    CreateUnloadableFactory(NewHumanController);
55
56    NewHumanController* NewHumanController::localController_s = 0;
57
58    NewHumanController::NewHumanController(BaseObject* creator)
59        : HumanController(creator)
60        , crossHairOverlay_(NULL)
61        , centerOverlay_(NULL)
62    {
63        RegisterObject(NewHumanController);
64
65        overlaySize_ = 0.08;
66        arrowsSize_ = 0.4;
67        controlMode_ = 0;
68        acceleration_ = 0;
69        accelerating_ = false;
70        firemode_ = -1;
71        showArrows_ = true;
72        showOverlays_ = false;
73
74        //currentPitch_ = 1;
75        //currentYaw_ = 1;
76
77        if (GameMode::showsGraphics())
78        {
79            crossHairOverlay_ = new OrxonoxOverlay(this);
80            crossHairOverlay_->setBackgroundMaterial("Orxonox/Crosshair3");
81            crossHairOverlay_->setSize(Vector2(overlaySize_, overlaySize_));
82            crossHairOverlay_->hide();
83            //crossHairOverlay_->setAspectCorrection(true); not working
84
85            centerOverlay_ = new OrxonoxOverlay(this);
86            centerOverlay_->setBackgroundMaterial("Orxonox/CenterOverlay");
87            centerOverlay_->setSize(Vector2(overlaySize_ * 2.5, overlaySize_ * 2.5));
88            centerOverlay_->setPosition(Vector2(0.5 - overlaySize_*2.5/2.0, 0.5 - overlaySize_*2.5/2.0));\
89            centerOverlay_->hide();
90
91            if (showArrows_)
92            {
93                arrowsOverlay1_ = new OrxonoxOverlay(this);
94                arrowsOverlay1_->setBackgroundMaterial("Orxonox/DirectionArrows1");
95                arrowsOverlay1_->setSize(Vector2(0.02727, 0.36 * arrowsSize_));
96                arrowsOverlay1_->setPickPoint(Vector2(0.5, 0.5));
97                arrowsOverlay1_->setPosition(Vector2(0.5, 0.5));
98                arrowsOverlay1_->hide();
99   
100                arrowsOverlay2_ = new OrxonoxOverlay(this);
101                arrowsOverlay2_->setBackgroundMaterial("Orxonox/DirectionArrows2");
102                arrowsOverlay2_->setSize(Vector2(0.02727, 0.59 * arrowsSize_));
103                arrowsOverlay2_->setPickPoint(Vector2(0.5, 0.5));
104                arrowsOverlay2_->setPosition(Vector2(0.5, 0.5));
105                arrowsOverlay2_->hide();
106   
107                arrowsOverlay3_ = new OrxonoxOverlay(this);
108                arrowsOverlay3_->setBackgroundMaterial("Orxonox/DirectionArrows3");
109                arrowsOverlay3_->setSize(Vector2(0.02727, 0.77 * arrowsSize_));
110                arrowsOverlay3_->setPickPoint(Vector2(0.5, 0.5));
111                arrowsOverlay3_->setPosition(Vector2(0.5, 0.5));
112                arrowsOverlay3_->hide();
113   
114                arrowsOverlay4_ = new OrxonoxOverlay(this);
115                arrowsOverlay4_->setBackgroundMaterial("Orxonox/DirectionArrows4");
116                arrowsOverlay4_->setSize(Vector2(0.02727, arrowsSize_));
117                arrowsOverlay4_->setPickPoint(Vector2(0.5, 0.5));
118                arrowsOverlay4_->setPosition(Vector2(0.5, 0.5));
119                arrowsOverlay4_->hide();
120            }
121        }
122
123        // HACK: Define which objects are targetable when considering the creator of an orxonox::Model
124        this->targetMask_.exclude(ClassByString("BaseObject"));
125        this->targetMask_.include(ClassByString("WorldEntity"));
126        this->targetMask_.exclude(ClassByString("Projectile"));
127
128        NewHumanController::localController_s = this;
129
130        controlPaused_ = false;
131
132//HumanController::localController_s->getControllableEntity()->getCamera()->setDrag(true);
133    }
134
135    NewHumanController::~NewHumanController()
136    {
137        if (this->isInitialized())
138        {
139            if (this->crossHairOverlay_)
140                this->crossHairOverlay_->destroy();
141            if (this->centerOverlay_)
142                this->centerOverlay_->destroy();
143
144            if (showArrows_)
145            {
146                if (this->arrowsOverlay1_)
147                    this->arrowsOverlay1_->destroy();
148                if (this->arrowsOverlay2_)
149                    this->arrowsOverlay2_->destroy();
150                if (this->arrowsOverlay3_)
151                    this->arrowsOverlay3_->destroy();
152                if (this->arrowsOverlay4_)
153                    this->arrowsOverlay4_->destroy();
154            }
155        }
156    }
157
158    void NewHumanController::tick(float dt)
159    {
160        if (GameMode::showsGraphics())
161        {
162
163            if( this->controllableEntity_ && !this->controllableEntity_->isInMouseLook() )
164            {
165                this->updateTarget();
166
167                if ( !controlPaused_ ) {
168                    if (this->getControllableEntity() && this->getControllableEntity()->getIdentifier()->getName() == "SpaceShip")
169                        this->showOverlays();
170
171                    this->crossHairOverlay_->setPosition(Vector2(static_cast<float>(this->currentYaw_)/2*-1+.5-overlaySize_/2, static_cast<float>(this->currentPitch_)/2*-1+.5-overlaySize_/2));
172
173                    if ( this->controlMode_ == 0 || ( this->controlMode_ == 1 && this->firemode_ == 1 ) )
174                    {
175                        if ( this->showOverlays_ && this->showArrows_)
176                            alignArrows();
177                    }
178                    else
179                        hideArrows();
180                }
181            }
182            else
183                this->hideOverlays();
184
185            if ( this->acceleration_ > 0 )
186            {
187/*
188if (this->controllableEntity_ && this->controllableEntity_->getEngine()) {
189    std::cout << this->controllableEntity_->getEngine()->getAccelerationFront() << endl;
190}
191*/
192                if ( this->accelerating_ )
193                    HumanController::moveFrontBack(Vector2(1, 0));
194                else
195                    HumanController::moveFrontBack(Vector2(this->acceleration_, 0)); 
196                this->accelerating_ = false;
197                //HumanController::moveFrontBack(Vector2(clamp(this->acceleration_ + this->currentAcceleration_, 0.0f, 1.0f), 0));
198            }
199        }
200
201        HumanController::tick(dt);
202    }
203
204    /*void NewHumanController::tick(float dt)
205    {
206        if (GameMode::playsSound() && NewHumanController::localController_s && NewHumanController::localController_s->controllableEntity_)
207        {
208            // Update sound listener
209            Camera* camera = NewHumanController::localController_s->controllableEntity_->getCamera();
210            if (camera)
211            {
212                SoundManager::getInstance().setListenerPosition(camera->getWorldPosition());
213                SoundManager::getInstance().setListenerOrientation(camera->getWorldOrientation());
214            }
215            else
216                COUT(3) << "NewHumanController, Warning: Using a ControllableEntity without Camera" << std::endl;
217        }
218    }*/
219   
220    void NewHumanController::doFire(unsigned int firemode)
221    {
222        //if (HumanController::localController_s && HumanController::localController_s->controllableEntity_) {
223
224/*
225        // Get results, create a node/entity on the position
226        for ( itr = result.begin(); itr != result.end(); itr++ )
227        {
228            if (itr->movable && itr->movable->getName() == "Head")
229            {
230                soundMgr->StopSound( &jaguarSoundChannel );
231                soundMgr->PlaySound( jaguarSound, headNode, &jaguarSoundChannel );
232                break;
233            } // if
234        }
235*/
236
237        this->firemode_ = firemode;
238
239        if (firemode == 1 && this->controlMode_ == 1)
240        {
241            //unlocked steering, steer on right mouse click
242            HumanController::yaw(Vector2(this->currentYaw_, 0));
243            HumanController::pitch(Vector2(this->currentPitch_, 0));
244        }
245        else
246            HumanController::localController_s->getControllableEntity()->fire(firemode);
247
248    }
249
250    void NewHumanController::unfire()
251    {
252        if (NewHumanController::localController_s)
253            NewHumanController::localController_s->doUnfire();
254    }
255
256    void NewHumanController::doUnfire()
257    {
258        this->firemode_ = -1;
259        hideArrows();
260    }
261
262    void NewHumanController::updateTarget()
263    {
264        Ogre::RaySceneQuery * rsq = HumanController::localController_s->getControllableEntity()->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
265
266        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);
267
268        rsq->setRay(mouseRay);
269        rsq->setSortByDistance(true);
270
271        /*
272        Distance of objects:
273        ignore everything under 200 maybe even take 1000 as min distance to shoot at
274
275        shots are regularly traced and are entities!!!!!!!!! this is the biggest problem
276        they vanish only after a distance of 10'000
277        */
278
279
280        Ogre::RaySceneQueryResult& result = rsq->execute();
281        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
282
283        Ogre::RaySceneQueryResult::iterator itr;
284        for (itr = result.begin(); itr != result.end(); ++itr)
285        {
286            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" && itr->distance > 500)
287            {
288                // Try to cast the user pointer
289                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(itr->movable->getUserObject());
290                if (wePtr)
291                {
292                    // go through all parents of object and look wheter they are Sightable or not
293                    bool isSightable = false;
294                    WorldEntity* parent = wePtr->getParent();
295                    while( parent )
296                    {
297                        if (this->targetMask_.isExcluded(parent->getIdentifier()))
298                        {
299                            parent = parent->getParent();
300                            continue;
301                        }
302                        else
303                        {
304                            isSightable = true;
305                            break;
306                        }
307                    }
308                    if ( !isSightable )
309                        continue;
310                }
311
312                if ( this->getControllableEntity() && this->getControllableEntity()->getTarget() != wePtr )
313                {
314                    this->getControllableEntity()->setTarget(wePtr);
315                }
316
317                if( pawn )
318                {
319                    pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance );
320                }
321
322                //itr->movable->getParentSceneNode()->showBoundingBox(true);
323                //std::cout << itr->movable->getParentSceneNode()->_getDerivedPosition() << endl;
324                //return mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance; //or itr->movable->getParentSceneNode()->_getDerivedPosition()
325                return;
326            }
327
328        }
329        if ( pawn )
330        {
331            pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * 1200 );
332        }
333
334        if( this->getControllableEntity() && this->getControllableEntity()->getTarget() != 0 )
335            this->getControllableEntity()->setTarget( 0 );
336   
337
338        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getWorldOrientation() * Vector3::NEGATIVE_UNIT_Z * 2000);
339        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getCamera()->getOgreCamera()->getOrientation() * Vector3::NEGATIVE_UNIT_Z);
340    }
341
342    void NewHumanController::frontback(const Vector2& value)
343    {
344        this->accelerating_ = true;
345
346        //if (this->acceleration_ == 0)
347            HumanController::frontback(value);
348    }
349
350    void NewHumanController::yaw(const Vector2& value)
351    {
352//         SUPER(NewHumanController, yaw, value);
353        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
354            HumanController::yaw(value);
355
356        this->currentYaw_ = value.x;
357    }
358
359    void NewHumanController::pitch(const Vector2& value)
360    {
361//         SUPER(NewHumanController, pitch, value);
362        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
363            HumanController::pitch(value);
364
365        this->currentPitch_ = value.x;
366    }
367
368    void NewHumanController::changeMode()
369    {
370        if (NewHumanController::localController_s && NewHumanController::localController_s->controlMode_ == 0)
371        {
372                NewHumanController::localController_s->controlMode_ = 1;
373                NewHumanController::localController_s->hideArrows();
374        }
375        else
376            NewHumanController::localController_s->controlMode_ = 0;
377    }
378
379    void NewHumanController::changedControllableEntity()
380    {
381        this->controlMode_ = 0;
382        this->currentYaw_ = 0;
383        this->currentPitch_ = 0;
384        if (this->getControllableEntity() && this->getControllableEntity()->getIdentifier()->getName() == "SpaceShip")
385        {
386            this->showOverlays_ = true;
387            if( !this->controlPaused_ )
388            {
389                this->showOverlays();
390                this->alignArrows();
391            }
392        }
393        else
394        {
395            this->showOverlays_ = false;
396            this->hideOverlays();
397        }
398    }
399
400    void NewHumanController::accelerate()
401    {
402        if ( NewHumanController::localController_s )
403        {
404            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ + 0.2f, 0.00f, 1.0f);
405        }
406    }
407
408    void NewHumanController::decelerate()
409    {
410        if ( NewHumanController::localController_s )
411        {
412            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ - 0.1f, 0.0f, 1.0f);
413        }
414    }
415
416    void NewHumanController::doResumeControl() {
417        this->controlPaused_ = false;
418        if( this->showOverlays_ ) {
419            this->showOverlays();
420        }
421    }
422
423    void NewHumanController::doPauseControl() {
424        this->controlPaused_ = true;
425
426        this->hideOverlays();
427    }
428
429    void NewHumanController::alignArrows() {
430        if (showArrows_) {
431            hideArrows();
432   
433            float distance = sqrt(pow(static_cast<float>(this->currentYaw_)/2*-1,2) + pow(static_cast<float>(this->currentPitch_)/2*-1,2));
434   
435            if ( distance > 0.04 && distance <= 0.59 * arrowsSize_ / 2.0 ) {
436                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));
437   
438                this->arrowsOverlay1_->show();
439            }
440            else if ( distance > 0.59 * arrowsSize_ / 2.0 && distance <= 0.77 * arrowsSize_ / 2.0 ) {
441                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));
442   
443                this->arrowsOverlay2_->show();
444            }
445            else if ( distance > 0.77 * arrowsSize_ / 2.0 && distance <= arrowsSize_ / 2.0 ) {
446                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));
447   
448                this->arrowsOverlay3_->show();
449            }
450            else if ( distance > arrowsSize_ / 2.0 ) {
451                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));
452   
453                this->arrowsOverlay4_->show();
454            }
455        }
456    }
457
458    void NewHumanController::showOverlays() {
459        this->crossHairOverlay_->show();
460        this->centerOverlay_->show();
461
462        if (showArrows_) {
463            this->arrowsOverlay1_->show();
464            this->arrowsOverlay2_->show();
465            this->arrowsOverlay3_->show();
466            this->arrowsOverlay4_->show();
467        }
468    }
469
470    void NewHumanController::hideOverlays() {
471        this->crossHairOverlay_->hide();
472        this->centerOverlay_->hide();
473
474        this->hideArrows();
475    }
476
477    void NewHumanController::hideArrows() {
478        if (showArrows_) {
479            this->arrowsOverlay1_->hide();
480            this->arrowsOverlay2_->hide();
481            this->arrowsOverlay3_->hide();
482            this->arrowsOverlay4_->hide();
483        }
484    }
485}
Note: See TracBrowser for help on using the repository browser.