Example #1
0
Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> polygon) {
	Vector<Vector<Vector2> > decomp;
	List<TriangulatorPoly> in_poly, out_poly;

	TriangulatorPoly inp;
	inp.Init(polygon.size());
	for (int i = 0; i < polygon.size(); i++) {
		inp.GetPoint(i) = polygon[i];
	}
	inp.SetOrientation(TRIANGULATOR_CCW);
	in_poly.push_back(inp);
	TriangulatorPartition tpart;
	if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
		ERR_PRINT("Convex decomposing failed!");
		return decomp;
	}

	decomp.resize(out_poly.size());
	int idx = 0;
	for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
		TriangulatorPoly &tp = I->get();

		decomp.write[idx].resize(tp.GetNumPoints());

		for (int i = 0; i < tp.GetNumPoints(); i++) {
			decomp.write[idx].write[i] = tp.GetPoint(i);
		}

		idx++;
	}

	return decomp;
}
Vector< Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() {

	Vector< Vector<Vector2> > decomp;
#if 0
	//fast but imprecise triangulator, gave us problems
	decomp = Geometry::decompose_polygon(polygon);
#else

	List<TriangulatorPoly> in_poly,out_poly;

	TriangulatorPoly inp;
	inp.Init(polygon.size());
	for(int i=0;i<polygon.size();i++) {
		inp.GetPoint(i)=polygon[i];
	}
	inp.SetOrientation(TRIANGULATOR_CCW);
	in_poly.push_back(inp);
	TriangulatorPartition tpart;
	if (tpart.ConvexPartition_HM(&in_poly,&out_poly)==0) { //failed!
		ERR_PRINT("Convex decomposing failed!");
		return decomp;
	}

	decomp.resize(out_poly.size());
	int idx=0;

	for(List<TriangulatorPoly>::Element*I = out_poly.front();I;I=I->next()) {

		TriangulatorPoly& tp = I->get();

		decomp[idx].resize(tp.GetNumPoints());

		for(int i=0;i<tp.GetNumPoints();i++) {

			decomp[idx][i]=tp.GetPoint(i);
		}

		idx++;
	}

#endif

	return decomp;
}
Example #3
0
void NavigationPolygon::make_polygons_from_outlines() {

    List<TriangulatorPoly> in_poly,out_poly;

    Vector2 outside_point(-1e10,-1e10);

    for(int i=0; i<outlines.size(); i++) {

        DVector<Vector2> ol = outlines[i];
        int olsize = ol.size();
        if (olsize<3)
            continue;
        DVector<Vector2>::Read r=ol.read();
        for(int j=0; j<olsize; j++) {
            outside_point.x = MAX( r[j].x, outside_point.x );
            outside_point.y = MAX( r[j].y, outside_point.y );
        }

    }

    outside_point+=Vector2(0.7239784,0.819238); //avoid precision issues



    for(int i=0; i<outlines.size(); i++) {

        DVector<Vector2> ol = outlines[i];
        int olsize = ol.size();
        if (olsize<3)
            continue;
        DVector<Vector2>::Read r=ol.read();

        int interscount=0;
        //test if this is an outer outline
        for(int k=0; k<outlines.size(); k++) {

            if (i==k)
                continue; //no self intersect

            DVector<Vector2> ol2 = outlines[k];
            int olsize2 = ol2.size();
            if (olsize2<3)
                continue;
            DVector<Vector2>::Read r2=ol2.read();

            for(int l=0; l<olsize2; l++) {

                if (Geometry::segment_intersects_segment_2d(r[0],outside_point,r2[l],r2[(l+1)%olsize2],NULL)) {
                    interscount++;
                }
            }

        }

        bool outer = (interscount%2)==0;

        TriangulatorPoly tp;
        tp.Init(olsize);
        for(int j=0; j<olsize; j++) {
            tp[j]=r[j];
        }

        if (outer)
            tp.SetOrientation(TRIANGULATOR_CCW);
        else {
            tp.SetOrientation(TRIANGULATOR_CW);
            tp.SetHole(true);
        }

        in_poly.push_back(tp);
    }


    TriangulatorPartition tpart;
    if (tpart.ConvexPartition_HM(&in_poly,&out_poly)==0) { //failed!
        print_line("convex partition failed!");
        return;
    }

    polygons.clear();
    vertices.resize(0);

    Map<Vector2,int> points;
    for(List<TriangulatorPoly>::Element*I = out_poly.front(); I; I=I->next()) {

        TriangulatorPoly& tp = I->get();

        struct Polygon p;

        for(int i=0; i<tp.GetNumPoints(); i++) {

            Map<Vector2,int>::Element *E=points.find(tp[i]);
            if (!E) {
                E=points.insert(tp[i],vertices.size());
                vertices.push_back(tp[i]);
            }
            p.indices.push_back(E->get());
        }

        polygons.push_back(p);
    }

    emit_signal(CoreStringNames::get_singleton()->changed);
}