Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1446 was 1425, checked in by scheusso, 17 years ago

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

File size: 6.2 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
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 */
28
29#include "OrxonoxStableHeaders.h"
30#include "NPC.h"
31
32#include "core/CoreIncludes.h"
33
34namespace orxonox {
35
36  CreateFactory(NPC);
37
38  NPC::NPC() :
39    movable_(true)
40  {
41    RegisterObject(NPC);
42    registerAllVariables();
43  }
44
45  NPC::~NPC()
46  {
47  }
48
49  void NPC::loadParams(TiXmlElement* xmlElem)
50  {
51    Model::loadParams(xmlElem);
52  }
53
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  }
63 
64  void NPC::registerAllVariables(){
65    Model::registerAllVariables();
66    registerVar(&movable_, sizeof(movable_), network::DATA);
67  }
68 
69
70  /**
71   * calculates the distance between the element and an other point given by temp
72   */
73  float NPC::getDistance(WorldEntity* temp)
74  {
75    Vector3 distance = temp->getPosition() - this->getPosition();
76    return distance.length();
77  }
78
79  /**
80   * updates the data of an element
81   */
82  void NPC::update()
83  {
84
85    //if element is movable, calculate acceleration
86    if (this->movable_ == true) calculateAcceleration();
87
88  }
89
90  /**
91   * tick this NPC
92   */
93  void NPC::tick(float dt)
94  {
95    update();
96    this->setVelocity(0.995*this->getVelocity() + this->getAcceleration()*dt);
97    this->translate(this->getVelocity()*dt);
98    this->setAcceleration(Vector3(0,0,0));
99  }
100
101  /**
102   * calculates the new acceleration of an element
103   */
104  void NPC::calculateAcceleration()
105  {
106    //acceleration consisting of flocking-functions
107    this->setAcceleration(separation() + alignment() + cohesion());
108  }
109
110  /**
111   * separation-function (keep elements separated, avoid crashs)
112   */
113  Vector3 NPC::separation()
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
119    for(Iterator<WorldEntity> it = ObjectList<WorldEntity>::start(); it; ++it) {  //go through all elements
120      distance = getDistance(*it);  //get distance between this and actual
121      if ((distance > 0) && (distance < SEPERATIONDISTANCE)) {  //do only if actual is inside detectionradius
122        inverseDistance = Vector3(0,0,0);
123        inverseDistance = this->getPosition() - it->getPosition();  //calculate the distancevector heading towards this
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   */
140  Vector3 NPC::alignment()
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
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
148      if ((distance > 0) && (distance < ALIGNMENTDISTANCE)) {  //check if actual element is inside detectionradius
149        steering = steering + it->getVelocity();  //add up all speedvectors inside the detectionradius
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   */
160  Vector3 NPC::cohesion()
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
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
168      if ((distance > 0) && (distance < COHESIONDISTANCE)) {  //check if actual element is inside detectionradius
169        steering = steering + it->getPosition();  //add up all locations of elements inside the detectionradius
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.