00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014
00015 #include "aiBehaviors.h"
00016
00017 static const float _PI = 3.14;
00018
00019 AIBehaviors::AIBehaviors() {
00020 _steering_force = LVecBase3f(0.0, 0.0, 0.0);
00021 _behaviors_flags = _behaviors_flags & _none;
00022 _previous_conflict = false;
00023 _conflict = false;
00024
00025 _seek_obj = NULL;
00026 _flee_obj = NULL;
00027 _pursue_obj = NULL;
00028 _evade_obj = NULL;
00029 _arrival_obj = NULL;
00030 _wander_obj = NULL;
00031 _flock_group = NULL;
00032 _path_follow_obj = NULL;
00033 _path_find_obj = NULL;
00034 _obstacle_avoidance_obj = NULL;
00035
00036 turn_off("seek");
00037 turn_off("flee");
00038 turn_off("pursue");
00039 turn_off("evade");
00040 turn_off("arrival");
00041 turn_off("flock");
00042 turn_off("wander");
00043 turn_off("obstacle_avoidance");
00044 }
00045
00046 AIBehaviors::~AIBehaviors() {
00047
00048 }
00049
00056
00058
00059 bool AIBehaviors::is_conflict() {
00060 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));
00061
00062 if(value > 1) {
00063 if(_previous_conflict == false) {
00064 if(is_on(_seek)) {
00065 _seek_force *= _seek_obj->_seek_weight;
00066 }
00067
00068 if(is_on(_flee)) {
00069 LVecBase3f dirn = _flee_force;
00070 dirn.normalize();
00071 _flee_force = _steering_force.length() * dirn * _flee_obj->_flee_weight;
00072 }
00073
00074 if(is_on(_pursue)) {
00075 _pursue_force *= _pursue_obj->_pursue_weight;
00076 }
00077
00078 if(is_on(_evade)) {
00079 LVecBase3f dirn = _evade_force;
00080 dirn.normalize();
00081 _evade_force = _steering_force.length() * dirn * _evade_obj->_evade_weight;
00082 }
00083
00084 if(is_on(_flock)) {
00085 _flock_force *= _flock_weight;
00086 }
00087
00088 if(is_on(_wander)) {
00089 _wander_force *= _wander_obj->_wander_weight;
00090 }
00091
00092 _previous_conflict = true;
00093 }
00094
00095 _conflict = true;
00096 return true;
00097 }
00098
00099 _conflict = false;
00100 _previous_conflict = false;
00101 return false;
00102 }
00103
00110
00112
00113 void AIBehaviors::accumulate_force(string force_type, LVecBase3f force) {
00114
00115 LVecBase3f old_force;
00116
00117 if(force_type == "seek") {
00118 old_force = _seek_force;
00119 _seek_force = old_force + force;
00120 }
00121
00122 if(force_type == "flee") {
00123 old_force = _flee_force;
00124 _flee_force = old_force + force;
00125 }
00126
00127 if(force_type == "pursue") {
00128 old_force = _pursue_force;
00129 double new_force = old_force.length() + force.length();
00130 _pursue_force = new_force * _pursue_obj->_pursue_direction;
00131 }
00132
00133 if(force_type == "evade") {
00134 old_force = _evade_force;
00135 double new_force = old_force.length() + force.length();
00136 force.normalize();
00137 _evade_force = new_force * force;
00138 }
00139
00140 if(force_type == "arrival") {
00141 _arrival_force = force;
00142 }
00143
00144 if(force_type == "flock") {
00145 old_force = _flock_force;
00146 _flock_force = old_force + force;
00147 }
00148
00149 if(force_type == "wander") {
00150 old_force = _wander_force;
00151 _wander_force = old_force + force;
00152 }
00153
00154 if(force_type == "obstacle_avoidance") {
00155 old_force = _obstacle_avoidance_force;
00156 _obstacle_avoidance_force = old_force +force;
00157 }
00158
00159 }
00160
00168
00170
00171 LVecBase3f AIBehaviors::calculate_prioritized() {
00172 LVecBase3f force;
00173
00174 if(is_on(_seek)) {
00175 if(_conflict) {
00176 force = _seek_obj->do_seek() * _seek_obj->_seek_weight;
00177 }
00178 else {
00179 force = _seek_obj->do_seek();
00180 }
00181 accumulate_force("seek",force);
00182 }
00183
00184 if(is_on(_flee_activate)) {
00185 for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
00186 _flee_itr->flee_activate();
00187 }
00188 }
00189
00190 if(is_on(_flee)) {
00191 for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
00192 if(_flee_itr->_flee_activate_done) {
00193 if(_conflict) {
00194 force = _flee_itr->do_flee() * _flee_itr->_flee_weight;
00195 }
00196 else {
00197 force = _flee_itr->do_flee();
00198 }
00199 accumulate_force("flee",force);
00200 }
00201 }
00202 }
00203
00204 if(is_on(_pursue)) {
00205 if(_conflict) {
00206 force = _pursue_obj->do_pursue() * _pursue_obj->_pursue_weight;
00207 }
00208 else {
00209 force = _pursue_obj->do_pursue();
00210 }
00211 accumulate_force("pursue",force);
00212 }
00213
00214 if(is_on(_evade_activate)) {
00215 for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
00216 _evade_itr->evade_activate();
00217 }
00218 }
00219
00220 if(is_on(_evade)) {
00221 for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
00222 if(_evade_itr->_evade_activate_done) {
00223 if(_conflict) {
00224 force = (_evade_itr->do_evade()) * (_evade_itr->_evade_weight);
00225 }
00226 else {
00227 force = _evade_itr->do_evade();
00228 }
00229 accumulate_force("evade",force);
00230 }
00231 }
00232 }
00233
00234 if(is_on(_arrival_activate)) {
00235 _arrival_obj->arrival_activate();
00236 }
00237
00238 if(is_on(_arrival)) {
00239 force = _arrival_obj->do_arrival();
00240 accumulate_force("arrival",force);
00241 }
00242
00243 if(is_on(_flock_activate)) {
00244 flock_activate();
00245 }
00246
00247 if(is_on(_flock)) {
00248 if(_conflict) {
00249 force = do_flock() * _flock_weight;
00250 }
00251 else {
00252 force = do_flock();
00253 }
00254 accumulate_force("flock",force);
00255 }
00256
00257 if(is_on(_wander)) {
00258 if(_conflict) {
00259 force = _wander_obj->do_wander() * _wander_obj->_wander_weight;
00260 }
00261 else {
00262 force = _wander_obj->do_wander();
00263 }
00264 accumulate_force("wander", force);
00265 }
00266
00267 if(is_on(_obstacle_avoidance_activate)) {
00268 _obstacle_avoidance_obj->obstacle_avoidance_activate();
00269 }
00270
00271 if(is_on(_obstacle_avoidance)) {
00272 if(_conflict) {
00273 force = _obstacle_avoidance_obj->do_obstacle_avoidance();
00274 }
00275 else {
00276 force = _obstacle_avoidance_obj->do_obstacle_avoidance();
00277 }
00278 accumulate_force("obstacle_avoidance", force);
00279 }
00280
00281 if(_path_follow_obj!=NULL) {
00282 if(_path_follow_obj->_start) {
00283 _path_follow_obj->do_follow();
00284 }
00285 }
00286
00287 is_conflict();
00288
00289 _steering_force += _seek_force * int(is_on(_seek)) + _flee_force * int(is_on(_flee)) +
00290 _pursue_force * int(is_on(_pursue)) + _evade_force * int(is_on(_evade)) +
00291 _flock_force * int(is_on(_flock)) + _wander_force * int(is_on(_wander)) +
00292 _obstacle_avoidance_force * int(is_on(_obstacle_avoidance));
00293
00294 if(_steering_force.length() > _ai_char->get_max_force()) {
00295 _steering_force.normalize();
00296 _steering_force = _steering_force * _ai_char->get_max_force();
00297 }
00298
00299 if(is_on(_arrival)) {
00300 if(_seek_obj != NULL) {
00301 LVecBase3f dirn = _steering_force;
00302 dirn.normalize();
00303 _steering_force = ((_steering_force.length() - _arrival_force.length()) * dirn);
00304 }
00305
00306 if(_pursue_obj != NULL) {
00307 LVecBase3f dirn = _steering_force;
00308 dirn.normalize();
00309 _steering_force = ((_steering_force.length() - _arrival_force.length()) * _arrival_obj->_arrival_direction);
00310 }
00311 }
00312 return _steering_force;
00313 }
00314
00319
00321
00322
00323 void AIBehaviors::remove_ai(string ai_type) {
00324 switch(char_to_int(ai_type)) {
00325 case 0: {
00326 remove_ai("seek");
00327 remove_ai("flee");
00328 remove_ai("pursue");
00329 remove_ai("evade");
00330 remove_ai("arrival");
00331 remove_ai("flock");
00332 remove_ai("wander");
00333 remove_ai("obstacle_avoidance");
00334 remove_ai("pathfollow");
00335 break;
00336 }
00337
00338 case 1: {
00339 if(_seek_obj != NULL) {
00340 turn_off("seek");
00341 delete _seek_obj;
00342 _seek_obj = NULL;
00343 }
00344 break;
00345 }
00346
00347 case 2: {
00348 while (!_flee_list.empty()) {
00349 turn_off("flee");
00350 turn_off("flee_activate");
00351 _flee_list.pop_front();
00352 }
00353 break;
00354 }
00355
00356 case 3: {
00357 if(_pursue_obj != NULL) {
00358 turn_off("pursue");
00359 delete _pursue_obj;
00360 _pursue_obj = NULL;
00361 }
00362 break;
00363 }
00364
00365 case 4: {
00366 while (!_evade_list.empty()) {
00367 turn_off("evade");
00368 turn_off("evade_activate");
00369 _evade_list.pop_front();
00370 }
00371 break;
00372 }
00373
00374 case 5: {
00375 if(_arrival_obj != NULL) {
00376 turn_off("arrival");
00377 turn_off("arrival_activate");
00378 delete _arrival_obj;
00379 _arrival_obj = NULL;
00380 }
00381 break;
00382 }
00383
00384 case 6: {
00385 if(_flock_group != NULL) {
00386 turn_off("flock");
00387 turn_off("flock_activate");
00388 _flock_group = NULL;
00389 }
00390 break;
00391 }
00392
00393 case 7: {
00394 if(_wander_obj != NULL) {
00395 turn_off("wander");
00396 delete _wander_obj;
00397 _wander_obj = NULL;
00398 }
00399 break;
00400 }
00401
00402 case 8: {
00403 if(_obstacle_avoidance_obj !=NULL) {
00404 turn_off("obstacle_avoidance");
00405 delete _obstacle_avoidance_obj;
00406 _obstacle_avoidance_obj = NULL;
00407 }
00408 break;
00409 }
00410
00411 case 9: {
00412 if(_pursue_obj != NULL && _path_follow_obj != NULL) {
00413 turn_off("pursue");
00414 delete _pursue_obj;
00415 _pursue_obj = NULL;
00416 delete _path_follow_obj;
00417 _path_follow_obj = NULL;
00418 }
00419 break;
00420 }
00421 case 16: {
00422 if(_pursue_obj != NULL && _path_follow_obj != NULL) {
00423 turn_off("pursue");
00424 delete _pursue_obj;
00425 _pursue_obj = NULL;
00426 delete _path_follow_obj;
00427 _path_follow_obj = NULL;
00428 }
00429 break;
00430 }
00431 default:
00432 cout<<"Invalid option!"<<endl;
00433 }
00434 }
00435
00440
00442
00443
00444 void AIBehaviors::pause_ai(string ai_type) {
00445 switch(char_to_int(ai_type)) {
00446 case 0: {
00447 pause_ai("seek");
00448 pause_ai("flee");
00449 pause_ai("pursue");
00450 pause_ai("evade");
00451 pause_ai("arrival");
00452 pause_ai("flock");
00453 pause_ai("wander");
00454 pause_ai("obstacle_avoidance");
00455 pause_ai("pathfollow");
00456 break;
00457 }
00458
00459 case 1: {
00460 if(_seek_obj != NULL) {
00461 turn_off("seek");
00462 }
00463 break;
00464 }
00465
00466 case 2: {
00467 for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
00468 turn_off("flee");
00469 turn_off("flee_activate");
00470 }
00471 break;
00472 }
00473
00474 case 3: {
00475 if(_pursue_obj != NULL) {
00476 turn_off("pursue");
00477 }
00478 break;
00479 }
00480
00481 case 4: {
00482 for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
00483 turn_off("evade");
00484 turn_off("evade_activate");
00485 }
00486 break;
00487 }
00488
00489 case 5: {
00490 if(_arrival_obj != NULL) {
00491 turn_off("arrival");
00492 turn_off("arrival_activate");
00493 }
00494 break;
00495 }
00496
00497 case 6: {
00498 if(_flock_group != NULL) {
00499 turn_off("flock");
00500 turn_off("flock_activate");
00501 }
00502 break;
00503 }
00504
00505 case 7: {
00506 if(_wander_obj != NULL) {
00507 turn_off("wander");
00508 }
00509 break;
00510 }
00511
00512 case 8: {
00513 if(_obstacle_avoidance != NULL) {
00514 turn_off("obstacle_avoidance");
00515 turn_off("obstacle_avoidance_activate");
00516 }
00517 break;
00518 }
00519
00520 case 9: {
00521 if(_pursue_obj != NULL && _path_follow_obj != NULL) {
00522 turn_off("pursue");
00523 _path_follow_obj->_start = false;
00524 }
00525 break;
00526 }
00527 case 16: {
00528 if(_pursue_obj != NULL && _path_follow_obj != NULL) {
00529 turn_off("pursue");
00530 _path_follow_obj->_start = false;
00531 }
00532 break;
00533 }
00534 default:
00535 cout<<"Invalid option!"<<endl;
00536 }
00537 }
00538
00543
00545
00546 void AIBehaviors::resume_ai(string ai_type) {
00547 switch(char_to_int(ai_type)) {
00548 case 0: {
00549 resume_ai("seek");
00550 resume_ai("flee");
00551 resume_ai("pursue");
00552 resume_ai("evade");
00553 resume_ai("arrival");
00554 resume_ai("flock");
00555 resume_ai("wander");
00556 resume_ai("obstacle_avoidance");
00557 resume_ai("pathfollow");
00558 break;
00559 }
00560
00561 case 1: {
00562 if(_seek_obj != NULL) {
00563 turn_on("seek");
00564 }
00565 break;
00566 }
00567
00568 case 2: {
00569 for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
00570 turn_on("flee");
00571 }
00572 break;
00573 }
00574
00575 case 3: {
00576 if(_pursue_obj != NULL) {
00577 turn_on("pursue");
00578 }
00579 break;
00580 }
00581
00582 case 4: {
00583 for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
00584 turn_on("evade");
00585 }
00586 break;
00587 }
00588
00589 case 5: {
00590 if(_arrival_obj != NULL) {
00591 turn_on("arrival");
00592 }
00593 break;
00594 }
00595
00596 case 6: {
00597 if(_flock_group != NULL) {
00598 turn_on("flock");
00599 }
00600 break;
00601 }
00602
00603 case 7: {
00604 if(_wander_obj != NULL) {
00605 turn_on("wander");
00606 }
00607 break;
00608 }
00609
00610 case 8: {
00611 if(_obstacle_avoidance_obj != NULL) {
00612 turn_on("obstacle_avoidance");
00613 }
00614 break;
00615 }
00616
00617 case 9: {
00618 if(_pursue_obj != NULL && _path_follow_obj != NULL) {
00619 turn_on("pursue");
00620 _path_follow_obj->_start = true;
00621 }
00622 break;
00623 }
00624 case 16: {
00625 if(_pursue_obj != NULL && _path_follow_obj != NULL) {
00626 turn_off("pursue");
00627 _path_follow_obj->_start = false;
00628 }
00629 break;
00630 }
00631 default:
00632 cout<<"Invalid option!"<<endl;
00633 }
00634 }
00635
00642
00644
00645 void AIBehaviors::seek(NodePath target_object, float seek_wt) {
00646 _seek_obj = new Seek(_ai_char, target_object, seek_wt);
00647 turn_on("seek");
00648 }
00649
00650 void AIBehaviors::seek(LVecBase3f pos, float seek_wt) {
00651 _seek_obj = new Seek(_ai_char, pos, seek_wt);
00652 turn_on("seek");
00653 }
00654
00660
00662
00663 void AIBehaviors::flee(NodePath target_object, double panic_distance, double relax_distance, float flee_wt) {
00664 _flee_obj = new Flee(_ai_char, target_object, panic_distance, relax_distance, flee_wt);
00665 _flee_list.insert(_flee_list.end(), *_flee_obj);
00666
00667 turn_on("flee_activate");
00668 }
00669
00670 void AIBehaviors::flee(LVecBase3f pos, double panic_distance, double relax_distance, float flee_wt) {
00671 _flee_obj = new Flee(_ai_char, pos, panic_distance, relax_distance, flee_wt);
00672 _flee_list.insert(_flee_list.end(), *_flee_obj);
00673
00674 turn_on("flee_activate");
00675 }
00676
00682
00684
00685 void AIBehaviors::pursue(NodePath target_object, float pursue_wt) {
00686 _pursue_obj = new Pursue(_ai_char, target_object, pursue_wt);
00687
00688 turn_on("pursue");
00689 }
00690
00695
00697
00698 void AIBehaviors::evade(NodePath target_object, double panic_distance, double relax_distance, float evade_wt) {
00699 _evade_obj = new Evade(_ai_char, target_object, panic_distance, relax_distance, evade_wt);
00700 _evade_list.insert(_evade_list.end(), *_evade_obj);
00701
00702 turn_on("evade_activate");
00703 }
00704
00710
00712
00713 void AIBehaviors::arrival(double distance) {
00714 if(_pursue_obj) {
00715 _arrival_obj = new Arrival(_ai_char, distance);
00716 _arrival_obj->_arrival_type = true;
00717 turn_on("arrival_activate");
00718 }
00719 else if(_seek_obj) {
00720 _arrival_obj = new Arrival(_ai_char, distance);
00721 _arrival_obj->_arrival_type = false;
00722 turn_on("arrival_activate");
00723 }
00724 else {
00725 cout<<"Note: A Seek or Pursue behavior is required to use Arrival behavior."<<endl;
00726 }
00727 }
00728
00734
00736
00737 void AIBehaviors::flock(float flock_wt) {
00738 _flock_weight = flock_wt;
00739
00740 _flock_done = false;
00741 turn_on("flock_activate");
00742 }
00743
00749
00751
00752 void AIBehaviors::flock_activate() {
00753 if(is_on(_seek) || is_on(_flee) || is_on(_pursue) || is_on(_evade) || is_on(_wander)) {
00754 turn_off("flock_activate");
00755 turn_on("flock");
00756 }
00757 }
00758
00768
00770
00771 LVecBase3f AIBehaviors::do_flock() {
00772
00774 unsigned int neighbor_count = 0;
00775 LVecBase3f separation_force = LVecBase3f(0.0, 0.0, 0.0);
00776 LVecBase3f alignment_force = LVecBase3f(0.0, 0.0, 0.0);
00777 LVecBase3f cohesion_force = LVecBase3f(0.0, 0.0, 0.0);
00778 LVecBase3f avg_neighbor_heading = LVecBase3f(0.0, 0.0, 0.0);
00779 LVecBase3f total_neighbor_heading = LVecBase3f(0.0, 0.0, 0.0);
00780 LVecBase3f avg_center_of_mass = LVecBase3f(0.0, 0.0, 0.0);
00781 LVecBase3f total_center_of_mass = LVecBase3f(0.0, 0.0, 0.0);
00782
00784 for(unsigned int i = 0; i < _flock_group->_ai_char_list.size(); i++) {
00785 if(_flock_group->_ai_char_list[i]->_name != _ai_char->_name) {
00786
00788 LVecBase3f dist_vect = _flock_group->_ai_char_list[i]->_ai_char_np.get_pos() - _ai_char->_ai_char_np.get_pos();
00789 LVecBase3f ai_char_heading = _ai_char->get_velocity();
00790 ai_char_heading.normalize();
00791
00793 if(dist_vect.dot(ai_char_heading) > ((dist_vect.length()) * (ai_char_heading.length()) * cos(_flock_group->_flock_vcone_angle * (_PI / 180)))
00794 && (dist_vect.length() < _flock_group->_flock_vcone_radius)) {
00796 LVecBase3f ai_char_to_units = _ai_char->_ai_char_np.get_pos() - _flock_group->_ai_char_list[i]->_ai_char_np.get_pos();
00797 float to_units_dist = ai_char_to_units.length();
00798 ai_char_to_units.normalize();
00799 separation_force += (ai_char_to_units / to_units_dist);
00800
00802 LVecBase3f neighbor_heading = _flock_group->_ai_char_list[i]->get_velocity();
00803 neighbor_heading.normalize();
00804 total_neighbor_heading += neighbor_heading;
00805 total_center_of_mass += _flock_group->_ai_char_list[i]->_ai_char_np.get_pos();
00806
00808 ++neighbor_count;
00809 }
00810 }
00811 }
00812
00813 if(neighbor_count > 0) {
00815 avg_neighbor_heading = total_neighbor_heading / neighbor_count;
00816 LVector3f ai_char_heading = _ai_char->get_velocity();
00817 ai_char_heading.normalize();
00818 avg_neighbor_heading -= ai_char_heading;
00819 avg_neighbor_heading.normalize();
00820 alignment_force = avg_neighbor_heading;
00821
00823 avg_center_of_mass = total_center_of_mass / neighbor_count;
00824 LVecBase3f cohesion_dir = avg_center_of_mass - _ai_char->_ai_char_np.get_pos();
00825 cohesion_dir.normalize();
00826 cohesion_force = cohesion_dir * _ai_char->_movt_force;
00827 }
00828 else if(is_on(_seek) || is_on(_flee) || is_on(_pursue) || is_on(_evade) || is_on(_wander)) {
00829 _flock_done = true;
00830 turn_off("flock");
00831 turn_on("flock_activate");
00832 return(LVecBase3f(0.0, 0.0, 0.0));
00833 }
00834
00837 return (separation_force * _flock_group->_separation_wt + avg_neighbor_heading * _flock_group->_alignment_wt
00838 + cohesion_force * _flock_group->_cohesion_wt);
00839 }
00840
00846
00848
00849 void AIBehaviors::wander(double wander_radius, int flag, double aoe, float wander_weight) {
00850 _wander_obj = new Wander(_ai_char, wander_radius, flag, aoe, wander_weight);
00851 turn_on("wander");
00852 }
00853
00860
00862
00863 void AIBehaviors::obstacle_avoidance(float obstacle_avoidance_weight) {
00864 _obstacle_avoidance_obj = new ObstacleAvoidance(_ai_char, obstacle_avoidance_weight);
00865 turn_on("obstacle_avoidance_activate");
00866 }
00867
00873
00875
00876 void AIBehaviors::path_follow(float follow_wt) {
00877 _path_follow_obj = new PathFollow(_ai_char, follow_wt);
00878 }
00879
00884
00886
00887 void AIBehaviors::add_to_path(LVecBase3f pos) {
00888 _path_follow_obj->add_to_path(pos);
00889 }
00890
00895
00897
00898 void AIBehaviors::start_follow(string type) {
00899 _path_follow_obj->start(type);
00900 }
00901
00908
00910
00911 void AIBehaviors::init_path_find(const char* navmesh_filename) {
00912 _path_find_obj = new PathFind(_ai_char);
00913 _path_find_obj->set_path_find(navmesh_filename);
00914 }
00915
00922
00924
00925 void AIBehaviors::path_find_to(LVecBase3f pos, string type) {
00926 _path_find_obj->path_find(pos, type);
00927 }
00928
00935
00937
00938 void AIBehaviors::path_find_to(NodePath target, string type) {
00939 _path_find_obj->path_find(target, type);
00940 }
00941
00949
00951
00952 void AIBehaviors::add_static_obstacle(NodePath obstacle) {
00953 _path_find_obj->add_obstacle_to_mesh(obstacle);
00954 }
00955
00961
00963
00964 void AIBehaviors::add_dynamic_obstacle(NodePath obstacle) {
00965 _path_find_obj->dynamic_avoid(obstacle);
00966 }
00967
00973
00975
00976 string AIBehaviors::behavior_status(string ai_type) {
00977 switch(char_to_int(ai_type)) {
00978 case 1:
00979 if(_seek_obj) {
00980 if(is_on(_seek)) {
00981 return "active";
00982 }
00983 else {
00984 if(_seek_obj->_seek_done) {
00985 return "done";
00986 }
00987 return "paused";
00988 }
00989 }
00990 else {
00991 return "disabled";
00992 }
00993 break;
00994
00995 case 2:
00996 if(_flee_obj) {
00997 if(is_on(_flee)) {
00998 unsigned int i = 0;
00999 for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) {
01000 if(_flee_itr->_flee_done == true) {
01001 ++i;
01002 }
01003 }
01004 if(i == _flee_list.size()) {
01005 return "done";
01006 }
01007 else {
01008 return "active";
01009 }
01010 }
01011 else {
01012 return "paused";
01013 }
01014 }
01015 else {
01016 return "disabled";
01017 }
01018 break;
01019
01020 case 3:
01021 if(_pursue_obj) {
01022 if(is_on(_pursue)) {
01023 if(_pursue_obj->_pursue_done) {
01024 return "done";
01025 }
01026 else {
01027 return "active";
01028 }
01029 }
01030 else {
01031 return "paused";
01032 }
01033 }
01034 else {
01035 return "disabled";
01036 }
01037 break;
01038
01039 case 4:
01040 if(_evade_obj) {
01041 if(is_on(_evade)) {
01042 unsigned int i = 0;
01043 for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) {
01044 if(_evade_itr->_evade_done == true) {
01045 ++i;
01046 }
01047 }
01048 if(i == _evade_list.size()) {
01049 return "done";
01050 }
01051 else {
01052 return "active";
01053 }
01054 }
01055 else {
01056 return "paused";
01057 }
01058 }
01059 else {
01060 return "disabled";
01061 }
01062 break;
01063
01064 case 5:
01065 if(_arrival_obj) {
01066 if(is_on(_arrival)) {
01067 if(_arrival_obj->_arrival_done) {
01068 return "done";
01069 }
01070 else {
01071 return "active";
01072 }
01073 }
01074 else {
01075 return "paused";
01076 }
01077 }
01078 else {
01079 return "disabled";
01080 }
01081 break;
01082
01083 case 6:
01084 if(_flock_group) {
01085 if(is_on(_flock)) {
01086 if(_flock_done) {
01087 return "done";
01088 }
01089 else {
01090 return "active";
01091 }
01092 return "active";
01093 }
01094 else {
01095 return "paused";
01096 }
01097 }
01098 else {
01099 return "disabled";
01100 }
01101 break;
01102
01103 case 7:
01104 if(_wander_obj) {
01105 if(is_on(_wander)) {
01106 return "active";
01107 }
01108 else {
01109 return "paused";
01110 }
01111 }
01112 else {
01113 return "disabled";
01114 }
01115 break;
01116
01117 case 8:
01118 if(_obstacle_avoidance_obj) {
01119 if(is_on(_obstacle_avoidance)) {
01120 return "active";
01121 }
01122 else {
01123 return "paused";
01124 }
01125 }
01126 else {
01127 return "disabled";
01128 }
01129 break;
01130
01131 case 9:
01132 if(_path_follow_obj) {
01133 if(is_on("pathfollow")) {
01134 if(_pursue_obj->_pursue_done) {
01135 return "done";
01136 }
01137 else {
01138 return "active";
01139 }
01140 }
01141 else {
01142 return "paused";
01143 }
01144 }
01145 else {
01146 return "disabled";
01147 }
01148 break;
01149
01150 case 16:
01151 if(_path_find_obj) {
01152 if(is_on("pathfind")) {
01153 if(_pursue_obj->_pursue_done) {
01154 return "done";
01155 }
01156 else {
01157 return "active";
01158 }
01159 }
01160 else {
01161 return "paused";
01162 }
01163 }
01164 else {
01165 return "disabled";
01166 }
01167 break;
01168
01169 case 10:
01170 if(_seek_obj || _flee_obj || _pursue_obj || _evade_obj || _arrival_obj || _flock_group || _wander_obj || _obstacle_avoidance_obj || _path_follow_obj) {
01171 if(is_on(_seek) || is_on(_flee) || is_on(_pursue)|| is_on(_evade) || is_on(_arrival) || is_on(_flock) || is_on(_wander)
01172 || is_on(_obstacle_avoidance) || is_on("pathfollow") || is_on("pathfinding")) {
01173 return "active";
01174 }
01175 else {
01176 return "paused";
01177 }
01178 }
01179 else {
01180 return "disabled";
01181 }
01182 break;
01183
01184 default:
01185 cout<<"Invalid value!"<<endl;
01186 }
01187 }
01188
01194
01196
01197 int AIBehaviors::char_to_int(string ai_type) {
01198 if(ai_type == "all") {
01199 return 0;
01200 }
01201 else if(ai_type == "seek") {
01202 return 1;
01203 }
01204 else if(ai_type == "flee") {
01205 return 2;
01206 }
01207 else if(ai_type == "pursue") {
01208 return 3;
01209 }
01210 else if(ai_type == "evade") {
01211 return 4;
01212 }
01213 else if(ai_type == "arrival") {
01214 return 5;
01215 }
01216 else if(ai_type == "flock") {
01217 return 6;
01218 }
01219 else if(ai_type == "wander") {
01220 return 7;
01221 }
01222 else if(ai_type == "obstacle_avoidance") {
01223 return 8;
01224 }
01225 else if(ai_type == "pathfollow") {
01226 return 9;
01227 }
01228 else if(ai_type == "any") {
01229 return 10;
01230 }
01231 else if(ai_type == "flee_activate") {
01232 return 11;
01233 }
01234 else if(ai_type == "evade_activate") {
01235 return 12;
01236 }
01237 else if(ai_type == "arrival_activate") {
01238 return 13;
01239 }
01240 else if(ai_type == "flock_activate") {
01241 return 14;
01242 }
01243 else if(ai_type == "obstacle_avoidance_activate") {
01244 return 15;
01245 }
01246 else if(ai_type == "path_finding") {
01247 return 16;
01248 }
01249
01250 return -1;
01251 }
01252
01257
01259
01260 void AIBehaviors::turn_on(string ai_type) {
01261 switch(char_to_int(ai_type)) {
01262 case 1: {
01263 _behaviors_flags |= _seek;
01264 break;
01265 }
01266 case 2: {
01267 _behaviors_flags |= _flee;
01268 break;
01269 }
01270 case 3: {
01271 _behaviors_flags |= _pursue;
01272 break;
01273 }
01274 case 4: {
01275 _behaviors_flags |= _evade;
01276 break;
01277 }
01278 case 5: {
01279 _behaviors_flags |= _arrival;
01280 break;
01281 }
01282 case 6: {
01283 _behaviors_flags |= _flock;
01284 break;
01285 }
01286 case 7: {
01287 _behaviors_flags |= _wander;
01288 break;
01289 }
01290 case 8: {
01291 _behaviors_flags |= _obstacle_avoidance;
01292 break;
01293 }
01294 case 11:{
01295 _behaviors_flags |= _flee_activate;
01296 break;
01297 }
01298 case 12:{
01299 _behaviors_flags |= _evade_activate;
01300 break;
01301 }
01302 case 13:{
01303 _behaviors_flags |= _arrival_activate;
01304 break;
01305 }
01306 case 14:{
01307 _behaviors_flags |= _flock_activate;
01308 break;
01309 }
01310 case 15:{
01311 _behaviors_flags |= _obstacle_avoidance_activate;
01312 break;
01313 }
01314 default:
01315 cout<<"Invalid option!"<<endl;
01316 }
01317 }
01318
01323
01325
01326 void AIBehaviors::turn_off(string ai_type) {
01327 switch(char_to_int(ai_type)) {
01328 case 1: {
01329 if (is_on(_seek)) {
01330 _behaviors_flags ^= _seek;
01331 }
01332 _seek_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01333 break;
01334 }
01335 case 2: {
01336 if (is_on(_flee)) {
01337 _behaviors_flags ^= _flee;
01338 }
01339 _flee_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01340 break;
01341 }
01342 case 3: {
01343 if(is_on(_pursue)) {
01344 _behaviors_flags ^= _pursue;
01345 }
01346 _pursue_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01347 break;
01348 }
01349 case 4: {
01350 if(is_on(_evade)) {
01351 _behaviors_flags ^= _evade;
01352 }
01353 _evade_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01354 break;
01355 }
01356 case 5: {
01357 if (is_on(_arrival)) {
01358 _behaviors_flags ^= _arrival;
01359 }
01360 _arrival_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01361 break;
01362 }
01363 case 6: {
01364 if(is_on(_flock)) {
01365 _behaviors_flags ^= _flock;
01366 }
01367 _flock_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01368 break;
01369 }
01370 case 7: {
01371 if(is_on(_wander)) {
01372 _behaviors_flags ^= _wander;
01373 }
01374 _wander_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01375 break;
01376 }
01377 case 8: {
01378 if(is_on(_obstacle_avoidance)) {
01379 _behaviors_flags ^= _obstacle_avoidance;
01380 }
01381 _obstacle_avoidance_force = LVecBase3f(0.0f, 0.0f, 0.0f);
01382 break;
01383 }
01384 case 9:{
01385 turn_off("pursue");
01386 break;
01387 }
01388 case 11:{
01389 if (is_on(_flee_activate)) {
01390 _behaviors_flags ^= _flee_activate;
01391 }
01392 break;
01393 }
01394 case 12:{
01395 if (is_on(_evade_activate)) {
01396 _behaviors_flags ^= _evade_activate;
01397 }
01398 break;
01399 }
01400 case 13:{
01401 if (is_on(_arrival_activate)) {
01402 _behaviors_flags ^= _arrival_activate;
01403 }
01404 break;
01405 }
01406 case 14:{
01407 if (is_on(_flock_activate)) {
01408 _behaviors_flags ^= _flock_activate;
01409 }
01410 break;
01411 }
01412 case 15:{
01413 if (is_on(_obstacle_avoidance_activate)) {
01414 _behaviors_flags ^= _obstacle_avoidance_activate;
01415 }
01416 break;
01417 }
01418 case 16:{
01419 turn_off("pathfollow");
01420 break;
01421 }
01422 default:
01423 cout<<"Invalid option!"<<endl;
01424 }
01425 }
01426
01431
01433
01434 bool AIBehaviors::is_on(_behavior_type bt) {
01435 return (_behaviors_flags & bt) == bt;
01436 }
01437
01442
01444
01445 bool AIBehaviors::is_on(string ai_type) {
01446 if(ai_type == "pathfollow") {
01447 if(_path_follow_obj) {
01448 return (is_on(_pursue) && _path_follow_obj->_start);
01449 }
01450 else {
01451 return false;
01452 }
01453 }
01454
01455 if(ai_type == "pathfinding") {
01456 if(_path_follow_obj && _path_find_obj) {
01457 return (is_on(_pursue) && _path_follow_obj->_start);
01458 }
01459 else {
01460 return false;
01461 }
01462 }
01463
01464 return false;
01465 }
01466
01471
01473
01474 bool AIBehaviors::is_off(_behavior_type bt) {
01475 return ((_behaviors_flags | bt) == bt);
01476 }
01477
01482
01484
01485 bool AIBehaviors::is_off(string ai_type) {
01486 if(ai_type == "pathfollow") {
01487 if(_path_follow_obj && _path_follow_obj->_start) {
01488 return true;
01489 }
01490 else {
01491 return false;
01492 }
01493 }
01494
01495 if(ai_type == "pathfinding") {
01496 if(_path_find_obj && _path_follow_obj && _path_follow_obj->_start) {
01497 return true;
01498 }
01499 else {
01500 return false;
01501 }
01502 }
01503
01504 cout<<"You passed an invalid string, defaulting return value to false!"<<endl;
01505 return false;
01506 }