Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6279 was 6279, checked in by scheusso, 14 years ago

overlay fix in NHC

  • 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/CenterOverlay");
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/CenterOverlay");
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/CenterOverlay");
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/CenterOverlay");
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                if (this->getControllableEntity() && this->getControllableEntity()->getIdentifier()->getName() == "SpaceShip")
166                    this->showOverlays();
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            else
181                this->hideOverlays();
182
183            if ( this->acceleration_ > 0 )
184            {
185/*
186if (this->controllableEntity_ && this->controllableEntity_->getEngine()) {
187    std::cout << this->controllableEntity_->getEngine()->getAccelerationFront() << endl;
188}
189*/
190                if ( this->accelerating_ )
191                    HumanController::moveFrontBack(Vector2(1, 0));
192                else
193                    HumanController::moveFrontBack(Vector2(this->acceleration_, 0)); 
194                this->accelerating_ = false;
195                //HumanController::moveFrontBack(Vector2(clamp(this->acceleration_ + this->currentAcceleration_, 0.0f, 1.0f), 0));
196            }
197        }
198
199        HumanController::tick(dt);
200    }
201
202    /*void NewHumanController::tick(float dt)
203    {
204        if (GameMode::playsSound() && NewHumanController::localController_s && NewHumanController::localController_s->controllableEntity_)
205        {
206            // Update sound listener
207            Camera* camera = NewHumanController::localController_s->controllableEntity_->getCamera();
208            if (camera)
209            {
210                SoundManager::getInstance().setListenerPosition(camera->getWorldPosition());
211                SoundManager::getInstance().setListenerOrientation(camera->getWorldOrientation());
212            }
213            else
214                COUT(3) << "NewHumanController, Warning: Using a ControllableEntity without Camera" << std::endl;
215        }
216    }*/
217   
218    void NewHumanController::doFire(unsigned int firemode)
219    {
220        //if (HumanController::localController_s && HumanController::localController_s->controllableEntity_) {
221
222/*
223        // Get results, create a node/entity on the position
224        for ( itr = result.begin(); itr != result.end(); itr++ )
225        {
226            if (itr->movable && itr->movable->getName() == "Head")
227            {
228                soundMgr->StopSound( &jaguarSoundChannel );
229                soundMgr->PlaySound( jaguarSound, headNode, &jaguarSoundChannel );
230                break;
231            } // if
232        }
233*/
234
235        this->firemode_ = firemode;
236
237        if (firemode == 1 && this->controlMode_ == 1)
238        {
239            //unlocked steering, steer on right mouse click
240            HumanController::yaw(Vector2(this->currentYaw_, 0));
241            HumanController::pitch(Vector2(this->currentPitch_, 0));
242        }
243        else
244            HumanController::localController_s->getControllableEntity()->fire(firemode);
245
246    }
247
248    void NewHumanController::unfire()
249    {
250        if (NewHumanController::localController_s)
251            NewHumanController::localController_s->doUnfire();
252    }
253
254    void NewHumanController::doUnfire()
255    {
256        this->firemode_ = -1;
257        hideArrows();
258    }
259
260    void NewHumanController::updateTarget()
261    {
262        Ogre::RaySceneQuery * rsq = HumanController::localController_s->getControllableEntity()->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
263
264        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);
265
266        rsq->setRay(mouseRay);
267        rsq->setSortByDistance(true);
268
269        /*
270        Distance of objects:
271        ignore everything under 200 maybe even take 1000 as min distance to shoot at
272
273        shots are regularly traced and are entities!!!!!!!!! this is the biggest problem
274        they vanish only after a distance of 10'000
275        */
276
277
278        Ogre::RaySceneQueryResult& result = rsq->execute();
279        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
280
281        Ogre::RaySceneQueryResult::iterator itr;
282        for (itr = result.begin(); itr != result.end(); ++itr)
283        {
284            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" && itr->distance > 500)
285            {
286                // Try to cast the user pointer
287                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(itr->movable->getUserObject());
288                if (wePtr)
289                {
290                    // go through all parents of object and look wheter they are Sightable or not
291                    bool isSightable = false;
292                    WorldEntity* parent = wePtr->getParent();
293                    while( parent )
294                    {
295                        if (this->targetMask_.isExcluded(parent->getIdentifier()))
296                        {
297                            parent = parent->getParent();
298                            continue;
299                        }
300                        else
301                        {
302                            isSightable = true;
303                            break;
304                        }
305                    }
306                    if ( !isSightable )
307                        continue;
308                }
309
310                if ( this->getControllableEntity() && this->getControllableEntity()->getTarget() != wePtr )
311                {
312                    this->getControllableEntity()->setTarget(wePtr);
313                }
314
315                if( pawn )
316                {
317                    pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance );
318                }
319
320                //itr->movable->getParentSceneNode()->showBoundingBox(true);
321                //std::cout << itr->movable->getParentSceneNode()->_getDerivedPosition() << endl;
322                //return mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance; //or itr->movable->getParentSceneNode()->_getDerivedPosition()
323                return;
324            }
325
326        }
327        if ( pawn )
328        {
329            pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * 1200 );
330        }
331
332        if( this->getControllableEntity() && this->getControllableEntity()->getTarget() != 0 )
333            this->getControllableEntity()->setTarget( 0 );
334   
335
336        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getWorldOrientation() * Vector3::NEGATIVE_UNIT_Z * 2000);
337        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getCamera()->getOgreCamera()->getOrientation() * Vector3::NEGATIVE_UNIT_Z);
338    }
339
340    void NewHumanController::frontback(const Vector2& value)
341    {
342        this->accelerating_ = true;
343
344        //if (this->acceleration_ == 0)
345            HumanController::frontback(value);
346    }
347
348    void NewHumanController::yaw(const Vector2& value)
349    {
350//         SUPER(NewHumanController, yaw, value);
351        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
352            HumanController::yaw(value);
353
354        this->currentYaw_ = value.x;
355    }
356
357    void NewHumanController::pitch(const Vector2& value)
358    {
359//         SUPER(NewHumanController, pitch, value);
360        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
361            HumanController::pitch(value);
362
363        this->currentPitch_ = value.x;
364    }
365
366    void NewHumanController::changeMode()
367    {
368        if (NewHumanController::localController_s && NewHumanController::localController_s->controlMode_ == 0)
369        {
370                NewHumanController::localController_s->controlMode_ = 1;
371                NewHumanController::localController_s->hideArrows();
372        }
373        else
374            NewHumanController::localController_s->controlMode_ = 0;
375    }
376
377    void NewHumanController::changedControllableEntity()
378    {
379        this->controlMode_ = 0;
380        this->currentYaw_ = 0;
381        this->currentPitch_ = 0;
382        if (this->getControllableEntity() && this->getControllableEntity()->getIdentifier()->getName() == "SpaceShip")
383        {
384            this->showOverlays_ = true;
385            if( !this->controlPaused_ )
386            {
387                this->showOverlays();
388                this->alignArrows();
389            }
390        }
391        else
392        {
393            this->showOverlays_ = false;
394            this->hideOverlays();
395        }
396    }
397
398    void NewHumanController::accelerate()
399    {
400        if ( NewHumanController::localController_s )
401        {
402            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ + 0.2f, 0.00f, 1.0f);
403        }
404    }
405
406    void NewHumanController::decelerate()
407    {
408        if ( NewHumanController::localController_s )
409        {
410            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ - 0.1f, 0.0f, 1.0f);
411        }
412    }
413
414    void NewHumanController::doResumeControl() {
415        this->controlPaused_ = false;
416        if( this->showOverlays_ ) {
417            this->showOverlays();
418        }
419    }
420
421    void NewHumanController::doPauseControl() {
422        this->controlPaused_ = true;
423       
424        this->hideOverlays();
425    }
426
427    void NewHumanController::alignArrows() {
428        if (showArrows_) {
429            hideArrows();
430   
431            float distance = sqrt(pow(static_cast<float>(this->currentYaw_)/2*-1,2) + pow(static_cast<float>(this->currentPitch_)/2*-1,2));
432   
433            if ( distance > 0.04 && distance <= 0.59 * arrowsSize_ / 2.0 ) {
434                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));
435   
436                this->arrowsOverlay1_->show();
437            }
438            else if ( distance > 0.59 * arrowsSize_ / 2.0 && distance <= 0.77 * arrowsSize_ / 2.0 ) {
439                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));
440   
441                this->arrowsOverlay2_->show();
442            }
443            else if ( distance > 0.77 * arrowsSize_ / 2.0 && distance <= arrowsSize_ / 2.0 ) {
444                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));
445   
446                this->arrowsOverlay3_->show();
447            }
448            else if ( distance > arrowsSize_ / 2.0 ) {
449                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));
450   
451                this->arrowsOverlay4_->show();
452            }
453        }
454    }
455
456    void NewHumanController::showOverlays() {
457        this->crossHairOverlay_->show();
458        this->centerOverlay_->show();
459       
460        if (showArrows_) {
461            this->arrowsOverlay1_->show();
462            this->arrowsOverlay2_->show();
463            this->arrowsOverlay3_->show();
464            this->arrowsOverlay4_->show();
465        }
466    }
467
468    void NewHumanController::hideOverlays() {
469        this->crossHairOverlay_->hide();
470        this->centerOverlay_->hide();
471       
472        this->hideArrows();
473    }
474
475    void NewHumanController::hideArrows() {
476        if (showArrows_) {
477            this->arrowsOverlay1_->hide();
478            this->arrowsOverlay2_->hide();
479            this->arrowsOverlay3_->hide();
480            this->arrowsOverlay4_->hide();
481        }
482    }
483}
Note: See TracBrowser for help on using the repository browser.