[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" |
---|
[10135] | 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 | // |
---|
| 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 | MovementModule::MovementModule(NPC2* object){ this->myNPC=object; } |
---|
| 65 | MovementModule::~MovementModule(){} |
---|
| 66 | |
---|
| 67 | |
---|
| 68 | |
---|
| 69 | |
---|
| 70 | float MovementModule::getRadius(WorldEntity* object) |
---|
[10071] | 71 | { |
---|
| 72 | AABB* aabb = object->getModelAABB(); |
---|
[10112] | 73 | if( aabb == NULL)return -1; |
---|
[10135] | 74 | |
---|
[10112] | 75 | float a = aabb->halfLength[0]; |
---|
| 76 | float b = aabb->halfLength[1]; |
---|
| 77 | float c = aabb->halfLength[2]; |
---|
[10071] | 78 | |
---|
[10112] | 79 | if(a>b){ |
---|
| 80 | return (c>a)?c:a; |
---|
[10071] | 81 | }else{ |
---|
[10112] | 82 | return (c>b)?c:b; |
---|
[10071] | 83 | } |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | |
---|
| 87 | |
---|
| 88 | |
---|
[10135] | 89 | // void MovementModule::collectInformation(float dt) |
---|
| 90 | // { |
---|
| 91 | // //return if already processed.. |
---|
| 92 | // if(dt==this->oldDT)return; |
---|
| 93 | // this->oldDT=dt; |
---|
| 94 | // |
---|
| 95 | // |
---|
| 96 | // //clear old Information.. |
---|
| 97 | // hidingPoint.clear(); |
---|
| 98 | // hidingPointSize.clear(); |
---|
| 99 | // |
---|
| 100 | // npcList.clear(); |
---|
| 101 | // npcPosition.clear(); |
---|
| 102 | // npcRadius.clear(); |
---|
| 103 | // npcSwarm.clear(); |
---|
| 104 | // npcTeam.clear(); |
---|
| 105 | // |
---|
| 106 | // swarmCenter.clear(); |
---|
| 107 | // swarmMemberCount.clear(); |
---|
| 108 | // |
---|
| 109 | // |
---|
| 110 | // //get all NPCs.. |
---|
| 111 | // for(ObjectList<NPC2>::const_iterator it = NPC2::objectList().begin(); it != NPC2::objectList().end(); ++it) |
---|
| 112 | // { |
---|
| 113 | // npcList.push_back(*it); |
---|
| 114 | // npcRadius.push_back(getRadius(*it)); |
---|
| 115 | // npcPosition.push_back((*it)->getAbsCoor()); |
---|
| 116 | // npcSwarm.push_back((*it)->swarm); |
---|
| 117 | // npcTeam.push_back((*it)->team); |
---|
| 118 | // } |
---|
| 119 | // |
---|
| 120 | // |
---|
| 121 | // //Swarm Information |
---|
| 122 | // unsigned int tmpSwarm; |
---|
| 123 | // for(unsigned int i=0;i<npcList.size();i++){ |
---|
| 124 | // tmpSwarm = npcSwarm.at(i); |
---|
| 125 | // if(tmpSwarm > swarmMemberCount.size()){ |
---|
| 126 | // //swarmMemberCount.insert(swarmMemberCount.size(), tmpSwarm - swarmMemberCount.size(), 0); |
---|
| 127 | // //swarmCenter.insert(swarmCenter.size(), tmpSwarm - swarmCenter.size(), Vector(0,0,0)); |
---|
| 128 | // } |
---|
| 129 | // //swarmMemberCount.at(tmpSwarm)++; |
---|
| 130 | // //swarmCenter.at(tmpSwarm)=swarmCenter.at(tmpSwarm)+npcPosition.at(i); |
---|
| 131 | // } |
---|
| 132 | // for(unsigned int i=0;i<swarmCenter.size();i++){ |
---|
| 133 | // //swarmCenter.at(i)=swarmCenter.at(i)/swarmMemberCount.at(i); |
---|
| 134 | // } |
---|
| 135 | // |
---|
| 136 | // |
---|
| 137 | // //get information about Player |
---|
| 138 | // Player* pl = State::getPlayer(); |
---|
| 139 | // if( pl != NULL){ |
---|
| 140 | // playerPosition = pl->getPlayable()->getAbsCoor(); |
---|
| 141 | // playerRadius=getRadius( pl->getPlayable() ); |
---|
| 142 | // //PRINTF(0)("Player Radius: %f\n",playerRadius); |
---|
| 143 | // } |
---|
| 144 | // |
---|
| 145 | // |
---|
| 146 | // //calculate hiding Points.. |
---|
| 147 | // |
---|
| 148 | // } |
---|
| 149 | |
---|
| 150 | |
---|
| 151 | void MovementModule::process(float dt) |
---|
[10041] | 152 | { |
---|
[10135] | 153 | if(myNPC == NULL)return; |
---|
[10029] | 154 | |
---|
[10112] | 155 | //get information about Player |
---|
[10071] | 156 | Player* pl = State::getPlayer(); |
---|
[10135] | 157 | if( pl == NULL)return; |
---|
[10041] | 158 | |
---|
[10135] | 159 | Vector playerPosition = pl->getPlayable()->getAbsCoor(); |
---|
| 160 | float playerRadius=getRadius( pl->getPlayable() ); |
---|
[10041] | 161 | |
---|
| 162 | |
---|
[10135] | 163 | // collectInformation(dt); |
---|
[10041] | 164 | |
---|
[10135] | 165 | Vector myPosition = myNPC->getAbsCoor(); |
---|
| 166 | float myRadius = getRadius(myNPC); |
---|
[10041] | 167 | |
---|
| 168 | |
---|
[10135] | 169 | Vector vectorToPlayer = playerPosition - myPosition; |
---|
[10041] | 170 | |
---|
[10112] | 171 | Vector tmpVector; |
---|
| 172 | float tmpFloat; |
---|
[10135] | 173 | |
---|
| 174 | // Vector npcCollision; |
---|
| 175 | // Vector swarmVector; |
---|
[10112] | 176 | Vector playerCollision; |
---|
| 177 | |
---|
| 178 | |
---|
[10135] | 179 | |
---|
[10112] | 180 | //float a=200.0f; |
---|
| 181 | float vMax=200.0f; |
---|
[10135] | 182 | float maxAccleration=300.0f; |
---|
[10112] | 183 | //float safetyDistance=2.0f; |
---|
| 184 | |
---|
| 185 | |
---|
| 186 | //Anti Player Collision |
---|
[10135] | 187 | tmpFloat=vectorToPlayer.len()-playerRadius-myRadius-30;//distanceToPlayer; |
---|
[10112] | 188 | if(tmpFloat<0.1)tmpFloat=0.1; |
---|
| 189 | playerCollision=vectorToPlayer/(tmpFloat*tmpFloat)*(-1); |
---|
[10071] | 190 | |
---|
| 191 | |
---|
| 192 | |
---|
[10135] | 193 | // for (unsigned int i=0;i<npcList.size();i++) |
---|
| 194 | // { |
---|
| 195 | // if(npcList.at(i)==myNPC)continue; |
---|
| 196 | // |
---|
| 197 | // //Anti NPC Collision |
---|
| 198 | // tmpVector=myPosition-npcPosition.at(i); |
---|
| 199 | // tmpFloat=tmpVector.len()-myRadius-npcRadius.at(i)-distanceToNPC; |
---|
| 200 | // |
---|
| 201 | // if(tmpFloat<0.1)tmpFloat=0.1; |
---|
| 202 | // tmpVector=tmpVector/(tmpFloat*tmpFloat); |
---|
| 203 | // |
---|
| 204 | // npcCollision=npcCollision+tmpVector; |
---|
| 205 | // |
---|
| 206 | // //Schwarmverhalten |
---|
| 207 | // if(npcSwarm.at(i) == mySwarm){ |
---|
| 208 | // |
---|
| 209 | // |
---|
| 210 | // } |
---|
| 211 | // } |
---|
| 212 | |
---|
| 213 | |
---|
| 214 | |
---|
| 215 | |
---|
| 216 | |
---|
| 217 | //Vector correction=playerCollision*50+npcCollision*50+vectorToPlayer+Vector(70,0,0)-myMovement; |
---|
| 218 | Vector correction=playerCollision*50+vectorToPlayer+Vector(50,0,0)-myMovement; |
---|
| 219 | |
---|
[10071] | 220 | correction.y=0; |
---|
| 221 | float correctionLen=correction.len(); |
---|
[10112] | 222 | if(correctionLen>maxAccleration*dt)correction=correction/correctionLen*maxAccleration*dt; |
---|
| 223 | myMovement+=correction; |
---|
[10071] | 224 | |
---|
[10112] | 225 | float movementLen=myMovement.len(); |
---|
| 226 | if(movementLen>vMax)myMovement/movementLen*vMax; |
---|
[10071] | 227 | |
---|
| 228 | //Move NPC... |
---|
[10112] | 229 | myNPC->shiftCoor(myMovement * dt); |
---|
[10071] | 230 | |
---|
| 231 | //Rotate NPC |
---|
[10112] | 232 | Vector view = myMovement; |
---|
[10075] | 233 | //if(vectorToPlayer.dot(v)<0){ |
---|
| 234 | // view = v.cross( Vector(0,1,0) ).getNormalized(); |
---|
[10071] | 235 | //}else{ |
---|
[10112] | 236 | view = myMovement.cross( Vector(0,-1,0) ).getNormalized(); |
---|
[10071] | 237 | //} |
---|
| 238 | //if(dist<keepDist)view=view*-1; |
---|
[10112] | 239 | //myNPC->setAbsDir( Quaternion( view, Vector(0,1,0))); |
---|
| 240 | myNPC->setAbsDirSoft( Quaternion( view, Vector(0,1,0)),3); |
---|
[10041] | 241 | } |
---|
| 242 | |
---|
| 243 | |
---|