[10029] | 1 | /* |
---|
| 2 | orxonox - the future of 3D-vertical-scrollers |
---|
| 3 | |
---|
| 4 | Copyright (C) 2004 orx |
---|
| 5 | |
---|
| 6 | This program is free software; you can redistribute it and/or modify |
---|
| 7 | it under the terms of the GNU General Public License as published by |
---|
| 8 | the Free Software Foundation; either version 2, or (at your option) |
---|
| 9 | any later version. |
---|
| 10 | |
---|
| 11 | ### File Specific: |
---|
[10045] | 12 | main-programmer: Thomas Fahrni |
---|
[10029] | 13 | co-programmer: |
---|
| 14 | */ |
---|
[10045] | 15 | #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_AI |
---|
[10029] | 16 | |
---|
| 17 | #include "movement_module.h" |
---|
[10045] | 18 | #include "ai_engine.h" |
---|
| 19 | #include "state.h" |
---|
| 20 | #include "debug.h" |
---|
[10071] | 21 | #include "player.h" |
---|
| 22 | #include "playable.h" |
---|
| 23 | #include "aabb.h" |
---|
| 24 | #include "npcs/npc_test.h" |
---|
[10029] | 25 | |
---|
[10071] | 26 | #include "shell_command.h" |
---|
[10138] | 27 | SHELL_COMMAND(setDistanceToPlayer, MovementModule, setDistanceToPlayer); |
---|
| 28 | SHELL_COMMAND(setDistanceToNPC, MovementModule, setDistanceToNPC); |
---|
| 29 | SHELL_COMMAND(setMaxAccleartion, MovementModule, setMaxAccleartion); |
---|
| 30 | |
---|
| 31 | float MovementModule::distanceToPlayer=15; |
---|
| 32 | float MovementModule::distanceToNPC=2; |
---|
| 33 | float MovementModule::maxAccleration=200.0f; |
---|
| 34 | |
---|
| 35 | void MovementModule::setDistanceToPlayer(float newValue){ distanceToPlayer=newValue; } |
---|
| 36 | void MovementModule::setDistanceToNPC(float newValue){ distanceToNPC=newValue; } |
---|
| 37 | void MovementModule::setMaxAccleartion(float newValue){ maxAccleration=newValue; } |
---|
| 38 | |
---|
| 39 | |
---|
| 40 | |
---|
| 41 | |
---|
| 42 | |
---|
| 43 | |
---|
[10135] | 44 | // std::vector<Vector> MovementModule::hidingPoint; |
---|
| 45 | // std::vector<float> MovementModule::hidingPointSize; |
---|
| 46 | // |
---|
| 47 | // std::vector<NPC2*> MovementModule::npcList; |
---|
| 48 | // std::vector<Vector> MovementModule::npcPosition; |
---|
| 49 | // std::vector<float> MovementModule::npcRadius; |
---|
| 50 | // std::vector<int> MovementModule::npcSwarm; |
---|
| 51 | // std::vector<int> MovementModule::npcTeam; |
---|
| 52 | // |
---|
| 53 | // Vector MovementModule::playerPosition; |
---|
| 54 | // Vector MovementModule::playerMovement; |
---|
| 55 | // float MovementModule::playerRadius; |
---|
| 56 | // |
---|
| 57 | // std::vector<Vector> MovementModule::swarmCenter; |
---|
| 58 | // std::vector<int> MovementModule::swarmMemberCount; |
---|
| 59 | // |
---|
| 60 | // |
---|
| 61 | // |
---|
| 62 | // |
---|
| 63 | // |
---|
[10112] | 64 | |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | float MovementModule::getRadius(WorldEntity* object) |
---|
[10071] | 68 | { |
---|
| 69 | AABB* aabb = object->getModelAABB(); |
---|
[10112] | 70 | if( aabb == NULL)return -1; |
---|
[10135] | 71 | |
---|
[10112] | 72 | float a = aabb->halfLength[0]; |
---|
| 73 | float b = aabb->halfLength[1]; |
---|
| 74 | float c = aabb->halfLength[2]; |
---|
[10071] | 75 | |
---|
[10112] | 76 | if(a>b){ |
---|
| 77 | return (c>a)?c:a; |
---|
[10071] | 78 | }else{ |
---|
[10112] | 79 | return (c>b)?c:b; |
---|
[10071] | 80 | } |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | |
---|
| 84 | |
---|
| 85 | |
---|
[10135] | 86 | // void MovementModule::collectInformation(float dt) |
---|
| 87 | // { |
---|
| 88 | // //return if already processed.. |
---|
| 89 | // if(dt==this->oldDT)return; |
---|
| 90 | // this->oldDT=dt; |
---|
| 91 | // |
---|
| 92 | // |
---|
| 93 | // //clear old Information.. |
---|
| 94 | // hidingPoint.clear(); |
---|
| 95 | // hidingPointSize.clear(); |
---|
| 96 | // |
---|
| 97 | // npcList.clear(); |
---|
| 98 | // npcPosition.clear(); |
---|
| 99 | // npcRadius.clear(); |
---|
| 100 | // npcSwarm.clear(); |
---|
| 101 | // npcTeam.clear(); |
---|
| 102 | // |
---|
| 103 | // swarmCenter.clear(); |
---|
| 104 | // swarmMemberCount.clear(); |
---|
| 105 | // |
---|
| 106 | // |
---|
| 107 | // //get all NPCs.. |
---|
| 108 | // for(ObjectList<NPC2>::const_iterator it = NPC2::objectList().begin(); it != NPC2::objectList().end(); ++it) |
---|
| 109 | // { |
---|
| 110 | // npcList.push_back(*it); |
---|
| 111 | // npcRadius.push_back(getRadius(*it)); |
---|
| 112 | // npcPosition.push_back((*it)->getAbsCoor()); |
---|
| 113 | // npcSwarm.push_back((*it)->swarm); |
---|
| 114 | // npcTeam.push_back((*it)->team); |
---|
| 115 | // } |
---|
| 116 | // |
---|
| 117 | // |
---|
| 118 | // //Swarm Information |
---|
| 119 | // unsigned int tmpSwarm; |
---|
| 120 | // for(unsigned int i=0;i<npcList.size();i++){ |
---|
| 121 | // tmpSwarm = npcSwarm.at(i); |
---|
| 122 | // if(tmpSwarm > swarmMemberCount.size()){ |
---|
| 123 | // //swarmMemberCount.insert(swarmMemberCount.size(), tmpSwarm - swarmMemberCount.size(), 0); |
---|
| 124 | // //swarmCenter.insert(swarmCenter.size(), tmpSwarm - swarmCenter.size(), Vector(0,0,0)); |
---|
| 125 | // } |
---|
| 126 | // //swarmMemberCount.at(tmpSwarm)++; |
---|
| 127 | // //swarmCenter.at(tmpSwarm)=swarmCenter.at(tmpSwarm)+npcPosition.at(i); |
---|
| 128 | // } |
---|
| 129 | // for(unsigned int i=0;i<swarmCenter.size();i++){ |
---|
| 130 | // //swarmCenter.at(i)=swarmCenter.at(i)/swarmMemberCount.at(i); |
---|
| 131 | // } |
---|
| 132 | // |
---|
| 133 | // |
---|
| 134 | // //get information about Player |
---|
| 135 | // Player* pl = State::getPlayer(); |
---|
| 136 | // if( pl != NULL){ |
---|
| 137 | // playerPosition = pl->getPlayable()->getAbsCoor(); |
---|
| 138 | // playerRadius=getRadius( pl->getPlayable() ); |
---|
| 139 | // //PRINTF(0)("Player Radius: %f\n",playerRadius); |
---|
| 140 | // } |
---|
| 141 | // |
---|
| 142 | // |
---|
| 143 | // //calculate hiding Points.. |
---|
| 144 | // |
---|
| 145 | // } |
---|
| 146 | |
---|
| 147 | |
---|
| 148 | void MovementModule::process(float dt) |
---|
[10041] | 149 | { |
---|
[10135] | 150 | if(myNPC == NULL)return; |
---|
[10029] | 151 | |
---|
[10112] | 152 | //get information about Player |
---|
[10071] | 153 | Player* pl = State::getPlayer(); |
---|
[10135] | 154 | if( pl == NULL)return; |
---|
| 155 | Vector playerPosition = pl->getPlayable()->getAbsCoor(); |
---|
| 156 | float playerRadius=getRadius( pl->getPlayable() ); |
---|
[10138] | 157 | |
---|
[10041] | 158 | |
---|
[10138] | 159 | //get information about myself |
---|
[10135] | 160 | Vector myPosition = myNPC->getAbsCoor(); |
---|
| 161 | float myRadius = getRadius(myNPC); |
---|
[10041] | 162 | |
---|
| 163 | |
---|
[10135] | 164 | Vector vectorToPlayer = playerPosition - myPosition; |
---|
[10041] | 165 | |
---|
[10112] | 166 | Vector tmpVector; |
---|
| 167 | float tmpFloat; |
---|
[10138] | 168 | |
---|
| 169 | Vector npcCollision; |
---|
[10112] | 170 | Vector playerCollision; |
---|
| 171 | |
---|
| 172 | |
---|
[10135] | 173 | |
---|
[10112] | 174 | //float a=200.0f; |
---|
| 175 | float vMax=200.0f; |
---|
[10138] | 176 | //float maxAccleration=300.0f; |
---|
[10112] | 177 | //float safetyDistance=2.0f; |
---|
| 178 | |
---|
| 179 | |
---|
| 180 | //Anti Player Collision |
---|
[10138] | 181 | tmpFloat=vectorToPlayer.len()-playerRadius-myRadius-distanceToPlayer; |
---|
[10112] | 182 | if(tmpFloat<0.1)tmpFloat=0.1; |
---|
| 183 | playerCollision=vectorToPlayer/(tmpFloat*tmpFloat)*(-1); |
---|
[10071] | 184 | |
---|
| 185 | |
---|
[10138] | 186 | //Anti NPC Collision |
---|
| 187 | for(ObjectList<WorldEntity>::const_iterator it = WorldEntity::objectList().begin(); it != WorldEntity::objectList().end(); ++it) |
---|
| 188 | { |
---|
| 189 | if(*it==myNPC)continue; |
---|
[10071] | 190 | |
---|
[10138] | 191 | tmpVector=myPosition-(*it)->getAbsCoor(); |
---|
| 192 | tmpFloat=tmpVector.len()-myRadius-distanceToNPC-getRadius(*it); |
---|
[10135] | 193 | |
---|
[10138] | 194 | if(tmpFloat<0.1)tmpFloat=0.1; |
---|
| 195 | tmpVector=tmpVector/(tmpFloat*tmpFloat); |
---|
[10135] | 196 | |
---|
[10138] | 197 | npcCollision=npcCollision+tmpVector; |
---|
| 198 | } |
---|
[10135] | 199 | |
---|
| 200 | |
---|
| 201 | |
---|
[10138] | 202 | Vector vectorToDestination=destination-myPosition; |
---|
[10135] | 203 | |
---|
[10138] | 204 | Vector correction=playerCollision*50+npcCollision*50+vectorToDestination+Vector(0,0,0)-myMovement; |
---|
| 205 | |
---|
[10071] | 206 | correction.y=0; |
---|
| 207 | float correctionLen=correction.len(); |
---|
[10112] | 208 | if(correctionLen>maxAccleration*dt)correction=correction/correctionLen*maxAccleration*dt; |
---|
| 209 | myMovement+=correction; |
---|
[10071] | 210 | |
---|
[10112] | 211 | float movementLen=myMovement.len(); |
---|
| 212 | if(movementLen>vMax)myMovement/movementLen*vMax; |
---|
[10071] | 213 | |
---|
| 214 | //Move NPC... |
---|
[10112] | 215 | myNPC->shiftCoor(myMovement * dt); |
---|
[10071] | 216 | |
---|
| 217 | //Rotate NPC |
---|
[10112] | 218 | Vector view = myMovement; |
---|
[10075] | 219 | //if(vectorToPlayer.dot(v)<0){ |
---|
| 220 | // view = v.cross( Vector(0,1,0) ).getNormalized(); |
---|
[10071] | 221 | //}else{ |
---|
[10138] | 222 | view = myMovement.cross( Vector(0,1,0) ).getNormalized(); |
---|
[10071] | 223 | //} |
---|
| 224 | //if(dist<keepDist)view=view*-1; |
---|
[10112] | 225 | //myNPC->setAbsDir( Quaternion( view, Vector(0,1,0))); |
---|
| 226 | myNPC->setAbsDirSoft( Quaternion( view, Vector(0,1,0)),3); |
---|
[10041] | 227 | } |
---|
| 228 | |
---|
| 229 | |
---|