- Timestamp:
- Dec 3, 2014, 12:49:15 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/towerdefenseHS14/src/modules/objects/Turret.cc
r9945 r10144 21 21 * 22 22 * Author: 23 * Marian Runo 23 * Marian Runo, Martin Mueller 24 24 * Co-authors: 25 25 * ... … … 29 29 #include "Turret.h" 30 30 #include "core/CoreIncludes.h" 31 #include "OgreQuaternion.h"32 31 #include "core/XMLPort.h" 33 #include "controllers/WaypointPatrolController.h" 32 #include "Scene.h" 33 #include <OgreSceneManager.h> 34 34 35 35 36 namespace orxonox … … 37 38 RegisterClass(Turret); 38 39 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 41 48 */ 42 Turret::Turret(Context* context) : SpaceShip(context)49 Turret::Turret(Context* context) : Pawn(context) 43 50 { 44 51 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) . 50 72 */ 51 73 Turret::~Turret() 52 74 { 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 */ 57 158 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 */ 78 216 void Turret::XMLPort(Element& xmlelement, XMLPort::Mode mode) 79 217 { 80 218 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 } 85 284 }
Note: See TracChangeset
for help on using the changeset viewer.