Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10935 was 10923, checked in by gania, 9 years ago

check in

File size: 8.0 KB
RevLine 
[10871]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:
[10885]23 *      Gani Aliguzhinov
24
[10871]25 *   Co-authors:
[10923]26 *   ...
[10871]27 *
28 */
29#include "controllers/FlyingController.h"
30#include "core/XMLPort.h"
31#include "worldentities/pawns/SpaceShip.h"
[10875]32#include "util/Math.h"
[10879]33#include <OgreMatrix3.h>
[10885]34
[10871]35namespace orxonox
36{   
37    RegisterClass (FlyingController);
38   
[10885]39    FlyingController::FlyingController(Context* context): CommonController(context)
[10871]40    {
[10885]41        RegisterObject(FlyingController);       
[10879]42        this->rotationProgress_ = 0;
[10871]43        this->spread_ = 200;
[10888]44        this->tolerance_ = 80;
[10871]45    }
46    FlyingController::~FlyingController() 
47    {
48    }
[10877]49
[10885]50    void FlyingController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
[10871]51    {
[10885]52        XMLPortParam(FlyingController, "spread", setSpread, getSpread,  xmlelement, mode);
53        XMLPortParam(FlyingController, "formationMode", setFormationModeXML, getFormationModeXML,  xmlelement, mode);
54        SUPER(FlyingController, XMLPort, xmlelement, mode);
[10871]55    }
56   
[10885]57    void FlyingController::setFormationModeXML(std::string val)
[10871]58    {
[10885]59        const std::string valUpper = getUppercase(val);
[10871]60        FormationMode::Value value;
61       
62        if ( valUpper == "WALL" )
63            value = FormationMode::WALL;
64        else if ( valUpper == "FINGER4" )
65            value = FormationMode::FINGER4;
66        else if ( valUpper == "DIAMOND" )
67            value = FormationMode::DIAMOND;
68        else
[10885]69            ThrowException(ParseError, std::string( "Attempting to set an unknown FormationMode: '" )+ val + "'.");
70        this->setFormationMode(value);
[10871]71    }
[10885]72    std::string FlyingController::getFormationModeXML() const
[10871]73    {
74        switch ( this->formationMode_ )
75        {
76            case FormationMode::WALL:
[10923]77            { return "WALL"; }
[10871]78            case FormationMode::FINGER4:
[10923]79            { return "FINGER4"; }
[10871]80            case FormationMode::DIAMOND:
[10923]81            { return "DIAMOND"; }
[10871]82            default:
[10923]83                return "DIAMOND";
[10871]84        }
85    }
86    void FlyingController::stopMoving()
87    {
88        this->bHasTargetPosition_ = false;
89    }
[10923]90    void FlyingController::moveToPosition(const Vector3& targetPosition, float dt)
[10871]91    {
[10923]92        if (!this->getControllableEntity())
93            return;
[10871]94        ControllableEntity* entity = this->getControllableEntity();
95
[10923]96        float distance = ( targetPosition - entity->getPosition() ).length();
[10871]97
[10881]98        if ( distance >= this->tolerance_ )
[10871]99        {
[10880]100            Vector2 coord = get2DViewCoordinates
101                ( entity->getPosition() , 
102                entity->getOrientation()  * WorldEntity::FRONT, 
103                entity->getOrientation()  * WorldEntity::UP, 
[10923]104                targetPosition );
[10880]105            float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
106            float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
[10885]107            entity->rotateYaw( ROTATEFACTOR * rotateX * dt );
108            entity->rotatePitch( ROTATEFACTOR * rotateY * dt );
[10879]109         
[10923]110            if (distance > this->tolerance_*1.5f || (rotateX > -0.03 && rotateX < 0.03 && rotateY > -0.03 && rotateY < 0.03))
[10885]111                entity->moveFrontBack( SPEED * dt );
112                copyTargetOrientation(dt);
[10871]113        }
114        else
115        {     
116            bHasTargetPosition_ = false;
117        }
118    }
[10880]119   
[10871]120    void FlyingController::moveToTargetPosition(float dt)
121    {
122        this->moveToPosition (this->targetPosition_, dt);
123    }
[10885]124    void FlyingController::copyOrientation(const Quaternion& orient, float dt)
[10871]125    {
[10923]126        //copied from
[10879]127        //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_
128        //how can I make my objects rotate smoothly?
[10923]129        if (!this->getControllableEntity())
130            return;
[10879]131        Quaternion myOrient = this->getControllableEntity()->getOrientation();
[10881]132        this->rotationProgress_ += dt;
[10875]133
[10879]134        if (this->rotationProgress_ > 1)
135        {
136            this->rotationProgress_ = 0;
[10881]137            this->bHasTargetOrientation_ = false;
[10879]138        }
139        else
140        {
[10923]141            Quaternion deltaOrientation = Quaternion::Slerp(rotationProgress_, myOrient, orient, true);
[10881]142           
[10923]143            Matrix3 deltaMatrix, myMatrix;
[10881]144
[10923]145            deltaOrientation.ToRotationMatrix(deltaMatrix);
[10879]146            myOrient.ToRotationMatrix (myMatrix);
[10875]147
[10923]148            Radian yawDelta, pitchDelta, rollDelta, yawMy, pitchMy, rollMy;
149            deltaMatrix.ToEulerAnglesYXZ(yawDelta, pitchDelta, rollDelta);
150            myMatrix.ToEulerAnglesYXZ (yawMy, pitchMy, rollMy);
[10881]151
[10923]152            if (!this->getControllableEntity())
153                return;
154            this->getControllableEntity()->rotateRoll ((rollDelta.valueRadians() - rollMy.valueRadians())*ROTATEFACTOR*dt);
[10879]155        }
[10871]156    }
[10923]157
[10885]158    void FlyingController::copyTargetOrientation(float dt)
[10871]159    {
[10885]160        if (bHasTargetOrientation_)
[10871]161        {   
[10923]162            this->copyOrientation(targetOrientation_, dt);
[10871]163        }
164    }
165   
[10885]166    void FlyingController::setTargetPosition(const Vector3& target)
[10871]167    {
168        this->targetPosition_ = target;
169        this->bHasTargetPosition_ = true;
170    }
171
[10885]172    void FlyingController::setTargetOrientation(const Quaternion& orient)
[10871]173    {
174        this->targetOrientation_=orient;
175        this->bHasTargetOrientation_=true;
176    }
177
[10885]178    void FlyingController::setTargetOrientation(ControllableEntity* target)
[10871]179    {
[10885]180        if (target)
[10923]181            this->setTargetOrientation(target->getOrientation());
[10871]182    }
183    void FlyingController::boostControl()
184    {
[10923]185        if (!this->getControllableEntity())
186            return;
[10871]187        SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity());
188        if(ship == NULL) return;
189        if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower() ) //upper limit ->boost
190        {
191            this->getControllableEntity()->boost(true);
192        }
193        else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost
194        {
195           this->getControllableEntity()->boost(false);
196        }
197    }
[10886]198    void FlyingController::keepFormation(const ControllableEntity* leaderEntity, Vector3& targetRelativePosition)
199    {
200        ControllableEntity* myEntity = this->getControllableEntity();
201        Vector3 myPosition = myEntity->getWorldPosition();
202
203        if (!leaderEntity)
204        {
205            return;
206        }
207        Quaternion orient = leaderEntity->getWorldOrientation();
208        Vector3 leaderPosition = leaderEntity->getWorldPosition();
209
210        if (!leaderEntity)
211        {
212            return;
213        }
214        Vector3 targetAbsolutePosition = 
215            (leaderPosition + (orient*WorldEntity::FRONT) * (leaderEntity->getVelocity().length()/5)
216             + (orient* (targetRelativePosition)));
217        //let ship finish rotating. also don't call copyOrientation to often as it is a slow function.
[10923]218        if (static_cast<int>(rnd(1.0f) * 100) % 3 == 0)
[10886]219            this->setTargetOrientation (orient);
220        this->setTargetPosition (targetAbsolutePosition);
221        if ((targetAbsolutePosition - myPosition).length() > this->tolerance_ * 1.5f)
222        {
223            this->boostControl();
224        }
225        else
226        {
227           this->getControllableEntity()->boost(false);
228        }
229    }
[10871]230}
Note: See TracBrowser for help on using the repository browser.