Changeset 10060
- Timestamp:
- May 15, 2014, 5:10:55 PM (11 years ago)
- Location:
- code/branches/turretFS14
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/turretFS14/data/levels/turretTest.oxw
r10049 r10060 3 3 <LevelInfo 4 4 name = "turret Test" 5 description = "A level with a turret in it."5 description = "A level to test turrets with." 6 6 tags = "test" 7 7 screenshot = "emptylevel.png" … … 16 16 <?lua 17 17 include("templates/spaceshipAssff.oxt") 18 include("templates/spaceshipTransporter.oxt")19 18 include("templates/standardTurret.oxt") 20 19 ?> … … 33 32 <SpawnPoint team=0 position="-200,0,0" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff /> 34 33 35 <SpaceShip> 34 <SpaceShip position = "0,0,800" collisionType="dynamic" team=10> 35 <controller> 36 <TeamTargetProxy team=10/> 37 </controller> 36 38 <attached> 37 <Turret position="10,2,0" pitch="90" yaw="0" roll="0" scale3D="0.2,0.2,0.2"> 38 <templates> 39 <Template link=standardturret /> 40 </templates> 41 </Turret> 42 <Turret position="-10,2,0" pitch="90" yaw="0" roll="0" scale3D="0.2,0.2,0.2"> 43 <templates> 44 <Template link=standardturret /> 45 </templates> 46 </Turret> 47 <Turret position="0,2,0" pitch="90" yaw="0" roll="0" scale3D="0.2,0.2,0.2"> 48 <templates> 49 <Template link=standardturret /> 50 </templates> 51 </Turret> 39 <Model position="0,0,0" mesh="plane.mesh" scale3D="20,20,20" pitch=-90/> 40 41 <?lua for i = 1, 10, 1 do ?> 42 <Turret position="<?lua print(150-i*30) ?>,<?lua print(150-i*30) ?>,0" pitch="0" yaw="0" roll="0"> 43 <templates> 44 <Template link=standardturret /> 45 </templates> 46 </Turret> 47 <?lua end ?> 48 52 49 </attached> 53 <templates> 54 <Template link=spaceshipassff /> 55 </templates> 56 <!-- <controller> 57 <AIController /> 58 </controller> --> 50 <collisionShapes> 51 <BoxCollisionShape radius="10" position="0,0,0" halfExtents="200, 200, 0"/> 52 </collisionShapes> 59 53 </SpaceShip> 60 54 55 <Turret collisionType="dynamic" pitch=90 position="30,0,0"> 56 <attached> 57 <Model position="0,0,0" mesh="turretSocketFront.mesh" scale3D="10,10,10" pitch=-90/> 58 <Model position="0,0,0" mesh="turretSocketIn.mesh" scale3D="10,10,10" pitch=-90/> 59 <Model position="0,0,0" mesh="turretSocketTop.mesh" scale3D="10,10,10" pitch=-90/> 60 <Model position="0,0,0" mesh="turretSocketLeft.mesh" scale3D="10,10,10" pitch=-90/> 61 <Model position="0,0,0" mesh="turretSocketRight.mesh" scale3D="10,10,10" pitch=-90/> 62 63 <Turret position="0,0,-10" collisionType="dynamic" pitch=20 angularDamping=0.999999 mass=100 maxPitch=45 maxYaw=45 maxAttackRadius=2000 minAttackRadius=30> 64 <attached> 65 <Model position="0,0,0" pitch="-90" roll="0" mesh="turretHead.mesh" scale3D="10,10,10"/> 66 </attached> 67 <collisionShapes> 68 <SphereCollisionShape radius="10" position = "0,0,0"/> 69 </collisionShapes> 70 <controller> 71 <TurretController/> 72 </controller> 73 <?lua 74 include("includes/weaponSettingsTurret.oxi") 75 ?> 76 </Turret> 77 </attached> 78 79 <controller> 80 <TeamTargetProxy team=10/> 81 </controller> 82 </Turret> 61 83 62 84 -
code/branches/turretFS14/src/modules/objects/Turret.cc
r10049 r10060 30 30 #include "core/CoreIncludes.h" 31 31 #include "core/XMLPort.h" 32 #include "Scene.h" 33 #include <OgreSceneQuery.h> 34 32 35 33 36 namespace orxonox … … 73 76 /** 74 77 @brief 75 Checks, if a (world)positionis inside the turret's range.78 Checks, if a WorldEntity is inside the turret's range. 76 79 77 80 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 84 90 { 85 91 //Check distance 86 Vector3 distance = position- this->getWorldPosition();92 Vector3 distance = target->getWorldPosition() - this->getWorldPosition(); 87 93 float distanceVal = distance.squaredLength(); 88 94 if(distanceVal > (this->maxAttackRadius_ * this->maxAttackRadius_) || distanceVal < (this->minAttackRadius_ * this->minAttackRadius_)) 89 95 { 90 return false;96 return -1.f; 91 97 } 92 98 … … 100 106 if(angle > this->maxPitch_) 101 107 { 102 return false;108 return -1.f; 103 109 } 104 110 … … 111 117 if(angle > this->maxYaw_) 112 118 { 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; 116 128 } 117 129 … … 215 227 216 228 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 217 232 */ 218 233 void Turret::tick(float dt) … … 220 235 SUPER(Turret, tick, dt); 221 236 222 237 //Stuff isn't properly initialized in the c'tor, so we have to do it like this 223 238 if(!this->once_) 224 239 { … … 256 271 { 257 272 //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 258 275 Quaternion drot = Quaternion::nlerp(dt*this->rotationThrust_/20.f, Quaternion::IDENTITY, this->rotation_); 259 276 this->rotate(drot, WorldEntity::World); -
code/branches/turretFS14/src/modules/objects/Turret.h
r10049 r10060 46 46 it's behaviour. 47 47 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 48 53 @note 49 54 The rotation isn't limited "physically". You have to call isInRange to find out if the turret is allowed to shoot at a target. … … 58 63 virtual void rotateYaw(const Vector2& value); 59 64 virtual void rotateRoll(const Vector2& value); 60 virtual bool isInRange(const Vector3 &position);65 virtual float isInRange(const WorldEntity* target) const; 61 66 virtual void aimAtPosition(const Vector3 &position); 62 67 -
code/branches/turretFS14/src/modules/objects/controllers/TeamTargetProxy.cc
r10049 r10060 28 28 29 29 #include "TeamTargetProxy.h" 30 #include "worldentities/ControllableEntity.h" 30 31 #include "worldentities/pawns/Pawn.h" 31 32 32 33 34 33 namespace orxonox 34 { 35 RegisterClass(TeamTargetProxy); 35 36 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) 37 45 { 38 46 RegisterObject(TeamTargetProxy); … … 41 49 } 42 50 51 /** 52 @brief 53 Destructor. Nothing to see here. 54 */ 43 55 TeamTargetProxy::~TeamTargetProxy() 44 56 { 45 57 } 46 58 59 /** 60 @brief 61 Copies the team and the target from the parent. 62 63 That's all there is. 64 */ 47 65 void TeamTargetProxy::tick(float dt) 48 66 { … … 51 69 52 70 ControllableEntity* parent = orxonox_cast<ControllableEntity*> (this->getControllableEntity()->getParent()); 53 54 71 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 } 55 94 56 95 if(parent) 57 96 { 58 59 if(!this->once_)60 {61 //Set the same team62 if(parent)63 {64 Controller* parentcontroller = parent->getController();65 if(parentcontroller)66 {67 this->setTeam(parentcontroller->getTeam());68 }69 else70 {71 this->setTeam(parent->getTeam());72 }73 this->getControllableEntity()->setTeam(parent->getTeam());74 }75 this->once_ = true;76 }77 78 97 Pawn* parenttarget = orxonox_cast<Pawn*>(parent->getTarget()); 79 98 if(parenttarget) … … 83 102 } 84 103 } 85 86 104 } 87 105 } -
code/branches/turretFS14/src/modules/objects/controllers/TeamTargetProxy.h
r10049 r10060 35 35 namespace orxonox 36 36 { 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 */ 37 47 class _OrxonoxExport TeamTargetProxy : public FormationController, public Tickable 38 48 { … … 44 54 45 55 private: 46 bool once_; 56 bool once_; //!< Flag for executing code in the tick function only once. 47 57 }; 48 58 } -
code/branches/turretFS14/src/modules/objects/controllers/TurretController.cc
r10049 r10060 35 35 RegisterClass(TurretController); 36 36 37 /** 38 @brief 39 Sets default values for all variables. 40 41 @param context 42 The context 43 */ 37 44 TurretController::TurretController(Context* context) : ArtificialController(context) 38 45 { … … 43 50 } 44 51 52 /** 53 @brief 54 Destructor. Nothing to see here. 55 */ 45 56 TurretController::~TurretController() 46 57 { … … 48 59 } 49 60 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 */ 50 71 void TurretController::searchTarget() 51 72 { 52 73 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())) 54 77 { 55 78 return; … … 66 89 { 67 90 Pawn* parenttarget = orxonox_cast<Pawn*>(parent->getTarget()); 68 if(parenttarget && turret->isInRange(parenttarget ->getWorldPosition()))91 if(parenttarget && turret->isInRange(parenttarget)) 69 92 { 70 93 this->setTarget(parenttarget); … … 74 97 } 75 98 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) 77 104 { 78 105 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())) 80 107 continue; 81 82 if(t urret->isInRange(entity->getWorldPosition()))108 tempScore = turret->isInRange(entity); 109 if(tempScore != -1.f) 83 110 { 84 this->setTarget(entity); 85 turret->setTarget(entity); 86 break; 111 if(tempScore > maxScore) 112 { 113 maxScore = tempScore; 114 maxScorePawn = entity; 115 } 87 116 } 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 */ 91 131 bool TurretController::isLookingAtTargetNew(float angle) const 92 132 { … … 94 134 } 95 135 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 */ 96 160 void TurretController::tick(float dt) 97 161 { … … 100 164 101 165 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()); 127 188 } 128 189 129 190 this->searchTarget(); 130 if(t arget_)191 if(this->target_) 131 192 { 132 193 Turret* turret = orxonox_cast<Turret*> (this->getControllableEntity()); -
code/branches/turretFS14/src/modules/objects/controllers/TurretController.h
r10049 r10060 57 57 void searchTarget(); 58 58 bool isLookingAtTargetNew(float angle) const; 59 float targetScore(Pawn* pawn, float distance) const; 59 60 60 bool once_; 61 bool once_; //!< Flag for executing code in the tick function only once. 61 62 }; 62 63 } -
code/branches/turretFS14/src/orxonox/worldentities/WorldEntity.cc
r10039 r10060 414 414 else if (this->isDynamic()) 415 415 { 416 // hacky hack, really shouldn't do that416 //***HACKY HACK (to allow turrets to be attached)*** 417 417 //orxout(internal_warning) << "Cannot attach a dynamic object to a WorldEntity." << endl; 418 418 //return false;
Note: See TracChangeset
for help on using the changeset viewer.