diff options
Diffstat (limited to 'scene/2d/navigation2d.cpp')
-rw-r--r-- | scene/2d/navigation2d.cpp | 556 |
1 files changed, 256 insertions, 300 deletions
diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp index 7f48749dc3..f0280a2f81 100644 --- a/scene/2d/navigation2d.cpp +++ b/scene/2d/navigation2d.cpp @@ -33,61 +33,59 @@ void Navigation2D::_navpoly_link(int p_id) { ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm=navpoly_map[p_id]; + NavMesh &nm = navpoly_map[p_id]; ERR_FAIL_COND(nm.linked); - PoolVector<Vector2> vertices=nm.navpoly->get_vertices(); + PoolVector<Vector2> vertices = nm.navpoly->get_vertices(); int len = vertices.size(); - if (len==0) + if (len == 0) return; - PoolVector<Vector2>::Read r=vertices.read(); + PoolVector<Vector2>::Read r = vertices.read(); - for(int i=0;i<nm.navpoly->get_polygon_count();i++) { + for (int i = 0; i < nm.navpoly->get_polygon_count(); i++) { //build - List<Polygon>::Element *P=nm.polygons.push_back(Polygon()); - Polygon &p=P->get(); - p.owner=&nm; + List<Polygon>::Element *P = nm.polygons.push_back(Polygon()); + Polygon &p = P->get(); + p.owner = &nm; Vector<int> poly = nm.navpoly->get_polygon(i); - int plen=poly.size(); - const int *indices=poly.ptr(); - bool valid=true; + int plen = poly.size(); + const int *indices = poly.ptr(); + bool valid = true; p.edges.resize(plen); Vector2 center; - float sum=0; + float sum = 0; - for(int j=0;j<plen;j++) { + for (int j = 0; j < plen; j++) { int idx = indices[j]; - if (idx<0 || idx>=len) { - valid=false; + if (idx < 0 || idx >= len) { + valid = false; break; } Polygon::Edge e; - Vector2 ep=nm.xform.xform(r[idx]); - center+=ep; - e.point=_get_point(ep); - p.edges[j]=e; - - int idxn = indices[(j+1)%plen]; - if (idxn<0 || idxn>=len) { - valid=false; + Vector2 ep = nm.xform.xform(r[idx]); + center += ep; + e.point = _get_point(ep); + p.edges[j] = e; + + int idxn = indices[(j + 1) % plen]; + if (idxn < 0 || idxn >= len) { + valid = false; break; } Vector2 epn = nm.xform.xform(r[idxn]); - sum+=(epn.x-ep.x)*(epn.y+ep.y); - - + sum += (epn.x - ep.x) * (epn.y + ep.y); } - p.clockwise=sum>0; + p.clockwise = sum > 0; if (!valid) { nm.polygons.pop_back(); @@ -95,106 +93,103 @@ void Navigation2D::_navpoly_link(int p_id) { continue; } - p.center=center/plen; + p.center = center / plen; //connect - for(int j=0;j<plen;j++) { + for (int j = 0; j < plen; j++) { - int next = (j+1)%plen; - EdgeKey ek(p.edges[j].point,p.edges[next].point); + int next = (j + 1) % plen; + EdgeKey ek(p.edges[j].point, p.edges[next].point); - Map<EdgeKey,Connection>::Element *C=connections.find(ek); + Map<EdgeKey, Connection>::Element *C = connections.find(ek); if (!C) { Connection c; - c.A=&p; - c.A_edge=j; - c.B=NULL; - c.B_edge=-1; - connections[ek]=c; + c.A = &p; + c.A_edge = j; + c.B = NULL; + c.B_edge = -1; + connections[ek] = c; } else { - if (C->get().B!=NULL) { + if (C->get().B != NULL) { ConnectionPending pending; - pending.polygon=&p; - pending.edge=j; - p.edges[j].P=C->get().pending.push_back(pending); + pending.polygon = &p; + pending.edge = j; + p.edges[j].P = C->get().pending.push_back(pending); continue; //print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b)); } - C->get().B=&p; - C->get().B_edge=j; - C->get().A->edges[C->get().A_edge].C=&p; - C->get().A->edges[C->get().A_edge].C_edge=j; - p.edges[j].C=C->get().A; - p.edges[j].C_edge=C->get().A_edge; + C->get().B = &p; + C->get().B_edge = j; + C->get().A->edges[C->get().A_edge].C = &p; + C->get().A->edges[C->get().A_edge].C_edge = j; + p.edges[j].C = C->get().A; + p.edges[j].C_edge = C->get().A_edge; //connection successful. } } } - nm.linked=true; - + nm.linked = true; } - void Navigation2D::_navpoly_unlink(int p_id) { ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm=navpoly_map[p_id]; + NavMesh &nm = navpoly_map[p_id]; ERR_FAIL_COND(!nm.linked); //print_line("UNLINK"); - for (List<Polygon>::Element *E=nm.polygons.front();E;E=E->next()) { - + for (List<Polygon>::Element *E = nm.polygons.front(); E; E = E->next()) { - Polygon &p=E->get(); + Polygon &p = E->get(); int ec = p.edges.size(); - Polygon::Edge *edges=p.edges.ptr(); + Polygon::Edge *edges = p.edges.ptr(); - for(int i=0;i<ec;i++) { - int next = (i+1)%ec; + for (int i = 0; i < ec; i++) { + int next = (i + 1) % ec; - EdgeKey ek(edges[i].point,edges[next].point); - Map<EdgeKey,Connection>::Element *C=connections.find(ek); + EdgeKey ek(edges[i].point, edges[next].point); + Map<EdgeKey, Connection>::Element *C = connections.find(ek); ERR_CONTINUE(!C); if (edges[i].P) { C->get().pending.erase(edges[i].P); - edges[i].P=NULL; + edges[i].P = NULL; } else if (C->get().B) { //disconnect - C->get().B->edges[C->get().B_edge].C=NULL; - C->get().B->edges[C->get().B_edge].C_edge=-1; - C->get().A->edges[C->get().A_edge].C=NULL; - C->get().A->edges[C->get().A_edge].C_edge=-1; + C->get().B->edges[C->get().B_edge].C = NULL; + C->get().B->edges[C->get().B_edge].C_edge = -1; + C->get().A->edges[C->get().A_edge].C = NULL; + C->get().A->edges[C->get().A_edge].C_edge = -1; - if (C->get().A==&E->get()) { + if (C->get().A == &E->get()) { - C->get().A=C->get().B; - C->get().A_edge=C->get().B_edge; + C->get().A = C->get().B; + C->get().A_edge = C->get().B_edge; } - C->get().B=NULL; - C->get().B_edge=-1; + C->get().B = NULL; + C->get().B_edge = -1; if (C->get().pending.size()) { //reconnect if something is pending ConnectionPending cp = C->get().pending.front()->get(); C->get().pending.pop_front(); - C->get().B=cp.polygon; - C->get().B_edge=cp.edge; - C->get().A->edges[C->get().A_edge].C=cp.polygon; - C->get().A->edges[C->get().A_edge].C_edge=cp.edge; - cp.polygon->edges[cp.edge].C=C->get().A; - cp.polygon->edges[cp.edge].C_edge=C->get().A_edge; - cp.polygon->edges[cp.edge].P=NULL; + C->get().B = cp.polygon; + C->get().B_edge = cp.edge; + C->get().A->edges[C->get().A_edge].C = cp.polygon; + C->get().A->edges[C->get().A_edge].C_edge = cp.edge; + cp.polygon->edges[cp.edge].C = C->get().A; + cp.polygon->edges[cp.edge].C_edge = C->get().A_edge; + cp.polygon->edges[cp.edge].P = NULL; } } else { @@ -206,46 +201,39 @@ void Navigation2D::_navpoly_unlink(int p_id) { nm.polygons.clear(); - nm.linked=false; - - + nm.linked = false; } - -int Navigation2D::navpoly_create(const Ref<NavigationPolygon>& p_mesh, const Transform2D& p_xform, Object *p_owner) { +int Navigation2D::navpoly_create(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) { int id = last_id++; NavMesh nm; - nm.linked=false; - nm.navpoly=p_mesh; - nm.xform=p_xform; - nm.owner=p_owner; - navpoly_map[id]=nm; + nm.linked = false; + nm.navpoly = p_mesh; + nm.xform = p_xform; + nm.owner = p_owner; + navpoly_map[id] = nm; _navpoly_link(id); return id; } -void Navigation2D::navpoly_set_transform(int p_id, const Transform2D& p_xform){ +void Navigation2D::navpoly_set_transform(int p_id, const Transform2D &p_xform) { ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm=navpoly_map[p_id]; - if (nm.xform==p_xform) + NavMesh &nm = navpoly_map[p_id]; + if (nm.xform == p_xform) return; //bleh _navpoly_unlink(p_id); - nm.xform=p_xform; + nm.xform = p_xform; _navpoly_link(p_id); - - - } -void Navigation2D::navpoly_remove(int p_id){ +void Navigation2D::navpoly_remove(int p_id) { ERR_FAIL_COND(!navpoly_map.has(p_id)); _navpoly_unlink(p_id); navpoly_map.erase(p_id); - } #if 0 void Navigation2D::_clip_path(Vector<Vector2>& path, Polygon *from_poly, const Vector2& p_to_point, Polygon* p_to_poly) { @@ -284,96 +272,91 @@ void Navigation2D::_clip_path(Vector<Vector2>& path, Polygon *from_poly, const V } #endif -Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vector2& p_end, bool p_optimize) { +Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) { - - Polygon *begin_poly=NULL; - Polygon *end_poly=NULL; + Polygon *begin_poly = NULL; + Polygon *end_poly = NULL; Vector2 begin_point; Vector2 end_point; - float begin_d=1e20; - float end_d=1e20; + float begin_d = 1e20; + float end_d = 1e20; //look for point inside triangle - for (Map<int,NavMesh>::Element*E=navpoly_map.front();E;E=E->next()) { + for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { if (!E->get().linked) continue; - for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) { - + for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - Polygon &p=F->get(); + Polygon &p = F->get(); if (begin_d || end_d) { - for(int i=2;i<p.edges.size();i++) { + for (int i = 2; i < p.edges.size(); i++) { - if (begin_d>0) { + if (begin_d > 0) { - if (Geometry::is_point_in_triangle(p_start,_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point))) { + if (Geometry::is_point_in_triangle(p_start, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - begin_poly=&p; - begin_point=p_start; - begin_d=0; - if (end_d==0) + begin_poly = &p; + begin_point = p_start; + begin_d = 0; + if (end_d == 0) break; - } } - if (end_d>0) { + if (end_d > 0) { - if (Geometry::is_point_in_triangle(p_end,_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point))) { + if (Geometry::is_point_in_triangle(p_end, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - end_poly=&p; - end_point=p_end; - end_d=0; - if (begin_d==0) + end_poly = &p; + end_point = p_end; + end_d = 0; + if (begin_d == 0) break; } } - } } - p.prev_edge=-1; + p.prev_edge = -1; } } //start or end not inside triangle.. look for closest segment :| if (begin_d || end_d) { - for (Map<int,NavMesh>::Element*E=navpoly_map.front();E;E=E->next()) { + for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { if (!E->get().linked) continue; - for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) { + for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - Polygon &p=F->get(); + Polygon &p = F->get(); int es = p.edges.size(); - for(int i=0;i<es;i++) { + for (int i = 0; i < es; i++) { - Vector2 edge[2]={ + Vector2 edge[2] = { _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i+1)%es].point) + _get_vertex(p.edges[(i + 1) % es].point) }; - - if (begin_d>0) { - Vector2 spoint=Geometry::get_closest_point_to_segment_2d(p_start,edge); + if (begin_d > 0) { + Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_start, edge); float d = spoint.distance_to(p_start); - if (d<begin_d) { - begin_poly=&p; - begin_point=spoint; - begin_d=d; + if (d < begin_d) { + begin_poly = &p; + begin_point = spoint; + begin_d = d; } } - if (end_d>0) { - Vector2 spoint=Geometry::get_closest_point_to_segment_2d(p_end,edge); + if (end_d > 0) { + Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_end, edge); float d = spoint.distance_to(p_end); - if (d<end_d) { - end_poly=&p; - end_point=spoint; - end_d=d; + if (d < end_d) { + end_poly = &p; + end_point = spoint; + end_d = d; } } } @@ -386,96 +369,91 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect return Vector<Vector2>(); //no path } - if (begin_poly==end_poly) { + if (begin_poly == end_poly) { Vector<Vector2> path; path.resize(2); - path[0]=begin_point; - path[1]=end_point; + path[0] = begin_point; + path[1] = end_point; //print_line("Direct Path"); return path; } + bool found_route = false; - bool found_route=false; - - List<Polygon*> open_list; + List<Polygon *> open_list; - begin_poly->entry=p_start; + begin_poly->entry = p_start; - for(int i=0;i<begin_poly->edges.size();i++) { + for (int i = 0; i < begin_poly->edges.size(); i++) { if (begin_poly->edges[i].C) { - begin_poly->edges[i].C->prev_edge=begin_poly->edges[i].C_edge; + begin_poly->edges[i].C->prev_edge = begin_poly->edges[i].C_edge; #ifdef USE_ENTRY_POINT - Vector2 edge[2]={ + Vector2 edge[2] = { _get_vertex(begin_poly->edges[i].point), - _get_vertex(begin_poly->edges[(i+1)%begin_poly->edges.size()].point) + _get_vertex(begin_poly->edges[(i + 1) % begin_poly->edges.size()].point) }; - Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry,edge); + Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry, edge); begin_poly->edges[i].C->distance = begin_poly->entry.distance_to(entry); - begin_poly->edges[i].C->entry=entry; + begin_poly->edges[i].C->entry = entry; #else - begin_poly->edges[i].C->distance=begin_poly->center.distance_to(begin_poly->edges[i].C->center); + begin_poly->edges[i].C->distance = begin_poly->center.distance_to(begin_poly->edges[i].C->center); #endif open_list.push_back(begin_poly->edges[i].C); - if (begin_poly->edges[i].C==end_poly) { - found_route=true; + if (begin_poly->edges[i].C == end_poly) { + found_route = true; } } } + while (!found_route) { - while(!found_route) { - - if (open_list.size()==0) { + if (open_list.size() == 0) { //print_line("NOU OPEN LIST"); break; } //check open list - List<Polygon*>::Element *least_cost_poly=NULL; - float least_cost=1e30; + List<Polygon *>::Element *least_cost_poly = NULL; + float least_cost = 1e30; //this could be faster (cache previous results) - for (List<Polygon*>::Element *E=open_list.front();E;E=E->next()) { - - Polygon *p=E->get(); + for (List<Polygon *>::Element *E = open_list.front(); E; E = E->next()) { + Polygon *p = E->get(); - float cost=p->distance; - cost+=p->center.distance_to(end_point); + float cost = p->distance; + cost += p->center.distance_to(end_point); - if (cost<least_cost) { + if (cost < least_cost) { - least_cost_poly=E; - least_cost=cost; + least_cost_poly = E; + least_cost = cost; } } - - Polygon *p=least_cost_poly->get(); + Polygon *p = least_cost_poly->get(); //open the neighbours for search int es = p->edges.size(); - for(int i=0;i<es;i++) { + for (int i = 0; i < es; i++) { - - Polygon::Edge &e=p->edges[i]; + Polygon::Edge &e = p->edges[i]; if (!e.C) continue; #ifdef USE_ENTRY_POINT - Vector2 edge[2]={ + Vector2 edge[2] = { _get_vertex(p->edges[i].point), - _get_vertex(p->edges[(i+1)%es].point) + _get_vertex(p->edges[(i + 1) % es].point) }; - Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry,edge); + Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry, edge); float distance = p->entry.distance_to(edge_entry) + p->distance; #else @@ -484,36 +462,33 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect #endif - - if (e.C->prev_edge!=-1) { + if (e.C->prev_edge != -1) { //oh this was visited already, can we win the cost? - if (e.C->distance>distance) { + if (e.C->distance > distance) { - e.C->prev_edge=e.C_edge; - e.C->distance=distance; + e.C->prev_edge = e.C_edge; + e.C->distance = distance; #ifdef USE_ENTRY_POINT - e.C->entry=edge_entry; + e.C->entry = edge_entry; #endif } } else { //add to open neighbours - e.C->prev_edge=e.C_edge; - e.C->distance=distance; + e.C->prev_edge = e.C_edge; + e.C->distance = distance; #ifdef USE_ENTRY_POINT - e.C->entry=edge_entry; + e.C->entry = edge_entry; #endif open_list.push_back(e.C); - if (e.C==end_poly) { + if (e.C == end_poly) { //oh my reached end! stop algorithm - found_route=true; + found_route = true; break; - } - } } @@ -552,40 +527,40 @@ debug path if (p_optimize) { //string pulling - Vector2 apex_point=end_point; - Vector2 portal_left=apex_point; - Vector2 portal_right=apex_point; - Polygon *left_poly=end_poly; - Polygon *right_poly=end_poly; - Polygon *p=end_poly; + Vector2 apex_point = end_point; + Vector2 portal_left = apex_point; + Vector2 portal_right = apex_point; + Polygon *left_poly = end_poly; + Polygon *right_poly = end_poly; + Polygon *p = end_poly; path.push_back(end_point); - while(p) { + while (p) { Vector2 left; Vector2 right; //#define CLOCK_TANGENT(m_a,m_b,m_c) ( ((m_a)-(m_c)).cross((m_a)-(m_b)) ) -#define CLOCK_TANGENT(m_a,m_b,m_c) ((((m_a).x - (m_c).x) * ((m_b).y - (m_c).y) - ((m_b).x - (m_c).x) * ((m_a).y - (m_c).y))) +#define CLOCK_TANGENT(m_a, m_b, m_c) ((((m_a).x - (m_c).x) * ((m_b).y - (m_c).y) - ((m_b).x - (m_c).x) * ((m_a).y - (m_c).y))) - if (p==begin_poly) { - left=begin_point; - right=begin_point; + if (p == begin_poly) { + left = begin_point; + right = begin_point; } else { int prev = p->prev_edge; - int prev_n = (p->prev_edge+1)%p->edges.size(); + int prev_n = (p->prev_edge + 1) % p->edges.size(); left = _get_vertex(p->edges[prev].point); right = _get_vertex(p->edges[prev_n].point); if (p->clockwise) { - SWAP(left,right); + SWAP(left, right); } /*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){ SWAP(left,right); }*/ } - bool skip=false; + bool skip = false; /* print_line("-----\nAPEX: "+(apex_point-end_point)); @@ -603,221 +578,202 @@ debug path print_line("\tRight Test: "+rtos(CLOCK_TANGENT(apex_point,right,portal_left))); */ - - if (CLOCK_TANGENT(apex_point,portal_left,left) >= 0){ + if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) { //process - if (portal_left.distance_squared_to(apex_point)<CMP_EPSILON || CLOCK_TANGENT(apex_point,left,portal_right) > 0) { - left_poly=p; - portal_left=left; + if (portal_left.distance_squared_to(apex_point) < CMP_EPSILON || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { + left_poly = p; + portal_left = left; //print_line("***ADVANCE LEFT"); } else { - apex_point=portal_right; - p=right_poly; - left_poly=p; - portal_left=apex_point; - portal_right=apex_point; - if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON) + apex_point = portal_right; + p = right_poly; + left_poly = p; + portal_left = apex_point; + portal_right = apex_point; + if (path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON) path.push_back(apex_point); - skip=true; + skip = true; //print_line("addpoint left"); //print_line("***CLIP LEFT"); } } - if (!skip && CLOCK_TANGENT(apex_point,portal_right,right) <= 0){ + if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) { //process - if (portal_right.distance_squared_to(apex_point)<CMP_EPSILON || CLOCK_TANGENT(apex_point,right,portal_left) < 0) { - right_poly=p; - portal_right=right; + if (portal_right.distance_squared_to(apex_point) < CMP_EPSILON || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { + right_poly = p; + portal_right = right; //print_line("***ADVANCE RIGHT"); } else { - apex_point=portal_left; - p=left_poly; - right_poly=p; - portal_right=apex_point; - portal_left=apex_point; - if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON) + apex_point = portal_left; + p = left_poly; + right_poly = p; + portal_right = apex_point; + portal_left = apex_point; + if (path[path.size() - 1].distance_to(apex_point) > CMP_EPSILON) path.push_back(apex_point); //print_line("addpoint right"); //print_line("***CLIP RIGHT"); - } } - if (p!=begin_poly) - p=p->edges[p->prev_edge].C; + if (p != begin_poly) + p = p->edges[p->prev_edge].C; else - p=NULL; - + p = NULL; } - if (path[path.size()-1].distance_to(begin_point)>CMP_EPSILON) + if (path[path.size() - 1].distance_to(begin_point) > CMP_EPSILON) path.push_back(begin_point); path.invert(); - - - } else { //midpoints - Polygon *p=end_poly; + Polygon *p = end_poly; path.push_back(end_point); - while(true) { + while (true) { int prev = p->prev_edge; - int prev_n = (p->prev_edge+1)%p->edges.size(); - Vector2 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point))*0.5; + int prev_n = (p->prev_edge + 1) % p->edges.size(); + Vector2 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point)) * 0.5; path.push_back(point); p = p->edges[prev].C; - if (p==begin_poly) + if (p == begin_poly) break; } path.push_back(begin_point); - path.invert(); } return path; } - return Vector<Vector2>(); - } +Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) { -Vector2 Navigation2D::get_closest_point(const Vector2& p_point) { - - Vector2 closest_point=Vector2(); - float closest_point_d=1e20; + Vector2 closest_point = Vector2(); + float closest_point_d = 1e20; - for (Map<int,NavMesh>::Element*E=navpoly_map.front();E;E=E->next()) { + for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { if (!E->get().linked) continue; - for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) { + for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - Polygon &p=F->get(); - for(int i=2;i<p.edges.size();i++) { + Polygon &p = F->get(); + for (int i = 2; i < p.edges.size(); i++) { - if (Geometry::is_point_in_triangle(p_point,_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point))) { + if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { return p_point; //inside triangle, nothing else to discuss } - } } } - for (Map<int,NavMesh>::Element*E=navpoly_map.front();E;E=E->next()) { + for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { if (!E->get().linked) continue; - for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) { + for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - Polygon &p=F->get(); + Polygon &p = F->get(); int es = p.edges.size(); - for(int i=0;i<es;i++) { + for (int i = 0; i < es; i++) { - Vector2 edge[2]={ + Vector2 edge[2] = { _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i+1)%es].point) + _get_vertex(p.edges[(i + 1) % es].point) }; - - Vector2 spoint=Geometry::get_closest_point_to_segment_2d(p_point,edge); + Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge); float d = spoint.distance_squared_to(p_point); - if (d<closest_point_d) { + if (d < closest_point_d) { - closest_point=spoint; - closest_point_d=d; + closest_point = spoint; + closest_point_d = d; } } } } return closest_point; - } -Object* Navigation2D::get_closest_point_owner(const Vector2& p_point) { +Object *Navigation2D::get_closest_point_owner(const Vector2 &p_point) { - Object *owner=NULL; - Vector2 closest_point=Vector2(); - float closest_point_d=1e20; + Object *owner = NULL; + Vector2 closest_point = Vector2(); + float closest_point_d = 1e20; - for (Map<int,NavMesh>::Element*E=navpoly_map.front();E;E=E->next()) { + for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { if (!E->get().linked) continue; - for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) { + for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - Polygon &p=F->get(); - for(int i=2;i<p.edges.size();i++) { + Polygon &p = F->get(); + for (int i = 2; i < p.edges.size(); i++) { - if (Geometry::is_point_in_triangle(p_point,_get_vertex(p.edges[0].point),_get_vertex(p.edges[i-1].point),_get_vertex(p.edges[i].point))) { + if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { E->get().owner; } - } } } - for (Map<int,NavMesh>::Element*E=navpoly_map.front();E;E=E->next()) { + for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { if (!E->get().linked) continue; - for(List<Polygon>::Element *F=E->get().polygons.front();F;F=F->next()) { + for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - Polygon &p=F->get(); + Polygon &p = F->get(); int es = p.edges.size(); - for(int i=0;i<es;i++) { + for (int i = 0; i < es; i++) { - Vector2 edge[2]={ + Vector2 edge[2] = { _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i+1)%es].point) + _get_vertex(p.edges[(i + 1) % es].point) }; - - Vector2 spoint=Geometry::get_closest_point_to_segment_2d(p_point,edge); + Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge); float d = spoint.distance_squared_to(p_point); - if (d<closest_point_d) { + if (d < closest_point_d) { - closest_point=spoint; - closest_point_d=d; - owner=E->get().owner; + closest_point = spoint; + closest_point_d = d; + owner = E->get().owner; } } } } return owner; - } - void Navigation2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("navpoly_create","mesh:NavigationPolygon","xform","owner"),&Navigation2D::navpoly_create,DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("navpoly_set_transform","id","xform"),&Navigation2D::navpoly_set_transform); - ClassDB::bind_method(D_METHOD("navpoly_remove","id"),&Navigation2D::navpoly_remove); - - ClassDB::bind_method(D_METHOD("get_simple_path","start","end","optimize"),&Navigation2D::get_simple_path,DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_closest_point","to_point"),&Navigation2D::get_closest_point); - ClassDB::bind_method(D_METHOD("get_closest_point_owner","to_point"),&Navigation2D::get_closest_point_owner); + ClassDB::bind_method(D_METHOD("navpoly_create", "mesh:NavigationPolygon", "xform", "owner"), &Navigation2D::navpoly_create, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("navpoly_set_transform", "id", "xform"), &Navigation2D::navpoly_set_transform); + ClassDB::bind_method(D_METHOD("navpoly_remove", "id"), &Navigation2D::navpoly_remove); + ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point); + ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner); } Navigation2D::Navigation2D() { - ERR_FAIL_COND( sizeof(Point)!=8 ); - cell_size=1; // one pixel - last_id=1; - + ERR_FAIL_COND(sizeof(Point) != 8); + cell_size = 1; // one pixel + last_id = 1; } |