diff --git a/sdk/map/convert_map.cpp b/sdk/map/convert_map.cpp index 59d2af4..0f288af 100644 --- a/sdk/map/convert_map.cpp +++ b/sdk/map/convert_map.cpp @@ -54,8 +54,13 @@ uint8_t* imageData; uint8_t* tempImageData; size_t width,height,rowSize; -std::unordered_map>,BGRHash> -pixelsPerProvincesPerState; +struct prov +{ + std::vector vertices; + std::vector indices; +}; + +std::unordered_map,BGRHash> pixelsPerProvincesPerState; inline BGR getPixelSafe(size_t r,size_t c){ if(r>=height||c>=width) return EMPTY_COLOR; @@ -93,7 +98,7 @@ void FloodFill(){ if(n%width) q.push(n-1); if(n%width+1&prov,BGR id){ void FindContour(){ for(auto&[state,provs]:pixelsPerProvincesPerState){ for(auto&prov:provs){ - if(prov.empty()) continue; - BGR id=getPixelSafeIndex(prov[0]); - size_t start=FindStart(prov,id); + if(prov.vertices.empty()) continue; + BGR id=getPixelSafeIndex(prov.vertices[0]); + size_t start=FindStart(prov.vertices,id); if(start==std::numeric_limits::max()) continue; std::vector contour; @@ -157,7 +162,7 @@ void FindContour(){ size_t prev = (start % width > 0) ? start - 1 : start + 1; - const size_t MAX=prov.size()*8; + const size_t MAX=prov.vertices.size()*8; for(size_t i=0;i& prov : provs) + for(prov& prov : provs) { - if(prov.size() < 3) + if(prov.vertices.size() < 3) continue; - const size_t n = prov.size(); + const size_t n = prov.vertices.size(); std::vector keep_point(n, true); std::stack> st; @@ -225,9 +230,9 @@ void Aproximate(size_t epsilon) if(keep_point[i]) { double d = PerpendicularDistance( - prov[i], - prov[startIndex], - prov[endIndex], + prov.vertices[i], + prov.vertices[startIndex], + prov.vertices[endIndex], width ); @@ -258,10 +263,10 @@ void Aproximate(size_t epsilon) for(size_t i = 0; i < n; ++i) { if(keep_point[i]) - result.push_back(prov[i]); + result.push_back(prov.vertices[i]); } - prov.swap(result); + prov.vertices.swap(result); } } } @@ -369,12 +374,49 @@ void Triangulate() { for(auto& [state, provs] : pixelsPerProvincesPerState) { - for(std::vector& prov : provs) + for(prov& prov : provs) { - if (prov.size() < 3) + if (prov.vertices.size() < 3) continue; - prov = triangulate_prov(prov, width); + prov.vertices = triangulate_prov(prov.vertices, width); + } + } +} + +void Optimize() +{ + for(auto& [state, provs] : pixelsPerProvincesPerState) + { + for(prov& prov : provs) + { + std::unordered_map vertexToIndex; + vertexToIndex.reserve(prov.vertices.size()); + + std::vector uniqueVertices; + uniqueVertices.reserve(prov.vertices.size()); + + prov.indices.clear(); + + for (size_t v : prov.vertices) + { + auto it = vertexToIndex.find(v); + if (it != vertexToIndex.end()) + { + // вершина уже есть + prov.indices.push_back(it->second); + } + else + { + // новая вершина + uint16_t newIndex = static_cast(uniqueVertices.size()); + uniqueVertices.push_back(v); + vertexToIndex[v] = newIndex; + prov.indices.push_back(newIndex); + } + } + + prov.vertices.swap(uniqueVertices); } } } @@ -382,19 +424,41 @@ void Triangulate() /* ================= OUTPUT ================= */ void GenVertices(std::ofstream&out){ - uint32_t sc=pixelsPerProvincesPerState.size(); - out.write(bytes(&sc),4); - for(auto&[s,provs]:pixelsPerProvincesPerState){ - out.write(bytes(&s),3); - uint32_t pc=provs.size(); - out.write(bytes(&pc),4); - for(auto&p:provs){ - uint32_t vc=p.size(); - out.write(bytes(&vc),4); - for(size_t i:p){ - vertex v{float(i%width),float(i/width)}; + uint32_t statesCount = static_cast(pixelsPerProvincesPerState.size()); + out.write(bytes(&statesCount),4); + + for(auto&[color, provs]:pixelsPerProvincesPerState) + { + out.write(bytes(&color), sizeof(BGR)); + + uint32_t provsCount = static_cast(provs.size()); + out.write(bytes(&provsCount), sizeof(uint32_t)); + + for(prov& prov:provs) + { + //Skip invalid meshes + if (prov.indices.size() % 3 != 0) + { + prov.vertices.clear(); + prov.indices.clear(); + } + + uint32_t verticesCount = static_cast(prov.vertices.size()); + out.write(bytes(&verticesCount), sizeof(uint32_t)); + + for(size_t i: prov.vertices) + { + vertex v{ + static_cast(i%width), + static_cast(i/width) + }; out.write(bytes(&v),sizeof(v)); } + + uint32_t indicesCount = static_cast(prov.indices.size()); + out.write(bytes(&indicesCount), sizeof(uint32_t)); + + out.write(reinterpret_cast(prov.indices.data()), prov.indices.size() * sizeof(uint16_t)); } } } @@ -429,5 +493,6 @@ int main(int argc,char**argv){ FindContour(); Aproximate(1); Triangulate(); + Optimize(); GenVertices(fout); } diff --git a/sdk/map/provinces.map b/sdk/map/provinces.map index c098e62..cdec31f 100644 Binary files a/sdk/map/provinces.map and b/sdk/map/provinces.map differ