14 _path_finder_obj = NULL;
15 _dynamic_avoid =
false;
18 PathFind::~PathFind() {
41 ifstream nav_mesh_file (navmesh_filename);
43 if(nav_mesh_file.is_open()) {
45 getline(nav_mesh_file, line);
46 int pos = line.find(
",");
47 _grid_size = atoi((line.substr(pos + 1)).c_str());
50 for(
int r = 0; r < _grid_size; ++r) {
51 _nav_mesh.push_back(vector<Node*>());
52 for(
int c = 0; c < _grid_size; ++c) {
53 _nav_mesh[r].push_back(NULL);
58 getline(nav_mesh_file, line);
61 while(!nav_mesh_file.eof()) {
62 getline(nav_mesh_file, line);
67 for(
int i = 0; i < 10; ++i) {
68 getline(linestream, fields[i],
',');
72 if(fields[0] ==
"0" && fields[1] ==
"0") {
73 grid_x = atoi(fields[2].c_str());
74 grid_y = atoi(fields[3].c_str());
75 l = atof(fields[4].c_str());
76 w = atof(fields[5].c_str());
77 h = atof(fields[6].c_str());
78 position =
LVecBase3(atof(fields[7].c_str()), atof(fields[8].c_str()), atof(fields[9].c_str()));
80 Node *stage_node =
new Node(grid_x, grid_y, position, w, l, h);
83 _nav_mesh[grid_y][grid_x] = stage_node;
85 else if(fields[0] ==
"") {
87 nav_mesh_file.close();
95 cout<<
"error opening navmesh.csv file!"<<endl;
108 ifstream nav_mesh_file (navmesh_filename);
111 int gd_x, gd_y, gd_xn, gd_yn;
116 if(nav_mesh_file.is_open()) {
117 getline(nav_mesh_file, ln);
118 getline(nav_mesh_file, ln);
120 while(!nav_mesh_file.eof()) {
121 getline(nav_mesh_file, ln);
123 for(
int i = 0; i < 10; ++i) {
124 getline(linestream, fields[i],
',');
126 if(fields[0] ==
"0" && fields[1] ==
"0") {
128 gd_x = atoi(fields[2].c_str());
129 gd_y = atoi(fields[3].c_str());
130 for(
int i = 0; i < 8; ++i) {
131 getline(nav_mesh_file, ln);
133 for(
int j = 0; j < 10; ++j) {
134 getline(linestream_n, fields_n[j],
',');
136 gd_xn = atoi(fields_n[2].c_str());
137 gd_yn = atoi(fields_n[3].c_str());
139 if(fields_n[0] ==
"0" && fields_n[1] ==
"1") {
142 _nav_mesh[gd_y][gd_x]->_neighbours[i] = _nav_mesh[gd_yn][gd_xn];
144 else if(fields_n[0] ==
"1" && fields_n[1] ==
"1") {
146 _nav_mesh[gd_y][gd_x]->_neighbours[i] = NULL;
149 cout<<
"Warning: Corrupt data!"<<endl;
153 else if(fields[0] ==
"") {
155 nav_mesh_file.close();
160 cout<<
"error opening navmesh.csv file!"<<endl;
176 if(_ai_char->_steering->_path_follow_obj) {
177 _ai_char->_steering->
remove_ai(
"pathfollow");
182 if(_path_finder_obj) {
183 delete _path_finder_obj;
184 _path_finder_obj = NULL;
201 if(type ==
"addPath") {
202 if(_ai_char->_steering->_path_follow_obj) {
203 _ai_char->_steering->
remove_ai(
"pathfollow");
211 Node* src = find_in_mesh(_nav_mesh, _ai_char->_ai_char_np.
get_pos(_ai_char->_window_render), _grid_size);
214 cout<<
"couldnt find source"<<endl;
217 Node* dst = find_in_mesh(_nav_mesh, pos, _grid_size);
220 cout<<
"couldnt find destination"<<endl;
223 if(src != NULL && dst != NULL) {
228 if(!_ai_char->_steering->_path_follow_obj->_start) {
243 if(type ==
"addPath") {
244 if(_ai_char->_steering->_path_follow_obj) {
245 _ai_char->_steering->
remove_ai(
"pathfollow");
253 _path_find_target = target;
254 _prev_position = target.
get_pos(_ai_char->_window_render);
256 Node* src = find_in_mesh(_nav_mesh, _ai_char->_ai_char_np.
get_pos(_ai_char->_window_render), _grid_size);
259 cout<<
"couldnt find source"<<endl;
262 Node* dst = find_in_mesh(_nav_mesh, _prev_position, _grid_size);
265 cout<<
"couldnt find destination"<<endl;
268 if(src != NULL && dst != NULL) {
273 if(_ai_char->_steering->_path_follow_obj!=NULL) {
274 if(!_ai_char->_steering->_path_follow_obj->_start) {
289 for(
int i = 0; i < _grid_size; ++i) {
290 for(
int j = 0; j < _grid_size; ++j) {
291 if(_nav_mesh[i][j] != NULL) {
292 _nav_mesh[i][j]->_status = _nav_mesh[i][j]->neutral;
293 _nav_mesh[i][j]->_cost = 0;
294 _nav_mesh[i][j]->_heuristic = 0;
295 _nav_mesh[i][j]->_score = 0;
296 _nav_mesh[i][j]->_prv_node = NULL;
301 if(_path_finder_obj) {
302 _path_finder_obj->_open_list.clear();
303 _path_finder_obj->_closed_list.clear();
317 if(_ai_char->_pf_guide) {
318 _parent->remove_all_children();
321 _parent->remove_all_children();
324 if(_path_finder_obj->_closed_list.size() > 0) {
325 Node *traversor = _path_finder_obj->_closed_list[_path_finder_obj->_closed_list.size() - 0.5];
326 while(traversor != src) {
327 if(_ai_char->_pf_guide) {
328 _pen->
move_to(traversor->_position.get_x(), traversor->_position.get_y(), 1);
329 _pen->
draw_to(traversor->_prv_node->_position.get_x(), traversor->_prv_node->_position.get_y(), 0.5);
333 _ai_char->_steering->
add_to_path(traversor->_position);
334 traversor = traversor->_prv_node;
353 Node* temp = find_in_mesh(_nav_mesh, obstacle.
get_pos(), _grid_size);
356 float left = temp->_position.get_x() - np_sphere->get_radius();
357 float right = temp->_position.get_x() + np_sphere->get_radius();
358 float top = temp->_position.get_y() + np_sphere->get_radius();
359 float down = temp->_position.get_y() - np_sphere->get_radius();
361 for(
int i = 0; i < _grid_size; ++i) {
362 for(
int j = 0; j < _grid_size; ++j) {
363 if(_nav_mesh[i][j] != NULL && _nav_mesh[i][j]->_type ==
true) {
364 if(_nav_mesh[i][j]->_position.get_x() >= left && _nav_mesh[i][j]->_position.get_x() <= right &&
365 _nav_mesh[i][j]->_position.get_y() >= down && _nav_mesh[i][j]->_position.get_y() <= top) {
366 _nav_mesh[i][j]->_type =
false;
367 _previous_obstacles.insert(_previous_obstacles.end(), i);
368 _previous_obstacles.insert(_previous_obstacles.end(), j);
386 _previous_obstacles.clear();
387 for(
unsigned int i = 0; i < _dynamic_obstacle.size(); ++i) {
401 for(
unsigned int i = 0; i < _previous_obstacles.size(); i = i + 2) {
402 _nav_mesh[_previous_obstacles[i]][_previous_obstacles[i + 1]]->_type =
true;
415 _dynamic_avoid =
true;
416 _dynamic_obstacle.insert(_dynamic_obstacle.end(), obstacle);
void clear_path()
Helper function to restore the path and mesh to its initial state.
void clear_previous_obstacles()
Helper function to reset the collisions if the obstacle is not on the node anymore.
void add_to_path(LVecBase3 pos)
This function adds positions to the path to follow.
This is the base class for all three-component vectors and points.
void dynamic_avoid(NodePath obstacle)
This function starts the pathfinding obstacle navigation for the passed in obstacle.
This class is used to assign the nodes on the mesh.
This defines a bounding sphere, consisting of a center and a radius.
This class implements pathfinding using A* algorithm.
void create_nav_mesh(const char *navmesh_filename)
This function recreates the navigation mesh from the .csv file.
GeomNode * create(bool dynamic=false)
Creates a new GeomNode that will render the series of line segments and points described via calls to...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a=1.0f)
Establishes the color that will be assigned to all vertices created by future calls to move_to() and ...
void set_thickness(PN_stdfloat thick)
Establishes the line thickness or point size in pixels that will be assigned to all lines and points ...
void find_path(Node *src_node, Node *dest_node)
This function initializes the pathfinding process by accepting the source and destination nodes...
void move_to(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Moves the pen to the given point without drawing a line.
Encapsulates creation of a series of connected or disconnected line segments or points, for drawing paths or rays.
LPoint3 get_pos() const
Retrieves the translation component of the transform.
void add_obstacle_to_mesh(NodePath obstacle)
This function allows the user to dynamically add obstacles to the game environment.
void assign_neighbor_nodes(const char *navmesh_filename)
This function assigns the neighbor nodes for each main node present in _nav_mesh. ...
void path_find(LVecBase3 pos, string type="normal")
This function checks for the source and target in the navigation mesh for its availability and then f...
void remove_ai(string ai_type)
This function removes individual or all the AIs.
void draw_to(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Draws a line segment from the pen's last position (the last call to move_to or draw_to) to the indica...
void trace_path(Node *src)
This function is the function which sends the path information one by one to the path follower so tha...
void path_follow(float follow_wt)
This function activates path following.
void start_follow(string type="normal")
This function starts the path follower.
void do_dynamic_avoid()
This function does the updation of the collisions to the mesh based on the new positions of the obsta...
void add_child(PandaNode *child_node, int sort=0, Thread *current_thread=Thread::get_current_thread())
Adds a new child to the node.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
A node that holds Geom objects, renderable pieces of geometry.
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...
void set_path_find(const char *navmesh_filename)
This function starts the path finding process after reading the given navigation mesh.