Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

changed arrows because michi didn't upload the arrow pictures

  • Property svn:eol-style set to native
File size: 17.3 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        firemode_ = -1;
72        showArrows_ = true;
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_ = true;
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                if ( !controlPaused_ ) {
167                    this->crossHairOverlay_->setPosition(Vector2(static_cast<float>(this->currentYaw_)/2*-1+.5-overlaySize_/2, static_cast<float>(this->currentPitch_)/2*-1+.5-overlaySize_/2));
168
169                    if ( this->controlMode_ == 0 || ( this->controlMode_ == 1 && this->firemode_ == 1 ) )
170                        alignArrows();
171                    else
172                        hideArrows();
173
174                    this->crossHairOverlay_->show();
175                    this->centerOverlay_->show();
176                }
177            }
178            else {
179                this->crossHairOverlay_->hide();
180                this->centerOverlay_->hide();
181
182                hideArrows();
183            }
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        COUT(0) << "dounfire" << endl;
259        this->firemode_ = -1;
260        hideArrows();
261    }
262
263    void NewHumanController::updateTarget()
264    {
265        Ogre::RaySceneQuery * rsq = HumanController::localController_s->getControllableEntity()->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
266
267        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);
268
269        rsq->setRay(mouseRay);
270        rsq->setSortByDistance(true);
271
272        /*
273        Distance of objects:
274        ignore everything under 200 maybe even take 1000 as min distance to shoot at
275
276        shots are regularly traced and are entities!!!!!!!!! this is the biggest problem
277        they vanish only after a distance of 10'000
278        */
279
280
281        Ogre::RaySceneQueryResult& result = rsq->execute();
282        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
283
284        Ogre::RaySceneQueryResult::iterator itr;
285        for (itr = result.begin(); itr != result.end(); ++itr)
286        {
287            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" && itr->distance > 500)
288            {
289                // Try to cast the user pointer
290                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(itr->movable->getUserObject());
291                if (wePtr)
292                {
293                    // go through all parents of object and look wheter they are Sightable or not
294                    bool isSightable = false;
295                    WorldEntity* parent = wePtr->getParent();
296                    while( parent )
297                    {
298                        if (this->targetMask_.isExcluded(parent->getIdentifier()))
299                        {
300                            parent = parent->getParent();
301                            continue;
302                        }
303                        else
304                        {
305                            isSightable = true;
306                            break;
307                        }
308                    }
309                    if ( !isSightable )
310                        continue;
311                }
312
313                if ( this->getControllableEntity() && this->getControllableEntity()->getTarget() != wePtr )
314                {
315                    this->getControllableEntity()->setTarget(wePtr);
316                }
317
318                if( pawn )
319                {
320                    pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance );
321                }
322
323                //itr->movable->getParentSceneNode()->showBoundingBox(true);
324                //std::cout << itr->movable->getParentSceneNode()->_getDerivedPosition() << endl;
325                //return mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance; //or itr->movable->getParentSceneNode()->_getDerivedPosition()
326                return;
327            }
328
329        }
330        if ( pawn )
331        {
332            pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * 1200 );
333        }
334
335        if( this->getControllableEntity() && this->getControllableEntity()->getTarget() != 0 )
336            this->getControllableEntity()->setTarget( 0 );
337   
338
339        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getWorldOrientation() * Vector3::NEGATIVE_UNIT_Z * 2000);
340        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getCamera()->getOgreCamera()->getOrientation() * Vector3::NEGATIVE_UNIT_Z);
341    }
342
343    void NewHumanController::frontback(const Vector2& value)
344    {
345        this->accelerating_ = true;
346
347        //if (this->acceleration_ == 0)
348            HumanController::frontback(value);
349    }
350
351    void NewHumanController::yaw(const Vector2& value)
352    {
353//         SUPER(NewHumanController, yaw, value);
354        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
355            HumanController::yaw(value);
356
357        this->currentYaw_ = value.x;
358    }
359
360    void NewHumanController::pitch(const Vector2& value)
361    {
362//         SUPER(NewHumanController, pitch, value);
363        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
364            HumanController::pitch(value);
365
366        this->currentPitch_ = value.x;
367    }
368
369    void NewHumanController::changeMode()
370    {
371        if (NewHumanController::localController_s && NewHumanController::localController_s->controlMode_ == 0)
372        {
373                NewHumanController::localController_s->controlMode_ = 1;
374                NewHumanController::localController_s->hideArrows();
375        }
376        else
377            NewHumanController::localController_s->controlMode_ = 0;
378    }
379
380    void NewHumanController::changedControllableEntity()
381    {
382        this->controlMode_ = 0;
383        this->currentYaw_ = 0;
384        this->currentPitch_ = 0;
385        if (this->getControllableEntity() && this->getControllableEntity()->getIdentifier()->getName() == "SpaceShip") {
386            this->doResumeControl();
387        }
388    }
389
390    void NewHumanController::accelerate()
391    {
392        if ( NewHumanController::localController_s )
393        {
394            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ + 0.2f, 0.00f, 1.0f);
395        }
396    }
397
398    void NewHumanController::decelerate()
399    {
400        if ( NewHumanController::localController_s )
401        {
402            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ - 0.1f, 0.0f, 1.0f);
403        }
404    }
405
406    void NewHumanController::doResumeControl() {
407        this->controlPaused_ = false;
408        this->crossHairOverlay_->show();
409        this->centerOverlay_->show();
410    }
411
412    void NewHumanController::doPauseControl() {
413        this->controlPaused_ = true;
414
415        this->crossHairOverlay_->hide();
416        this->centerOverlay_->hide();
417
418        hideArrows();
419    }
420
421    void NewHumanController::alignArrows() {
422        if (showArrows_) {
423            hideArrows();
424   
425            float distance = sqrt(pow(static_cast<float>(this->currentYaw_)/2*-1,2) + pow(static_cast<float>(this->currentPitch_)/2*-1,2));
426   
427            if ( distance > 0.04 && distance <= 0.59 * arrowsSize_ / 2.0 ) {
428                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));
429   
430                this->arrowsOverlay1_->show();
431            }
432            else if ( distance > 0.59 * arrowsSize_ / 2.0 && distance <= 0.77 * arrowsSize_ / 2.0 ) {
433                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));
434   
435                this->arrowsOverlay2_->show();
436            }
437            else if ( distance > 0.77 * arrowsSize_ / 2.0 && distance <= arrowsSize_ / 2.0 ) {
438                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));
439   
440                this->arrowsOverlay3_->show();
441            }
442            else if ( distance > arrowsSize_ / 2.0 ) {
443                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));
444   
445                this->arrowsOverlay4_->show();
446            }
447        }
448    }
449
450    void NewHumanController::hideArrows() {
451        if (showArrows_) {
452            this->arrowsOverlay1_->hide();
453            this->arrowsOverlay2_->hide();
454            this->arrowsOverlay3_->hide();
455            this->arrowsOverlay4_->hide();
456        }
457    }
458}
Note: See TracBrowser for help on using the repository browser.