Panda3D
 All Classes Functions Variables Enumerations
aiBehaviors.cxx
1 ////////////////////////////////////////////////////////////////////////
2 // Filename : aiBehaviors.cxx
3 // Created by : Deepak, John, Navin
4 // Date : 8 Sep 09
5 ////////////////////////////////////////////////////////////////////
6 //
7 // PANDA 3D SOFTWARE
8 // Copyright (c) Carnegie Mellon University. All rights reserved.
9 //
10 // All use of this software is subject to the terms of the revised BSD
11 // license. You should have received a copy of this license along
12 // with this source code in a file named "LICENSE."
13 //
14 ////////////////////////////////////////////////////////////////////
15 
16 #include "aiBehaviors.h"
17 
18 static const float _PI = 3.14;
19 
20 AIBehaviors::AIBehaviors() {
21  _steering_force = LVecBase3(0.0, 0.0, 0.0);
22  _behaviors_flags = _behaviors_flags & _none;
23  _previous_conflict = false;
24  _conflict = false;
25 
26  _seek_obj = NULL;
27  _flee_obj = NULL;
28  _pursue_obj = NULL;
29  _evade_obj = NULL;
30  _arrival_obj = NULL;
31  _wander_obj = NULL;
32  _flock_group = NULL;
33  _path_follow_obj = NULL;
34  _path_find_obj = NULL;
35  _obstacle_avoidance_obj = NULL;
36 
37  turn_off("seek");
38  turn_off("flee");
39  turn_off("pursue");
40  turn_off("evade");
41  turn_off("arrival");
42  turn_off("flock");
43  turn_off("wander");
44  turn_off("obstacle_avoidance");
45 }
46 
47 AIBehaviors::~AIBehaviors() {
48 
49 }
50 
51 /////////////////////////////////////////////////////////////////////////////////
52 //
53 // Function : is_conflict
54 // Description : Checks for conflict between steering forces.
55 // If there is a conflict it returns 'true' and sets _conflict to 'true'.
56 // If there is no conflict it returns 'false' and sets _conflict to 'false'.
57 
58 /////////////////////////////////////////////////////////////////////////////////
59 
61  int value = int(is_on(_seek)) + int(is_on(_flee)) + int(is_on(_pursue)) + int(is_on(_evade)) + int(is_on(_wander)) + int(is_on(_flock))+ int(is_on(_obstacle_avoidance));
62 
63  if(value > 1) {
64  if(_previous_conflict == false) {
65  if(is_on(_seek)) {
66  _seek_force *= _seek_obj->_seek_weight;
67  }
68 
69  if(is_on(_flee)) {
70  LVecBase3 dirn = _flee_force;
71  dirn.normalize();
72  _flee_force = _steering_force.length() * dirn * _flee_obj->_flee_weight;
73  }
74 
75  if(is_on(_pursue)) {
76  _pursue_force *= _pursue_obj->_pursue_weight;
77  }
78 
79  if(is_on(_evade)) {
80  LVecBase3 dirn = _evade_force;
81  dirn.normalize();
82  _evade_force = _steering_force.length() * dirn * _evade_obj->_evade_weight;
83  }
84 
85  if(is_on(_flock)) {
86  _flock_force *= _flock_weight;
87  }
88 
89  if(is_on(_wander)) {
90  _wander_force *= _wander_obj->_wander_weight;
91  }
92 
93  _previous_conflict = true;
94  }
95 
96  _conflict = true;
97  return true;
98  }
99 
100  _conflict = false;
101  _previous_conflict = false;
102  return false;
103 }
104 
105 /////////////////////////////////////////////////////////////////////////////////////////////////////
106 //
107 // Function : accumulate_force
108 // Description : This function updates the individual steering forces for each of the ai characters.
109 // These accumulated forces are eventually what comprise the resultant
110 // steering force of the character.
111 
112 /////////////////////////////////////////////////////////////////////////////////////////////////////
113 
114 void AIBehaviors::accumulate_force(string force_type, LVecBase3 force) {
115 
116  LVecBase3 old_force;
117 
118  if(force_type == "seek") {
119  old_force = _seek_force;
120  _seek_force = old_force + force;
121  }
122 
123  if(force_type == "flee") {
124  old_force = _flee_force;
125  _flee_force = old_force + force;
126  }
127 
128  if(force_type == "pursue") {
129  old_force = _pursue_force;
130  double new_force = old_force.length() + force.length();
131  _pursue_force = new_force * _pursue_obj->_pursue_direction;
132  }
133 
134  if(force_type == "evade") {
135  old_force = _evade_force;
136  double new_force = old_force.length() + force.length();
137  force.normalize();
138  _evade_force = new_force * force;
139  }
140 
141  if(force_type == "arrival") {
142  _arrival_force = force;
143  }
144 
145  if(force_type == "flock") {
146  old_force = _flock_force;
147  _flock_force = old_force + force;
148  }
149 
150  if(force_type == "wander") {
151  old_force = _wander_force;
152  _wander_force = old_force + force;
153  }
154 
155  if(force_type == "obstacle_avoidance") {
156  old_force = _obstacle_avoidance_force;
157  _obstacle_avoidance_force = old_force +force;
158  }
159 
160 }
161 
162 //////////////////////////////////////////////////////////////////////////////////////////////
163 //
164 // Function : calculate_prioritized
165 // Description : This function updates the main steering force for the ai character using
166 // the accumulate function and checks for max force and arrival force.
167 // It finally returns this steering force which is accessed by the update
168 // function in the AICharacter class.
169 
170 //////////////////////////////////////////////////////////////////////////////////////////////
171 
173  LVecBase3 force;
174 
175  if(is_on(_seek)) {
176  if(_conflict) {
177  force = _seek_obj->do_seek() * _seek_obj->_seek_weight;
178  }
179  else {
180  force = _seek_obj->do_seek();
181  }
182  accumulate_force("seek",force);
183  }
184 
185  if(is_on(_flee_activate)) {
186  for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
187  _flee_itr->flee_activate();
188  }
189  }
190 
191  if(is_on(_flee)) {
192  for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
193  if(_flee_itr->_flee_activate_done) {
194  if(_conflict) {
195  force = _flee_itr->do_flee() * _flee_itr->_flee_weight;
196  }
197  else {
198  force = _flee_itr->do_flee();
199  }
200  accumulate_force("flee",force);
201  }
202  }
203  }
204 
205  if(is_on(_pursue)) {
206  if(_conflict) {
207  force = _pursue_obj->do_pursue() * _pursue_obj->_pursue_weight;
208  }
209  else {
210  force = _pursue_obj->do_pursue();
211  }
212  accumulate_force("pursue",force);
213  }
214 
215  if(is_on(_evade_activate)) {
216  for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
217  _evade_itr->evade_activate();
218  }
219  }
220 
221  if(is_on(_evade)) {
222  for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
223  if(_evade_itr->_evade_activate_done) {
224  if(_conflict) {
225  force = (_evade_itr->do_evade()) * (_evade_itr->_evade_weight);
226  }
227  else {
228  force = _evade_itr->do_evade();
229  }
230  accumulate_force("evade",force);
231  }
232  }
233  }
234 
235  if(is_on(_arrival_activate)) {
236  _arrival_obj->arrival_activate();
237  }
238 
239  if(is_on(_arrival)) {
240  force = _arrival_obj->do_arrival();
241  accumulate_force("arrival",force);
242  }
243 
244  if(is_on(_flock_activate)) {
245  flock_activate();
246  }
247 
248  if(is_on(_flock)) {
249  if(_conflict) {
250  force = do_flock() * _flock_weight;
251  }
252  else {
253  force = do_flock();
254  }
255  accumulate_force("flock",force);
256  }
257 
258  if(is_on(_wander)) {
259  if(_conflict) {
260  force = _wander_obj->do_wander() * _wander_obj->_wander_weight;
261  }
262  else {
263  force = _wander_obj->do_wander();
264  }
265  accumulate_force("wander", force);
266  }
267 
268  if(is_on(_obstacle_avoidance_activate)) {
269  _obstacle_avoidance_obj->obstacle_avoidance_activate();
270  }
271 
272  if(is_on(_obstacle_avoidance)) {
273  if(_conflict) {
274  force = _obstacle_avoidance_obj->do_obstacle_avoidance();
275  }
276  else {
277  force = _obstacle_avoidance_obj->do_obstacle_avoidance();
278  }
279  accumulate_force("obstacle_avoidance", force);
280  }
281 
282  if(_path_follow_obj!=NULL) {
283  if(_path_follow_obj->_start) {
284  _path_follow_obj->do_follow();
285  }
286  }
287 
288  is_conflict();
289 
290  _steering_force += _seek_force * int(is_on(_seek)) + _flee_force * int(is_on(_flee)) +
291  _pursue_force * int(is_on(_pursue)) + _evade_force * int(is_on(_evade)) +
292  _flock_force * int(is_on(_flock)) + _wander_force * int(is_on(_wander)) +
293  _obstacle_avoidance_force * int(is_on(_obstacle_avoidance));
294 
295  if(_steering_force.length() > _ai_char->get_max_force()) {
296  _steering_force.normalize();
297  _steering_force = _steering_force * _ai_char->get_max_force();
298  }
299 
300  if(is_on(_arrival)) {
301  if(_seek_obj != NULL) {
302  LVecBase3 dirn = _steering_force;
303  dirn.normalize();
304  _steering_force = ((_steering_force.length() - _arrival_force.length()) * dirn);
305  }
306 
307  if(_pursue_obj != NULL) {
308  LVecBase3 dirn = _steering_force;
309  dirn.normalize();
310  _steering_force = ((_steering_force.length() - _arrival_force.length()) * _arrival_obj->_arrival_direction);
311  }
312  }
313  return _steering_force;
314 }
315 
316 /////////////////////////////////////////////////////////////////////////////////
317 //
318 // Function : remove_ai
319 // Description : This function removes individual or all the AIs.
320 
321 /////////////////////////////////////////////////////////////////////////////////
322 
323 //add for path follow
324 void AIBehaviors::remove_ai(string ai_type) {
325  switch(char_to_int(ai_type)) {
326  case 0: {
327  remove_ai("seek");
328  remove_ai("flee");
329  remove_ai("pursue");
330  remove_ai("evade");
331  remove_ai("arrival");
332  remove_ai("flock");
333  remove_ai("wander");
334  remove_ai("obstacle_avoidance");
335  remove_ai("pathfollow");
336  break;
337  }
338 
339  case 1: {
340  if(_seek_obj != NULL) {
341  turn_off("seek");
342  delete _seek_obj;
343  _seek_obj = NULL;
344  }
345  break;
346  }
347 
348  case 2: {
349  while (!_flee_list.empty()) {
350  turn_off("flee");
351  turn_off("flee_activate");
352  _flee_list.pop_front();
353  }
354  break;
355  }
356 
357  case 3: {
358  if(_pursue_obj != NULL) {
359  turn_off("pursue");
360  delete _pursue_obj;
361  _pursue_obj = NULL;
362  }
363  break;
364  }
365 
366  case 4: {
367  while (!_evade_list.empty()) {
368  turn_off("evade");
369  turn_off("evade_activate");
370  _evade_list.pop_front();
371  }
372  break;
373  }
374 
375  case 5: {
376  if(_arrival_obj != NULL) {
377  turn_off("arrival");
378  turn_off("arrival_activate");
379  delete _arrival_obj;
380  _arrival_obj = NULL;
381  }
382  break;
383  }
384 
385  case 6: {
386  if(_flock_group != NULL) {
387  turn_off("flock");
388  turn_off("flock_activate");
389  _flock_group = NULL;
390  }
391  break;
392  }
393 
394  case 7: {
395  if(_wander_obj != NULL) {
396  turn_off("wander");
397  delete _wander_obj;
398  _wander_obj = NULL;
399  }
400  break;
401  }
402 
403  case 8: {
404  if(_obstacle_avoidance_obj !=NULL) {
405  turn_off("obstacle_avoidance");
406  delete _obstacle_avoidance_obj;
407  _obstacle_avoidance_obj = NULL;
408  }
409  break;
410  }
411 
412  case 9: {
413  if(_pursue_obj != NULL && _path_follow_obj != NULL) {
414  turn_off("pursue");
415  delete _pursue_obj;
416  _pursue_obj = NULL;
417  delete _path_follow_obj;
418  _path_follow_obj = NULL;
419  }
420  break;
421  }
422  case 16: {
423  if(_pursue_obj != NULL && _path_follow_obj != NULL) {
424  turn_off("pursue");
425  delete _pursue_obj;
426  _pursue_obj = NULL;
427  delete _path_follow_obj;
428  _path_follow_obj = NULL;
429  }
430  break;
431  }
432  default:
433  cout<<"Invalid option!"<<endl;
434  }
435 }
436 
437 /////////////////////////////////////////////////////////////////////////////////
438 //
439 // Function : pause_ai
440 // Description : This function pauses individual or all the AIs.
441 
442 /////////////////////////////////////////////////////////////////////////////////
443 
444 //add for path follow
445 void AIBehaviors::pause_ai(string ai_type) {
446  switch(char_to_int(ai_type)) {
447  case 0: {
448  pause_ai("seek");
449  pause_ai("flee");
450  pause_ai("pursue");
451  pause_ai("evade");
452  pause_ai("arrival");
453  pause_ai("flock");
454  pause_ai("wander");
455  pause_ai("obstacle_avoidance");
456  pause_ai("pathfollow");
457  break;
458  }
459 
460  case 1: {
461  if(_seek_obj != NULL) {
462  turn_off("seek");
463  }
464  break;
465  }
466 
467  case 2: {
468  for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
469  turn_off("flee");
470  turn_off("flee_activate");
471  }
472  break;
473  }
474 
475  case 3: {
476  if(_pursue_obj != NULL) {
477  turn_off("pursue");
478  }
479  break;
480  }
481 
482  case 4: {
483  for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
484  turn_off("evade");
485  turn_off("evade_activate");
486  }
487  break;
488  }
489 
490  case 5: {
491  if(_arrival_obj != NULL) {
492  turn_off("arrival");
493  turn_off("arrival_activate");
494  }
495  break;
496  }
497 
498  case 6: {
499  if(_flock_group != NULL) {
500  turn_off("flock");
501  turn_off("flock_activate");
502  }
503  break;
504  }
505 
506  case 7: {
507  if(_wander_obj != NULL) {
508  turn_off("wander");
509  }
510  break;
511  }
512 
513  case 8: {
514  if(_obstacle_avoidance_obj != NULL) {
515  turn_off("obstacle_avoidance");
516  turn_off("obstacle_avoidance_activate");
517  }
518  break;
519  }
520 
521  case 9: {
522  if(_pursue_obj != NULL && _path_follow_obj != NULL) {
523  turn_off("pursue");
524  _path_follow_obj->_start = false;
525  }
526  break;
527  }
528  case 16: {
529  if(_pursue_obj != NULL && _path_follow_obj != NULL) {
530  turn_off("pursue");
531  _path_follow_obj->_start = false;
532  }
533  break;
534  }
535  default:
536  cout<<"Invalid option!"<<endl;
537  }
538 }
539 
540 /////////////////////////////////////////////////////////////////////////////////
541 //
542 // Function : resume_ai
543 // Description : This function resumes individual or all the AIs
544 
545 /////////////////////////////////////////////////////////////////////////////////
546 
547 void AIBehaviors::resume_ai(string ai_type) {
548  switch(char_to_int(ai_type)) {
549  case 0: {
550  resume_ai("seek");
551  resume_ai("flee");
552  resume_ai("pursue");
553  resume_ai("evade");
554  resume_ai("arrival");
555  resume_ai("flock");
556  resume_ai("wander");
557  resume_ai("obstacle_avoidance");
558  resume_ai("pathfollow");
559  break;
560  }
561 
562  case 1: {
563  if(_seek_obj != NULL) {
564  turn_on("seek");
565  }
566  break;
567  }
568 
569  case 2: {
570  for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
571  turn_on("flee");
572  }
573  break;
574  }
575 
576  case 3: {
577  if(_pursue_obj != NULL) {
578  turn_on("pursue");
579  }
580  break;
581  }
582 
583  case 4: {
584  for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
585  turn_on("evade");
586  }
587  break;
588  }
589 
590  case 5: {
591  if(_arrival_obj != NULL) {
592  turn_on("arrival");
593  }
594  break;
595  }
596 
597  case 6: {
598  if(_flock_group != NULL) {
599  turn_on("flock");
600  }
601  break;
602  }
603 
604  case 7: {
605  if(_wander_obj != NULL) {
606  turn_on("wander");
607  }
608  break;
609  }
610 
611  case 8: {
612  if(_obstacle_avoidance_obj != NULL) {
613  turn_on("obstacle_avoidance");
614  }
615  break;
616  }
617 
618  case 9: {
619  if(_pursue_obj != NULL && _path_follow_obj != NULL) {
620  turn_on("pursue");
621  _path_follow_obj->_start = true;
622  }
623  break;
624  }
625  case 16: {
626  if(_pursue_obj != NULL && _path_follow_obj != NULL) {
627  turn_off("pursue");
628  _path_follow_obj->_start = false;
629  }
630  break;
631  }
632  default:
633  cout<<"Invalid option!"<<endl;
634  }
635 }
636 
637 /////////////////////////////////////////////////////////////////////////////////
638 //
639 // Function : seek
640 // Description : This function activates seek and makes an object of the Seek class.
641 // This is the function we want the user to call for seek to be done.
642 // This function is overloaded to accept a NodePath or an LVecBase3.
643 
644 /////////////////////////////////////////////////////////////////////////////////
645 
646 void AIBehaviors::seek(NodePath target_object, float seek_wt) {
647  _seek_obj = new Seek(_ai_char, target_object, seek_wt);
648  turn_on("seek");
649 }
650 
651 void AIBehaviors::seek(LVecBase3 pos, float seek_wt) {
652  _seek_obj = new Seek(_ai_char, pos, seek_wt);
653  turn_on("seek");
654 }
655 
656 //////////////////////////////////////////////////////////////////////////////////////////////////
657 //
658 // Function : flee
659 // Description : This function activates flee_activate and creates an object of the Flee class.
660 // This function is overloaded to accept a NodePath or an LVecBase3.
661 
662 //////////////////////////////////////////////////////////////////////////////////////////////////
663 
664 void AIBehaviors::flee(NodePath target_object, double panic_distance, double relax_distance, float flee_wt) {
665  _flee_obj = new Flee(_ai_char, target_object, panic_distance, relax_distance, flee_wt);
666  _flee_list.insert(_flee_list.end(), *_flee_obj);
667 
668  turn_on("flee_activate");
669 }
670 
671 void AIBehaviors::flee(LVecBase3 pos, double panic_distance, double relax_distance, float flee_wt) {
672  _flee_obj = new Flee(_ai_char, pos, panic_distance, relax_distance, flee_wt);
673  _flee_list.insert(_flee_list.end(), *_flee_obj);
674 
675  turn_on("flee_activate");
676 }
677 
678 /////////////////////////////////////////////////////////////////////////////////
679 //
680 // Function : pursue
681 // Description : This function activates pursue.
682 // This is the function we want the user to call for pursue to be done.
683 
684 /////////////////////////////////////////////////////////////////////////////////
685 
686 void AIBehaviors::pursue(NodePath target_object, float pursue_wt) {
687  _pursue_obj = new Pursue(_ai_char, target_object, pursue_wt);
688 
689  turn_on("pursue");
690 }
691 
692 /////////////////////////////////////////////////////////////////////////////////
693 //
694 // Function : evade
695 // Description : This function activates evade_activate.
696 
697 /////////////////////////////////////////////////////////////////////////////////
698 
699 void AIBehaviors::evade(NodePath target_object, double panic_distance, double relax_distance, float evade_wt) {
700  _evade_obj = new Evade(_ai_char, target_object, panic_distance, relax_distance, evade_wt);
701  _evade_list.insert(_evade_list.end(), *_evade_obj);
702 
703  turn_on("evade_activate");
704 }
705 
706 /////////////////////////////////////////////////////////////////////////////////
707 //
708 // Function : arrival
709 // Description : This function activates arrival.
710 // This is the function we want the user to call for arrival to be done.
711 
712 /////////////////////////////////////////////////////////////////////////////////
713 
714 void AIBehaviors::arrival(double distance) {
715  if(_pursue_obj) {
716  _arrival_obj = new Arrival(_ai_char, distance);
717  _arrival_obj->_arrival_type = true;
718  turn_on("arrival_activate");
719  }
720  else if(_seek_obj) {
721  _arrival_obj = new Arrival(_ai_char, distance);
722  _arrival_obj->_arrival_type = false;
723  turn_on("arrival_activate");
724  }
725  else {
726  cout<<"Note: A Seek or Pursue behavior is required to use Arrival behavior."<<endl;
727  }
728 }
729 
730 /////////////////////////////////////////////////////////////////////////////////
731 //
732 // Function : flock
733 // Description : This function activates flock.
734 // This is the function we want the user to call for flock to be done.
735 
736 /////////////////////////////////////////////////////////////////////////////////
737 
738 void AIBehaviors::flock(float flock_wt) {
739  _flock_weight = flock_wt;
740 
741  _flock_done = false;
742  turn_on("flock_activate");
743 }
744 
745 /////////////////////////////////////////////////////////////////////////////////
746 //
747 // Function : flock_activate
748 // Description : This function checks whether any other behavior exists to work with flock.
749 // When this is true, it calls the do_flock function.
750 
751 /////////////////////////////////////////////////////////////////////////////////
752 
754  if(is_on(_seek) || is_on(_flee) || is_on(_pursue) || is_on(_evade) || is_on(_wander)) {
755  turn_off("flock_activate");
756  turn_on("flock");
757  }
758 }
759 
760 /////////////////////////////////////////////////////////////////////////////////
761 //
762 // Function : do_flock
763 // Description : This function contains the logic for flocking behavior. This is
764 // an emergent behavior and is obtained by combining three other
765 // behaviors which are separation, cohesion and alignment based on
766 // Craig Reynold's algorithm. Also, this behavior does not work by
767 // itself. It works only when combined with other steering behaviors
768 // such as wander, pursue, evade, seek and flee.
769 
770 /////////////////////////////////////////////////////////////////////////////////
771 
773 
774  //! Initialize variables required to compute the flocking force on the ai char.
775  unsigned int neighbor_count = 0;
776  LVecBase3 separation_force = LVecBase3(0.0, 0.0, 0.0);
777  LVecBase3 alignment_force = LVecBase3(0.0, 0.0, 0.0);
778  LVecBase3 cohesion_force = LVecBase3(0.0, 0.0, 0.0);
779  LVecBase3 avg_neighbor_heading = LVecBase3(0.0, 0.0, 0.0);
780  LVecBase3 total_neighbor_heading = LVecBase3(0.0, 0.0, 0.0);
781  LVecBase3 avg_center_of_mass = LVecBase3(0.0, 0.0, 0.0);
782  LVecBase3 total_center_of_mass = LVecBase3(0.0, 0.0, 0.0);
783 
784  //! Loop through all the other AI units in the flock to check if they are neigbours.
785  for(unsigned int i = 0; i < _flock_group->_ai_char_list.size(); i++) {
786  if(_flock_group->_ai_char_list[i]->_name != _ai_char->_name) {
787 
788  //! Using visibilty cone to detect neighbors.
789  LVecBase3 dist_vect = _flock_group->_ai_char_list[i]->_ai_char_np.get_pos() - _ai_char->_ai_char_np.get_pos();
790  LVecBase3 ai_char_heading = _ai_char->get_velocity();
791  ai_char_heading.normalize();
792 
793  //! Check if the current unit is a neighbor.
794  if(dist_vect.dot(ai_char_heading) > ((dist_vect.length()) * (ai_char_heading.length()) * cos(_flock_group->_flock_vcone_angle * (_PI / 180)))
795  && (dist_vect.length() < _flock_group->_flock_vcone_radius)) {
796  //! Separation force calculation.
797  LVecBase3 ai_char_to_units = _ai_char->_ai_char_np.get_pos() - _flock_group->_ai_char_list[i]->_ai_char_np.get_pos();
798  float to_units_dist = ai_char_to_units.length();
799  ai_char_to_units.normalize();
800  separation_force += (ai_char_to_units / to_units_dist);
801 
802  //! Calculating the total heading and center of mass of all the neighbors.
803  LVecBase3 neighbor_heading = _flock_group->_ai_char_list[i]->get_velocity();
804  neighbor_heading.normalize();
805  total_neighbor_heading += neighbor_heading;
806  total_center_of_mass += _flock_group->_ai_char_list[i]->_ai_char_np.get_pos();
807 
808  //! Update the neighbor count.
809  ++neighbor_count;
810  }
811  }
812  }
813 
814  if(neighbor_count > 0) {
815  //! Alignment force calculation
816  avg_neighbor_heading = total_neighbor_heading / neighbor_count;
817  LVector3 ai_char_heading = _ai_char->get_velocity();
818  ai_char_heading.normalize();
819  avg_neighbor_heading -= ai_char_heading;
820  avg_neighbor_heading.normalize();
821  alignment_force = avg_neighbor_heading;
822 
823  //! Cohesion force calculation
824  avg_center_of_mass = total_center_of_mass / neighbor_count;
825  LVecBase3 cohesion_dir = avg_center_of_mass - _ai_char->_ai_char_np.get_pos();
826  cohesion_dir.normalize();
827  cohesion_force = cohesion_dir * _ai_char->_movt_force;
828  }
829  else if(is_on(_seek) || is_on(_flee) || is_on(_pursue) || is_on(_evade) || is_on(_wander)) {
830  _flock_done = true;
831  turn_off("flock");
832  turn_on("flock_activate");
833  return(LVecBase3(0.0, 0.0, 0.0));
834  }
835 
836  //! Calculate the resultant force on the ai character by taking into account the separation, alignment and cohesion
837  //! forces along with their corresponding weights.
838  return (separation_force * _flock_group->_separation_wt + avg_neighbor_heading * _flock_group->_alignment_wt
839  + cohesion_force * _flock_group->_cohesion_wt);
840 }
841 
842 /////////////////////////////////////////////////////////////////////////////////
843 //
844 // Function : wander
845 // Description : This function activates wander.
846 // This is the function we want the user to call for flock to be done.
847 
848 /////////////////////////////////////////////////////////////////////////////////
849 
850 void AIBehaviors::wander(double wander_radius, int flag, double aoe, float wander_weight) {
851  _wander_obj = new Wander(_ai_char, wander_radius, flag, aoe, wander_weight);
852  turn_on("wander");
853 }
854 
855 /////////////////////////////////////////////////////////////////////////////////
856 //
857 // Function : obstacle avoidance
858 // Description : This function activates obstacle avoidance for a given character.
859 // This is the function we want the user to call for
860 // obstacle avoidance to be performed.
861 
862 /////////////////////////////////////////////////////////////////////////////////
863 
864 void AIBehaviors::obstacle_avoidance(float obstacle_avoidance_weight) {
865  _obstacle_avoidance_obj = new ObstacleAvoidance(_ai_char, obstacle_avoidance_weight);
866  turn_on("obstacle_avoidance_activate");
867 }
868 
869 /////////////////////////////////////////////////////////////////////////////////
870 //
871 // Function : path_follow
872 // Description : This function activates path following.
873 // This is the function we want the user to call for path following.
874 
875 /////////////////////////////////////////////////////////////////////////////////
876 
877 void AIBehaviors::path_follow(float follow_wt) {
878  _path_follow_obj = new PathFollow(_ai_char, follow_wt);
879 }
880 
881 /////////////////////////////////////////////////////////////////////////////////
882 //
883 // Function : add_to_path
884 // Description : This function adds positions to the path to follow.
885 
886 /////////////////////////////////////////////////////////////////////////////////
887 
889  _path_follow_obj->add_to_path(pos);
890 }
891 
892 /////////////////////////////////////////////////////////////////////////////////
893 //
894 // Function : start_follow
895 // Description : This function starts the path follower.
896 
897 /////////////////////////////////////////////////////////////////////////////////
898 
899 void AIBehaviors::start_follow(string type) {
900  _path_follow_obj->start(type);
901 }
902 
903 /////////////////////////////////////////////////////////////////////////////////
904 //
905 // Function : init_path_find
906 // Description : This function activates path finding in the character.
907 // This function accepts the meshdata in .csv format.
908 //
909 
910 /////////////////////////////////////////////////////////////////////////////////
911 
912 void AIBehaviors::init_path_find(const char* navmesh_filename) {
913  _path_find_obj = new PathFind(_ai_char);
914  _path_find_obj->set_path_find(navmesh_filename);
915 }
916 
917 ///////////////////////////////////////////////////////////////////////////////////////
918 //
919 // Function : path_find_to (for pathfinding towards a static position)
920 // Description : This function checks for the source and target in the navigation mesh
921 // for its availability and then finds the best path via the A* algorithm
922 // Then it calls the path follower to make the object follow the path.
923 
924 ///////////////////////////////////////////////////////////////////////////////////////
925 
926 void AIBehaviors::path_find_to(LVecBase3 pos, string type) {
927  _path_find_obj->path_find(pos, type);
928 }
929 
930 ///////////////////////////////////////////////////////////////////////////////////////
931 //
932 // Function : path_find_to (for pathfinding towards a moving target (a NodePath))
933 // Description : This function checks for the source and target in the navigation mesh
934 // for its availability and then finds the best path via the A* algorithm
935 // Then it calls the path follower to make the object follow the path.
936 
937 ///////////////////////////////////////////////////////////////////////////////////////
938 
939 void AIBehaviors::path_find_to(NodePath target, string type) {
940  _path_find_obj->path_find(target, type);
941 }
942 
943 ///////////////////////////////////////////////////////////////////////////////////////
944 //
945 // Function : add_static_obstacle
946 // Description : This function allows the user to dynamically add obstacles to the
947 // game environment. The function will update the nodes within the
948 // bounding volume of the obstacle as non-traversable. Hence will not be
949 // considered by the pathfinding algorithm.
950 
951 ///////////////////////////////////////////////////////////////////////////////////////
952 
954  _path_find_obj->add_obstacle_to_mesh(obstacle);
955 }
956 
957 ///////////////////////////////////////////////////////////////////////////////////////
958 //
959 // Function : add_dynamic_obstacle
960 // Description : This function starts the pathfinding obstacle navigation for the
961 // passed in obstacle.
962 
963 ///////////////////////////////////////////////////////////////////////////////////////
964 
966  _path_find_obj->dynamic_avoid(obstacle);
967 }
968 
969 ///////////////////////////////////////////////////////////////////////////////////////
970 //
971 // Function : behavior_status
972 // Description : This function returns the status of an AI Type whether it is active,
973 // paused or disabled. It returns -1 if an invalid string is passed.
974 
975 ///////////////////////////////////////////////////////////////////////////////////////
976 
977 string AIBehaviors::behavior_status(string ai_type) {
978  switch(char_to_int(ai_type)) {
979  case 1:
980  if(_seek_obj) {
981  if(is_on(_seek)) {
982  return "active";
983  }
984  else {
985  if(_seek_obj->_seek_done) {
986  return "done";
987  }
988  return "paused";
989  }
990  }
991  else {
992  return "disabled";
993  }
994  break;
995 
996  case 2:
997  if(_flee_obj) {
998  if(is_on(_flee)) {
999  unsigned int i = 0;
1000  for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
1001  if(_flee_itr->_flee_done == true) {
1002  ++i;
1003  }
1004  }
1005  if(i == _flee_list.size()) {
1006  return "done";
1007  }
1008  else {
1009  return "active";
1010  }
1011  }
1012  else {
1013  return "paused";
1014  }
1015  }
1016  else {
1017  return "disabled";
1018  }
1019  break;
1020 
1021  case 3:
1022  if(_pursue_obj) {
1023  if(is_on(_pursue)) {
1024  if(_pursue_obj->_pursue_done) {
1025  return "done";
1026  }
1027  else {
1028  return "active";
1029  }
1030  }
1031  else {
1032  return "paused";
1033  }
1034  }
1035  else {
1036  return "disabled";
1037  }
1038  break;
1039 
1040  case 4:
1041  if(_evade_obj) {
1042  if(is_on(_evade)) {
1043  unsigned int i = 0;
1044  for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
1045  if(_evade_itr->_evade_done == true) {
1046  ++i;
1047  }
1048  }
1049  if(i == _evade_list.size()) {
1050  return "done";
1051  }
1052  else {
1053  return "active";
1054  }
1055  }
1056  else {
1057  return "paused";
1058  }
1059  }
1060  else {
1061  return "disabled";
1062  }
1063  break;
1064 
1065  case 5:
1066  if(_arrival_obj) {
1067  if(is_on(_arrival)) {
1068  if(_arrival_obj->_arrival_done) {
1069  return "done";
1070  }
1071  else {
1072  return "active";
1073  }
1074  }
1075  else {
1076  return "paused";
1077  }
1078  }
1079  else {
1080  return "disabled";
1081  }
1082  break;
1083 
1084  case 6:
1085  if(_flock_group) {
1086  if(is_on(_flock)) {
1087  if(_flock_done) {
1088  return "done";
1089  }
1090  else {
1091  return "active";
1092  }
1093  return "active";
1094  }
1095  else {
1096  return "paused";
1097  }
1098  }
1099  else {
1100  return "disabled";
1101  }
1102  break;
1103 
1104  case 7:
1105  if(_wander_obj) {
1106  if(is_on(_wander)) {
1107  return "active";
1108  }
1109  else {
1110  return "paused";
1111  }
1112  }
1113  else {
1114  return "disabled";
1115  }
1116  break;
1117 
1118  case 8:
1119  if(_obstacle_avoidance_obj) {
1120  if(is_on(_obstacle_avoidance)) {
1121  return "active";
1122  }
1123  else {
1124  return "paused";
1125  }
1126  }
1127  else {
1128  return "disabled";
1129  }
1130  break;
1131 
1132  case 9:
1133  if(_path_follow_obj) {
1134  if(is_on("pathfollow")) {
1135  if(_pursue_obj->_pursue_done) {
1136  return "done";
1137  }
1138  else {
1139  return "active";
1140  }
1141  }
1142  else {
1143  return "paused";
1144  }
1145  }
1146  else {
1147  return "disabled";
1148  }
1149  break;
1150 
1151  case 16:
1152  if(_path_find_obj) {
1153  if(is_on("pathfind")) {
1154  if(_pursue_obj->_pursue_done) {
1155  return "done";
1156  }
1157  else {
1158  return "active";
1159  }
1160  }
1161  else {
1162  return "paused";
1163  }
1164  }
1165  else {
1166  return "disabled";
1167  }
1168  break;
1169 
1170  case 10:
1171  if(_seek_obj || _flee_obj || _pursue_obj || _evade_obj || _arrival_obj || _flock_group || _wander_obj || _obstacle_avoidance_obj || _path_follow_obj) {
1172  if(is_on(_seek) || is_on(_flee) || is_on(_pursue)|| is_on(_evade) || is_on(_arrival) || is_on(_flock) || is_on(_wander)
1173  || is_on(_obstacle_avoidance) || is_on("pathfollow") || is_on("pathfinding")) {
1174  return "active";
1175  }
1176  else {
1177  return "paused";
1178  }
1179  }
1180  else {
1181  return "disabled";
1182  }
1183  break;
1184 
1185  default:
1186  cout<<"Invalid value!"<<endl;
1187  return "invalid";
1188  }
1189  }
1190 
1191 ///////////////////////////////////////////////////////////////////////////////////////
1192 //
1193 // Function : char_to_int
1194 // Description : This function is used to derive int values from the ai types strings.
1195 // Returns -1 if an invalid string is passed.
1196 
1197 ///////////////////////////////////////////////////////////////////////////////////////
1198 
1199 int AIBehaviors::char_to_int(string ai_type) {
1200  if(ai_type == "all") {
1201  return 0;
1202  }
1203  else if(ai_type == "seek") {
1204  return 1;
1205  }
1206  else if(ai_type == "flee") {
1207  return 2;
1208  }
1209  else if(ai_type == "pursue") {
1210  return 3;
1211  }
1212  else if(ai_type == "evade") {
1213  return 4;
1214  }
1215  else if(ai_type == "arrival") {
1216  return 5;
1217  }
1218  else if(ai_type == "flock") {
1219  return 6;
1220  }
1221  else if(ai_type == "wander") {
1222  return 7;
1223  }
1224  else if(ai_type == "obstacle_avoidance") {
1225  return 8;
1226  }
1227  else if(ai_type == "pathfollow") {
1228  return 9;
1229  }
1230  else if(ai_type == "any") {
1231  return 10;
1232  }
1233  else if(ai_type == "flee_activate") {
1234  return 11;
1235  }
1236  else if(ai_type == "evade_activate") {
1237  return 12;
1238  }
1239  else if(ai_type == "arrival_activate") {
1240  return 13;
1241  }
1242  else if(ai_type == "flock_activate") {
1243  return 14;
1244  }
1245  else if(ai_type == "obstacle_avoidance_activate") {
1246  return 15;
1247  }
1248  else if(ai_type == "path_finding") {
1249  return 16;
1250  }
1251 
1252  return -1;
1253 }
1254 
1255 ///////////////////////////////////////////////////////////////////////////////////////
1256 //
1257 // Function : turn_on
1258 // Description : This function turns on any aiBehavior which is passed as a string.
1259 
1260 ///////////////////////////////////////////////////////////////////////////////////////
1261 
1262 void AIBehaviors::turn_on(string ai_type) {
1263  switch(char_to_int(ai_type)) {
1264  case 1: {
1265  _behaviors_flags |= _seek;
1266  break;
1267  }
1268  case 2: {
1269  _behaviors_flags |= _flee;
1270  break;
1271  }
1272  case 3: {
1273  _behaviors_flags |= _pursue;
1274  break;
1275  }
1276  case 4: {
1277  _behaviors_flags |= _evade;
1278  break;
1279  }
1280  case 5: {
1281  _behaviors_flags |= _arrival;
1282  break;
1283  }
1284  case 6: {
1285  _behaviors_flags |= _flock;
1286  break;
1287  }
1288  case 7: {
1289  _behaviors_flags |= _wander;
1290  break;
1291  }
1292  case 8: {
1293  _behaviors_flags |= _obstacle_avoidance;
1294  break;
1295  }
1296  case 11:{
1297  _behaviors_flags |= _flee_activate;
1298  break;
1299  }
1300  case 12:{
1301  _behaviors_flags |= _evade_activate;
1302  break;
1303  }
1304  case 13:{
1305  _behaviors_flags |= _arrival_activate;
1306  break;
1307  }
1308  case 14:{
1309  _behaviors_flags |= _flock_activate;
1310  break;
1311  }
1312  case 15:{
1313  _behaviors_flags |= _obstacle_avoidance_activate;
1314  break;
1315  }
1316  default:
1317  cout<<"Invalid option!"<<endl;
1318  }
1319 }
1320 
1321 ///////////////////////////////////////////////////////////////////////////////////////
1322 //
1323 // Function : turn_off
1324 // Description : This function turns off any aiBehavior which is passed as a string.
1325 
1326 ///////////////////////////////////////////////////////////////////////////////////////
1327 
1328 void AIBehaviors::turn_off(string ai_type) {
1329 switch(char_to_int(ai_type)) {
1330  case 1: {
1331  if (is_on(_seek)) {
1332  _behaviors_flags ^= _seek;
1333  }
1334  _seek_force = LVecBase3(0.0f, 0.0f, 0.0f);
1335  break;
1336  }
1337  case 2: {
1338  if (is_on(_flee)) {
1339  _behaviors_flags ^= _flee;
1340  }
1341  _flee_force = LVecBase3(0.0f, 0.0f, 0.0f);
1342  break;
1343  }
1344  case 3: {
1345  if(is_on(_pursue)) {
1346  _behaviors_flags ^= _pursue;
1347  }
1348  _pursue_force = LVecBase3(0.0f, 0.0f, 0.0f);
1349  break;
1350  }
1351  case 4: {
1352  if(is_on(_evade)) {
1353  _behaviors_flags ^= _evade;
1354  }
1355  _evade_force = LVecBase3(0.0f, 0.0f, 0.0f);
1356  break;
1357  }
1358  case 5: {
1359  if (is_on(_arrival)) {
1360  _behaviors_flags ^= _arrival;
1361  }
1362  _arrival_force = LVecBase3(0.0f, 0.0f, 0.0f);
1363  break;
1364  }
1365  case 6: {
1366  if(is_on(_flock)) {
1367  _behaviors_flags ^= _flock;
1368  }
1369  _flock_force = LVecBase3(0.0f, 0.0f, 0.0f);
1370  break;
1371  }
1372  case 7: {
1373  if(is_on(_wander)) {
1374  _behaviors_flags ^= _wander;
1375  }
1376  _wander_force = LVecBase3(0.0f, 0.0f, 0.0f);
1377  break;
1378  }
1379  case 8: {
1380  if(is_on(_obstacle_avoidance)) {
1381  _behaviors_flags ^= _obstacle_avoidance;
1382  }
1383  _obstacle_avoidance_force = LVecBase3(0.0f, 0.0f, 0.0f);
1384  break;
1385  }
1386  case 9:{
1387  turn_off("pursue");
1388  break;
1389  }
1390  case 11:{
1391  if (is_on(_flee_activate)) {
1392  _behaviors_flags ^= _flee_activate;
1393  }
1394  break;
1395  }
1396  case 12:{
1397  if (is_on(_evade_activate)) {
1398  _behaviors_flags ^= _evade_activate;
1399  }
1400  break;
1401  }
1402  case 13:{
1403  if (is_on(_arrival_activate)) {
1404  _behaviors_flags ^= _arrival_activate;
1405  }
1406  break;
1407  }
1408  case 14:{
1409  if (is_on(_flock_activate)) {
1410  _behaviors_flags ^= _flock_activate;
1411  }
1412  break;
1413  }
1414  case 15:{
1415  if (is_on(_obstacle_avoidance_activate)) {
1416  _behaviors_flags ^= _obstacle_avoidance_activate;
1417  }
1418  break;
1419  }
1420  case 16:{
1421  turn_off("pathfollow");
1422  break;
1423  }
1424  default:
1425  cout<<"Invalid option!"<<endl;
1426  }
1427 }
1428 
1429 ///////////////////////////////////////////////////////////////////////////////////////
1430 //
1431 // Function : is_on
1432 // Description : This function returns true if an aiBehavior is on
1433 
1434 ///////////////////////////////////////////////////////////////////////////////////////
1435 
1436 bool AIBehaviors::is_on(_behavior_type bt) {
1437  return (_behaviors_flags & bt) == bt;
1438 }
1439 
1440 ///////////////////////////////////////////////////////////////////////////////////////
1441 //
1442 // Function : is_on
1443 // Description : This function returns true if pathfollow or pathfinding is on
1444 
1445 ///////////////////////////////////////////////////////////////////////////////////////
1446 
1447 bool AIBehaviors::is_on(string ai_type) {
1448  if(ai_type == "pathfollow") {
1449  if(_path_follow_obj) {
1450  return (is_on(_pursue) && _path_follow_obj->_start);
1451  }
1452  else {
1453  return false;
1454  }
1455  }
1456 
1457  if(ai_type == "pathfinding") {
1458  if(_path_follow_obj && _path_find_obj) {
1459  return (is_on(_pursue) && _path_follow_obj->_start);
1460  }
1461  else {
1462  return false;
1463  }
1464  }
1465 
1466  return false;
1467 }
1468 
1469 ///////////////////////////////////////////////////////////////////////////////////////
1470 //
1471 // Function : is_off
1472 // Description : This function returns true if an aiBehavior is off
1473 
1474 ///////////////////////////////////////////////////////////////////////////////////////
1475 
1476 bool AIBehaviors::is_off(_behavior_type bt) {
1477  return ((_behaviors_flags | bt) == bt);
1478 }
1479 
1480 ///////////////////////////////////////////////////////////////////////////////////////
1481 //
1482 // Function : is_off
1483 // Description : This function returns true if pathfollow or pathfinding is off
1484 
1485 ///////////////////////////////////////////////////////////////////////////////////////
1486 
1487 bool AIBehaviors::is_off(string ai_type) {
1488  if(ai_type == "pathfollow") {
1489  if(_path_follow_obj && _path_follow_obj->_start) {
1490  return true;
1491  }
1492  else {
1493  return false;
1494  }
1495  }
1496 
1497  if(ai_type == "pathfinding") {
1498  if(_path_find_obj && _path_follow_obj && _path_follow_obj->_start) {
1499  return true;
1500  }
1501  else {
1502  return false;
1503  }
1504  }
1505 
1506  cout<<"You passed an invalid string, defaulting return value to false!"<<endl;
1507  return false;
1508 }
string behavior_status(string ai_type)
This function returns the status of an AI Type whether it is active, paused or disabled.
void pause_ai(string ai_type)
This function pauses individual or all the AIs.
void arrival(double distance=10.0)
This function activates arrival.
void add_to_path(LVecBase3 pos)
This function adds positions to the path to follow.
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
LVecBase3 calculate_prioritized()
This function updates the main steering force for the ai character using the accumulate function and ...
bool is_off(_behavior_type bt)
This function returns true if an aiBehavior is off.
void dynamic_avoid(NodePath obstacle)
This function starts the pathfinding obstacle navigation for the passed in obstacle.
Definition: pathFind.cxx:414
void start(string type)
This function initiates the path follow behavior.
Definition: pathFollow.cxx:34
void do_follow()
This function allows continuous path finding by ai chars.
Definition: pathFollow.cxx:59
void flock(float flock_wt)
This function activates flock.
float _flock_weight
Since Flock is a collective behavior the variables are declared within the AIBehaviors class...
Definition: aiBehaviors.h:102
void evade(NodePath target_object, double panic_distance=10.0, double relax_distance=10.0, float evade_wt=1.0)
This function activates evade_activate.
Definition: wander.h:23
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
void init_path_find(const char *navmesh_filename)
This function activates path finding in the character.
void add_to_path(LVecBase3 pos)
This function adds the positions generated from a pathfind or a simple path follow behavior to the _p...
Definition: pathFollow.cxx:23
bool is_conflict()
Checks for conflict between steering forces.
Definition: aiBehaviors.cxx:60
void add_dynamic_obstacle(NodePath obstacle)
This function starts the pathfinding obstacle navigation for the passed in obstacle.
int char_to_int(string ai_type)
This function is used to derive int values from the ai types strings.
Definition: evade.h:24
float length() const
Returns the length of the vector, by the Pythagorean theorem.
Definition: lvecBase3.h:765
LVecBase3 do_arrival()
This function performs the arrival and returns an arrival force which is used in the calculate_priori...
Definition: arrival.cxx:39
ListEvade _evade_list
This list is used if the ai character needs to evade from multiple onjects.
Definition: aiBehaviors.h:95
LVecBase3 do_flock()
This function contains the logic for flocking behavior.
LPoint3 get_pos() const
Retrieves the translation component of the transform.
Definition: nodePath.cxx:1178
void add_static_obstacle(NodePath obstacle)
This function allows the user to dynamically add obstacles to the game environment.
void add_obstacle_to_mesh(NodePath obstacle)
This function allows the user to dynamically add obstacles to the game environment.
Definition: pathFind.cxx:349
void turn_off(string ai_type)
This function turns off any aiBehavior which is passed as a string.
void wander(double wander_radius=5.0, int flag=0, double aoe=0.0, float wander_weight=1.0)
This function activates wander.
This class contains all the members and functions that are required to form an interface between the ...
Definition: pathFind.h:36
void flee(NodePath target_object, double panic_distance=10.0, double relax_distance=10.0, float flee_wt=1.0)
This function activates flee_activate and creates an object of the Flee class.
void path_find(LVecBase3 pos, string type="normal")
This function checks for the source and target in the navigation mesh for its availability and then f...
Definition: pathFind.cxx:200
void remove_ai(string ai_type)
This function removes individual or all the AIs.
void turn_on(string ai_type)
This function turns on any aiBehavior which is passed as a string.
void obstacle_avoidance_activate()
This function activates obstacle_avoidance if a obstacle is detected.
bool is_on(_behavior_type bt)
This function returns true if an aiBehavior is on.
void accumulate_force(string force_type, LVecBase3 force)
This function updates the individual steering forces for each of the ai characters.
void path_follow(float follow_wt)
This function activates path following.
Definition: seek.h:24
void start_follow(string type="normal")
This function starts the path follower.
Definition: pursue.h:24
void obstacle_avoidance(float feeler_length=1.0)
This function activates obstacle avoidance for a given character.
void seek(NodePath target_object, float seek_wt=1.0)
This function activates seek and makes an object of the Seek class.
LVecBase3 do_pursue()
This function performs the pursue and returns a pursue force which is used in the calculate_prioritiz...
Definition: pursue.cxx:40
void path_find_to(LVecBase3 pos, string type="normal")
This function checks for the source and target in the navigation mesh for its availability and then f...
Definition: flee.h:24
void flock_activate()
This function checks whether any other behavior exists to work with flock.
LVecBase3 do_wander()
This function performs the wander and returns the wander force which is used in the calculate_priorit...
Definition: wander.cxx:94
bool normalize()
Normalizes the vector in place.
Definition: lvecBase3.h:782
LVecBase3 do_obstacle_avoidance()
This function returns the force necessary by the AICharacter to avoid the nearest obstacle detected b...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165
LVecBase3 do_seek()
This function performs the seek and returns a seek force which is used in the calculate_prioritized f...
Definition: seek.cxx:54
void set_path_find(const char *navmesh_filename)
This function starts the path finding process after reading the given navigation mesh.
Definition: pathFind.cxx:173
ListFlee _flee_list
This list is used if the ai character needs to flee from multiple onjects.
Definition: aiBehaviors.h:85
void pursue(NodePath target_object, float pursue_wt=1.0)
This function activates pursue.
void resume_ai(string ai_type)
This function resumes individual or all the AIs.
void arrival_activate()
This function checks for whether the target is within the arrival distance.
Definition: arrival.cxx:100