Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fixed a memory leak, added documentation

File size: 5.8 KB
RevLine 
[212]1
[495]2//Headerfile: Flocking.h
[212]3
4#ifndef Flocking_Class
5#define Flocking_Class
6
7#include <Ogre.h>
8#include <OgreVector3.h>
9
[426]10
[325]11#include <iostream>
[212]12
[325]13
[212]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
[495]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
[212]30
[495]31  //default constructor
[325]32  Element() {
33    acceleration = (0,0,0);
34    speed = (0,0,0);
35    location = (0,0,0);
[426]36    movable = true;
[325]37  }
[212]38
[495]39  //constructor
[426]40  Element(Vector3 location_, Vector3 speed_, Vector3 acceleration_, bool movable_) {
[212]41    acceleration = acceleration_;
42    speed = speed_;
43    location = location_;
[426]44    movable = movable_;
[212]45  }
46
[495]47  //function to chance values of an element
[426]48  void setValues(Vector3 location_, Vector3 speed_, Vector3 acceleration_, bool movable_) {
[325]49    acceleration = acceleration_;
50    speed = speed_;
51    location = location_;
[426]52    movable = movable_;
[325]53  }
54
[212]55  //calculates the distance between the element and an other point given by temp
56  float getDistance(Element temp) {
[495]57    Vector3 distance = temp.location-location;
[212]58    return distance.length();
59  }
60
[495]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
[212]64  }
65
[495]66  //calculates the new acceleration of an element
[325]67  void calculateAcceleration(Element arrayOfElements[]) {
[495]68    acceleration = separation(arrayOfElements) + alignment(arrayOfElements) + cohesion(arrayOfElements);  //acceleration consisting of flocking-functions
[212]69  }
70
[495]71  //separation-function (keep elements separated, avoid crashs)
[325]72  Vector3 separation(Element arrayOfElements[]) {
[495]73    Vector3 steering = Vector3(0,0,0); //steeringvector
74    Vector3 inverseDistance = Vector3(0,0,0);  //vector pointing away from possible collisions
[325]75    int numberOfNeighbour = 0;  //number of observed neighbours
[495]76    float distance = 0;  // distance to the actual element
77    for(int i=0; i<ANZELEMENTS; i++) {  //go through all elements
[212]78      Element actual = arrayOfElements[i];  //get the actual element
[426]79      distance = getDistance(actual);  //get distance between this and actual
[495]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
[212]89        numberOfNeighbour++;  //counts the elements inside the detectionradius
90      }
91    }
[495]92    if(numberOfNeighbour > 0) { steering = steering / (float)numberOfNeighbour; }  //devide the sum of steeringvectors by the number of elements -> separation steeringvector
93    return steering;
[212]94  }
95
[495]96  //alignment-function (lead elements to the same heading)
[325]97  Vector3 alignment(Element arrayOfElements[]) {
[495]98    Vector3 steering = Vector3(0,0,0); //steeringvector
[325]99    int numberOfNeighbour = 0;  //number of observed neighbours
[426]100    float distance = 0;
[212]101    //go through all elements
[495]102    for(int i=0; i<ANZELEMENTS; i++) {  //just working with 3 elements at the moment
[212]103      Element actual = arrayOfElements[i];  //get the actual element
[233]104      float distance = getDistance(actual);  //get distance between this and actual
[495]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
[212]107        numberOfNeighbour++;  //counts the elements inside the detectionradius
108      }
109    }
[495]110    if(numberOfNeighbour > 0) { steering = steering / (float)numberOfNeighbour; }  //devide the sum of steeringvectors by the number of elements -> alignment steeringvector
111    return steering;
[212]112  }
113
[495]114  //cohseion-function (keep elements close to each other)
[325]115  Vector3 cohesion(Element arrayOfElements[]) {
[495]116    Vector3 steering = Vector3(0,0,0); //steeringvector
[325]117    int numberOfNeighbour = 0;  //number of observed neighbours
[426]118    float distance = 0;
[212]119    //go through all elements
[495]120    for(int i=0; i<ANZELEMENTS; i++) {  //just working with 3 elements at the moment
[212]121      Element actual = arrayOfElements[i];  //get the actual element
[233]122      float distance = getDistance(actual);  //get distance between this and actual
[495]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
[212]125        numberOfNeighbour++;  //counts the elements inside the detectionradius
126      }
[495]127    }
[212]128    if(numberOfNeighbour > 0) {
[495]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
[212]131    }
[495]132    return steering;
[212]133  }
[495]134};     //End of class Element
Note: See TracBrowser for help on using the repository browser.