Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/AI/src/Flocking.h @ 1967

Last change on this file since 1967 was 495, checked in by motth, 17 years ago

fixed a memory leak, added documentation

File size: 5.8 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
16using namespace Ogre;
17
18class Element // An element that flocks
19{
20
21  public:
22    Vector3 location;  // locationvector of the element
23    Vector3 speed;  // speedvector of the element
24    Vector3 acceleration;  // accelerationvector of the element
25    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
26    static int const SEPERATIONDISTANCE = 300;  //detectionradius of seperation
27    static int const ALIGNMENTDISTANCE = 300;  //detectionradius of alignment
28    static int const COHESIONDISTANCE = 5000;  //detectionradius of cohesion
29    static int const ANZELEMENTS = 9;  //number of elements
30
31  //default constructor
32  Element() {
33    acceleration = (0,0,0);
34    speed = (0,0,0);
35    location = (0,0,0);
36    movable = true;
37  }
38
39  //constructor
40  Element(Vector3 location_, Vector3 speed_, Vector3 acceleration_, bool movable_) {
41    acceleration = acceleration_;
42    speed = speed_;
43    location = location_;
44    movable = movable_;
45  }
46
47  //function to chance values of an element
48  void setValues(Vector3 location_, Vector3 speed_, Vector3 acceleration_, bool movable_) {
49    acceleration = acceleration_;
50    speed = speed_;
51    location = location_;
52    movable = movable_;
53  }
54
55  //calculates the distance between the element and an other point given by temp
56  float getDistance(Element temp) {
57    Vector3 distance = temp.location-location;
58    return distance.length();
59  }
60
61  //updates the data of an element
62  void update(Element arrayOfElements[]) {
63    if (this->movable == true) {calculateAcceleration(arrayOfElements);} //if element is movable, calculate acceleration
64  }
65
66  //calculates the new acceleration of an element
67  void calculateAcceleration(Element arrayOfElements[]) {
68    acceleration = separation(arrayOfElements) + alignment(arrayOfElements) + cohesion(arrayOfElements);  //acceleration consisting of flocking-functions
69  }
70
71  //separation-function (keep elements separated, avoid crashs)
72  Vector3 separation(Element arrayOfElements[]) {
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  Vector3 alignment(Element arrayOfElements[]) {
98    Vector3 steering = Vector3(0,0,0); //steeringvector
99    int numberOfNeighbour = 0;  //number of observed neighbours
100    float distance = 0;
101    //go through all elements
102    for(int i=0; i<ANZELEMENTS; i++) {  //just working with 3 elements at the moment
103      Element actual = arrayOfElements[i];  //get the actual element
104      float distance = getDistance(actual);  //get distance between this and actual
105      if ((distance > 0) && (distance < ALIGNMENTDISTANCE)) {  //check if actual element is inside detectionradius
106        steering = steering + actual.speed;  //add up all speedvectors inside the detectionradius
107        numberOfNeighbour++;  //counts the elements inside the detectionradius
108      }
109    }
110    if(numberOfNeighbour > 0) { steering = steering / (float)numberOfNeighbour; }  //devide the sum of steeringvectors by the number of elements -> alignment steeringvector
111    return steering;
112  }
113
114  //cohseion-function (keep elements close to each other)
115  Vector3 cohesion(Element arrayOfElements[]) {
116    Vector3 steering = Vector3(0,0,0); //steeringvector
117    int numberOfNeighbour = 0;  //number of observed neighbours
118    float distance = 0;
119    //go through all elements
120    for(int i=0; i<ANZELEMENTS; i++) {  //just working with 3 elements at the moment
121      Element actual = arrayOfElements[i];  //get the actual element
122      float distance = getDistance(actual);  //get distance between this and actual
123      if ((distance > 0) && (distance < COHESIONDISTANCE)) {  //check if actual element is inside detectionradius
124        steering = steering + actual.location;  //add up all locations of elements inside the detectionradius
125        numberOfNeighbour++;  //counts the elements inside the detectionradius
126      }
127    }
128    if(numberOfNeighbour > 0) {
129      steering = steering  / (float)numberOfNeighbour;  //devide the sum steeringvector by the number of elements -> cohesion steeringvector
130      steering = steering - this->location;  //transform the vector for the ship
131    }
132    return steering;
133  }
134};     //End of class Element
Note: See TracBrowser for help on using the repository browser.