Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6295 was 6295, checked in by wirthmi, 16 years ago

Changed a function call when hit from damage() to hit(). Pass through to controller

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