示例#1
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);
}