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