Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/campaignHS15/src/orxonox/controllers/FlyingController.cc @ 10882

Last change on this file since 10882 was 10882, checked in by gania, 8 years ago

fixed a bug in DivisionController, made action transitions smoother

File size: 7.5 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 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Dominik Solenicki
26 *
27 */
28#include "controllers/FlyingController.h"
29#include "core/XMLPort.h"
30#include "worldentities/pawns/SpaceShip.h"
31#include "util/Math.h"
32#include <OgreMatrix3.h>
33namespace orxonox
34{   
35    RegisterClass (FlyingController);
36   
37    FlyingController::FlyingController( Context* context ): CommonController( context )
38    {
39        this->rotationProgress_ = 0;
40        this->spread_ = 200;
41        this->tolerance_ = 60;
42        RegisterObject( FlyingController );
43    }
44    FlyingController::~FlyingController() 
45    {
46
47    }
48
49    void FlyingController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
50    {
51        XMLPortParam( FlyingController, "spread", setSpread, getSpread,  xmlelement, mode );
52        XMLPortParam( FlyingController, "formationMode", setFormationModeXML, getFormationModeXML,  xmlelement, mode );
53        SUPER( FlyingController, XMLPort, xmlelement, mode );
54    }
55   
56    void FlyingController::setFormationModeXML( std::string val )
57    {
58        const std::string valUpper = getUppercase( val );
59        FormationMode::Value value;
60       
61        if ( valUpper == "WALL" )
62            value = FormationMode::WALL;
63        else if ( valUpper == "FINGER4" )
64            value = FormationMode::FINGER4;
65        else if ( valUpper == "DIAMOND" )
66            value = FormationMode::DIAMOND;
67        else
68            ThrowException( ParseError, std::string( "Attempting to set an unknown FormationMode: '" )+ val + "'." );
69        this->setFormationMode( value );
70    }
71    std::string FlyingController::getFormationModeXML() 
72    {
73        switch ( this->formationMode_ )
74        {
75            case FormationMode::WALL:
76            { return "WALL"; break; }
77            case FormationMode::FINGER4:
78            { return "FINGER4"; break; }
79            case FormationMode::DIAMOND:
80            { return "DIAMOND"; break; }
81            default:
82                return "DIAMOND"; break;
83        }
84    }
85
86   
87
88    void FlyingController::stopMoving()
89    {
90        this->bHasTargetPosition_ = false;
91    }
92
93    void FlyingController::moveToPosition( const Vector3& target, float dt )
94    {
95        ControllableEntity* entity = this->getControllableEntity();
96
97        float distance = ( target - this->getControllableEntity() ->getPosition() ).length();
98
99
100        if ( distance >= this->tolerance_ )
101        {
102            Vector2 coord = get2DViewCoordinates
103                ( entity->getPosition() , 
104                entity->getOrientation()  * WorldEntity::FRONT, 
105                entity->getOrientation()  * WorldEntity::UP, 
106                target );
107            float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
108            float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
109            this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
110            this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
111
112         
113            if (distance > this->tolerance_*1.5f || (rotateX > -0.01 && rotateX < 0.01 && rotateY > -0.01 && rotateY < 0.01))
114                this->getControllableEntity() ->moveFrontBack( SPEED * dt );
115        }
116        else
117        {     
118            bHasTargetPosition_ = false;
119        }
120        copyTargetOrientation(dt);
121    }
122   
123    void FlyingController::moveToTargetPosition(float dt)
124    {
125        this->moveToPosition (this->targetPosition_, dt);
126    }
127    void FlyingController::copyOrientation( const Quaternion& orient, float dt )
128    {
129        //inspired by
130        //http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Quaternion+and+Rotation+Primer&structure=Tutorials#Q._How_can_I_make_my_objects_rotate_smoothly_You_mentioned_slerp_etc_
131        //how can I make my objects rotate smoothly?
132       
133        Quaternion myOrient = this->getControllableEntity()->getOrientation();
134        this->rotationProgress_ += dt;
135
136        if (this->rotationProgress_ > 1)
137        {
138            this->rotationProgress_ = 0;
139            this->bHasTargetOrientation_ = false;
140        }
141        else
142        {
143
144            Quaternion delta = Quaternion::Slerp(rotationProgress_, myOrient, orient, true);
145           
146            //rotate roll builds a Quaternion in roll method of WorldEntity, then it sets orientation.
147            //it is faster just to set orientation, plus that way there is no need in calculating the roll angle.
148            //On the downside, however, ship might also yaw and pitch, but this effect is neglectable, as we only call
149            //copyOrientation after we move our ship, thus it doesn't affect ships's flying direction too much.
150            //If you don't like the code style, you are welcomed to uncomment the code below
151            //and comment out setOrientation part, it will work just fine, but it will also be a tiny bit slower.
152            //P.S. apperantly it did affect ship's direction and did so way too much.
153            Matrix3 orientMatrix, myMatrix;
154
155            delta.ToRotationMatrix(orientMatrix);
156            myOrient.ToRotationMatrix (myMatrix);
157
158            Radian yRad, pRad, rRad, yMy, pMy, rMy;
159            orientMatrix.ToEulerAnglesYXZ(yRad, pRad, rRad);
160            myMatrix.ToEulerAnglesYXZ (yMy, pMy, rMy);
161
162            this->getControllableEntity()->rotateRoll ((rRad.valueRadians() - rMy.valueRadians())*ROTATEFACTOR*dt);
163            // this->getControllableEntity()->setOrientation(delta);
164        }
165       
166       
167    }
168    //change log: increased precision, increased rotation speed
169    void FlyingController::copyTargetOrientation( float dt )
170    {
171        if ( bHasTargetOrientation_ )
172        {   
173            copyOrientation( targetOrientation_, dt );
174        }
175    }
176   
177    void FlyingController::setTargetPosition( const Vector3& target )
178    {
179        this->targetPosition_ = target;
180        this->bHasTargetPosition_ = true;
181    }
182
183    void FlyingController::setTargetOrientation( const Quaternion& orient )
184    {
185        this->targetOrientation_=orient;
186        this->bHasTargetOrientation_=true;
187    }
188
189    void FlyingController::setTargetOrientation( ControllableEntity* target )
190    {
191        if ( target )
192            setTargetOrientation( target->getOrientation() );
193    }
194    void FlyingController::boostControl()
195    {
196        SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity());
197        if(ship == NULL) return;
198        if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower() ) //upper limit ->boost
199        {
200
201            this->getControllableEntity()->boost(true);
202        }
203        else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost
204        {
205           this->getControllableEntity()->boost(false);
206        }
207    }
208   
209}
Note: See TracBrowser for help on using the repository browser.