Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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;

}
Exemple #4
0
 point_t get_point(const I& indiv) const {
   return _get_point(indiv);
 }