Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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