Panda3D
pathFollow.cxx
1 
2 #include "pathFollow.h"
3 
4 PathFollow::PathFollow(AICharacter *ai_ch, float follow_wt) {
5  _follow_weight = follow_wt;
6  _curr_path_waypoint = -1;
7  _start = false;
8  _ai_char = ai_ch;
10 }
11 
12 PathFollow::~PathFollow() {
13 }
14 
15 /**
16  * This function adds the positions generated from a pathfind or a simple path
17  * follow behavior to the _path list.
18  */
19 void PathFollow::add_to_path(LVecBase3 pos) {
20  _path.push_back(pos);
21 }
22 
23 /**
24  * This function initiates the path follow behavior.
25  */
26 void PathFollow::start(std::string type) {
27  _type = type;
28  _start = true;
29  if(_path.size() > 0) {
30  _curr_path_waypoint = _path.size() - 1;
31  _dummy = _ai_char->_window_render.attach_new_node("dummy");
32  _dummy.set_pos(_path[_curr_path_waypoint]);
33  _ai_char->_steering->pursue(_dummy, _follow_weight);
34  _time = _myClock->get_real_time();
35  }
36 }
37 
38 /**
39  * This function allows continuous path finding by ai chars. There are 2 ways
40  * in which this is implemented. 1. The character re-calculates the optimal
41  * path everytime the target changes its position. Less computationally
42  * expensive. 2. The character continuosly re-calculates its optimal path to
43  * the target. This is used in a scenario where the ai chars have to avoid
44  * other ai chars. More computationally expensive.
45  */
47  if((_myClock->get_real_time() - _time) > 0.5) {
48  if(_type=="pathfind") {
49  // This 'if' statement when 'true' causes the path to be re-calculated
50  // irrespective of target position. This is done when _dynamice_avoid
51  // is active. More computationally expensive.
52  if(_ai_char->_steering->_path_find_obj->_dynamic_avoid) {
53  _ai_char->_steering->_path_find_obj->do_dynamic_avoid();
54  if(check_if_possible()) {
55  _path.clear();
56  _ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target);
57  // Ensure that the path size is not 0.
58  if(_path.size() > 0) {
59  _curr_path_waypoint = _path.size() - 1;
60  _dummy.set_pos(_path[_curr_path_waypoint]);
61  }
62  else {
63  // Refresh the _curr_path_waypoint value if path size is <= 0.
64  _curr_path_waypoint = -1;
65  }
66  }
67  }
68  // This 'if' statement causes the path to be re-calculated only when
69  // there is a change in target position. Less computationally
70  // expensive.
71  else if(_ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render)
72  != _ai_char->_steering->_path_find_obj->_prev_position) {
73  if(check_if_possible()) {
74  _path.clear();
75  _ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target);
76  // Ensure that the path size is not 0.
77  if(_path.size() > 0) {
78  _curr_path_waypoint = _path.size() - 1;
79  _dummy.set_pos(_path[_curr_path_waypoint]);
80  }
81  else {
82  // Refresh the _curr_path_waypoint value if path size is 0.
83  _curr_path_waypoint = -1;
84  }
85  }
86  }
87  _time = _myClock->get_real_time();
88  }
89  }
90 
91  if(_curr_path_waypoint > 0) {
92  double distance = (_path[_curr_path_waypoint] - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length();
93 
94  if(distance < 5) {
95  _curr_path_waypoint--;
96  _dummy.set_pos(_path[_curr_path_waypoint]);
97  }
98  }
99 }
100 
101 /**
102  * This function checks if the current positions of the ai char and the target
103  * char can be used to generate an optimal path.
104  */
106  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);
107  LVecBase3 _prev_position = _ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render);
108  Node* dst = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _prev_position, _ai_char->_steering->_path_find_obj->_grid_size);
109 
110  if(src && dst) {
111  return true;
112  }
113  else {
114  return false;
115  }
116 }
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:215
Node * find_in_mesh(NavMesh nav_mesh, LVecBase3 pos, int grid_size)
This function allows the user to pass a position and it returns the corresponding node on the navigat...
This class is used to assign the nodes on the mesh.
Definition: meshNode.h:16
void do_follow()
This function allows continuous path finding by ai chars.
Definition: pathFollow.cxx:46
void add_to_path(LVecBase3 pos)
This function adds the positions generated from a pathfind or a simple path follow behavior to the _p...
Definition: pathFollow.cxx:19
void path_find(LVecBase3 pos, std::string type="normal")
This function checks for the source and target in the navigation mesh for its availability and then f...
Definition: pathFind.cxx:201
NodePath attach_new_node(PandaNode *node, int sort=0, Thread *current_thread=Thread::get_current_thread()) const
Attaches a new node, with or without existing parents, to the scene graph below the referenced node o...
Definition: nodePath.cxx:563
get_real_time
Returns the actual number of seconds elapsed since the ClockObject was created, or since it was last ...
Definition: clockObject.h:92
LPoint3 get_pos() const
Retrieves the translation component of the transform.
Definition: nodePath.cxx:992
bool check_if_possible()
This function checks if the current positions of the ai char and the target char can be used to gener...
Definition: pathFollow.cxx:105
void do_dynamic_avoid()
This function does the updation of the collisions to the mesh based on the new positions of the obsta...
Definition: pathFind.cxx:365
void start(std::string type)
This function initiates the path follow behavior.
Definition: pathFollow.cxx:26
void pursue(NodePath target_object, float pursue_wt=1.0)
This function activates pursue.