Eina_List* find_points(Eina_List *poly, double x1, double y1, double x2, double y2) { XY *a, *b; Eina_List *sect = NULL; Eina_List *l; double x3, x4, y3, y4; XY *ret; if (!poly) return NULL; a = (XY *) eina_list_last(poly)->data; x3 = a->x; y3 = a->y; b = (XY *) poly->data; x4 = b->x; y4 = b->y; ret = _get_point(x1, y1, x2, y2, x3, y3, x4, y4); if (ret) sect = eina_list_append(sect, ret); for (l = poly; l->next; l = l->next) { a = (XY *) l->data; x3 = a->x; y3 = a->y; b = (XY *) l->next->data; x4 = b->x; y4 = b->y; ret = _get_point(x1, y1, x2, y2, x3, y3, x4, y4); if (ret) sect = eina_list_append(sect, ret); } if (!sect) return NULL; if (!sect->next) return NULL; for (l = sect; l; l = l->next) ENGY_ASSERT(l->data); return sort_list(sect); }
void Navigation2D::_navpoly_link(int p_id) { ERR_FAIL_COND(!navpoly_map.has(p_id)); NavMesh &nm = navpoly_map[p_id]; ERR_FAIL_COND(nm.linked); PoolVector<Vector2> vertices = nm.navpoly->get_vertices(); int len = vertices.size(); if (len == 0) return; PoolVector<Vector2>::Read r = vertices.read(); 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; Vector<int> poly = nm.navpoly->get_polygon(i); int plen = poly.size(); const int *indices = poly.ptr(); bool valid = true; p.edges.resize(plen); Vector2 center; float sum = 0; for (int j = 0; j < plen; j++) { int idx = indices[j]; 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.write[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); } p.clockwise = sum > 0; if (!valid) { nm.polygons.pop_back(); ERR_CONTINUE(!valid); continue; } p.center = center / plen; //connect for (int j = 0; j < plen; j++) { int next = (j + 1) % plen; EdgeKey ek(p.edges[j].point, p.edges[next].point); 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; } else { if (C->get().B != NULL) { ConnectionPending pending; pending.polygon = &p; pending.edge = j; p.edges.write[j].P = C->get().pending.push_back(pending); continue; } C->get().B = &p; C->get().B_edge = j; C->get().A->edges.write[C->get().A_edge].C = &p; C->get().A->edges.write[C->get().A_edge].C_edge = j; p.edges.write[j].C = C->get().A; p.edges.write[j].C_edge = C->get().A_edge; //connection successful. } } } nm.linked = true; }
void Navigation::_navmesh_link(int p_id) { ERR_FAIL_COND(!navmesh_map.has(p_id)); NavMesh &nm=navmesh_map[p_id]; ERR_FAIL_COND(nm.linked); print_line("LINK"); DVector<Vector3> vertices=nm.navmesh->get_vertices(); int len = vertices.size(); if (len==0) return; DVector<Vector3>::Read r=vertices.read(); for(int i=0;i<nm.navmesh->get_polygon_count();i++) { //build List<Polygon>::Element *P=nm.polygons.push_back(Polygon()); Polygon &p=P->get(); p.owner=&nm; Vector<int> poly = nm.navmesh->get_polygon(i); int plen=poly.size(); const int *indices=poly.ptr(); bool valid=true; p.edges.resize(plen); Vector3 center; float sum=0; for(int j=0;j<plen;j++) { int idx = indices[j]; if (idx<0 || idx>=len) { valid=false; break; } Polygon::Edge e; Vector3 ep=nm.xform.xform(r[idx]); center+=ep; e.point=_get_point(ep); p.edges[j]=e; if (j>=2) { Vector3 epa = nm.xform.xform(r[indices[j-2]]); Vector3 epb = nm.xform.xform(r[indices[j-1]]); sum+=up.dot((epb-epa).cross(ep-epa)); } } p.clockwise=sum>0; if (!valid) { nm.polygons.pop_back(); ERR_CONTINUE(!valid); continue; } p.center=center/plen; //connect for(int j=0;j<plen;j++) { int next = (j+1)%plen; EdgeKey ek(p.edges[j].point,p.edges[next].point); 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; } else { if (C->get().B!=NULL) { ConnectionPending 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)); } //ERR_CONTINUE(C->get().B!=NULL); //wut 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; }
point_t get_point(const I& indiv) const { return _get_point(indiv); }