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, 14 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
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#include "tools/BulletConversions.h"
47#include "bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
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/DirectionArrows1");
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/DirectionArrows2");
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/DirectionArrows3");
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/DirectionArrows4");
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
169                if ( !controlPaused_ ) {
170                    if (this->getControllableEntity() && this->getControllableEntity()->getIdentifier()->getName() == "SpaceShip")
171                        this->showOverlays();
172
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));
174
175                    if ( this->controlMode_ == 0 || ( this->controlMode_ == 1 && this->firemode_ == 1 ) )
176                    {
177                        if ( this->showOverlays_ && this->showArrows_)
178                            alignArrows();
179                    }
180                    else
181                        hideArrows();
182                }
183            }
184            else
185                this->hideOverlays();
186
187            if ( this->acceleration_ > 0 )
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            }
201        }
202
203        HumanController::tick(dt);
204    }
205
206    /*void NewHumanController::tick(float dt)
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        }
220    }*/
221   
222    void NewHumanController::doFire(unsigned int firemode)
223    {
224        //if (HumanController::localController_s && HumanController::localController_s->controllableEntity_) {
225
226/*
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        }
237*/
238
239        this->firemode_ = firemode;
240
241        if (firemode == 1 && this->controlMode_ == 1)
242        {
243            //unlocked steering, steer on right mouse click
244            HumanController::yaw(Vector2(this->currentYaw_, 0));
245            HumanController::pitch(Vector2(this->currentPitch_, 0));
246        }
247        else
248            HumanController::localController_s->getControllableEntity()->fire(firemode);
249
250    }
251
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
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
275    void NewHumanController::updateTarget()
276    {
277        Ogre::RaySceneQuery * rsq = HumanController::localController_s->getControllableEntity()->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
278
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);
280
281        rsq->setRay(mouseRay);
282        rsq->setSortByDistance(true);
283
284        /*
285        Distance of objects:
286        ignore everything under 200 maybe even take 1000 as min distance to shoot at
287
288        shots are regularly traced and are entities!!!!!!!!! this is the biggest problem
289        they vanish only after a distance of 10'000
290        */
291
292
293        Ogre::RaySceneQueryResult& result = rsq->execute();
294        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
295
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)
300            {
301                // Try to cast the user pointer
302                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(itr->movable->getUserObject());
303                if (wePtr)
304                {
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 )
322                        continue;
323                }
324
325                if ( this->getControllableEntity() && this->getControllableEntity()->getTarget() != wePtr )
326                {
327                    this->getControllableEntity()->setTarget(wePtr);
328                }
329
330                if( pawn )
331                {
332                    pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance );
333                }
334
335                //itr->movable->getParentSceneNode()->showBoundingBox(true);
336                //std::cout << itr->movable->getParentSceneNode()->_getDerivedPosition() << endl;
337                //return mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance; //or itr->movable->getParentSceneNode()->_getDerivedPosition()
338                return;
339            }
340
341        }
342        if ( pawn )
343        {
344            pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * 1200 );
345        }
346
347        if( this->getControllableEntity() && this->getControllableEntity()->getTarget() != 0 )
348            this->getControllableEntity()->setTarget( 0 );
349   
350
351        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getWorldOrientation() * Vector3::NEGATIVE_UNIT_Z * 2000);
352        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getCamera()->getOgreCamera()->getOrientation() * Vector3::NEGATIVE_UNIT_Z);
353    }
354
355    void NewHumanController::frontback(const Vector2& value)
356    {
357        this->accelerating_ = true;
358
359        //if (this->acceleration_ == 0)
360            HumanController::frontback(value);
361    }
362
363    void NewHumanController::yaw(const Vector2& value)
364    {
365//         SUPER(NewHumanController, yaw, value);
366        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
367            HumanController::yaw(value);
368
369        this->currentYaw_ = value.x;
370    }
371
372    void NewHumanController::pitch(const Vector2& value)
373    {
374//         SUPER(NewHumanController, pitch, value);
375        if (this->controlMode_ == 0 || ( this->controllableEntity_ && this->controllableEntity_->isInMouseLook() ) )
376            HumanController::pitch(value);
377
378        this->currentPitch_ = value.x;
379    }
380
381    void NewHumanController::changeMode()
382    {
383        if (NewHumanController::localController_s && NewHumanController::localController_s->controlMode_ == 0)
384        {
385                NewHumanController::localController_s->controlMode_ = 1;
386                NewHumanController::localController_s->hideArrows();
387        }
388        else
389            NewHumanController::localController_s->controlMode_ = 0;
390    }
391
392    void NewHumanController::changedControllableEntity()
393    {
394        this->controlMode_ = 0;
395        this->currentYaw_ = 0;
396        this->currentPitch_ = 0;
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        }
411    }
412
413    void NewHumanController::accelerate()
414    {
415        if ( NewHumanController::localController_s )
416        {
417            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ + 0.2f, 0.00f, 1.0f);
418        }
419    }
420
421    void NewHumanController::decelerate()
422    {
423        if ( NewHumanController::localController_s )
424        {
425            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ - 0.1f, 0.0f, 1.0f);
426        }
427    }
428
429    void NewHumanController::doResumeControl() {
430        this->controlPaused_ = false;
431        if( this->showOverlays_ ) {
432            this->showOverlays();
433        }
434    }
435
436    void NewHumanController::doPauseControl() {
437        this->controlPaused_ = true;
438
439        this->hideOverlays();
440    }
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
471    void NewHumanController::showOverlays() {
472        this->crossHairOverlay_->show();
473        this->centerOverlay_->show();
474
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();
486
487        this->hideArrows();
488    }
489
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    }
498}
Note: See TracBrowser for help on using the repository browser.