30 _path_finder_obj =
nullptr;
31 _dynamic_avoid =
false;
34 PathFind::~PathFind() {
53 std::ifstream nav_mesh_file (navmesh_filename);
55 if(nav_mesh_file.is_open()) {
57 getline(nav_mesh_file, line);
58 int pos = line.find(
",");
59 _grid_size = atoi((line.substr(pos + 1)).c_str());
62 for(
int r = 0; r < _grid_size; ++r) {
63 _nav_mesh.push_back(std::vector<Node*>());
64 for(
int c = 0; c < _grid_size; ++c) {
65 _nav_mesh[r].push_back(
nullptr);
70 getline(nav_mesh_file, line);
73 while(!nav_mesh_file.eof()) {
74 getline(nav_mesh_file, line);
75 std::stringstream linestream (line);
80 for(
int i = 0; i < 10; ++i) {
81 getline(linestream, fields[i],
',');
85 if(fields[0] ==
"0" && fields[1] ==
"0") {
86 grid_x = atoi(fields[2].c_str());
87 grid_y = atoi(fields[3].c_str());
88 l = atof(fields[4].c_str());
89 w = atof(fields[5].c_str());
90 h = atof(fields[6].c_str());
91 position = LVecBase3(atof(fields[7].c_str()), atof(fields[8].c_str()), atof(fields[9].c_str()));
93 Node *stage_node =
new Node(grid_x, grid_y, position, w, l, h);
96 _nav_mesh[grid_y][grid_x] = stage_node;
98 else if(fields[0] ==
"") {
100 nav_mesh_file.close();
109 cout<<
"error opening navmesh.csv file!"<<endl;
118 std::ifstream nav_mesh_file (navmesh_filename);
121 int gd_x, gd_y, gd_xn, gd_yn;
126 if(nav_mesh_file.is_open()) {
127 getline(nav_mesh_file, ln);
128 getline(nav_mesh_file, ln);
130 while(!nav_mesh_file.eof()) {
131 getline(nav_mesh_file, ln);
132 std::stringstream linestream (ln);
133 for(
int i = 0; i < 10; ++i) {
134 getline(linestream, fields[i],
',');
136 if(fields[0] ==
"0" && fields[1] ==
"0") {
138 gd_x = atoi(fields[2].c_str());
139 gd_y = atoi(fields[3].c_str());
140 for(
int i = 0; i < 8; ++i) {
141 getline(nav_mesh_file, ln);
142 std::stringstream linestream_n (ln);
143 for(
int j = 0; j < 10; ++j) {
144 getline(linestream_n, fields_n[j],
',');
146 gd_xn = atoi(fields_n[2].c_str());
147 gd_yn = atoi(fields_n[3].c_str());
149 if(fields_n[0] ==
"0" && fields_n[1] ==
"1") {
153 _nav_mesh[gd_y][gd_x]->_neighbours[i] = _nav_mesh[gd_yn][gd_xn];
155 else if(fields_n[0] ==
"1" && fields_n[1] ==
"1") {
157 _nav_mesh[gd_y][gd_x]->_neighbours[i] =
nullptr;
160 cout<<
"Warning: Corrupt data!"<<endl;
164 else if(fields[0] ==
"") {
166 nav_mesh_file.close();
171 cout<<
"error opening navmesh.csv file!"<<endl;
182 if(_ai_char->_steering->_path_follow_obj) {
183 _ai_char->_steering->
remove_ai(
"pathfollow");
188 if(_path_finder_obj) {
189 delete _path_finder_obj;
190 _path_finder_obj =
nullptr;
202 if(type ==
"addPath") {
203 if(_ai_char->_steering->_path_follow_obj) {
204 _ai_char->_steering->
remove_ai(
"pathfollow");
215 cout<<
"couldnt find source"<<endl;
221 cout<<
"couldnt find destination"<<endl;
224 if(src !=
nullptr && dst !=
nullptr) {
229 if(!_ai_char->_steering->_path_follow_obj->_start) {
240 if(type ==
"addPath") {
241 if(_ai_char->_steering->_path_follow_obj) {
242 _ai_char->_steering->
remove_ai(
"pathfollow");
250 _path_find_target = target;
251 _prev_position = target.
get_pos(_ai_char->_window_render);
256 cout<<
"couldnt find source"<<endl;
262 cout<<
"couldnt find destination"<<endl;
265 if(src !=
nullptr && dst !=
nullptr) {
270 if(_ai_char->_steering->_path_follow_obj!=
nullptr) {
271 if(!_ai_char->_steering->_path_follow_obj->_start) {
282 for(
int i = 0; i < _grid_size; ++i) {
283 for(
int j = 0; j < _grid_size; ++j) {
284 if(_nav_mesh[i][j] !=
nullptr) {
285 _nav_mesh[i][j]->_status = _nav_mesh[i][j]->neutral;
286 _nav_mesh[i][j]->_cost = 0;
287 _nav_mesh[i][j]->_heuristic = 0;
288 _nav_mesh[i][j]->_score = 0;
289 _nav_mesh[i][j]->_prv_node =
nullptr;
294 if(_path_finder_obj) {
295 _path_finder_obj->_open_list.clear();
296 _path_finder_obj->_closed_list.clear();
306 if(_ai_char->_pf_guide) {
307 _parent->remove_all_children();
310 _parent->remove_all_children();
313 if(_path_finder_obj->_closed_list.size() > 0) {
314 Node *traversor = _path_finder_obj->_closed_list[_path_finder_obj->_closed_list.size() - 0.5];
315 while(traversor != src) {
316 if(_ai_char->_pf_guide) {
317 _pen->
move_to(traversor->_position.get_x(), traversor->_position.get_y(), 1);
318 _pen->
draw_to(traversor->_prv_node->_position.get_x(), traversor->_prv_node->_position.get_y(), 0.5);
320 _parent->add_child(gnode);
322 _ai_char->_steering->
add_to_path(traversor->_position);
323 traversor = traversor->_prv_node;
340 if(temp !=
nullptr) {
341 float left = temp->_position.get_x() - np_sphere->get_radius();
342 float right = temp->_position.get_x() + np_sphere->get_radius();
343 float top = temp->_position.get_y() + np_sphere->get_radius();
344 float down = temp->_position.get_y() - np_sphere->get_radius();
346 for(
int i = 0; i < _grid_size; ++i) {
347 for(
int j = 0; j < _grid_size; ++j) {
348 if(_nav_mesh[i][j] !=
nullptr && _nav_mesh[i][j]->_type ==
true) {
349 if(_nav_mesh[i][j]->_position.get_x() >= left && _nav_mesh[i][j]->_position.get_x() <= right &&
350 _nav_mesh[i][j]->_position.get_y() >= down && _nav_mesh[i][j]->_position.get_y() <= top) {
351 _nav_mesh[i][j]->_type =
false;
352 _previous_obstacles.insert(_previous_obstacles.end(), i);
353 _previous_obstacles.insert(_previous_obstacles.end(), j);
367 _previous_obstacles.clear();
368 for(
unsigned int i = 0; i < _dynamic_obstacle.size(); ++i) {
378 for(
unsigned int i = 0; i < _previous_obstacles.size(); i = i + 2) {
379 _nav_mesh[_previous_obstacles[i]][_previous_obstacles[i + 1]]->_type =
true;
388 _dynamic_avoid =
true;
389 _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.
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...
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.
void remove_ai(std::string ai_type)
This function removes individual or all the AIs.
Encapsulates creation of a series of connected or disconnected line segments or points,...
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...
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 add_obstacle_to_mesh(NodePath obstacle)
This function allows the user to dynamically add obstacles to the game environment.
void start_follow(std::string type="normal")
This function starts the path follower.
void assign_neighbor_nodes(const char *navmesh_filename)
This function assigns the neighbor nodes for each main node present in _nav_mesh.
LPoint3 get_pos() const
Retrieves the translation component of the transform.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void do_dynamic_avoid()
This function does the updation of the collisions to the mesh based on the new positions of the obsta...
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.
void set_path_find(const char *navmesh_filename)
This function starts the path finding process after reading the given navigation mesh.