Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

showing and hiding of overlays should now work correct with respawning and menu toggling

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