Panda3D
|
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 }