Panda3D

pathFollow.cxx

00001 
00002 #include "pathFollow.h"
00003 
00004 PathFollow::PathFollow(AICharacter *ai_ch, float follow_wt) {
00005     _follow_weight = follow_wt;
00006   _curr_path_waypoint = -1;
00007   _start = false;
00008   _ai_char = ai_ch;
00009   _myClock = ClockObject::get_global_clock();
00010 }
00011 
00012 PathFollow::~PathFollow() {
00013 }
00014 
00015 /////////////////////////////////////////////////////////////////////////////////////////
00016 //
00017 // Function : add_to_path
00018 // Description : This function adds the positions generated from a pathfind or a simple
00019 //               path follow behavior to the _path list.
00020 
00021 /////////////////////////////////////////////////////////////////////////////////////////
00022 
00023 void PathFollow::add_to_path(LVecBase3f pos) {
00024     _path.push_back(pos);
00025 }
00026 
00027 /////////////////////////////////////////////////////////////////////////////////////////
00028 //
00029 // Function : start
00030 // Description : This function initiates the path follow behavior.
00031 
00032 /////////////////////////////////////////////////////////////////////////////////////////
00033 
00034 void PathFollow::start(string type) {
00035     _type = type;
00036   _start = true;
00037   if(_path.size() > 0) {
00038     _curr_path_waypoint = _path.size() - 1;
00039     _dummy = _ai_char->_window_render.attach_new_node("dummy");
00040     _dummy.set_pos(_path[_curr_path_waypoint]);
00041     _ai_char->_steering->pursue(_dummy, _follow_weight);
00042     _time = _myClock->get_real_time();
00043   }
00044 }
00045 
00046 /////////////////////////////////////////////////////////////////////////////////////////
00047 //
00048 // Function : do_follow
00049 // Description : This function allows continuous path finding by ai chars. There are 2
00050 //               ways in which this is implemented.
00051 //               1. The character re-calculates the optimal path everytime the target
00052 //                  changes its position. Less computationally expensive.
00053 //               2. The character continuosly re-calculates its optimal path to the
00054 //                  target. This is used in a scenario where the ai chars have to avoid
00055 //                  other ai chars. More computationally expensive.
00056 
00057 /////////////////////////////////////////////////////////////////////////////////////////
00058 
00059 void PathFollow::do_follow() {
00060   if((_myClock->get_real_time() - _time) > 0.5) {
00061       if(_type=="pathfind") {
00062       // This 'if' statement when 'true' causes the path to be re-calculated irrespective of target position.
00063       // This is done when _dynamice_avoid is active. More computationally expensive.
00064       if(_ai_char->_steering->_path_find_obj->_dynamic_avoid) {
00065         _ai_char->_steering->_path_find_obj->do_dynamic_avoid();
00066         if(check_if_possible()) {
00067           _path.clear();
00068           _ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target);
00069           // Ensure that the path size is not 0.
00070           if(_path.size() > 0) {
00071             _curr_path_waypoint = _path.size() - 1;
00072             _dummy.set_pos(_path[_curr_path_waypoint]);
00073           }
00074           else {
00075           // Refresh the _curr_path_waypoint value if path size is <= 0.
00076           _curr_path_waypoint = -1;
00077           }
00078         }
00079       }
00080       // This 'if' statement causes the path to be re-calculated only when there is a change in target position.
00081       // Less computationally expensive.
00082       else if(_ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render)
00083         != _ai_char->_steering->_path_find_obj->_prev_position) {
00084         if(check_if_possible()) {
00085           _path.clear();
00086           _ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target);
00087           // Ensure that the path size is not 0.
00088           if(_path.size() > 0) {
00089             _curr_path_waypoint = _path.size() - 1;
00090             _dummy.set_pos(_path[_curr_path_waypoint]);
00091           }
00092           else {
00093             // Refresh the _curr_path_waypoint value if path size is 0.
00094             _curr_path_waypoint = -1;
00095           }
00096         }
00097       }
00098       _time = _myClock->get_real_time();
00099     }
00100     }
00101 
00102     if(_curr_path_waypoint > 0) {
00103     double distance = (_path[_curr_path_waypoint] - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length();
00104 
00105     if(distance < 5) {
00106       _curr_path_waypoint--;
00107       _dummy.set_pos(_path[_curr_path_waypoint]);
00108     }
00109   }
00110 }
00111 
00112 /////////////////////////////////////////////////////////////////////////////////////////
00113 //
00114 // Function : check_if_possible
00115 // Description : This function checks if the current positions of the ai char and the
00116 //               target char can be used to generate an optimal path.
00117 
00118 /////////////////////////////////////////////////////////////////////////////////////////
00119 
00120 bool PathFollow::check_if_possible() {
00121   Node* src = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _ai_char->_steering->_path_find_obj->_grid_size);
00122   LVecBase3f _prev_position = _ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render);
00123   Node* dst = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _prev_position, _ai_char->_steering->_path_find_obj->_grid_size);
00124 
00125   if(src && dst) {
00126     return true;
00127   }
00128   else {
00129     return false;
00130   }
00131 }
 All Classes Functions Variables Enumerations