Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Merged turretFS14 branch

Location:
code/branches/presentationFS14
Files:
4 edited
6 copied

Legend:

Unmodified
Added
Removed
  • code/branches/presentationFS14

  • code/branches/presentationFS14/src/modules/objects/CMakeLists.txt

    r9526 r10072  
    1111ADD_SUBDIRECTORY(eventsystem)
    1212ADD_SUBDIRECTORY(triggers)
     13ADD_SUBDIRECTORY(controllers)
    1314
    1415ORXONOX_ADD_LIBRARY(objects
  • 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}
  • code/branches/presentationFS14/src/modules/objects/Turret.h

    r9667 r10072  
    2121 *
    2222 *   Author:
    23  *      Marian Runo
     23 *      Marian Runo, Martin Mueller
    2424 *   Co-authors:
    2525 *      ...
     
    2828
    2929/**
    30     @file Turret.h
    3130    @brief Definition of the Turret class.
    3231    @ingroup Objects
     
    3736
    3837#include "objects/ObjectsPrereqs.h"
    39 
    40 #include "worldentities/pawns/SpaceShip.h"
     38#include "worldentities/pawns/Pawn.h"
     39#include <OgreSceneQuery.h>
    4140
    4241namespace orxonox
    4342{
    44     class _ObjectsExport Turret : public SpaceShip
     43    /**
     44    @brief
     45        Creates a turret with limited rotation. The point of this class is to be able to attach
     46        a turret to a spaceship or a spacestation which is more or less completely autonomous in
     47        it's behaviour.
     48
     49        This class also contains a custom local coordinate system, which gets initially rotated through xml, and
     50        afterwards is updated with the parent's rotation (if there is one). This allows for almost trivialal calculation
     51        of pitch, yaw and roll through coordinate transformation. (TODO: Ogre should do something like this already, investigate...)
     52       
     53
     54    @note
     55        The rotation isn't limited "physically". You have to call isInRange to find out if the turret is allowed to shoot at a target.
     56    */
     57    class _ObjectsExport Turret : public Pawn
    4558    {
    4659        public:
     
    4861            virtual ~Turret();
    4962
    50             //virtual void tick(float dt);
    51 
    5263            virtual void rotatePitch(const Vector2& value);
    53 
    54             void setAlertnessRadius(float value);
    55             float getAlertnessRadius();
     64            virtual void rotateYaw(const Vector2& value);
     65            virtual void rotateRoll(const Vector2& value);
     66            virtual float isInRange(const WorldEntity* target);
     67            virtual void aimAtPosition(const Vector3 &position);
    5668
    5769            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
     70            virtual void tick(float dt);
    5871
     72            /** @brief Sets the maximum distance the turret is allowed to shoot. @param radius The distance*/
     73            inline void setMaxAttackRadius(float radius)
     74                { this->maxAttackRadius_ = radius; }
     75
     76            /** @brief Sets the minimum distance the turret is allowed to shoot. @param radius The distance*/
     77            inline void setMinAttackRadius(float radius)
     78                { this->minAttackRadius_ = radius; }
     79
     80            /** @brief Sets the maximum pitch the turret can have (in both directions). @param pitch The pitch (in one direction)*/
     81            inline void setMaxPitch(float pitch)
     82                { this->maxPitch_ = pitch; }
     83
     84            /** @brief Sets the maximum yaw the turret can have (in both directions). @param yaw The yaw (in one direction)*/
     85            inline void setMaxYaw(float yaw)
     86                { this->maxYaw_ = yaw; }
     87
     88            /** @brief Returns the maximum distance the turret is allowed to shoot. @return The distance */
     89            inline float getMaxAttackRadius() const
     90                { return this->maxAttackRadius_; }               
     91
     92            /** @brief Returns the minimum distance the turret is allowed to shoot. @return The distance */
     93            inline float getMinAttackRadius() const
     94                { return this->minAttackRadius_; }   
     95
     96            /** @brief Returns the maximum pitch the turret can have. @return The pitch */
     97            inline float getMaxPitch() const
     98                { return this->maxPitch_; }
     99
     100            /** @brief Returns the maximum yaw the turret can have. @return The yaw */
     101            inline float getMaxYaw() const
     102                { return this->maxYaw_; }
    59103
    60104        protected:
    61             WaypointPatrolController* controller_;
     105            Vector3 startDir_; //!< The initial facing direction, in local coordinates.
     106            Vector3 localZ_; //!< The local z-axis, includes for the parent's rotation and rotations done in xml.
     107            Vector3 localY_; //!< The local y-axis, includes for the parent's rotation and rotations done in xml.
     108            Vector3 localX_; //!< The local x-axis, includes for the parent's rotation and rotations done in xml.     
     109            Quaternion rotation_; //!< The rotation to be done by the turret.
     110
    62111        private:
     112            bool once_; //!< Flag for executing code in the tick function only once.
     113
     114            Vector3 localZStart_; //!< The local z-axis, without the parent's rotation.
     115            Vector3 localYStart_; //!< The local y-axis, without the parent's rotation.
     116            Vector3 localXStart_; //!< The local x-axis, without the parent's rotation.
     117            float maxAttackRadius_; //!< The maximum distance the turret is allowed to shoot.
     118            float minAttackRadius_; //!< The minimum distance the turret is allowed to shoot.
     119            Ogre::Real maxPitch_; //!< The maxmium pitch the turret can have (on one side).
     120            Ogre::Real maxYaw_; //!< The maxmium yaw the turret can have (on one side).
     121            float rotationThrust_;  //!< The velocity the turret rotates with.
     122            Ogre::RaySceneQuery* rayTest_; //!< Used to perform a raytest, currently unused @see isInRange
    63123
    64124    };
     
    66126
    67127#endif
    68 
Note: See TracChangeset for help on using the changeset viewer.