void NavMesh::BuildPointsTriangle(int width, int depth, std::function<bool (int, int)> predicate) { for (int i=0; i<triangles.size(); i++) { delete triangles[i]; } triangles.clear(); navigation.clear(); collision.clear(); trianglesPerVertex.clear(); std::vector<double> outer = { 0,0, (double)width,0, 0,(double)depth, (double)width,(double)depth, }; std::vector<int> segments = { 0,1, 1,3, 3,2, 2,0, }; std::vector<double> holes; int lastPos = width - 1; for (int z=0; z<depth; ++z) { int unblockPos = 0; for (int x=0; x<width; ++x) { bool blocked = predicate(x,z); //if (blocked) { // AddHole(outer, segments, holes, {(float)x,(float)z}, {1.0f, 1.0f}); //} //continue; if (!blocked || x == lastPos) { int size = x - unblockPos; if (x == lastPos ) { size++; } if (size>0) { AddHole(outer, segments, holes, {(float)unblockPos,(float)z}, {(float)size, 1.0f}); } unblockPos = x + 1; } } } triangulateio in; memset(&in, 0, sizeof(triangulateio)); in.numberofpoints = (int)outer.size()/2; in.pointlist = &outer[0]; in.holelist = &holes[0]; in.numberofholes = (int)holes.size()/2; in.segmentlist = &segments[0]; in.numberofsegments = (int)segments.size()/2; triangulateio out; memset(&out, 0, sizeof(triangulateio)); triangulate("zpnQ", &in, &out, (struct triangulateio *) NULL ); triangles.resize(out.numberoftriangles); for (int i=0; i<out.numberoftriangles; i++) { triangles[i] = new NavTriangle(); } collision.resize(out.numberofpoints); trianglesPerVertex.resize(out.numberofpoints); for (int i=0; i<out.numberofpoints; i++) { double* pos = &out.pointlist[i*2]; collision[i].x = (float)pos[0]; collision[i].y = (float)pos[1]; } navigation = collision; std::cout<<"-------------"<<std::endl; for (int i=0; i<out.numberoftriangles; i++) { int* triangleIndex = &out.trianglelist[i*3]; //std::cout<<triangle[0]<<", "<<triangle[1]<<", " <<triangle[2]<<std::endl; NavTriangle& tri = *triangles[i]; tri.corners[0]= triangleIndex[0]; tri.corners[1]= triangleIndex[1]; tri.corners[2]= triangleIndex[2]; int* neighbor = &out.neighborlist[i*3]; tri.neighbors[1] = neighbor[0]>=0 ? triangles[neighbor[0]] : 0; tri.neighbors[2] = neighbor[1]>=0 ? triangles[neighbor[1]] : 0; tri.neighbors[0] = neighbor[2]>=0 ? triangles[neighbor[2]] : 0; // std::cout<<"neightbor"<<std::endl; // std::cout<<neighbor[0]<<", "<<neighbor[1]<<", " <<neighbor[2]<<std::endl; } trifree(out.pointlist); trifree(out.neighborlist); trifree(out.trianglelist); TrimSmallTriangles(); Grow(navigation, -0.5f); version++; }
int delaunay_triangulation(Point2f* points, int size, int** edges) { struct triangulateio in, mid; /* Define input points. */ in.numberofpoints = size; in.numberofpointattributes = 0; in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL)); for (int i = 0; i < size; i++) { in.pointlist[i*2] = points[i].x; in.pointlist[i*2+1] = points[i].y; } in.pointattributelist = (REAL *) NULL; in.pointmarkerlist = (int *) NULL; in.numberofsegments = 0; in.numberofholes = 0; in.numberofregions = 0; in.regionlist = (REAL *) NULL; mid.pointlist = (REAL *) NULL; /* Not needed if -N switch used. */ /* Not needed if -N switch used or number of point attributes is zero: */ mid.pointattributelist = (REAL *) NULL; mid.pointmarkerlist = (int *) NULL; /* Not needed if -N or -B switch used. */ mid.trianglelist = (int *) NULL; /* Not needed if -E switch used. */ mid.trianglearealist = (double *) NULL; /* Not needed if -E switch used. */ /* Not needed if -E switch used or number of triangle attributes is zero: */ mid.triangleattributelist = (REAL *) NULL; mid.neighborlist = (int *) NULL; /* Needed only if -n switch used. */ /* Needed only if segments are output (-p or -c) and -P not used: */ mid.segmentlist = (int *) NULL; /* Needed only if segments are output (-p or -c) and -P and -B not used: */ mid.segmentmarkerlist = (int *) NULL; mid.edgelist = (int *) NULL; /* Needed only if -e switch used. */ mid.edgemarkerlist = (int *) NULL; /* Needed if -e used and -B not used. */ /* Triangulate the points. Switches are chosen to read and write a */ /* PSLG (p), preserve the convex hull (c), number everything from */ /* zero (z), assign a regional attribute to each element (A), and */ /* produce an edge list (e), a Voronoi diagram (v), and a triangle */ /* neighbor list (n). */ triangulate("zeQ", &in, &mid, NULL); trifree(in.pointlist); trifree(in.pointattributelist); trifree(in.pointmarkerlist); trifree(in.regionlist); trifree(mid.pointlist); trifree(mid.pointattributelist); trifree(mid.pointmarkerlist); trifree(mid.trianglelist); trifree(mid.triangleattributelist); trifree(mid.trianglearealist); trifree(mid.neighborlist); trifree(mid.segmentlist); trifree(mid.segmentmarkerlist); trifree(mid.edgemarkerlist); *edges = mid.edgelist; return mid.numberofedges; //trifree(mid.edgelist); }