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 00020 00022 00023 void PathFollow::add_to_path(LVecBase3f pos) { 00024 _path.push_back(pos); 00025 } 00026 00031 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 00056 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 00117 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 }