虚幻地形高度图生成及测试

devtools/2024/10/17 18:05:48/

虚幻地形高度图生成及测试

虚幻引擎地形系统将高度数据存储在高度图中,这是一个灰阶图像,使用黑白色值来存储地貌高程。在高度图中,纯黑色值表示最低点,纯白色值表示最高点。支持16位灰阶PNG、8位灰阶r8及16位灰阶r16格式。

本文测试使用开源的opencvcgal库将地形网格体采样插值生成栅格,并写入到16位灰阶PNG图片中,结果可支持导入虚幻UE Landscape

示例代码

#include<iostream>
#include<cmath>#include<CGAL/Surface_mesh.h>
#include<CGAL/Surface_mesh/IO/PLY.h>#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Projection_traits_xy_3.h>
#include <CGAL/Delaunay_triangulation_2.h>#include <CGAL/Polygon_mesh_processing/locate.h>#include <opencv2/opencv.hpp>using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Projection_traits = CGAL::Projection_traits_xy_3<Kernel>;
using Point_2 = Kernel::Point_2;
using Point_3 = Kernel::Point_3;// Triangulated Irregular Network
using TIN = CGAL::Delaunay_triangulation_2<Projection_traits>;
using Mesh = CGAL::Surface_mesh<Point_3>;int main(){Mesh mesh;CGAL::IO::read_PLY("test.ply",mesh);CGAL::Bbox_3 bbox = CGAL::bbox_3(mesh.points().begin(), mesh.points().end());std::cout << "with:" << bbox.x_span() << "\nheight:" << bbox.y_span() << std::endl;int width = std::ceil(bbox.x_span());int height = std::ceil(bbox.y_span());width = std::max(width, height);height = width;// 特殊处理,虚幻地形表示的范围为512单位 (可略)//  int max_multiple = std::ceil(bbox.zmax() / 512);//  int min_multiple = std::ceil(std::abs(bbox.zmin()) / 512);//  min_multiple = bbox.zmin() < 0 ? min_multiple : 0;int maxHeight = max_multiple * 512;int minHeight = min_multiple * 512;int maxGray = (1 << 16) - 1;//65535 cv::Mat image(height, width, CV_16UC1);TIN tin (mesh.points().begin(), mesh.points().end());TIN::Face_handle location;for (std::size_t y = 0; y < height; ++y)for (std::size_t x = 0; x < width; ++x){Point_3 query(bbox.xmin() + x * (bbox.xmax() - bbox.xmin()) / double(width),bbox.ymin() + (height - y) * (bbox.ymax() - bbox.ymin()) / double(height),0); // not relevant for location in 2Dlocation = tin.locate(query, location);// Points outside the convex hull will be colored blackif (!tin.is_infinite(location)){std::array<double, 3> barycentric_coordinates= CGAL::Polygon_mesh_processing::barycentric_coordinates(Point_2(location->vertex(0)->point().x(), location->vertex(0)->point().y()),Point_2(location->vertex(1)->point().x(), location->vertex(1)->point().y()),Point_2(location->vertex(2)->point().x(), location->vertex(2)->point().y()),Point_2(query.x(), query.y()),Kernel());double height_at_query= (barycentric_coordinates[0] * location->vertex(0)->point().z()+ barycentric_coordinates[1] * location->vertex(1)->point().z()+ barycentric_coordinates[2] * location->vertex(2)->point().z());// 重新映射高度值到0~65535double height_ratio = (height_at_query + minHeight) / (maxHeight+minHeight);image.at<uint16_t>(y,x)=(uint16_t)(height_ratio* maxGray);}else {image.at<uint16_t>(y, x) = (uint16_t)0;}}cv::imwrite("output.png", image);return 0;
}

测试运行

cmake_minimum_required(VERSION 3.1...3.23)
project(main)
# cgal
find_package(CGAL REQUIRED)
# opencv 
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )create_single_source_cgal_program("main.cpp")
target_link_libraries(main PRIVATE ${OpenCV_LIBS})

编译&构建
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake
cmake --build build --config Debug

结果

测试地形网格
在这里插入图片描述

生成的灰度图
在这里插入图片描述

导入虚幻Landscape
在这里插入图片描述

参考

  1. https://dev.epicgames.com/documentation/zh-cn/unreal-engine/importing-and-exporting-landscape-heightmaps-in-unreal-engine
  2. https://blog.csdn.net/mrbaolong/article/details/141643001?spm=1001.2014.3001.5501

http://www.ppmy.cn/devtools/107870.html

相关文章

行为型设计模式-解释器(interpreter)模式

设计模式汇总&#xff1a;查看 通俗示例 想象一下你正在编写一个简单的计算器程序&#xff0c;用户可以输入类似 “3 4” 或 “5 * 2” 这样的表达式&#xff0c;并且你的程序需要计算出结果。为了解析和计算这些表达式&#xff0c;你可以设计一个解释器&#xff0c;它能够理…

rancher搭建k8s及jenkins自动化部署

1、准备环境 角色IP用途k8s-rancher-master192.168.3.63master节点k8s-rancher-node01192.168.3.64node节点k8s-rancher-node02192.168.3.66node节点k8s-rancher-server192.168.2.33rancher-server节点注: 服务器名需要配置不同,相同服务器名不能加入node节点 在所有节点进行…

macos下的 sed命令安装与使用 gnu-sed

sed命令是我们在linu类系统中非常重要的一个命令, 但是在macos下面默认是没有sed命令的, 不过我们可以通过brew install gnu-sed ( 或者通过 sudo port install gsed )这个软件包来获得这个命令 GNU sed 命令安装 下面2种方式,选择一种安装即可 # brew安装 brew install gn…

记录 PyQt6 / PySide 6 自定义边框窗口的 Bug 及可能可行的解决方案:窗口抖动和添加 DWM 环绕阴影的大致原理

前言&#xff1a; 本篇文章将要讨论我在前不久发表的关于 PyQt6 / PySide6 自定义边框窗口代码及内容中的问题&#xff1a; &#xff08;终&#xff09;PyQt6 / PySide 6 Pywin32 自定义标题栏窗口 完全还原 Windows 原生窗口边框特效_pyside6 win32 无边框窗口-CSDN博客ht…

51单片机-定时器介绍

时间&#xff1a;2024.8.31 作者&#xff1a;Whappy 目的&#xff1a;手撕51 代码&#xff1a; 现象&#xff1a;

在Go中迅速使用RabbitMQ

文章目录 1 认识1.1 MQ分类1.2 安装1.3 基本流程 2 [Work模型](https://www.rabbitmq.com/tutorials/tutorial-two-go#preparation)3 交换机3.1 fanout3.2 direct3.3 [topic](https://www.rabbitmq.com/tutorials/tutorial-five-go) 4 Golang创建交换机/队列/Publish/Consume/B…

开源-基于J2EE分布式架构的会议管理系统,支持会议资源管理,预订会议,冲突检测,提醒与签到

自20世纪末至21世纪初&#xff0c;数字化和互联网技术的迅猛发展彻底改变了工作方式和商业模式。企业迅速采用电子邮件、即时通讯和在线会议等数字工具以提升沟通效率。 在信息爆炸的时代&#xff0c;工作中面临的信息量剧增&#xff0c;而企业对效率和生产力的要求也日益提高…

基于JavaWeb开发的Java+SpringBoot+vue+element实现物流管理系统

基于JavaWeb开发的JavaSpringBootvueelement实现物流管理系统 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定…