ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Arnis 如何把一张地图变成 Minecraft 城市:4 个核心模块

Arnis 如何把一张地图变成 Minecraft 城市:4 个核心模块 Arnis 如何把一张地图变成 Minecraft 城市4 个核心模块【免费下载链接】arnisGenerate any location from the real world in Minecraft with a high level of detail.项目地址: https://gitcode.com/GitHub_Trending/ar/arnis用鼠标在地图上拖一个矩形框住城区里几平方公里的街道与楼宇点下开始生成——几分钟后Minecraft 里就能走进这座复刻城市的街巷。这就是 Arnis 在做的事读取真实世界的地理数据OpenStreetMap 矢量要素 高程数据转换为可游玩的 Minecraft、基岩版乃至 Luanti 世界让地理数据变成 Minecraft 城市与地形的立体生成结果。一条数据流从经纬度到区块文件先看清数据去哪儿了。OSM 与高程数据先被坐标转换层处理src/coordinate_system/把 WGS84 经纬度映射到游戏的 XZ 平面接着src/element_processing/下二十多个模块逐一把建筑、道路、水系、树木翻译成方块布局产出统一写入中间结构WorldToModify再由src/world_editor/按目标版本落盘成 Java 版 Anvil 格式或基岩版.mcworldfloodfill 与确定性随机数等算法则全程托着速度和可复现性。下面按这条流走一圈。两套坐标系家族从经纬度到 XZ 平面球面上的一段经纬度落到游戏的 XZ 平面必须处理非线性变形——小范围近似线性即可大范围则要正经投影。Arnis 把这件事拆成两族类型src/coordinate_system/geographic/llpoint.rs、llbbox.rs表示地理侧的点与边界框cartesian/xzpoint.rs、xzvector.rs、xzbbox/表示游戏侧。transformation.rs里的CoordTransformer用枚举区分两种模式Local线性插值和带本地原点的 Web Mercator 投影EPSG:3857后者与src/projection/web_mercator.rs共用同一个地球半径常数保证投影参数一致。xzbbox 子模块里枚举与矩形结构组合负责边界框的选取与范围计算选区界面就是它的直接出口。边界在于线性模式对超大范围会累积误差所以大区域走投影路径——投影四角后取轴对齐包络得到一个略大于实际区域的 XZ 框。建筑是怎么被程序搭出来的OSM 里一条 way 可能带高度、用途、屋顶等标签怎么变成 Minecraft 的墙与楼板src/element_processing/buildings.rs的做法是轮廓 高度挤出先把建筑 way 的节点转成游戏坐标下的轮廓按 height 属性向 Y 轴挤出墙体与楼板再按BuildingStylePreset里 residential、skyscraper、historic 等预设挑外墙、窗带与屋顶形态——高宽比超过阈值且足够高的楼会走摩天楼分支。道路侧的highways.rs则按中心线 宽度参数铺路面。这个目录的组织方式是一类要素一个文件water_areas.rs、natural.rs、tree.rs、bridges.rs各自独立。新增要素类型时不需要动现有代码加一个模块、挂进处理链即可。细节上能看出踩坑痕迹mod.rs里的merge_way_segments负责把被裁剪的 way 段拼回闭合环注释说明旧实现用Vecusize做标记导致环拼接近似三次方复杂度改成布尔标记后降到常数额外开销——bbox 裁剪产生的合成节点还要按邻近距离兜底匹配。一份中间形态三种世界的落盘同一座城要写成三种格式Java 版 Anvil、基岩版.mcworld、Luanti。src/world_editor/common.rs定义的WorldToModify是统一中间形态所有要素处理结果先落在这里java.rs与bedrock.rs各自负责格式转换与写入luanti.rs处理 Minetest 映射其方块名表来自 MC2MT 项目的 LGPL 代码。方块 ID 的版本差异由bedrock_block_map.rs、luanti_block_map.rs这类映射表消化保证视觉一致。这里有个容易忽略的工程点写入是分区region流式进行的配合progress.rs的细粒度进度上报保存失败时is_disk_full_error会沿错误链下钻识别 Windows 112 / Unix 28 /StorageFull三种盘满信号给用户一个可读提示而不是抛裸异常。分块、位图、确定性随机性能三板斧地理要素填充是典型的面积敏感操作src/floodfill.rs给了两套自动切换的算法小区域用位图 flood fill——FloodBitmap每个坐标只占 1 bit5000×5000 的区域约 3MB而HashSet方案下同尺寸要 1.2GB 左右区域超过 2500 万格时自动切到扫描线填充代价变成行数 × 边数而非面积适合细长发散形状。另一处关键设计在deterministic_rng.rs用 OSM 元素 ID 做种子生成ChaCha8Rng同一栋楼不管在哪个区、被处理几遍跨区要素会重复经过随机序列都一致——墙色、屋顶样式不会因为分块顺序不同而抖动。效果与走向上面这张四联预览就是整条流水线的终端产物街区的位置精度来自坐标转换层的投影选择水体与绿地的完整填充来自 floodfill 的位图路径而同一栋楼每次生成长得一样来自确定性随机种子。往后看可以期待几个具体方向用分类模型提升复杂建筑形态与特殊地貌的自动识别把 region 级流式写入扩展为跨机器的分布式生成承接更大范围的城市开放配置文件让用户自定义转换规则比如指定道路等级到路面材质的映射以及对接实时地理数据源让世界在 OSM 更新后能增量重生成。【免费下载链接】arnisGenerate any location from the real world in Minecraft with a high level of detail.项目地址: https://gitcode.com/GitHub_Trending/ar/arnis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进