Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/Flocking.h @ 674

Last change on this file since 674 was 673, checked in by rgrieder, 17 years ago
  • deleted obsolete classes: BaseEntity, Entity, Light and SceneNode (please complain if not agreed)
  • improved include guard naming consistency
File size: 6.4 KB
Line 
1
2//Headerfile: Flocking.h
3
4#ifndef _Flocking_H__
5#define _Flocking_H__
6
7// #include <Ogre.h>
8#include <OgreVector3.h>
9
10
11#include <iostream>
12
13
14
15class Element // An element that flocks
16{
17
18  public:
19    Ogre::Vector3 location;                       //!< locationvector of the element
20    Ogre::Vector3 speed;                          //!< speedvector of the element
21    Ogre::Vector3 acceleration;                   //!< accelerationvector of the element
22    bool movable;                                 //!< movability of the element, (false) gives the possiblity that an object can`t be moved by flocking but still gets into the calculation
23    static int const SEPERATIONDISTANCE = 300;    //!< detectionradius of seperation
24    static int const ALIGNMENTDISTANCE = 300;     //!< detectionradius of alignment
25    static int const COHESIONDISTANCE = 5000;     //!< detectionradius of cohesion
26    static int const ANZELEMENTS = 9;             //!< number of elements
27
28  //! default constructor
29  Element() {
30    acceleration = Ogre::Vector3(0,0,0);
31    speed = Ogre::Vector3(0,0,0);
32    location = Ogre::Vector3(0,0,0);
33    movable = true;
34  }
35
36  /** constructor
37   *  @param location_ sets locationvector of the element
38   *  @param speed_ sets speedvector of the element
39   *  @param acceleration_ sets accelerationvector of the element
40   *  @param movable_ sets movability of the element
41   */
42  Element(Ogre::Vector3 location_, Ogre::Vector3 speed_, Ogre::Vector3 acceleration_, bool movable_) {
43    acceleration = acceleration_;
44    speed = speed_;
45    location = location_;
46    movable = movable_;
47  }
48
49  //! function to chance values of an element
50  void setValues(Ogre::Vector3 location_, Ogre::Vector3 speed_, Ogre::Vector3 acceleration_, bool movable_) {
51    acceleration = acceleration_;
52    speed = speed_;
53    location = location_;
54    movable = movable_;
55  }
56
57  /** calculates the distance between the element and an other point given by temp
58   * @param e remote object to calculate distance to
59   */
60  float getDistance(Element e) {
61    Ogre::Vector3 distance = e.location - location;
62    return distance.length();
63  }
64
65  //! updates the data of an element
66  void update(Element arrayOfElements[]) {
67    if (this->movable == true) {calculateAcceleration(arrayOfElements);} //if element is movable, calculate acceleration
68  }
69
70  //! calculates the new acceleration of an element
71  void calculateAcceleration(Element arrayOfElements[]) {
72    acceleration = separation(arrayOfElements) + alignment(arrayOfElements) + cohesion(arrayOfElements);  //acceleration consisting of flocking-functions
73  }
74
75  //! separation-function (keep elements separated, avoid crashs)
76  Ogre::Vector3 separation(Element arrayOfElements[]) {
77    using namespace Ogre;
78    Vector3 steering = Vector3(0,0,0); //steeringvector
79    Vector3 inverseDistance = Vector3(0,0,0);  //vector pointing away from possible collisions
80    int numberOfNeighbour = 0;  //number of observed neighbours
81    float distance = 0;  // distance to the actual element
82    for(int i=0; i<ANZELEMENTS; i++) {  //go through all elements
83      Element actual = arrayOfElements[i];  //get the actual element
84      distance = getDistance(actual);  //get distance between this and actual
85      if ((distance > 0) && (distance < SEPERATIONDISTANCE)) {  //do only if actual is inside detectionradius
86        inverseDistance = (0,0,0);
87        inverseDistance = location-actual.location;  //calculate the distancevector heading towards this
88        //adaptation of the inverseDistance to the distance
89        if ((distance < 200) && (distance >= 120)) {inverseDistance = 2*inverseDistance;}
90        if ((distance < 120) && (distance >= 80)) {inverseDistance = 5*inverseDistance;}
91        if ((distance < 80) && (distance >= 40)) {inverseDistance = 10*inverseDistance;}
92        if ((distance < 40) && (distance > 0)) {inverseDistance = 10*inverseDistance;}
93        steering = steering + inverseDistance;  //add up all significant steeringvectors
94        numberOfNeighbour++;  //counts the elements inside the detectionradius
95      }
96    }
97    if(numberOfNeighbour > 0) { steering = steering / (float)numberOfNeighbour; }  //devide the sum of steeringvectors by the number of elements -> separation steeringvector
98    return steering;
99  }
100
101  //! alignment-function (lead elements to the same heading)
102  Ogre::Vector3 alignment(Element arrayOfElements[]) {
103    using namespace Ogre;
104    Vector3 steering = Vector3(0,0,0); //steeringvector
105    int numberOfNeighbour = 0;  //number of observed neighbours
106    float distance = 0;
107    //go through all elements
108    for(int i=0; i<ANZELEMENTS; i++) {  //just working with 3 elements at the moment
109      Element actual = arrayOfElements[i];  //get the actual element
110      float distance = getDistance(actual);  //get distance between this and actual
111      if ((distance > 0) && (distance < ALIGNMENTDISTANCE)) {  //check if actual element is inside detectionradius
112        steering = steering + actual.speed;  //add up all speedvectors inside the detectionradius
113        numberOfNeighbour++;  //counts the elements inside the detectionradius
114      }
115    }
116    if(numberOfNeighbour > 0) { steering = steering / (float)numberOfNeighbour; }  //devide the sum of steeringvectors by the number of elements -> alignment steeringvector
117    return steering;
118  }
119
120  //! cohseion-function (keep elements close to each other)
121  Ogre::Vector3 cohesion(Element arrayOfElements[]) {
122    using namespace Ogre;
123    Vector3 steering = Vector3(0,0,0); //steeringvector
124    int numberOfNeighbour = 0;  //number of observed neighbours
125    float distance = 0;
126    //go through all elements
127    for(int i=0; i<ANZELEMENTS; i++) {  //just working with 3 elements at the moment
128      Element actual = arrayOfElements[i];  //get the actual element
129      float distance = getDistance(actual);  //get distance between this and actual
130      if ((distance > 0) && (distance < COHESIONDISTANCE)) {  //check if actual element is inside detectionradius
131        steering = steering + actual.location;  //add up all locations of elements inside the detectionradius
132        numberOfNeighbour++;  //counts the elements inside the detectionradius
133      }
134    }
135    if(numberOfNeighbour > 0) {
136      steering = steering  / (float)numberOfNeighbour;  //devide the sum steeringvector by the number of elements -> cohesion steeringvector
137      steering = steering - this->location;  //transform the vector for the ship
138    }
139    return steering;
140  }
141};     //End of class Element
142
143#endif /* _Flocking_H__*/
Note: See TracBrowser for help on using the repository browser.