Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 15, 2014, 5:10:55 PM (11 years ago)
Author:
muemart
Message:

Fix team acquisition, edit test level and start to try to make a raytest

Location:
code/branches/turretFS14/src/modules/objects
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • code/branches/turretFS14/src/modules/objects/Turret.cc

    r10049 r10060  
    3030#include "core/CoreIncludes.h"
    3131#include "core/XMLPort.h"
     32#include "Scene.h"
     33#include <OgreSceneQuery.h>
     34
    3235
    3336namespace orxonox
     
    7376    /**
    7477        @brief
    75         Checks, if a (world)position is inside the turret's range.
     78        Checks, if a WorldEntity is inside the turret's range.
    7679
    7780        This function is safe to use on turrets that are attached, rotated, etc.
    78         The turret's range is determined with the maxPitch, maxYaw, and the two attackRadius'.
    79 
    80         @param position
    81         The position to check
    82     */
    83     bool Turret::isInRange(const Vector3 &position)
     81        The turret's range is determined with the maxPitch, maxYaw, and the two attackRadius.
     82
     83        @param target
     84        The WorldEntity to check
     85
     86        @return
     87        The squared distance to the position. -1, if it's ouside of range
     88    */
     89    float Turret::isInRange(const WorldEntity* target ) const
    8490    {
    8591        //Check distance
    86         Vector3 distance = position - this->getWorldPosition();
     92        Vector3 distance = target->getWorldPosition() - this->getWorldPosition();
    8793        float distanceVal = distance.squaredLength();
    8894        if(distanceVal > (this->maxAttackRadius_ * this->maxAttackRadius_) || distanceVal < (this->minAttackRadius_ * this->minAttackRadius_))
    8995        {
    90             return false;
     96            return -1.f;
    9197        }
    9298
     
    100106        if(angle > this->maxPitch_)
    101107        {
    102             return false;
     108            return -1.f;
    103109        }
    104110
     
    111117        if(angle > this->maxYaw_)
    112118        {
    113             return false;
    114         }
    115         return true;
     119            return -1.f;
     120        }
     121
     122        Ogre::SceneManager* scenemanager = this->getScene()->getSceneManager();
     123        Ogre::Ray ray = Ogre::Ray(this->getWorldPosition(), distance);
     124        Ogre::DefaultRaySceneQuery rayscenequery = Ogre::DefaultRaySceneQuery(scenemanager);
     125        rayscenequery.setRay(ray);
     126
     127        return distanceVal;
    116128    }
    117129
     
    215227
    216228        Every tick, the turret gets rotated if it should, and the local axes get updated with the parent's rotation.
     229   
     230        @param dt
     231        Duration of the tick
    217232    */
    218233    void Turret::tick(float dt)
     
    220235        SUPER(Turret, tick, dt);
    221236
    222 
     237        //Stuff isn't properly initialized in the c'tor, so we have to do it like this
    223238        if(!this->once_)
    224239        {
     
    256271        {
    257272            //Don't make the rotation instantaneous. Use an arbitrary interpolation, not that great...
     273            //TODO: make the rotation better (constant velocity etc.). At the moment, the turret rotates
     274            //      slower the closer it is to the destination
    258275            Quaternion drot = Quaternion::nlerp(dt*this->rotationThrust_/20.f, Quaternion::IDENTITY, this->rotation_);
    259276            this->rotate(drot, WorldEntity::World);
  • code/branches/turretFS14/src/modules/objects/Turret.h

    r10049 r10060  
    4646        it's behaviour.
    4747
     48        This class also contains a custom local coordinate system, which gets initially rotated through xml, and
     49        afterwards is updated with the parent's rotation (if there is one). This allows for almost trivialal calculation
     50        of pitch, yaw and roll through coordinate transformation. (TODO: Ogre should do something like this already, investigate...)
     51       
     52
    4853    @note
    4954        The rotation isn't limited "physically". You have to call isInRange to find out if the turret is allowed to shoot at a target.
     
    5863            virtual void rotateYaw(const Vector2& value);
    5964            virtual void rotateRoll(const Vector2& value);
    60             virtual bool isInRange(const Vector3 &position);
     65            virtual float isInRange(const WorldEntity* target) const;
    6166            virtual void aimAtPosition(const Vector3 &position);
    6267
  • code/branches/turretFS14/src/modules/objects/controllers/TeamTargetProxy.cc

    r10049 r10060  
    2828
    2929#include "TeamTargetProxy.h"
     30#include "worldentities/ControllableEntity.h"
    3031#include "worldentities/pawns/Pawn.h"
    3132
    32  namespace orxonox
    33  {
    34         RegisterClass(TeamTargetProxy);
     33namespace orxonox
     34{
     35        RegisterClass(TeamTargetProxy);
    3536
    36         TeamTargetProxy::TeamTargetProxy(Context* context) : FormationController(context)
     37   /**
     38       @brief
     39       Sets default values for all variables.
     40
     41       @param context
     42       The context
     43    */
     44        TeamTargetProxy::TeamTargetProxy(Context* context) : FormationController(context)
    3745        {
    3846                RegisterObject(TeamTargetProxy);
     
    4149        }
    4250
     51    /**
     52        @brief
     53        Destructor. Nothing to see here.
     54     */
    4355        TeamTargetProxy::~TeamTargetProxy()
    4456        {
    4557        }
    4658
     59    /**
     60        @brief
     61        Copies the team and the target from the parent.
     62
     63        That's all there is.
     64    */
    4765        void TeamTargetProxy::tick(float dt)
    4866        {
     
    5169
    5270        ControllableEntity* parent = orxonox_cast<ControllableEntity*> (this->getControllableEntity()->getParent());
    53                
    5471
     72        if(this->getTeam() != -1 && !this->once_ && parent)
     73        {
     74            orxout(internal_warning) << "TeamTargetProxy: Team already set, may result in undesired behaviour. Will get overridden by the parent's team." << endl;
     75        }
     76
     77        if(!this->once_)
     78            this->once_ = true;
     79
     80        //Teams aren't set immediately, after creation, so we have to check every tick...
     81        if(parent)
     82        {
     83            Controller* parentcontroller = parent->getController();
     84            if(parentcontroller)
     85            {
     86                this->setTeam(parentcontroller->getTeam());
     87            }
     88            else
     89            {
     90                this->setTeam(parent->getTeam());
     91            }
     92            this->getControllableEntity()->setTeam(parent->getTeam());
     93        }
    5594
    5695        if(parent)
    5796        {
    58 
    59             if(!this->once_)
    60             {
    61                 //Set the same team
    62                 if(parent)
    63                 {
    64                     Controller* parentcontroller = parent->getController();
    65                     if(parentcontroller)
    66                     {
    67                         this->setTeam(parentcontroller->getTeam());
    68                     }
    69                     else
    70                     {
    71                         this->setTeam(parent->getTeam());
    72                     }
    73                     this->getControllableEntity()->setTeam(parent->getTeam());
    74                 }
    75                 this->once_ = true;
    76             }
    77 
    7897            Pawn* parenttarget = orxonox_cast<Pawn*>(parent->getTarget());
    7998            if(parenttarget)
     
    83102            }
    84103        }
    85 
    86104        }
    87  }
     105}
  • code/branches/turretFS14/src/modules/objects/controllers/TeamTargetProxy.h

    r10049 r10060  
    3535 namespace orxonox
    3636 {
     37        /**
     38                @brief
     39                A controller, that just copies the team and the target of a parent for itself and it's controllable entity.
     40
     41                Useful for following (and similar) situations: (-> means attached to)
     42                        turret (rotates) -> some kind of turret base (looks nice) -> spaceship (flies around)
     43                        The turret has a controller that wants to copy the spaceship's target and team. In this case it doesn't work though,
     44                        because the turret isn't directly attached to the spaceship. Here's where this controller comes in. Drawback: the base
     45                        has to be controllable and ticks every second (performance?)
     46        */
    3747        class _OrxonoxExport TeamTargetProxy : public FormationController, public Tickable
    3848        {
     
    4454
    4555                private:
    46                         bool once_;
     56                        bool once_; //!< Flag for executing code in the tick function only once.
    4757        };
    4858 }
  • code/branches/turretFS14/src/modules/objects/controllers/TurretController.cc

    r10049 r10060  
    3535        RegisterClass(TurretController);
    3636
     37    /**
     38        @brief
     39        Sets default values for all variables.
     40
     41        @param context
     42        The context
     43    */
    3744        TurretController::TurretController(Context* context) : ArtificialController(context)
    3845        {
     
    4350        }
    4451
     52    /**
     53        @brief
     54        Destructor. Nothing to see here.
     55    */
    4556        TurretController::~TurretController()
    4657        {
     
    4859        }
    4960
     61    /**
     62        @brief
     63        Searches a valid target for the turret to aim at.
     64
     65        Loops through all pawns and tests, if it is in range. Scores every pawn and chooses the best one (the one with the lowest score).
     66        If the turret has a parent, try to aim at the same target the parent has, if there is one.
     67
     68        @see targetScore
     69        The function that scores the pawns.
     70    */
    5071        void TurretController::searchTarget()
    5172        {
    5273        Turret* turret = orxonox_cast<Turret*>(this->getControllableEntity());
    53         if(target_ && turret->isInRange(target_->getWorldPosition()))
     74
     75        //The controller might find a target before teams are set, so we need to check again here.
     76        if(this->target_ && turret->isInRange(target_) != -1.f && !FormationController::sameTeam(turret, this->target_, this->getGametype()))
    5477        {
    5578                return;
     
    6689        {
    6790                Pawn* parenttarget = orxonox_cast<Pawn*>(parent->getTarget());
    68                 if(parenttarget && turret->isInRange(parenttarget->getWorldPosition()))
     91                if(parenttarget && turret->isInRange(parenttarget))
    6992                {
    7093                        this->setTarget(parenttarget);
     
    7497        }
    7598
    76                 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
     99        float maxScore = 0;
     100        float tempScore;
     101        Pawn* maxScorePawn = 0;
     102
     103                for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)     
    77104        {
    78105                Pawn* entity = orxonox_cast<Pawn*>(*it);
    79             if (this->FormationController::sameTeam(this->getControllableEntity(), entity, this->getGametype()))
     106            if (!entity || FormationController::sameTeam(this->getControllableEntity(), entity, this->getGametype()))
    80107                continue;
    81 
    82             if(turret->isInRange(entity->getWorldPosition()))
     108            tempScore = turret->isInRange(entity);
     109            if(tempScore != -1.f)
    83110            {
    84                 this->setTarget(entity);
    85                 turret->setTarget(entity);
    86                 break;
     111                if(tempScore > maxScore)
     112                {
     113                        maxScore = tempScore;
     114                        maxScorePawn = entity;
     115                }
    87116            }
    88         }               
    89         }
    90 
     117        }
     118        this->setTarget(maxScorePawn);
     119        turret->setTarget(maxScorePawn);
     120        }
     121
     122    /**
     123        @brief
     124        Tests, if the turret is looking at the target, with a specified tolerance
     125
     126                This uses the world position as opposed to the local position in the old version.
     127
     128                @param angle
     129                The tolerance, in radians
     130    */
    91131    bool TurretController::isLookingAtTargetNew(float angle) const
    92132    {
     
    94134    }
    95135
     136    /**
     137        @brief
     138        Scores a pawn as a target, based on distance and health.
     139
     140        The more health and distance a pawn has, the higher the score. This means lower equals better target.
     141
     142                @param pawn
     143                The pawn to score
     144
     145                @param distance
     146                The distance. Can be squared or normed, doesn't matter as long as all are treated the same.
     147    */   
     148        float TurretController::targetScore(Pawn* pawn, float distance) const
     149        {
     150                return pawn->getHealth()/pawn->getMaxHealth() + distance;
     151        }
     152
     153    /**
     154        @brief
     155        Does all the controlling of the turret.
     156
     157        If the turret has a parent, copies the team from there, if it's not already set.
     158        Other actions are: Search a target. If a target has been found, aim and shoot at it.
     159    */
    96160        void TurretController::tick(float dt)
    97161        {
     
    100164
    101165
    102                 if(!this->once_)
    103                 {
    104                         if(this->getTeam() != -1)
    105                         {
    106                                 orxout(internal_warning) << "Turret: Team already set, may result in undesired behaviour" << endl;
    107                         }
    108                         else
    109                         {
    110                     //Make sure the turret is in the same team as the parent
    111                     ControllableEntity* parent = orxonox_cast<ControllableEntity*> (this->getControllableEntity()->getParent());
    112                     if(parent)
    113                     {
    114                         Controller* parentcontroller = parent->getController();
    115                         if(parentcontroller)
    116                         {
    117                             this->setTeam(parentcontroller->getTeam());
    118                         }
    119                         else
    120                         {
    121                             this->setTeam(parent->getTeam());
    122                         }
    123                         this->getControllableEntity()->setTeam(parent->getTeam());
    124                     }
    125                 }
    126             this->once_ = true;
     166        ControllableEntity* parent = orxonox_cast<ControllableEntity*> (this->getControllableEntity()->getParent());
     167        if(this->getTeam() != -1 && !this->once_ && parent)
     168        {
     169            orxout(internal_warning) << "TurretController: Team already set, may result in undesired behaviour. Will get overridden by the parent's team." << endl;
     170        }
     171
     172        if(!this->once_)
     173                this->once_ = true;
     174     
     175        //Teams aren't set immediately, after creation, so we have to check every tick...
     176        if(parent)
     177        {
     178            Controller* parentcontroller = parent->getController();
     179            if(parentcontroller)
     180            {
     181                this->setTeam(parentcontroller->getTeam());
     182            }
     183            else
     184            {
     185                this->setTeam(parent->getTeam());
     186            }
     187            this->getControllableEntity()->setTeam(parent->getTeam());
    127188        }
    128189
    129190                this->searchTarget();
    130                 if(target_)
     191                if(this->target_)
    131192                {
    132193                        Turret* turret = orxonox_cast<Turret*> (this->getControllableEntity());
  • code/branches/turretFS14/src/modules/objects/controllers/TurretController.h

    r10049 r10060  
    5757                        void searchTarget();
    5858                        bool isLookingAtTargetNew(float angle) const;
     59                        float targetScore(Pawn* pawn, float distance) const;
    5960
    60                         bool once_;
     61                        bool once_; //!< Flag for executing code in the tick function only once.
    6162        };
    6263 }
Note: See TracChangeset for help on using the changeset viewer.