Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 22, 2014, 2:35:02 PM (10 years ago)
Author:
smerkli
Message:

Merged turretFS14 branch

Location:
code/branches/presentationFS14
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentationFS14

  • code/branches/presentationFS14/src/modules/objects/Turret.cc

    r9945 r10072  
    2121 *
    2222 *   Author:
    23  *      Marian Runo
     23 *      Marian Runo, Martin Mueller
    2424 *   Co-authors:
    2525 *      ...
     
    2929#include "Turret.h"
    3030#include "core/CoreIncludes.h"
    31 #include "OgreQuaternion.h"
    3231#include "core/XMLPort.h"
    33 #include "controllers/WaypointPatrolController.h"
     32#include "Scene.h"
     33#include <OgreSceneManager.h>
     34
    3435
    3536namespace orxonox
     
    3738    RegisterClass(Turret);
    3839
    39     /**
    40      * @brief Constructor
     40
     41
     42    /**
     43        @brief
     44        Sets default values for all variables. Also hides the turret from the radar.
     45
     46        @param context
     47        The context
    4148     */
    42     Turret::Turret(Context* context) : SpaceShip(context)
     49    Turret::Turret(Context* context) : Pawn(context)
    4350    {
    4451        RegisterObject(Turret);
    45         this->controller_ = new WaypointPatrolController(this->getContext());
    46     }
    47 
    48     /**
    49      * @brief Destructor
     52        this->rotationThrust_ = 50;
     53        this->startDir_ = Vector3::ZERO;
     54        this->localZ_ = Vector3::UNIT_Z;
     55        this->localY_ = Vector3::UNIT_Y;
     56        this->localX_ = Vector3::UNIT_X;
     57        this->maxAttackRadius_ = 200;
     58        this->minAttackRadius_ = 0;
     59        this->maxPitch_ = 90;
     60        this->maxYaw_ = 90;
     61        this->once_ = false;
     62        this->rotation_ = Quaternion::IDENTITY;
     63
     64        this->setRadarVisibility(false);
     65
     66        //this->rayTest_ = this->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
     67    }
     68
     69    /**
     70        @brief
     71        Destructor. Destroys the rayTest_ element (if it was used)  .
    5072     */
    5173    Turret::~Turret()
    5274    {
    53 
    54     }
    55 
    56 
     75        //this->getScene()->getSceneManager()->destroyQuery(this->rayTest_);
     76    }
     77
     78    /**
     79        @brief
     80        Checks, if a WorldEntity is inside the turret's range.
     81
     82        This function is safe to use on turrets that are attached, rotated, etc.
     83        The turret's range is determined with the maxPitch, maxYaw, and the two attackRadius.
     84
     85        @param target
     86        The WorldEntity to check
     87
     88        @return
     89        The squared distance to the position. -1, if it's ouside of range
     90    */
     91    float Turret::isInRange(const WorldEntity* target )
     92    {
     93        //Check distance
     94        Vector3 distance = target->getWorldPosition() - this->getWorldPosition();
     95        float distanceVal = distance.squaredLength();
     96        if(distanceVal > (this->maxAttackRadius_ * this->maxAttackRadius_) || distanceVal < (this->minAttackRadius_ * this->minAttackRadius_))
     97        {
     98            return -1.f;
     99        }
     100
     101        //Check pitch
     102        Vector3 dir = getTransformedVector(distance, this->localX_, this->localY_, this->localZ_);
     103        Vector3 dirProjected = dir;
     104        dirProjected.x = 0;
     105        Vector3 startDirProjected = this->startDir_;
     106        startDirProjected.x = 0;
     107        Ogre::Real angle = startDirProjected.angleBetween(dirProjected).valueDegrees();
     108        if(angle > this->maxPitch_)
     109        {
     110            return -1.f;
     111        }
     112
     113        //Check yaw
     114        dirProjected = dir;
     115        dirProjected.y = 0;
     116        startDirProjected = this->startDir_;
     117        startDirProjected.y = 0;
     118        angle = startDirProjected.angleBetween(dirProjected).valueDegrees();
     119        if(angle > this->maxYaw_)
     120        {
     121            return -1.f;
     122        }
     123
     124        //TODO: Finish this. Find a way to convert objects from Ogre to Orxonox
     125        /*Ogre::Ray ray = Ogre::Ray(this->getWorldPosition(), distance);
     126        this->rayTest_->setRay(ray);
     127        Ogre::RaySceneQueryResult result = this->rayTest_->execute();*/
     128
     129
     130        return distanceVal;
     131    }
     132
     133    /**
     134        @brief
     135        Rotates the turret to make it aim at a certain position.
     136
     137        @note
     138        There are no checks, if the position is valid (i.e. if the turret is allowed to aim there).
     139        This function must be called again for every tick, or the turret will stop rotating.
     140
     141        @param position
     142        The position to aim at
     143    */
     144    void Turret::aimAtPosition(const Vector3& position)
     145    {
     146        Vector3 currDir = this->getWorldOrientation() * WorldEntity::FRONT;
     147        Vector3 targetDir = position - this->getWorldPosition();
     148
     149        this->rotation_ = currDir.getRotationTo(targetDir);
     150    }
     151
     152    /**
     153        @brief
     154        Does currently nothing.
     155
     156        Should rotate the turret with the specified pitch. Contains a failed attempt at limiting said rotation.
     157    */
    57158    void Turret::rotatePitch(const Vector2& value)
    58     {
    59         orxout()<< "Turret rotate Pitch"<< endl;
    60 
    61         const Quaternion& orient = this->getOrientation();
    62         Radian pitch = orient.getPitch();
    63 
    64         if((value.x > 0 && pitch < Radian(180)) || (value.x < 0 && pitch > Radian(0)))
    65             SpaceShip::rotatePitch(value);
    66     }
    67 
    68 
    69     void Turret::setAlertnessRadius(float value)
    70     {
    71         this->controller_->setAlertnessRadius(value);
    72     }
    73     float Turret::getAlertnessRadius()
    74     {
    75         return this->controller_->getAlertnessRadius();
    76     }
    77 
     159    {   
     160        //This is a failed attempt at limiting the turret's rotation. It's handled in the controller (for now?)
     161        /*
     162        Vector3 currentDir = getTransformedVector(this->getOrientation() * WorldEntity::FRONT, this->localX_, this->localY_, this->localZ_);
     163        Vector3 currentDirProjected = currentDir;
     164        currentDirProjected.x = 0;
     165        Vector3 startDirProjected = this->startDir_;
     166        startDirProjected.x = 0;     
     167        Ogre::Real angle = startDirProjected.angleBetween(currentDirProjected).valueDegrees();
     168        //orxout() << "Pitch: " << angle << endl;   
     169        //if(angle < this->maxPitch_ || (currentDirProjected.y <= 0 && value.x > 0) || (currentDirProjected.y > 0 && value.x < 0) )
     170        {
     171            this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x*0.8f);
     172        }
     173        */
     174    }
     175
     176    /**
     177        @brief
     178        Does currently nothing.
     179
     180        Should rotate the turret with the specified yaw. Contains a failed attempt at limiting said rotation.
     181    */
     182    void Turret::rotateYaw(const Vector2& value)
     183    {
     184        //This is a failed attempt at limiting the turret's rotation. It's handled in the controller (for now?)
     185        /*
     186        Vector3 currentDir = getTransformedVector(this->getOrientation() * WorldEntity::FRONT, this->localX_, this->localY_, this->localZ_);
     187        Vector3 currentDirProjected = currentDir;
     188        currentDirProjected.y = 0;
     189        Vector3 startDirProjected = this->startDir_;
     190        startDirProjected.y = 0;
     191        Ogre::Real angle = startDirProjected.angleBetween(currentDirProjected).valueDegrees();
     192        orxout() << "Yaw: " << angle << endl;
     193        if(angle < this->maxYaw_ || (currentDirProjected.x <= 0 && value.x < 0) || (currentDirProjected.x > 0 && value.x > 0))
     194        {
     195            this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() + value.x*0.8f);
     196        }
     197        */
     198    }
     199
     200    /**
     201        @brief
     202        Does currently nothing.
     203
     204        May be used to limit turret's rotation in the future.
     205    */
     206    void Turret::rotateRoll(const Vector2& value)
     207    {
     208    }
     209
     210    /**
     211        @brief
     212        Loads parameters from xml
     213
     214        Parameters loaded are: rotationThrust, maxAttackRadius, minAttackRadius, maxYaw, maxPitch
     215    */
    78216    void Turret::XMLPort(Element& xmlelement, XMLPort::Mode mode)
    79217    {
    80218        SUPER(Turret, XMLPort, xmlelement, mode);
    81         XMLPortParam(Turret, "alertnessRadius", setAlertnessRadius, getAlertnessRadius, xmlelement, mode).defaultValues("400");
    82     }
    83 
    84 
     219       
     220        XMLPortParamVariable(Turret, "rotationThrust", rotationThrust_, xmlelement, mode);
     221        XMLPortParam(Turret, "maxAttackRadius", setMaxAttackRadius, getMaxAttackRadius, xmlelement, mode);
     222        XMLPortParam(Turret, "minAttackRadius", setMinAttackRadius, getMinAttackRadius, xmlelement, mode);
     223        XMLPortParam(Turret, "maxYaw", setMaxYaw, getMaxYaw, xmlelement, mode);
     224        XMLPortParam(Turret, "maxPitch", setMaxPitch, getMaxPitch, xmlelement, mode);
     225    }
     226
     227    /**
     228        @brief
     229        The turret's actions are done here.
     230
     231        Every tick, the turret gets rotated if it should, and the local axes get updated with the parent's rotation.
     232   
     233        @param dt
     234        Duration of the tick
     235    */
     236    void Turret::tick(float dt)
     237    {
     238        SUPER(Turret, tick, dt);
     239
     240        //Stuff isn't properly initialized in the c'tor, so we have to do it like this
     241        if(!this->once_)
     242        {
     243            //Account for rotations done in xml
     244            Quaternion startOrient = this->getOrientation();
     245            this->localXStart_ = startOrient * this->localX_;
     246            this->localXStart_.normalise();
     247            this->localX_ = this->localXStart_;
     248            this->localYStart_ = startOrient * this->localY_;
     249            this->localYStart_.normalise();
     250            this->localY_ = this->localYStart_;
     251            this->localZStart_ = startOrient * this->localZ_;
     252            this->localZStart_.normalise();
     253            this->localZ_ = this->localZStart_;
     254
     255            //startDir should always be (0,0,-1)
     256            this->startDir_ = getTransformedVector(startOrient * WorldEntity::FRONT, this->localX_, this->localY_, this->localZ_);
     257
     258            this->once_ = true;
     259
     260        }
     261
     262        //Adjust local axes to parent's rotation
     263        WorldEntity* parent = this->getParent();
     264        if(parent)
     265        {
     266            Quaternion parentrot = parent->getWorldOrientation();
     267            this->localX_ = parentrot * this->localXStart_;
     268            this->localY_ = parentrot * this->localYStart_;
     269            this->localZ_ = parentrot * this->localZStart_;
     270        }
     271
     272        //rotate
     273        if(this->rotation_ != Quaternion::IDENTITY)
     274        {
     275            //Don't make the rotation instantaneous. Use an arbitrary interpolation, not that great...
     276            //TODO: make the rotation better (constant velocity etc.). At the moment, the turret rotates
     277            //slower the closer it is to the destination
     278            Quaternion drot = Quaternion::nlerp(dt*this->rotationThrust_/20.f, Quaternion::IDENTITY, this->rotation_);
     279            this->rotate(drot, WorldEntity::World);
     280            this->rotation_ = Quaternion::IDENTITY;
     281        }
     282
     283    }
    85284}
Note: See TracChangeset for help on using the changeset viewer.