Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/orxonox/objects/NPC.cc @ 1443

Last change on this file since 1443 was 1425, checked in by scheusso, 16 years ago

implemented some sort of buffer for the spaceship movements (makes the movements on the client smoother)

File size: 6.2 KB
RevLine 
[603]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
[1425]3 *                    > www.orxonox.net <
[603]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 *      Benjamin Knecht, beni_at_orxonox.net
24 *   Co-authors:
25 *      ...
26 *
27 */
[1425]28
[1039]29#include "OrxonoxStableHeaders.h"
30#include "NPC.h"
[603]31
[1055]32#include "core/CoreIncludes.h"
[603]33
34namespace orxonox {
35
[627]36  CreateFactory(NPC);
37
[1293]38  NPC::NPC() :
39    movable_(true)
[603]40  {
[627]41    RegisterObject(NPC);
[1293]42    registerAllVariables();
[603]43  }
44
45  NPC::~NPC()
46  {
47  }
48
[627]49  void NPC::loadParams(TiXmlElement* xmlElem)
50  {
51    Model::loadParams(xmlElem);
52  }
53
[617]54  /**
55   * function to chance values of an element
56   */
57  void NPC::setValues(Vector3 location, Vector3 speed, Vector3 acceleration, bool movable) {
58    this->setAcceleration(acceleration);
59    this->setVelocity(speed);
60    this->translate(location);
61    movable_ = movable;
62  }
[1293]63 
64  void NPC::registerAllVariables(){
65    Model::registerAllVariables();
66    registerVar(&movable_, sizeof(movable_), network::DATA);
67  }
68 
[617]69
70  /**
71   * calculates the distance between the element and an other point given by temp
72   */
[627]73  float NPC::getDistance(WorldEntity* temp)
[617]74  {
75    Vector3 distance = temp->getPosition() - this->getPosition();
76    return distance.length();
77  }
78
79  /**
80   * updates the data of an element
81   */
[619]82  void NPC::update()
[617]83  {
84
85    //if element is movable, calculate acceleration
[627]86    if (this->movable_ == true) calculateAcceleration();
[617]87
88  }
89
90  /**
[619]91   * tick this NPC
92   */
93  void NPC::tick(float dt)
94  {
[1021]95    update();
[627]96    this->setVelocity(0.995*this->getVelocity() + this->getAcceleration()*dt);
97    this->translate(this->getVelocity()*dt);
98    this->setAcceleration(Vector3(0,0,0));
[619]99  }
100
101  /**
[617]102   * calculates the new acceleration of an element
103   */
[627]104  void NPC::calculateAcceleration()
[617]105  {
106    //acceleration consisting of flocking-functions
[627]107    this->setAcceleration(separation() + alignment() + cohesion());
[617]108  }
109
110  /**
111   * separation-function (keep elements separated, avoid crashs)
112   */
[627]113  Vector3 NPC::separation()
[617]114  {
115    Vector3 steering = Vector3(0,0,0); //steeringvector
116    Vector3 inverseDistance = Vector3(0,0,0);  //vector pointing away from possible collisions
117    int numberOfNeighbour = 0;  //number of observed neighbours
118    float distance = 0;  // distance to the actual element
[627]119    for(Iterator<WorldEntity> it = ObjectList<WorldEntity>::start(); it; ++it) {  //go through all elements
120      distance = getDistance(*it);  //get distance between this and actual
[617]121      if ((distance > 0) && (distance < SEPERATIONDISTANCE)) {  //do only if actual is inside detectionradius
122        inverseDistance = Vector3(0,0,0);
[627]123        inverseDistance = this->getPosition() - it->getPosition();  //calculate the distancevector heading towards this
[617]124        //adaptation of the inverseDistance to the distance
125        if ((distance < 200) && (distance >= 120)) {inverseDistance = 2*inverseDistance;}
126        if ((distance < 120) && (distance >= 80)) {inverseDistance = 5*inverseDistance;}
127        if ((distance < 80) && (distance >= 40)) {inverseDistance = 10*inverseDistance;}
128        if ((distance < 40) && (distance > 0)) {inverseDistance = 10*inverseDistance;}
129        steering = steering + inverseDistance;  //add up all significant steeringvectors
130        numberOfNeighbour++;  //counts the elements inside the detectionradius
131      }
132    }
133    if(numberOfNeighbour > 0) { steering = steering / (float)numberOfNeighbour; }  //devide the sum of steeringvectors by the number of elements -> separation steeringvector
134    return steering;
135  }
136
137  /**
138   * alignment-function (lead elements to the same heading)
139   */
[627]140  Vector3 NPC::alignment()
[617]141  {
142    Vector3 steering = Vector3(0,0,0); //steeringvector
143    int numberOfNeighbour = 0;  //number of observed neighbours
144    //float distance = 0;
145    //go through all elements
[627]146    for(Iterator<NPC> it = ObjectList<NPC>::start(); it; ++it) {  //just working with 3 elements at the moment
147      float distance = getDistance(*it);  //get distance between this and actual
[617]148      if ((distance > 0) && (distance < ALIGNMENTDISTANCE)) {  //check if actual element is inside detectionradius
[627]149        steering = steering + it->getVelocity();  //add up all speedvectors inside the detectionradius
[617]150        numberOfNeighbour++;  //counts the elements inside the detectionradius
151      }
152    }
153    if(numberOfNeighbour > 0) { steering = steering / (float)numberOfNeighbour; }  //devide the sum of steeringvectors by the number of elements -> alignment steeringvector
154    return steering;
155  }
156
157  /**
158   * cohseion-function (keep elements close to each other)
159   */
[627]160  Vector3 NPC::cohesion()
[617]161  {
162    Vector3 steering = Vector3(0,0,0); //steeringvector
163    int numberOfNeighbour = 0;  //number of observed neighbours
164    //float distance = 0;
165    //go through all elements
[627]166    for(Iterator<NPC> it = ObjectList<NPC>::start(); it; ++it) {  //just working with 3 elements at the moment
167      float distance = getDistance(*it);  //get distance between this and actual
[617]168      if ((distance > 0) && (distance < COHESIONDISTANCE)) {  //check if actual element is inside detectionradius
[627]169        steering = steering + it->getPosition();  //add up all locations of elements inside the detectionradius
[617]170        numberOfNeighbour++;  //counts the elements inside the detectionradius
171      }
172    }
173    if(numberOfNeighbour > 0) {
174      steering = steering  / (float)numberOfNeighbour;  //devide the sum steeringvector by the number of elements -> cohesion steeringvector
175      steering = steering - this->getPosition();  //transform the vector for the ship
176    }
177    return steering;
178  }
179
180} // end of class NPC
Note: See TracBrowser for help on using the repository browser.