Find map provs contour
This commit is contained in:
parent
90b28158be
commit
a157492b4b
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"cmake.debugConfig": {
|
||||||
|
"args": ["D:/PROJECTS/EtrediaEmpires/sdk/map/provinces.bmp", "D:/PROJECTS/EtrediaEmpires/sdk/map/provinces.map"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
project (EtrediaEmpires)
|
project (EtrediaEmpires)
|
||||||
|
|
||||||
|
add_subdirectory(sdk/map)
|
||||||
add_subdirectory(sdk/materials)
|
add_subdirectory(sdk/materials)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
add_subdirectory(p7lib)
|
add_subdirectory(p7lib)
|
||||||
|
|||||||
0
assets/map/provinces.map
Normal file
0
assets/map/provinces.map
Normal file
BIN
assets/materials/helloworld.mat
Normal file
BIN
assets/materials/helloworld.mat
Normal file
Binary file not shown.
@ -25,6 +25,7 @@ file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
|
|||||||
find_package(Boost REQUIRED COMPONENTS lockfree)
|
find_package(Boost REQUIRED COMPONENTS lockfree)
|
||||||
find_package(xxHash CONFIG REQUIRED)
|
find_package(xxHash CONFIG REQUIRED)
|
||||||
find_package(glfw3 CONFIG REQUIRED)
|
find_package(glfw3 CONFIG REQUIRED)
|
||||||
|
find_package(glm CONFIG REQUIRED)
|
||||||
|
|
||||||
# Link library
|
# Link library
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE Boost::lockfree)
|
|||||||
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE p7)
|
target_link_libraries(${PROJECT_NAME} PRIVATE p7)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE glfw)
|
target_link_libraries(${PROJECT_NAME} PRIVATE glfw)
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm)
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC include/)
|
target_include_directories(${PROJECT_NAME} PUBLIC include/)
|
||||||
|
|
||||||
|
|||||||
45
sdk/map/CMakeLists.txt
Normal file
45
sdk/map/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
cmake_minimum_required (VERSION 3.8)
|
||||||
|
|
||||||
|
if (POLICY CMP0141)
|
||||||
|
cmake_policy(SET CMP0141 NEW)
|
||||||
|
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
project (convert_map)
|
||||||
|
|
||||||
|
# find_package(glm CONFIG REQUIRED)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} convert_map.cpp)
|
||||||
|
|
||||||
|
# target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm)
|
||||||
|
# target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/engine/include/)
|
||||||
|
|
||||||
|
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||||
|
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(GLOB MAP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.bmp")
|
||||||
|
|
||||||
|
set(COMPILED_DIR "${CMAKE_SOURCE_DIR}/assets/map")
|
||||||
|
|
||||||
|
foreach(MAP ${MAP_FILES})
|
||||||
|
get_filename_component(MAP_NAME ${MAP} NAME_WE)
|
||||||
|
set(OUT_FILE "${COMPILED_DIR}/${MAP_NAME}.map")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${OUT_FILE}
|
||||||
|
COMMAND ${PROJECT_NAME} ${MAP} ${OUT_FILE}
|
||||||
|
DEPENDS ${MAP}
|
||||||
|
COMMENT "Converting map ${MAP_NAME}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND COMPILED_BINARIES ${OUT_FILE})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_custom_target(compile_maps ALL
|
||||||
|
DEPENDS ${COMPILED_BINARIES}
|
||||||
|
)
|
||||||
BIN
sdk/map/_provinces.bmp
Normal file
BIN
sdk/map/_provinces.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
230
sdk/map/convert_map.cpp
Normal file
230
sdk/map/convert_map.cpp
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <queue>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#define bytes(value) reinterpret_cast<const char*>(value)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct BMPFileHeader {
|
||||||
|
uint16_t bfType;
|
||||||
|
uint32_t bfSize;
|
||||||
|
uint16_t bfReserved1;
|
||||||
|
uint16_t bfReserved2;
|
||||||
|
uint32_t bfOffBits;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BMPInfoHeader {
|
||||||
|
uint32_t biSize;
|
||||||
|
int32_t biWidth;
|
||||||
|
int32_t biHeight;
|
||||||
|
uint16_t biPlanes;
|
||||||
|
uint16_t biBitCount;
|
||||||
|
uint32_t biCompression;
|
||||||
|
uint32_t biSizeImage;
|
||||||
|
int32_t biXPelsPerMeter;
|
||||||
|
int32_t biYPelsPerMeter;
|
||||||
|
uint32_t biClrUsed;
|
||||||
|
uint32_t biClrImportant;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BGR { uint8_t b,g,r; };
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct vertex { float x,y; };
|
||||||
|
|
||||||
|
struct BGRHash {
|
||||||
|
size_t operator()(const BGR& c) const noexcept {
|
||||||
|
return (c.r<<16)|(c.g<<8)|c.b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const BGR&a,const BGR&b){
|
||||||
|
return a.r==b.r && a.g==b.g && a.b==b.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
BGR EMPTY_COLOR{255,255,255};
|
||||||
|
|
||||||
|
uint8_t* imageData;
|
||||||
|
uint8_t* tempImageData;
|
||||||
|
size_t width,height,rowSize;
|
||||||
|
|
||||||
|
std::unordered_map<BGR,std::vector<std::vector<size_t>>,BGRHash>
|
||||||
|
pixelsPerProvincesPerState;
|
||||||
|
|
||||||
|
inline BGR getPixelSafe(size_t r,size_t c){
|
||||||
|
if(r>=height||c>=width) return EMPTY_COLOR;
|
||||||
|
return *reinterpret_cast<BGR*>(
|
||||||
|
imageData + r*rowSize + c*3
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BGR getPixelSafeIndex(size_t i){
|
||||||
|
return getPixelSafe(i/width,i%width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================= FLOOD FILL ================= */
|
||||||
|
|
||||||
|
void FloodFill(){
|
||||||
|
size_t size=width*height;
|
||||||
|
for(size_t i=0;i<size;i++){
|
||||||
|
if(*reinterpret_cast<BGR*>(tempImageData + (i/width)*rowSize + (i%width)*3)==EMPTY_COLOR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BGR color=*reinterpret_cast<BGR*>(tempImageData + (i/width)*rowSize + (i%width)*3);
|
||||||
|
std::vector<size_t> prov;
|
||||||
|
std::queue<size_t> q;
|
||||||
|
q.push(i);
|
||||||
|
|
||||||
|
while(!q.empty()){
|
||||||
|
size_t n=q.front(); q.pop();
|
||||||
|
BGR& px=*reinterpret_cast<BGR*>(tempImageData + (n/width)*rowSize + (n%width)*3);
|
||||||
|
if(px!=color) continue;
|
||||||
|
px=EMPTY_COLOR;
|
||||||
|
prov.push_back(n);
|
||||||
|
|
||||||
|
if(n>=width) q.push(n-width);
|
||||||
|
if(n+width<size) q.push(n+width);
|
||||||
|
if(n%width) q.push(n-1);
|
||||||
|
if(n%width+1<width) q.push(n+1);
|
||||||
|
}
|
||||||
|
pixelsPerProvincesPerState[color].push_back(prov);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================= MOORE ================= */
|
||||||
|
|
||||||
|
struct offset{int8_t x,y;};
|
||||||
|
|
||||||
|
static const offset moore[8]={
|
||||||
|
{1,0},{1,-1},{0,-1},{-1,-1},
|
||||||
|
{-1,0},{-1,1},{0,1},{1,1}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool MooreStep(size_t cur,size_t prev,BGR id,size_t& next){
|
||||||
|
int cr=cur/width, cc=cur%width;
|
||||||
|
int pr=prev/width,pc=prev%width;
|
||||||
|
|
||||||
|
int dx=cc-pc, dy=cr-pr;
|
||||||
|
int startDir=0;
|
||||||
|
for(int i=0;i<8;i++)
|
||||||
|
if(moore[i].x==dx&&moore[i].y==dy)
|
||||||
|
startDir=(i+6)&7;
|
||||||
|
|
||||||
|
for(int k=0;k<8;k++){
|
||||||
|
int d=(startDir+k)&7;
|
||||||
|
int nr=cr+moore[d].y;
|
||||||
|
int nc=cc+moore[d].x;
|
||||||
|
if(getPixelSafe(nr,nc)==id){
|
||||||
|
next=size_t(nr)*width+size_t(nc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================= FIND CONTOUR ================= */
|
||||||
|
|
||||||
|
size_t FindStart(const std::vector<size_t>&prov,BGR id){
|
||||||
|
for(size_t i:prov){
|
||||||
|
size_t r=i/width,c=i%width;
|
||||||
|
if(getPixelSafe(r-1,c)!=id||
|
||||||
|
getPixelSafe(r+1,c)!=id||
|
||||||
|
getPixelSafe(r,c-1)!=id||
|
||||||
|
getPixelSafe(r,c+1)!=id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return std::numeric_limits<size_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
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(start==std::numeric_limits<size_t>::max()) continue;
|
||||||
|
|
||||||
|
std::vector<size_t> contour;
|
||||||
|
contour.push_back(start);
|
||||||
|
|
||||||
|
size_t cur=start;
|
||||||
|
size_t prev = (start % width > 0) ? start - 1 : start + 1;
|
||||||
|
|
||||||
|
|
||||||
|
const size_t MAX=prov.size()*8;
|
||||||
|
for(size_t i=0;i<MAX;i++){
|
||||||
|
size_t next;
|
||||||
|
if(!MooreStep(cur,prev,id,next)) break;
|
||||||
|
if(next==start) break;
|
||||||
|
contour.push_back(next);
|
||||||
|
prev=cur;
|
||||||
|
cur=next;
|
||||||
|
}
|
||||||
|
prov.swap(contour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================= STUBS ================= */
|
||||||
|
|
||||||
|
void Aproximate(size_t){}
|
||||||
|
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)};
|
||||||
|
out.write(bytes(&v),sizeof(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================= MAIN ================= */
|
||||||
|
|
||||||
|
int main(int argc,char**argv){
|
||||||
|
std::ifstream fin(argv[1],std::ios::binary);
|
||||||
|
std::ofstream fout(argv[2],std::ios::binary);
|
||||||
|
|
||||||
|
BMPFileHeader fh;
|
||||||
|
BMPInfoHeader ih;
|
||||||
|
fin.read((char*)&fh,sizeof(fh));
|
||||||
|
fin.read((char*)&ih,sizeof(ih));
|
||||||
|
|
||||||
|
width=ih.biWidth;
|
||||||
|
height=ih.biHeight;
|
||||||
|
rowSize=(width*3+3)&~3;
|
||||||
|
|
||||||
|
std::vector<uint8_t> img(rowSize*height);
|
||||||
|
std::vector<uint8_t> tmp(rowSize*height);
|
||||||
|
|
||||||
|
fin.seekg(fh.bfOffBits);
|
||||||
|
fin.read((char*)img.data(),img.size());
|
||||||
|
fin.seekg(fh.bfOffBits);
|
||||||
|
fin.read((char*)tmp.data(),tmp.size());
|
||||||
|
|
||||||
|
imageData=img.data();
|
||||||
|
tempImageData=tmp.data();
|
||||||
|
|
||||||
|
FloodFill();
|
||||||
|
FindContour();
|
||||||
|
Aproximate(0);
|
||||||
|
Triangulate();
|
||||||
|
GenVertices(fout);
|
||||||
|
}
|
||||||
BIN
sdk/map/provinces.bmp
Normal file
BIN
sdk/map/provinces.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 MiB |
BIN
sdk/map/provinces.map
Normal file
BIN
sdk/map/provinces.map
Normal file
Binary file not shown.
@ -41,6 +41,6 @@ foreach(MAT ${MATERIAL_FILES})
|
|||||||
list(APPEND COMPILED_BINARIES ${OUT_FILE})
|
list(APPEND COMPILED_BINARIES ${OUT_FILE})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
add_custom_target(compile_assets ALL
|
add_custom_target(compile_material_assets ALL
|
||||||
DEPENDS ${COMPILED_BINARIES}
|
DEPENDS ${COMPILED_BINARIES}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
|
||||||
AssetMaterial,
|
AssetVulkanMaterial,
|
||||||
vertexShaderAssetID,
|
vertexShaderAssetID,
|
||||||
fragmentShaderAssetID,
|
fragmentShaderAssetID,
|
||||||
renderType,
|
renderType,
|
||||||
@ -51,7 +51,7 @@ int main(int argc, char **argv)
|
|||||||
data[key] = assetId;
|
data[key] = assetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetMaterial material = data.get<AssetMaterial>();
|
AssetVulkanMaterial material = data.get<AssetVulkanMaterial>();
|
||||||
fout.write(reinterpret_cast<const char*>(&material), sizeof(material));
|
fout.write(reinterpret_cast<const char*>(&material), sizeof(material));
|
||||||
|
|
||||||
fin.close();
|
fin.close();
|
||||||
@ -60,6 +60,7 @@ int main(int argc, char **argv)
|
|||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user