Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/turretFS14/src/modules/objects/controllers/TurretController.cc @ 10042

Last change on this file since 10042 was 10042, checked in by muemart, 10 years ago

Fix rotation if parent is already rotated. Everything hopefully now works as expected. It's a giant mess right now, so still have to clean it up.

File size: 6.4 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 *      Martin Mueller
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "TurretController.h"
30#include "worldentities/pawns/Pawn.h"
31#include "Turret.h"
32
33 namespace orxonox
34 {
35        RegisterClass(TurretController);
36
37        TurretController::TurretController(Context* context) : ArtificialController(context)
38        {
39                RegisterObject(TurretController);
40                this->startOrient_ = Quaternion::IDENTITY;
41        this->startDir_ = Vector3::ZERO;
42        this->localZ_ = Vector3::UNIT_Z;
43        this->localY_ = Vector3::UNIT_Y;
44        this->localX_ = Vector3::UNIT_X;
45        this->attackRadius_ = 200;
46        this->maxPitch_ = 90;
47        this->maxYaw_ = 90;
48        this->gotOrient_ = false;
49        }
50
51        TurretController::~TurretController()
52        {
53
54        }
55
56        void TurretController::searchTarget()
57        {
58        Turret* turret = orxonox_cast<Turret*>(this->getControllableEntity());
59        if(target_ && this->isInRange(target_->getWorldPosition()))
60        {
61                return;
62        }
63        else
64        {
65                this->forgetTarget();
66        }
67
68
69        ControllableEntity* parent = orxonox_cast<ControllableEntity*>(turret->getParent());
70        if(parent)
71        {
72                Pawn* parenttarget = orxonox_cast<Pawn*>(parent->getTarget());
73                if(parenttarget && this->isInRange(parenttarget->getWorldPosition()))
74                {
75                        this->setTarget(parenttarget);
76                        turret->setTarget(parenttarget);
77                        return;
78                }
79        }
80
81                for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
82        {
83                Pawn* entity = orxonox_cast<Pawn*>(*it);
84            if (ArtificialController::sameTeam(this->getControllableEntity(), entity, this->getGametype()))
85                continue;
86
87            if(this->isInRange(entity->getWorldPosition()))
88            {
89                this->setTarget(entity);
90                turret->setTarget(entity);
91                break;
92            }
93        }               
94        }
95
96        bool TurretController::isInRange(const Vector3 &position)
97    {
98        //Check distance
99        Vector3 distance = position - this->getControllableEntity()->getWorldPosition();
100        if(distance.squaredLength() > (this->attackRadius_ * this->attackRadius_))
101        {
102            return false;
103        }
104
105        //Check pitch
106        Vector3 dir = getTransformedVector(distance, this->localX_, this->localY_, this->localZ_);
107        Vector3 dirProjected = dir;
108        dirProjected.x = 0;
109        Vector3 startDirProjected = this->startDir_;
110        startDirProjected.x = 0;
111        Ogre::Real angle = startDirProjected.angleBetween(dirProjected).valueDegrees();
112        if(angle > this->maxPitch_)
113        {
114            return false;
115        }
116
117        //Check yaw
118        dirProjected = dir;
119        dirProjected.y = 0;
120        startDirProjected = this->startDir_;
121        startDirProjected.y = 0;
122        angle = startDirProjected.angleBetween(dirProjected).valueDegrees();
123        if(angle > this->maxYaw_)
124        {
125            return false;
126        }
127        return true;
128    }
129
130    void TurretController::aimAtPositionRot(const Vector3 &position)
131    {
132
133        Vector3 currDir = this->getControllableEntity()->getWorldOrientation() * WorldEntity::FRONT;
134        Vector3 targetDir = position - this->getControllableEntity()->getWorldPosition();
135
136        Quaternion rot = currDir.getRotationTo(targetDir);
137
138        //Don't make the rotation instantaneous
139        rot = Quaternion::Slerp(0.1, Quaternion::IDENTITY, rot);
140
141        this->getControllableEntity()->rotate(rot, WorldEntity::World);
142    }
143   
144
145    void TurretController::aimAtTargetRot()
146    {
147        this->aimAtPositionRot(this->target_->getWorldPosition());
148    }
149
150    bool TurretController::isLookingAtTargetNew(float angle) const
151    {
152        return (getAngle(this->getControllableEntity()->getWorldPosition(), this->getControllableEntity()->getWorldOrientation() * WorldEntity::FRONT, this->target_->getWorldPosition()) < angle);
153    }
154
155        void TurretController::tick(float dt)
156        {
157                        if(!gotOrient_)
158                {
159                    this->startOrient_ = this->getControllableEntity()->getOrientation();
160                    this->localXStart_ = this->startOrient_ * this->localX_;
161                    this->localXStart_.normalise();
162                    this->localX_ = this->localXStart_;
163                    this->localYStart_ = this->startOrient_ * this->localY_;
164                    this->localYStart_.normalise();
165                    this->localY_ = this->localYStart_;
166                    this->localZStart_ = this->startOrient_ * this->localZ_;
167                    this->localZStart_.normalise();
168                    this->localZ_ = this->localZStart_;
169
170                    //startDir should always be (0,0,-1)
171                    this->startDir_ = getTransformedVector(this->startOrient_ * WorldEntity::FRONT, this->localX_, this->localY_, this->localZ_);
172
173                    this->gotOrient_ = true;
174
175                }
176
177                WorldEntity* parent = this->getControllableEntity()->getParent();
178                if(parent)
179                {
180                    Quaternion parentrot = parent->getOrientation();
181                    this->localX_ = parentrot * this->localXStart_;
182                    this->localY_ = parentrot * this->localYStart_;
183                    this->localZ_ = parentrot * this->localZStart_;
184                }
185
186
187
188                if (!this->isActive() || !this->getControllableEntity())
189                    return;
190
191                        this->searchTarget();
192                        if(target_)
193                        {
194                                this->aimAtTarget();
195                                //this->getControllableEntity()->lookAt(this->targetPosition_);
196                                //It says move, but really it only turns
197                                this->aimAtTargetRot();
198                                if(this->isLookingAtTargetNew(Degree(5).valueRadians()))
199                                {
200                                        orxout() << 42 << endl;
201                                }
202                        }
203        }
204 }
Note: See TracBrowser for help on using the repository browser.